aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x.classpath30
-rw-r--r--.gitattributes1
-rw-r--r--.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--CONTRIBUTING.md11
-rw-r--r--README.md2
-rw-r--r--build.xml488
-rwxr-xr-xjitsi.eml192
-rw-r--r--jitsi.iml14
-rw-r--r--jitsi.ipr314
-rw-r--r--lib/accounts.properties.template41
-rw-r--r--lib/felix.client.run.properties84
-rw-r--r--lib/felix.jarbin690242 -> 690862 bytes
-rw-r--r--lib/felix.unit.test.properties84
-rw-r--r--lib/installer-exclude/bccontrib-1.0-SNAPSHOT.jarbin40669 -> 0 bytes
-rw-r--r--lib/installer-exclude/bccontrib-1.0.jarbin0 -> 41570 bytes
-rw-r--r--lib/installer-exclude/bcpkix-jdk15on-1.54.jarbin0 -> 673715 bytes
-rwxr-xr-xlib/installer-exclude/bcpkix-jdk15on-151.jarbin605519 -> 0 bytes
-rw-r--r--lib/installer-exclude/bcprov-jdk15on-1.54.jarbin0 -> 3277268 bytes
-rwxr-xr-xlib/installer-exclude/bcprov-jdk15on-151.jarbin2842667 -> 0 bytes
-rwxr-xr-xlib/installer-exclude/dict4j.jarbin10805 -> 0 bytes
-rw-r--r--lib/installer-exclude/dnsjava-2.1.7.jar (renamed from lib/installer-exclude/dnsjava.jar)bin308076 -> 310044 bytes
-rw-r--r--lib/installer-exclude/dnssecjava-1.1.jarbin0 -> 53599 bytes
-rw-r--r--lib/installer-exclude/fmj-1.0-SNAPSHOT.jarbin1138198 -> 1138875 bytes
-rw-r--r--lib/installer-exclude/httpclient.manifest.mf41
-rw-r--r--lib/installer-exclude/ice4j-2.0-20170111.193659-7.jarbin0 -> 500574 bytes
-rw-r--r--lib/installer-exclude/ice4j.jarbin427749 -> 0 bytes
-rw-r--r--lib/installer-exclude/jain-sdp.jarbin151866 -> 0 bytes
-rw-r--r--lib/installer-exclude/jain-sip-api.jarbin53813 -> 0 bytes
-rw-r--r--lib/installer-exclude/jain-sip-ri-ossonly-1.2.279-jitsi-oss1.jarbin0 -> 1029073 bytes
-rw-r--r--lib/installer-exclude/jain-sip-ri.jarbin750829 -> 0 bytes
-rw-r--r--lib/installer-exclude/java-sdp-nist-bridge-1.2.jarbin0 -> 8302 bytes
-rw-r--r--lib/installer-exclude/jcommon-1.0.0.jarbin294514 -> 0 bytes
-rw-r--r--lib/installer-exclude/jdom.jarbin153253 -> 0 bytes
-rw-r--r--lib/installer-exclude/jfontchooser-1.0.5.jarbin16703 -> 0 bytes
-rw-r--r--lib/installer-exclude/jfontchooser.manifest.mf10
-rw-r--r--lib/installer-exclude/jfreechart-1.0.1.jarbin1075691 -> 0 bytes
-rw-r--r--lib/installer-exclude/jitsi-gpl-dependencies-1.0-SNAPSHOT.jarbin0 -> 7862639 bytes
-rw-r--r--lib/installer-exclude/jitsi-lgpl-dependencies-1.0-SNAPSHOT.jarbin7902830 -> 46467 bytes
-rw-r--r--lib/installer-exclude/jmork-1.0.5-SNAPSHOT.jarbin44218 -> 0 bytes
-rw-r--r--lib/installer-exclude/jmork-1.0.5.jarbin0 -> 45171 bytes
-rw-r--r--lib/installer-exclude/jna.manifest.mf12
-rw-r--r--lib/installer-exclude/jsch-0.1.36.jarbin177603 -> 0 bytes
-rw-r--r--lib/installer-exclude/libjitsi-1.0-20170207.194207-242.jar (renamed from lib/installer-exclude/libjitsi-1.0-SNAPSHOT.jar)bin7705340 -> 9014770 bytes
-rw-r--r--lib/installer-exclude/p4j-exclusions.txt26
-rw-r--r--lib/installer-exclude/profiler4j-1.0-beta3-SC.jarbin603634 -> 0 bytes
-rw-r--r--lib/installer-exclude/sdp-api-1.0.jarbin0 -> 16131 bytes
-rw-r--r--lib/installer-exclude/sip-api-1.2-1.2.jarbin0 -> 58898 bytes
-rw-r--r--lib/installer-exclude/smack.jarbin326629 -> 413550 bytes
-rw-r--r--lib/installer-exclude/smackx-debug.jarbin56389 -> 56538 bytes
-rw-r--r--lib/installer-exclude/smackx.jarbin669340 -> 662514 bytes
-rw-r--r--lib/installer-exclude/swing-worker-1.2.jarbin12852 -> 0 bytes
-rw-r--r--lib/installer-exclude/weupnp-0.1.2-SNAPSHOT.jarbin11516 -> 0 bytes
-rw-r--r--lib/installer-exclude/weupnp-0.1.4.jarbin0 -> 29645 bytes
-rwxr-xr-xlib/installer-exclude/xalan-2.6.0.jar.antbin2633763 -> 0 bytes
-rw-r--r--lib/installer-exclude/ymsg_network_v0_67.jarbin142376 -> 0 bytes
-rw-r--r--lib/installer-exclude/zrtp4j-light-4.1.0-jitsi-1-SNAPSHOT.jarbin0 -> 214756 bytes
-rw-r--r--lib/installer-exclude/zrtp4j-light.jarbin189342 -> 0 bytes
-rw-r--r--lib/jitsi-defaults.properties5
-rw-r--r--lib/native/linux-64/libjunbound.sobin794320 -> 0 bytes
-rw-r--r--lib/native/linux/libjunbound.sobin785008 -> 0 bytes
-rw-r--r--lib/native/mac/libjunbound.jnilibbin1827792 -> 0 bytes
-rw-r--r--lib/native/solaris/libCvidPro.sobin157720 -> 0 bytes
-rw-r--r--lib/native/solaris/soundbank.gmbin1154250 -> 0 bytes
-rwxr-xr-xlib/native/windows-64/jmsofficecomm.dllbin300798 -> 333066 bytes
-rwxr-xr-xlib/native/windows-64/jmsoutlookaddrbook.dllbin302107 -> 244564 bytes
-rwxr-xr-xlib/native/windows-64/jmsoutlookaddrbookcomserver32.exebin249432 -> 246848 bytes
-rwxr-xr-xlib/native/windows-64/jmsoutlookaddrbookcomserver64.exebin308098 -> 252108 bytes
-rw-r--r--lib/native/windows-64/junbound.dllbin1856000 -> 0 bytes
-rw-r--r--lib/native/windows/IeEmbed.exebin61440 -> 0 bytes
-rwxr-xr-xlib/native/windows/jmsofficecomm.dllbin293227 -> 325497 bytes
-rwxr-xr-xlib/native/windows/jmsoutlookaddrbook.dllbin242469 -> 239403 bytes
-rwxr-xr-xlib/native/windows/jmsoutlookaddrbookcomserver32.exebin249432 -> 246848 bytes
-rwxr-xr-xlib/native/windows/jmsoutlookaddrbookcomserver64.exebin308098 -> 252108 bytes
-rw-r--r--lib/native/windows/junbound.dllbin1850382 -> 0 bytes
-rw-r--r--lib/testing.properties4
-rw-r--r--m2/jitsi-argdelegation/pom.xml57
-rw-r--r--m2/jitsi-certificate/pom.xml73
-rw-r--r--m2/jitsi-desktoputil/pom.xml57
-rw-r--r--m2/jitsi-dns/pom.xml61
-rw-r--r--m2/jitsi-globaldisplaydetails/pom.xml54
-rw-r--r--m2/jitsi-hid/pom.xml51
-rw-r--r--m2/jitsi-muc/pom.xml52
-rw-r--r--m2/jitsi-neomedia/pom.xml52
-rw-r--r--m2/jitsi-notification-service/pom.xml52
-rw-r--r--m2/jitsi-packetlogging/pom.xml8
-rw-r--r--m2/jitsi-protocol-sip/pom.xml92
-rw-r--r--m2/jitsi-protocol/pom.xml4
-rw-r--r--m2/jitsi-reconnect/pom.xml52
-rw-r--r--m2/jitsi-sysactivity/pom.xml128
-rw-r--r--m2/jitsi-systray-service/pom.xml52
-rw-r--r--m2/jitsi-util/pom.xml18
-rw-r--r--m2/jitsi-version/pom.xml57
-rw-r--r--m2/pom.xml32
-rw-r--r--nbproject/project.xml2
-rw-r--r--resources/config/defaults.properties5
-rw-r--r--resources/config/spellcheck/parameters.xml1
-rw-r--r--resources/images/images.properties49
-rw-r--r--resources/images/impl/systray/envelope.pngbin756 -> 0 bytes
-rw-r--r--resources/images/impl/systray/envelopeMacOSX.pngbin565 -> 0 bytes
-rw-r--r--resources/images/impl/systray/envelopeMacOSXWhite.pngbin554 -> 0 bytes
-rw-r--r--resources/images/impl/systray/envelopeWindows.pngbin1431 -> 0 bytes
-rw-r--r--resources/images/plugin/branding/splashScreenBackground.pngbin56561 -> 0 bytes
-rwxr-xr-xresources/images/protocol/dict/dict-16x16-offline.pngbin687 -> 0 bytes
-rw-r--r--resources/images/protocol/dict/dict-16x16.pngbin739 -> 0 bytes
-rw-r--r--resources/images/protocol/dict/dict-32x32.pngbin1663 -> 0 bytes
-rw-r--r--resources/images/protocol/dict/dict-48x48.pngbin3071 -> 0 bytes
-rw-r--r--resources/images/protocol/dict/dict-64x64.pngbin4367 -> 0 bytes
-rw-r--r--resources/images/protocol/facebook/facebook-online.pngbin537 -> 0 bytes
-rw-r--r--resources/images/protocol/facebook/facebook48.pngbin1521 -> 0 bytes
-rw-r--r--resources/images/protocol/facebook/logo32x32.pngbin1500 -> 0 bytes
-rw-r--r--resources/images/protocol/facebook/logo48x48.pngbin2155 -> 0 bytes
-rw-r--r--resources/images/protocol/facebook/logo64x64.pngbin2507 -> 0 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-away.pngbin786 -> 0 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-connecting.gifbin522 -> 0 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-connecting.pngbin694 -> 0 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-dnd.pngbin773 -> 0 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-ffc.pngbin871 -> 0 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-invisible.pngbin787 -> 0 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-meeting.pngbin1829 -> 0 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-offline.pngbin490 -> 0 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-online.pngbin537 -> 0 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-phone.pngbin816 -> 0 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-xa.pngbin756 -> 0 bytes
-rw-r--r--resources/images/protocol/sip2sip/sip16x16-away.pngbin2081 -> 0 bytes
-rw-r--r--resources/images/protocol/sip2sip/sip16x16-busy.pngbin2041 -> 0 bytes
-rw-r--r--resources/images/protocol/sip2sip/sip16x16-meeting.pngbin2101 -> 0 bytes
-rw-r--r--resources/images/protocol/sip2sip/sip16x16-offline.pngbin1775 -> 0 bytes
-rw-r--r--resources/images/protocol/sip2sip/sip16x16-online.pngbin1859 -> 0 bytes
-rw-r--r--resources/images/protocol/sip2sip/sip16x16-phone.pngbin2075 -> 0 bytes
-rw-r--r--resources/images/protocol/sip2sip/sip16x16.pngbin1859 -> 0 bytes
-rw-r--r--resources/images/protocol/sip2sip/sip32x32.pngbin2494 -> 0 bytes
-rw-r--r--resources/images/protocol/sip2sip/sip48x48.pngbin4545 -> 0 bytes
-rw-r--r--resources/images/protocol/sip2sip/sip64x64.pngbin6662 -> 0 bytes
-rw-r--r--resources/images/protocol/ssh/ssh-connected.pngbin1703 -> 0 bytes
-rw-r--r--resources/images/protocol/ssh/ssh-connecting.pngbin1657 -> 0 bytes
-rw-r--r--resources/images/protocol/ssh/ssh-filetransfer.pngbin1725 -> 0 bytes
-rw-r--r--resources/images/protocol/ssh/ssh-na.pngbin1719 -> 0 bytes
-rw-r--r--resources/images/protocol/ssh/ssh-offline.pngbin1309 -> 0 bytes
-rw-r--r--resources/images/protocol/ssh/ssh-online.pngbin1391 -> 0 bytes
-rw-r--r--resources/images/protocol/ssh/ssh32x32.pngbin1730 -> 0 bytes
-rw-r--r--resources/images/protocol/ssh/ssh48x48.pngbin3126 -> 0 bytes
-rw-r--r--resources/images/protocol/ssh/ssh64x64.pngbin4327 -> 0 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-away.pngbin728 -> 0 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-busy.pngbin721 -> 0 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-connecting.gifbin6152 -> 0 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-connecting.pngbin639 -> 0 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-idle.pngbin681 -> 0 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-invisible.pngbin742 -> 0 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-lunch.pngbin683 -> 0 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-na.pngbin697 -> 0 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-offline.pngbin459 -> 0 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-online.pngbin495 -> 0 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-phone.pngbin766 -> 0 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-vacation.pngbin699 -> 0 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16.pngbin495 -> 0 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo32x32.pngbin946 -> 0 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo48x48.pngbin1338 -> 0 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo64x64.pngbin1758 -> 0 bytes
-rw-r--r--resources/images/protocol/zeroconf/zeroconf-away.pngbin1962 -> 0 bytes
-rw-r--r--resources/images/protocol/zeroconf/zeroconf-dnd.pngbin1933 -> 0 bytes
-rw-r--r--resources/images/protocol/zeroconf/zeroconf-invisible.pngbin1967 -> 0 bytes
-rw-r--r--resources/images/protocol/zeroconf/zeroconf-offline.pngbin1673 -> 0 bytes
-rw-r--r--resources/images/protocol/zeroconf/zeroconf-online.pngbin1648 -> 0 bytes
-rw-r--r--resources/images/protocol/zeroconf/zeroconf16x16.pngbin1648 -> 0 bytes
-rw-r--r--resources/images/protocol/zeroconf/zeroconf32x32.pngbin1868 -> 0 bytes
-rw-r--r--resources/images/protocol/zeroconf/zeroconf48x48.pngbin3524 -> 0 bytes
-rw-r--r--resources/images/protocol/zeroconf/zeroconf64x64.pngbin4985 -> 0 bytes
-rw-r--r--resources/install/build.xml150
-rw-r--r--resources/install/debian/README.embedded-libraries10
-rw-r--r--resources/install/debian/control-src.tmpl12
-rw-r--r--resources/install/debian/control.tmpl14
-rw-r--r--resources/install/debian/jitsi.1.tmpl2
-rw-r--r--resources/install/debian/jitsi.sh.tmpl2
-rw-r--r--resources/install/debian/patches/encoding.patch17
-rw-r--r--resources/install/debian/postinst67
-rw-r--r--resources/install/debian/postrm56
-rw-r--r--resources/install/doc/License.rtf526
-rw-r--r--resources/install/doc/License.txt504
-rw-r--r--resources/install/doc/readme.txt6
-rwxr-xr-xresources/install/generic/installer-generic.xml2
-rw-r--r--resources/install/generic/run.sh2
-rw-r--r--resources/install/installers.properties6
-rwxr-xr-xresources/install/linux/installer-linux.xml2
-rwxr-xr-xresources/install/linux/run.sh2
-rw-r--r--resources/install/rpm/Readme.txt6
-rwxr-xr-xresources/install/rpm/SPECS/build-jitsi-rpm.sh11
-rw-r--r--resources/install/rpm/SPECS/jitsi.spec26
-rw-r--r--resources/install/rpm/readme.txt6
-rw-r--r--resources/install/windows/Microsoft.Windows.Build.Signing.mssign32.dll.manifest11
-rw-r--r--resources/install/windows/Microsoft.Windows.Build.Signing.wintrust.dll.manifest11
-rw-r--r--resources/install/windows/SCRegistrySpec.wxi55
-rwxr-xr-xresources/install/windows/makecat.exebin0 -> 34960 bytes
-rw-r--r--resources/install/windows/makecat.exe.manifest21
-rwxr-xr-xresources/install/windows/mssign32.dllbin0 -> 73872 bytes
-rwxr-xr-xresources/install/windows/signtool.exebin237392 -> 299664 bytes
-rw-r--r--resources/install/windows/signtool.exe.manifest26
-rwxr-xr-xresources/install/windows/wintrust.dllbin0 -> 220816 bytes
-rw-r--r--resources/languages/resources.properties232
-rw-r--r--resources/languages/resources_ar.properties224
-rw-r--r--resources/languages/resources_ast.properties219
-rw-r--r--resources/languages/resources_bg.properties207
-rw-r--r--resources/languages/resources_cs.properties231
-rw-r--r--resources/languages/resources_de.properties235
-rw-r--r--resources/languages/resources_el.properties216
-rw-r--r--resources/languages/resources_es.properties239
-rw-r--r--resources/languages/resources_fi.properties123
-rw-r--r--resources/languages/resources_fr.properties239
-rw-r--r--resources/languages/resources_ga.properties89
-rw-r--r--resources/languages/resources_gd.properties213
-rw-r--r--resources/languages/resources_he.properties165
-rw-r--r--resources/languages/resources_hi.properties68
-rw-r--r--resources/languages/resources_hr.properties66
-rw-r--r--resources/languages/resources_hu.properties297
-rw-r--r--resources/languages/resources_id.properties183
-rw-r--r--resources/languages/resources_it.properties243
-rw-r--r--resources/languages/resources_ja.properties743
-rw-r--r--resources/languages/resources_lt.properties88
-rw-r--r--resources/languages/resources_lv.properties72
-rw-r--r--resources/languages/resources_mk.properties51
-rw-r--r--resources/languages/resources_nl.properties216
-rw-r--r--resources/languages/resources_pl.properties250
-rw-r--r--resources/languages/resources_pt.properties195
-rw-r--r--resources/languages/resources_pt_BR.properties774
-rw-r--r--resources/languages/resources_ro.properties206
-rw-r--r--resources/languages/resources_ru.properties505
-rw-r--r--resources/languages/resources_si.properties189
-rw-r--r--resources/languages/resources_sk.properties122
-rw-r--r--resources/languages/resources_sl.properties486
-rw-r--r--resources/languages/resources_sq.properties86
-rw-r--r--resources/languages/resources_sr.properties210
-rw-r--r--resources/languages/resources_sv.properties219
-rw-r--r--resources/languages/resources_tr.properties306
-rw-r--r--resources/languages/resources_uk.properties220
-rw-r--r--resources/languages/resources_zh_CN.properties469
-rw-r--r--resources/languages/resources_zh_TW.properties1557
-rw-r--r--src/native/addrbook/msoutlook/MAPIBitness.cxx4
-rw-r--r--src/native/build.xml45
-rw-r--r--src/native/libjunbound/Makefile.am2
-rw-r--r--src/native/libjunbound/configure.ac69
-rw-r--r--src/native/libjunbound/make-linux.sh35
-rw-r--r--src/native/libjunbound/make-mac.sh76
-rw-r--r--src/native/libjunbound/makefile.linux16
-rw-r--r--src/native/libjunbound/makefile.w3225
-rw-r--r--src/native/libjunbound/makefile.w6426
-rw-r--r--src/native/libjunbound/readme.txt40
-rw-r--r--src/native/libjunbound/src/Makefile.am3
-rw-r--r--src/native/libjunbound/src/net_java_sip_communicator_impl_dns_UnboundApi.cpp284
-rw-r--r--src/native/libjunbound/src/net_java_sip_communicator_impl_dns_UnboundApi.h94
-rw-r--r--src/native/libjunbound/src/net_java_sip_communicator_impl_dns_UnboundApi_UnboundCallback.h13
-rw-r--r--src/native/libjunbound/unbound.patch54
-rw-r--r--src/native/libjunbound/windows32/libcrypto.abin2674964 -> 0 bytes
-rw-r--r--src/native/libjunbound/windows32/libldns.abin1148054 -> 0 bytes
-rw-r--r--src/native/libjunbound/windows32/libunbound.abin2184240 -> 0 bytes
-rw-r--r--src/native/libjunbound/windows32/unbound.h534
-rw-r--r--src/native/libjunbound/windows64/libcrypto.abin2891370 -> 0 bytes
-rw-r--r--src/native/libjunbound/windows64/libldns.abin1470734 -> 0 bytes
-rw-r--r--src/native/libjunbound/windows64/libunbound.abin6585198 -> 0 bytes
-rw-r--r--src/native/libjunbound/windows64/unbound.h534
-rw-r--r--src/native/windows/msofficecomm/OutOfProcessServer.cxx149
-rw-r--r--src/native/windows/msofficecomm/msofficecomm.vcxproj2
-rw-r--r--src/native/windows/run/run.c1
-rw-r--r--src/net/java/sip/communicator/impl/certificate/CertificateServiceImpl.java56
-rw-r--r--src/net/java/sip/communicator/impl/configuration/ConfigurationActivator.java69
-rw-r--r--src/net/java/sip/communicator/impl/configuration/JdbcConfigService.java29
-rw-r--r--src/net/java/sip/communicator/impl/dns/ConfigurableDnssecResolver.java832
-rw-r--r--src/net/java/sip/communicator/impl/dns/DnsUtilActivator.java2
-rw-r--r--src/net/java/sip/communicator/impl/dns/SecureMessage.java183
-rw-r--r--src/net/java/sip/communicator/impl/dns/SecureResolveMode.java76
-rw-r--r--src/net/java/sip/communicator/impl/dns/UnboundApi.java239
-rw-r--r--src/net/java/sip/communicator/impl/dns/UnboundResolver.java410
-rw-r--r--src/net/java/sip/communicator/impl/dns/UnboundResult.java128
-rw-r--r--src/net/java/sip/communicator/impl/dns/dns.manifest.mf2
-rw-r--r--src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsEntryImpl.java18
-rw-r--r--src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsQuery.java13
-rw-r--r--src/net/java/sip/communicator/impl/gui/UIServiceImpl.java83
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/MainFrame.java52
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/UINotification.java8
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/UINotificationGroup.java5
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/UINotificationListener.java7
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/UINotificationManager.java19
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/account/AccountsConfigurationPanel.java552
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/CallDialog.java1234
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java8
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/CallInfoFrame.java24
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/CallTransferHandler.java548
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/FullScreenLayout.java348
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/PreCallDialog.java6
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/SecurityPanel.java230
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/TransferCallDialog.java276
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java1136
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/conference/VideoConferenceCallPanel.java2786
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java7
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/ChatSessionChangeListener.java60
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatContactListModel.java466
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java2776
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/filetransfer/ReceiveFileConversationComponent.java4
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/toolBars/MainToolBar.java13
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomTableDialog.java13
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chatroomslist/ServerChatRoomsChoiceDialog.java190
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/AddContactDialog.java109
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/ContactInfoDialog.java131
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java2
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/PresenceFilter.java702
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFilter.java5
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java4
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/SourceUIContact.java4
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/menus/MacOSXPreferencesRegistration.java56
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/menus/MacOSXQuitRegistration.java132
-rw-r--r--src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf2
-rw-r--r--src/net/java/sip/communicator/impl/gui/utils/PluginContainer.java632
-rw-r--r--src/net/java/sip/communicator/impl/hid/HIDServiceImpl.java442
-rw-r--r--src/net/java/sip/communicator/impl/ldap/LdapPersonFoundImpl.java6
-rw-r--r--src/net/java/sip/communicator/impl/ldap/LdapSSLSocketFactoryDelegate.java146
-rw-r--r--src/net/java/sip/communicator/impl/muc/BaseChatRoomSourceContact.java278
-rw-r--r--src/net/java/sip/communicator/impl/muc/ChatRoomQuery.java1080
-rw-r--r--src/net/java/sip/communicator/impl/muc/ChatRoomSourceContact.java222
-rw-r--r--src/net/java/sip/communicator/impl/muc/MUCCustomContactActionService.java1686
-rw-r--r--src/net/java/sip/communicator/impl/muc/MUCServiceImpl.java2230
-rw-r--r--src/net/java/sip/communicator/impl/muc/ServerChatRoomQuery.java658
-rw-r--r--src/net/java/sip/communicator/impl/neomedia/AbstractDeviceConfigurationListener.java3
-rw-r--r--src/net/java/sip/communicator/impl/neomedia/AudioDeviceConfigurationListener.java18
-rw-r--r--src/net/java/sip/communicator/impl/neomedia/DeviceConfigurationComboBoxModel.java908
-rw-r--r--src/net/java/sip/communicator/impl/neomedia/EncodingConfigurationTableModel.java540
-rw-r--r--src/net/java/sip/communicator/impl/neomedia/MediaConfigurationImpl.java3
-rw-r--r--src/net/java/sip/communicator/impl/neomedia/codec/video/h264/ConfigurationPanel.java3
-rw-r--r--src/net/java/sip/communicator/impl/netaddr/netaddr.manifest.mf15
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/Desktop.java1
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/PopupMessageHandlerTrayIconImpl.java1
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/SystemTray.java215
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/TrayIcon.java412
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/jdic/StatusSubMenu.java15
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/jdic/SystrayServiceJdicImpl.java240
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/jdic/TrayMenuFactory.java27
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/osdependent.manifest.mf20
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/systemtray/SystemTray.java156
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/systemtray/TrayIcon.java (renamed from src/net/java/sip/communicator/impl/dns/UnboundException.java)52
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicator1.java189
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicatorTray.java78
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicatorTrayIcon.java695
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/Gobject.java90
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/Gtk.java68
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/systemtray/awt/AWTMouseAdapter.java124
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/systemtray/awt/AWTSystemTray.java78
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/systemtray/awt/AWTTrayIcon.java131
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/windows/ImageConverter.java172
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/windows/TaskBarList3.java150
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/windows/User32Ex.java47
-rw-r--r--src/net/java/sip/communicator/impl/packetlogging/PacketLoggingConfigurationImpl.java4
-rw-r--r--src/net/java/sip/communicator/impl/packetlogging/PacketLoggingServiceImpl.java64
-rw-r--r--src/net/java/sip/communicator/impl/packetlogging/packetlogging.manifest.mf3
-rw-r--r--src/net/java/sip/communicator/impl/phonenumbers/PhoneNumberI18nServiceImpl.java30
-rw-r--r--src/net/java/sip/communicator/impl/protocol/dict/ContactDictImpl.java343
-rw-r--r--src/net/java/sip/communicator/impl/protocol/dict/ContactGroupDictImpl.java588
-rw-r--r--src/net/java/sip/communicator/impl/protocol/dict/DictAccountID.java70
-rw-r--r--src/net/java/sip/communicator/impl/protocol/dict/DictActivator.java146
-rw-r--r--src/net/java/sip/communicator/impl/protocol/dict/DictStatusEnum.java88
-rw-r--r--src/net/java/sip/communicator/impl/protocol/dict/MessageDictImpl.java46
-rw-r--r--src/net/java/sip/communicator/impl/protocol/dict/OperationSetBasicInstantMessagingDictImpl.java412
-rw-r--r--src/net/java/sip/communicator/impl/protocol/dict/OperationSetPersistentPresenceDictImpl.java988
-rw-r--r--src/net/java/sip/communicator/impl/protocol/dict/ProtocolIconDictImpl.java133
-rw-r--r--src/net/java/sip/communicator/impl/protocol/dict/ProtocolProviderFactoryDictImpl.java200
-rw-r--r--src/net/java/sip/communicator/impl/protocol/dict/ProtocolProviderServiceDictImpl.java364
-rw-r--r--src/net/java/sip/communicator/impl/protocol/dict/dict.provider.manifest.mf15
-rw-r--r--src/net/java/sip/communicator/impl/protocol/gibberish/ContactGroupGibberishImpl.java25
-rw-r--r--src/net/java/sip/communicator/impl/protocol/icq/icq.provider.manifest.mf1
-rw-r--r--src/net/java/sip/communicator/impl/protocol/irc/OperationSetMultiUserChatIrcImpl.java2
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/AnonymousLoginStrategy.java2
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/CallJabberImpl.java2
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/CallPeerJabberImpl.java3287
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java44
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/ChatRoomJabberImpl.java21
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java141
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/InfoRetreiver.java2
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/JabberLoginStrategy.java2
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesCandidate.java4
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesHarvester.java21
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/LoginByClientCertificateStrategy.java2
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/LoginByPasswordStrategy.java2
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/MobileIndicator.java8
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java13
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java7
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/OperationSetContactCapabilitiesJabberImpl.java223
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/OperationSetJitsiMeetToolsJabberImpl.java10
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/OperationSetMultiUserChatJabberImpl.java4
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java17
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java1166
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/OperationSetVideoBridgeImpl.java560
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/OutgoingFileTransferJabberImpl.java2
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderFactoryJabberImpl.java10
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java229
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/RawUdpTransportManager.java1054
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/ScServiceDiscoveryManager.java13
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/SmackV3InteroperabilityLayer.java91
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/TransportManagerJabberImpl.java1922
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/DefaultPacketExtensionProvider.java11
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/EntityCapsManager.java113
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/UserCapsNodeListener.java10
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriBuilder.java629
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriConferenceIQ.java69
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriIQProvider.java131
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriStreamConnector.java144
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ShutdownIQ.java134
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/health/HealthCheckIQ.java (renamed from src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/GracefulShutdownIQ.java)21
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/health/HealthCheckIQProvider.java94
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/JibriIq.java413
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/JibriIqProvider.java112
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/JibriStatusPacketExt.java121
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/RecordingStatus.java126
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/XMPPErrorPE.java93
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/CandidatePacketExtension.java878
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/CryptoPacketExtension.java12
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/IceUdpTransportPacketExtension.java21
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/JingleIQ.java25
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/JingleIQProvider.java196
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/jitsimeet/ComponentVersionsExtension.java135
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/jitsimeet/SSRCInfoPacketExtension.java15
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/extensions/jitsimeet/VideoMutedExtension.java70
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/jinglesdp/JingleUtils.java9
-rw-r--r--src/net/java/sip/communicator/impl/protocol/mock/MockContactGroup.java25
-rw-r--r--src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java9
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/AddressResolverImpl.java12
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandlerSipImpl.java48
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/CallSipImpl.java121
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/ContactGroupSipImpl.java26
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/ContactSipImpl.java43
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/OperationSetBasicTelephonySipImpl.java15
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/OperationSetJitsiMeetToolsSipImpl.java10
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/OperationSetMessageWaitingSipImpl.java4
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/OperationSetPresenceSipImpl.java34
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/OperationSetTelephonyBLFSipImpl.java72
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java182
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/ProxyRouter.java26
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/SipRegistrarConnection.java5
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/SipStackSharing.java3
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/UriHandlerSipImpl.java33
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/net/ManualProxyConnection.java226
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/net/ProxyConnection.java360
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/net/RFC5922Matcher.java418
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/net/SslNetworkLayer.java6
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/sdp/SdpUtils.java31
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf18
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/ContactGroupSSHImpl.java580
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/ContactSSH.java370
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/ContactSSHImpl.java918
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/ContactTimerSSHImpl.java116
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/FileTransferSSHImpl.java96
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/MessageSSHImpl.java63
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/OperationSetBasicInstantMessagingSSHImpl.java312
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/OperationSetFileTransferSSHImpl.java161
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/OperationSetPersistentPresenceSSHImpl.java980
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/ProtocolIconSSHImpl.java159
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/ProtocolProviderFactorySSH.java49
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/ProtocolProviderFactorySSHImpl.java179
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/ProtocolProviderServiceSSHImpl.java662
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/Resources.java53
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/SSHAccountID.java45
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/SSHActivator.java145
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/SSHContactInfo.java352
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/SSHFileTransferDaemon.java468
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/SSHReaderDaemon.java211
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/SSHStatusEnum.java138
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/SSHUserInfo.java164
-rw-r--r--src/net/java/sip/communicator/impl/protocol/ssh/ssh.provider.manifest.mf20
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/AbstractContactGroupYahooImpl.java40
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomInvitationYahooImpl.java90
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomYahooImpl.java581
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/ContactGroupYahooImpl.java445
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/ContactYahooImpl.java397
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/FileTransferImpl.java117
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/IncomingFileTransferRequestYahooImpl.java190
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/MessageYahooImpl.java48
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java714
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetBasicInstantMessagingYahooImpl.java649
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetFileTransferYahooImpl.java466
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetPersistentPresenceYahooImpl.java954
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetTypingNotificationsYahooImpl.java153
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolIconYahooImpl.java173
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderFactoryYahooImpl.java172
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java574
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/RootContactGroupYahooImpl.java280
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/ServerStoredContactListYahooImpl.java1274
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/VolatileContactGroupYahooImpl.java97
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/YahooAccountID.java42
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/YahooActivator.java145
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/YahooSession.java76
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/yahoo.provider.manifest.mf22
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/BonjourService.java706
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/ClientThread.java499
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/ContactGroupZeroconfImpl.java595
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/ContactZeroconfImpl.java468
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/MessageZeroconfImpl.java234
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/OperationSetBasicInstantMessagingZeroconfImpl.java192
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/OperationSetPersistentPresenceZeroconfImpl.java852
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/OperationSetTypingNotificationsZeroconfImpl.java83
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/ProtocolIconZeroconfImpl.java189
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/ProtocolProviderFactoryZeroconfImpl.java120
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/ProtocolProviderServiceZeroconfImpl.java302
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/ZeroconfAccountID.java96
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/ZeroconfActivator.java132
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/ZeroconfStatusEnum.java136
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSCache.java294
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSConstants.java160
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSEntry.java183
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSIncoming.java524
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSListener.java39
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSOutgoing.java405
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSQuestion.java68
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSRecord.java796
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSState.java139
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/HostInfo.java173
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/JmDNS.java3048
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/ServiceEvent.java124
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/ServiceInfo.java785
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/ServiceListener.java57
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/ServiceTypeListener.java37
-rw-r--r--src/net/java/sip/communicator/impl/protocol/zeroconf/zeroconf.provider.manifest.mf12
-rw-r--r--src/net/java/sip/communicator/impl/replacement/directimage/ReplacementServiceDirectImageImpl.java2
-rw-r--r--src/net/java/sip/communicator/impl/resources/ResourceManagementActivator.java20
-rw-r--r--src/net/java/sip/communicator/impl/resources/ResourceManagementServiceImpl.java20
-rw-r--r--src/net/java/sip/communicator/impl/sysactivity/DBusNetworkManager.java262
-rw-r--r--src/net/java/sip/communicator/impl/sysactivity/NetworkManagerListenerImpl.java324
-rw-r--r--src/net/java/sip/communicator/impl/sysactivity/SysActivityActivator.java198
-rw-r--r--src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotifications.java468
-rw-r--r--src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotificationsServiceImpl.java1274
-rw-r--r--src/net/java/sip/communicator/impl/version/VersionImpl.java2
-rw-r--r--src/net/java/sip/communicator/launcher/SIPCommunicator.java2
-rw-r--r--src/net/java/sip/communicator/plugin/accountinfo/AccountInfoActivator.java322
-rw-r--r--src/net/java/sip/communicator/plugin/accountinfo/AccountInfoPanel.java694
-rw-r--r--src/net/java/sip/communicator/plugin/accountinfo/Resources.java126
-rw-r--r--src/net/java/sip/communicator/plugin/addrbook/AdvancedConfigForm.java19
-rw-r--r--src/net/java/sip/communicator/plugin/addrbook/PtrCallback.java42
-rw-r--r--src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactQuery.java10
-rw-r--r--src/net/java/sip/communicator/plugin/addrbook/msoutlook/DefaultMailClientMessageDialog.java184
-rw-r--r--src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookMAPIHResultException.java216
-rw-r--r--src/net/java/sip/communicator/plugin/aimaccregwizz/aimaccregwizz.manifest.mf1
-rw-r--r--src/net/java/sip/communicator/plugin/branding/AboutWindow.java909
-rw-r--r--src/net/java/sip/communicator/plugin/branding/AboutWindowPluginComponent.java174
-rw-r--r--src/net/java/sip/communicator/plugin/branding/BrandingActivator.java138
-rw-r--r--src/net/java/sip/communicator/plugin/branding/Constants.java126
-rw-r--r--src/net/java/sip/communicator/plugin/branding/JitsiWarningWindow.java203
-rw-r--r--src/net/java/sip/communicator/plugin/branding/MacOSXAboutRegistration.java64
-rw-r--r--src/net/java/sip/communicator/plugin/branding/StyledHTMLEditorPane.java124
-rw-r--r--src/net/java/sip/communicator/plugin/branding/WelcomeWindow.java443
-rw-r--r--src/net/java/sip/communicator/plugin/busylampfield/BLFActivator.java10
-rw-r--r--src/net/java/sip/communicator/plugin/certconfig/CertConfigEntryDialog.java1142
-rw-r--r--src/net/java/sip/communicator/plugin/certconfig/CertConfigPanel.java530
-rw-r--r--src/net/java/sip/communicator/plugin/certconfig/CertConfigTableModel.java194
-rw-r--r--src/net/java/sip/communicator/plugin/contactinfo/ContactInfoActivator.java416
-rw-r--r--src/net/java/sip/communicator/plugin/contactinfo/ContactInfoContactPanel.java392
-rw-r--r--src/net/java/sip/communicator/plugin/contactinfo/ContactInfoDetailsPanel.java1352
-rw-r--r--src/net/java/sip/communicator/plugin/contactinfo/ContactInfoDialog.java172
-rw-r--r--src/net/java/sip/communicator/plugin/contactinfo/ContactInfoMenuItem.java326
-rw-r--r--src/net/java/sip/communicator/plugin/contactinfo/Resources.java154
-rw-r--r--src/net/java/sip/communicator/plugin/desktoputil/ColoredDefaultText.java80
-rw-r--r--src/net/java/sip/communicator/plugin/desktoputil/SIPCommCheckBox.java86
-rw-r--r--src/net/java/sip/communicator/plugin/desktoputil/SIPCommRadioButton.java86
-rw-r--r--src/net/java/sip/communicator/plugin/desktoputil/X509CertificatePanel.java1032
-rw-r--r--src/net/java/sip/communicator/plugin/desktoputil/chat/ChatRoomDestroyReasonDialog.java346
-rw-r--r--src/net/java/sip/communicator/plugin/desktoputil/chat/ChatRoomJoinOptionsDialog.java344
-rw-r--r--src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccRegWizzActivator.java151
-rw-r--r--src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccountRegistration.java104
-rw-r--r--src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccountRegistrationWizard.java429
-rw-r--r--src/net/java/sip/communicator/plugin/dictaccregwizz/FirstWizardPage.java637
-rw-r--r--src/net/java/sip/communicator/plugin/dictaccregwizz/ProgressPanel.java156
-rw-r--r--src/net/java/sip/communicator/plugin/dictaccregwizz/Resources.java75
-rw-r--r--src/net/java/sip/communicator/plugin/dictaccregwizz/StrategiesList.java240
-rw-r--r--src/net/java/sip/communicator/plugin/dictaccregwizz/ThreadManager.java199
-rw-r--r--src/net/java/sip/communicator/plugin/dictaccregwizz/dictaccregwizz.manifest.mf34
-rw-r--r--src/net/java/sip/communicator/plugin/dnsconfig/DnssecPanel.java2
-rw-r--r--src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccRegWizzActivator.java213
-rw-r--r--src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java300
-rw-r--r--src/net/java/sip/communicator/plugin/facebookaccregwizz/facebookaccregwizz.manifest.mf34
-rw-r--r--src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigPluginActivator.java24
-rw-r--r--src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigurationPanel.java178
-rw-r--r--src/net/java/sip/communicator/plugin/generalconfig/XMPPConfigForm.java101
-rw-r--r--src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayWatcher.java920
-rw-r--r--src/net/java/sip/communicator/plugin/generalconfig/autoaway/Preferences.java262
-rw-r--r--src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyPluginActivator.java10
-rw-r--r--src/net/java/sip/communicator/plugin/googletalkaccregwizz/GoogleTalkAccRegWizzActivator.java322
-rw-r--r--src/net/java/sip/communicator/plugin/googletalkaccregwizz/GoogleTalkAccountRegistrationWizard.java504
-rw-r--r--src/net/java/sip/communicator/plugin/iptelaccregwizz/IptelAccRegWizzActivator.java304
-rw-r--r--src/net/java/sip/communicator/plugin/iptelaccregwizz/IptelAccountRegistrationWizard.java406
-rw-r--r--src/net/java/sip/communicator/plugin/ircaccregwizz/IrcAccountRegistrationWizard.java3
-rw-r--r--src/net/java/sip/communicator/plugin/jabberaccregwizz/AccountPanel.java11
-rw-r--r--src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountCreationForm.java2
-rw-r--r--src/net/java/sip/communicator/plugin/keybindingchooser/chooser/BindingChooser.java44
-rw-r--r--src/net/java/sip/communicator/plugin/keybindingchooser/globalchooser/GlobalShortcutDialog.java974
-rw-r--r--src/net/java/sip/communicator/plugin/msofficecomm/Messenger.java18
-rw-r--r--src/net/java/sip/communicator/plugin/msofficecomm/MsOfficeCommActivator.java1
-rw-r--r--src/net/java/sip/communicator/plugin/msofficecomm/OutOfProcessServer.java5
-rw-r--r--src/net/java/sip/communicator/plugin/msofficecomm/RegistryHandler.java262
-rw-r--r--src/net/java/sip/communicator/plugin/msofficecomm/msofficecomm.manifest.mf1
-rw-r--r--src/net/java/sip/communicator/plugin/otr/OtrConfigurator.java338
-rw-r--r--src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java2652
-rw-r--r--src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java82
-rw-r--r--src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerImpl.java618
-rw-r--r--src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerListener.java26
-rw-r--r--src/net/java/sip/communicator/plugin/otr/ScSessionID.java162
-rw-r--r--src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java154
-rw-r--r--src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberSourceContact.java12
-rw-r--r--src/net/java/sip/communicator/plugin/pluginmanager/BundleComparator.java4
-rw-r--r--src/net/java/sip/communicator/plugin/profiler4j/ProfilerActivator.java78
-rw-r--r--src/net/java/sip/communicator/plugin/profiler4j/Resources.java58
-rw-r--r--src/net/java/sip/communicator/plugin/profiler4j/SettingsWindowMenuEntry.java72
-rw-r--r--src/net/java/sip/communicator/plugin/profiler4j/profiler4j.manifest.mf24
-rw-r--r--src/net/java/sip/communicator/plugin/simpleaccreg/InitialAccountRegistrationFrame.java1468
-rw-r--r--src/net/java/sip/communicator/plugin/simpleaccreg/Resources.java180
-rw-r--r--src/net/java/sip/communicator/plugin/sip2sipaccregwizz/CreateSip2SipAccountForm.java382
-rw-r--r--src/net/java/sip/communicator/plugin/sip2sipaccregwizz/Sip2SipAccRegWizzActivator.java136
-rw-r--r--src/net/java/sip/communicator/plugin/sip2sipaccregwizz/Sip2SipAccountRegistrationWizard.java269
-rw-r--r--src/net/java/sip/communicator/plugin/sip2sipaccregwizz/sip2sipaccregwizz.manifest.mf43
-rw-r--r--src/net/java/sip/communicator/plugin/skinmanager/BundleComparator.java4
-rw-r--r--src/net/java/sip/communicator/plugin/spellcheck/SpellCheckerConfigDialog.java842
-rw-r--r--src/net/java/sip/communicator/plugin/sshaccregwizz/FirstWizardPage.java423
-rw-r--r--src/net/java/sip/communicator/plugin/sshaccregwizz/Resources.java74
-rw-r--r--src/net/java/sip/communicator/plugin/sshaccregwizz/SSHAccRegWizzActivator.java145
-rw-r--r--src/net/java/sip/communicator/plugin/sshaccregwizz/SSHAccountRegistration.java101
-rw-r--r--src/net/java/sip/communicator/plugin/sshaccregwizz/SSHAccountRegistrationWizard.java342
-rw-r--r--src/net/java/sip/communicator/plugin/sshaccregwizz/sshaccregwizz.manifest.mf32
-rw-r--r--src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdActivator.java336
-rw-r--r--src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdContactQuery.java530
-rw-r--r--src/net/java/sip/communicator/plugin/update/CheckForUpdatesMenuItemComponent.java150
-rw-r--r--src/net/java/sip/communicator/plugin/update/UpdateActivator.java608
-rw-r--r--src/net/java/sip/communicator/plugin/update/UpdateServiceImpl.java32
-rw-r--r--src/net/java/sip/communicator/plugin/yahooaccregwizz/FirstWizardPage.java299
-rw-r--r--src/net/java/sip/communicator/plugin/yahooaccregwizz/Resources.java73
-rw-r--r--src/net/java/sip/communicator/plugin/yahooaccregwizz/YahooAccRegWizzActivator.java160
-rw-r--r--src/net/java/sip/communicator/plugin/yahooaccregwizz/YahooAccountRegistration.java83
-rw-r--r--src/net/java/sip/communicator/plugin/yahooaccregwizz/YahooAccountRegistrationWizard.java379
-rw-r--r--src/net/java/sip/communicator/plugin/yahooaccregwizz/yahooaccregwizz.manifest.mf33
-rw-r--r--src/net/java/sip/communicator/plugin/zeroconfaccregwizz/FirstWizardPage.java368
-rw-r--r--src/net/java/sip/communicator/plugin/zeroconfaccregwizz/Resources.java74
-rw-r--r--src/net/java/sip/communicator/plugin/zeroconfaccregwizz/ZeroconfAccRegWizzActivator.java147
-rw-r--r--src/net/java/sip/communicator/plugin/zeroconfaccregwizz/ZeroconfAccountRegistration.java130
-rw-r--r--src/net/java/sip/communicator/plugin/zeroconfaccregwizz/ZeroconfAccountRegistrationWizard.java392
-rw-r--r--src/net/java/sip/communicator/plugin/zeroconfaccregwizz/zeroconfaccregwizz.manifest.mf32
-rw-r--r--src/net/java/sip/communicator/service/certificate/CertificateConfigEntry.java340
-rw-r--r--src/net/java/sip/communicator/service/certificate/CertificateMatcher.java44
-rw-r--r--src/net/java/sip/communicator/service/certificate/CertificateService.java526
-rw-r--r--src/net/java/sip/communicator/service/certificate/KeyStoreType.java124
-rw-r--r--src/net/java/sip/communicator/service/contactsource/AbstractContactQuery.java568
-rw-r--r--src/net/java/sip/communicator/service/contactsource/AsyncContactQuery.java816
-rw-r--r--src/net/java/sip/communicator/service/contactsource/AsyncContactSourceService.java136
-rw-r--r--src/net/java/sip/communicator/service/contactsource/ContactDetail.java14
-rw-r--r--src/net/java/sip/communicator/service/contactsource/GenericSourceContact.java586
-rw-r--r--src/net/java/sip/communicator/service/dns/DnssecException.java50
-rw-r--r--src/net/java/sip/communicator/service/dns/DnssecRuntimeException.java60
-rw-r--r--src/net/java/sip/communicator/service/googlecontacts/GoogleContactsEntry.java15
-rw-r--r--src/net/java/sip/communicator/service/gui/AlertUIService.java246
-rw-r--r--src/net/java/sip/communicator/service/gui/ChatLinkClickedListener.java38
-rw-r--r--src/net/java/sip/communicator/service/gui/Container.java6
-rw-r--r--src/net/java/sip/communicator/service/gui/LazyConfigurationForm.java436
-rw-r--r--src/net/java/sip/communicator/service/gui/UIService.java26
-rw-r--r--src/net/java/sip/communicator/service/gui/internal/GuiServiceActivator.java152
-rw-r--r--src/net/java/sip/communicator/service/muc/ChatRoomPresenceStatus.java140
-rw-r--r--src/net/java/sip/communicator/service/muc/ChatRoomProviderWrapperListener.java80
-rw-r--r--src/net/java/sip/communicator/service/muc/MUCService.java792
-rw-r--r--src/net/java/sip/communicator/service/notification/CommandNotificationAction.java74
-rw-r--r--src/net/java/sip/communicator/service/notification/NotificationAction.java192
-rw-r--r--src/net/java/sip/communicator/service/notification/NotificationData.java298
-rw-r--r--src/net/java/sip/communicator/service/notification/PopupMessageNotificationAction.java212
-rw-r--r--src/net/java/sip/communicator/service/notification/SoundNotificationAction.java356
-rw-r--r--src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java8
-rw-r--r--src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java13
-rw-r--r--src/net/java/sip/communicator/service/protocol/AccountManager.java2166
-rw-r--r--src/net/java/sip/communicator/service/protocol/AccountManagerUtils.java332
-rw-r--r--src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java3
-rw-r--r--src/net/java/sip/communicator/service/protocol/Call.java12
-rw-r--r--src/net/java/sip/communicator/service/protocol/CallConference.java1858
-rw-r--r--src/net/java/sip/communicator/service/protocol/OperationSetBasicInstantMessaging.java16
-rw-r--r--src/net/java/sip/communicator/service/protocol/OperationSetJitsiMeetTools.java11
-rw-r--r--src/net/java/sip/communicator/service/protocol/OperationSetSecureSDesTelephony.java26
-rw-r--r--src/net/java/sip/communicator/service/protocol/OperationSetSecureZrtpTelephony.java26
-rw-r--r--src/net/java/sip/communicator/service/protocol/OperationSetTelephonyBLF.java18
-rw-r--r--src/net/java/sip/communicator/service/protocol/PhoneNumberI18nService.java104
-rw-r--r--src/net/java/sip/communicator/service/protocol/ProtocolNames.java35
-rw-r--r--src/net/java/sip/communicator/service/protocol/ProtocolProviderActivator.java586
-rw-r--r--src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java2609
-rw-r--r--src/net/java/sip/communicator/service/protocol/ProtocolProviderService.java24
-rw-r--r--src/net/java/sip/communicator/service/protocol/RegistrationState.java6
-rw-r--r--src/net/java/sip/communicator/service/protocol/ServerStoredDetails.java6
-rw-r--r--src/net/java/sip/communicator/service/protocol/WhiteboardPoint.java8
-rw-r--r--src/net/java/sip/communicator/service/protocol/event/AccountManagerEvent.java168
-rw-r--r--src/net/java/sip/communicator/service/protocol/event/AccountManagerListener.java52
-rw-r--r--src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityMessageEvent.java15
-rw-r--r--src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityStatusEvent.java15
-rw-r--r--src/net/java/sip/communicator/service/protocol/jabber/AbstractSmackInteroperabilityLayer.java141
-rw-r--r--src/net/java/sip/communicator/service/protocol/jabber/JabberAccountID.java29
-rw-r--r--src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java62
-rw-r--r--src/net/java/sip/communicator/service/protocol/media/MediaAwareCall.java2
-rw-r--r--src/net/java/sip/communicator/service/protocol/media/MediaAwareCallConference.java1286
-rw-r--r--src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java2490
-rw-r--r--src/net/java/sip/communicator/service/protocol/media/TransportManager.java1756
-rw-r--r--src/net/java/sip/communicator/service/protocol/media/protocol.media.manifest.mf1
-rw-r--r--src/net/java/sip/communicator/service/protocol/protocol.provider.manifest.mf4
-rw-r--r--src/net/java/sip/communicator/service/protocol/sip/SIPAccountRegistration.java38
-rw-r--r--src/net/java/sip/communicator/service/protocol/yahooconstants/YahooStatusEnum.java200
-rw-r--r--src/net/java/sip/communicator/service/resources/ImageID.java40
-rw-r--r--src/net/java/sip/communicator/service/resources/ResourceManagementServiceUtils.java144
-rw-r--r--src/net/java/sip/communicator/service/sysactivity/SystemActivityChangeListener.java52
-rw-r--r--src/net/java/sip/communicator/service/sysactivity/SystemActivityNotificationsService.java138
-rw-r--r--src/net/java/sip/communicator/service/sysactivity/event/SystemActivityEvent.java268
-rw-r--r--src/net/java/sip/communicator/service/systray/AbstractSystrayService.java9
-rw-r--r--src/net/java/sip/communicator/service/systray/SystrayService.java37
-rw-r--r--src/net/java/sip/communicator/util/ConfigurationUtils.java78
-rw-r--r--src/net/java/sip/communicator/util/GenericBuffer.java230
-rw-r--r--src/net/java/sip/communicator/util/JitsiDnsNameService.java151
-rw-r--r--src/net/java/sip/communicator/util/JitsiDnsNameServiceDescriptor.java58
-rw-r--r--src/net/java/sip/communicator/util/NetworkUtils.java45
-rw-r--r--src/net/java/sip/communicator/util/ScLogFormatter.java123
-rw-r--r--src/net/java/sip/communicator/util/UtilActivator.java18
-rw-r--r--src/net/java/sip/communicator/util/account/AccountStatusUtils.java386
-rw-r--r--src/net/java/sip/communicator/util/account/AccountUtils.java606
-rw-r--r--src/net/java/sip/communicator/util/account/LoginManager.java1150
-rw-r--r--src/net/java/sip/communicator/util/account/LoginRenderer.java182
-rw-r--r--src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java6
-rw-r--r--src/net/java/sip/communicator/util/util.manifest.mf4
-rw-r--r--test/net/java/sip/communicator/slick/configuration/ConfigurationServiceLick.java2
-rw-r--r--test/net/java/sip/communicator/slick/popupmessagehandler/PopupMessageHandlerSLick.java104
-rw-r--r--test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetAdHocMultiUserChat.java7
-rw-r--r--test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetFileTransfer.java3
-rw-r--r--test/net/java/sip/communicator/slick/protocol/icq/icq.provider.slick.manifest.mf1
-rw-r--r--test/net/java/sip/communicator/slick/protocol/sip/SipProtocolProviderServiceLick.java2
-rw-r--r--test/net/java/sip/communicator/slick/protocol/sip/TestAutoProxyDetection.java970
-rw-r--r--test/net/java/sip/communicator/slick/protocol/sip/TestProtocolProviderServiceSipImpl.java25
-rw-r--r--test/net/java/sip/communicator/slick/protocol/yahoo/TestAccountInstallation.java233
-rw-r--r--test/net/java/sip/communicator/slick/protocol/yahoo/TestAccountUninstallation.java287
-rw-r--r--test/net/java/sip/communicator/slick/protocol/yahoo/TestAccountUninstallationPersistence.java113
-rw-r--r--test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetAdHocMultiUserChatYahooImpl.java182
-rw-r--r--test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetBasicInstantMessaging.java537
-rw-r--r--test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetFileTransferImpl.java253
-rw-r--r--test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetPersistentPresence.java582
-rw-r--r--test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetPresence.java1003
-rw-r--r--test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetTypingNotifications.java318
-rw-r--r--test/net/java/sip/communicator/slick/protocol/yahoo/TestProtocolProviderServiceYahooImpl.java262
-rw-r--r--test/net/java/sip/communicator/slick/protocol/yahoo/YahooProtocolProviderServiceLick.java129
-rw-r--r--test/net/java/sip/communicator/slick/protocol/yahoo/YahooSlickFixture.java144
-rw-r--r--test/net/java/sip/communicator/slick/protocol/yahoo/yahoo.provider.slick.manifest.mf17
-rw-r--r--web-start/WebStartBuild.xml1
-rw-r--r--www/alm-process/snippets/page.xml2
-rw-r--r--www/images/pixel.gifbin43 -> 0 bytes
-rw-r--r--www/images/sc_logo136x169.jpgbin7271 -> 0 bytes
-rw-r--r--www/images/sc_logo136x169.pngbin12664 -> 0 bytes
-rw-r--r--www/images/sc_logo139x208.white.pngbin14906 -> 0 bytes
-rw-r--r--www/images/sc_logo50x62.jpgbin3510 -> 0 bytes
-rw-r--r--www/images/sc_logo50x62.pngbin3602 -> 0 bytes
-rw-r--r--www/images/sip-communicator.jpgbin25052 -> 0 bytes
-rw-r--r--www/images/sip-communicator.logo.jpgbin3903 -> 0 bytes
-rw-r--r--www/images/sip-communicator.logo.pngbin18199 -> 0 bytes
-rw-r--r--www/index-jn.html2
-rw-r--r--www/index.html14
-rw-r--r--www/role-approval.policy20
-rw-r--r--www/sc_logo16x16.pngbin791 -> 0 bytes
753 files changed, 54016 insertions, 93228 deletions
diff --git a/.classpath b/.classpath
index 8a39b4d..e368438 100755
--- a/.classpath
+++ b/.classpath
@@ -13,8 +13,7 @@
<classpathentry kind="lib" path="lib/installer-exclude/cglib-nodep.osgi-2.1_3.jar"/>
<classpathentry kind="lib" path="lib/bundle/commons-logging.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/dhcp4java-1.00.jar"/>
- <classpathentry kind="lib" path="lib/installer-exclude/dict4j.jar"/>
- <classpathentry kind="lib" path="lib/installer-exclude/dnsjava.jar">
+ <classpathentry kind="lib" path="lib/installer-exclude/dnsjava-2.1.7.jar" sourcepath="/dnsjava">
<attributes>
<attribute name="javadoc_location" value="http://www.dnsjava.org/dnsjava-current/doc/"/>
</attributes>
@@ -31,16 +30,16 @@
<classpathentry kind="lib" path="lib/installer-exclude/hexdump-0.2.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/httpclient-osgi-4.2.3.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/httpcore-osgi-4.2.3.jar"/>
- <classpathentry kind="lib" path="lib/installer-exclude/ice4j.jar" sourcepath="../ice4j/src"/>
- <classpathentry kind="lib" path="lib/installer-exclude/jain-sdp.jar">
+ <classpathentry kind="lib" path="lib/installer-exclude/ice4j-2.0-20170111.193659-7.jar" sourcepath="/ice4j/src/main/java"/>
+ <classpathentry kind="lib" path="lib/installer-exclude/sdp-api-1.0.jar"/>
+ <classpathentry kind="lib" path="lib/installer-exclude/sip-api-1.2-1.2.jar"/>
+ <classpathentry kind="lib" path="lib/installer-exclude/jain-sip-ri-ossonly-1.2.279-jitsi-oss1.jar" sourcepath="/jain-sip/src">
<attributes>
<attribute name="javadoc_location" value="https://hudson.jboss.org/jenkins/job/jain-sip/lastStableBuild/artifact/javadoc/"/>
</attributes>
</classpathentry>
- <classpathentry kind="lib" path="lib/installer-exclude/jain-sip-api.jar"/>
- <classpathentry kind="lib" path="lib/installer-exclude/jain-sip-ri.jar"/>
+ <classpathentry kind="lib" path="lib/installer-exclude/java-sdp-nist-bridge-1.2.jar" sourcepath="/java-sdp-nist-bridge/src/main/java"/>
<classpathentry kind="lib" path="lib/installer-exclude/jdic_misc.jar"/>
- <classpathentry kind="lib" path="lib/installer-exclude/jfontchooser-1.0.5.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/jmdns.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/jmyspell-core.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/jna.jar"/>
@@ -48,8 +47,6 @@
<classpathentry kind="lib" path="lib/installer-exclude/joscar-client.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/joscar-common.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/joscar-protocol.jar"/>
- <classpathentry kind="lib" path="lib/installer-exclude/jsch-0.1.36.jar"/>
- <classpathentry kind="lib" path="lib/installer-exclude/jsocks-klea.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/json-simple-1.1.1.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/junit.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/laf-widget.jar"/>
@@ -58,28 +55,24 @@
<attribute name="javadoc_location" value="http://dbus.freedesktop.org/doc/dbus-java/api/"/>
</attributes>
</classpathentry>
- <classpathentry kind="lib" path="lib/installer-exclude/libjitsi-1.0-SNAPSHOT.jar" sourcepath="/libjitsi/src"/>
+ <classpathentry kind="lib" path="lib/installer-exclude/libjitsi-1.0-20170207.194207-242.jar" sourcepath="/libjitsi/src"/>
<classpathentry kind="lib" path="lib/bundle/log4j.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/mac_widgets-0.9.5.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/objenesis-1.2.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/otr4j.jar"/>
- <classpathentry kind="lib" path="lib/installer-exclude/profiler4j-1.0-beta3-SC.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/libphonenumber-5.9.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/sdes4j-1.1.3.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/smack.jar" sourcepath="lib/installer-exclude/smack-src.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/smackx.jar"/>
- <classpathentry kind="lib" path="lib/installer-exclude/swing-worker-1.2.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/jna-platform.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/unix-0.5.jar"/>
- <classpathentry kind="lib" path="lib/installer-exclude/weupnp-0.1.2-SNAPSHOT.jar"/>
- <classpathentry kind="lib" path="lib/installer-exclude/ymsg_network_v0_67.jar"/>
<classpathentry kind="lib" path="lib/os-specific/mac/growl4j.jar"/>
<classpathentry kind="lib" path="lib/os-specific/mac/OrangeExtensions.jar"/>
- <classpathentry kind="lib" path="lib/installer-exclude/jmork-1.0.5-SNAPSHOT.jar" sourcepath="/jmork"/>
- <classpathentry kind="lib" path="lib/installer-exclude/bcprov-jdk15on-151.jar"/>
+ <classpathentry kind="lib" path="lib/installer-exclude/jmork-1.0.5.jar" sourcepath="/jmork"/>
+ <classpathentry kind="lib" path="lib/installer-exclude/bcprov-jdk15on-1.54.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/commons-lang3-3.1.jar"/>
- <classpathentry kind="lib" path="lib/installer-exclude/bccontrib-1.0-SNAPSHOT.jar"/>
- <classpathentry kind="lib" path="lib/installer-exclude/zrtp4j-light.jar"/>
+ <classpathentry kind="lib" path="lib/installer-exclude/bccontrib-1.0.jar"/>
+ <classpathentry kind="lib" path="lib/installer-exclude/zrtp4j-light-4.1.0-jitsi-1-SNAPSHOT.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/jcalendar-1.4.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/hsqldb.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/irc-api-1.0.jar" sourcepath="lib/installer-exclude/irc-api-1.0-sources.jar"/>
@@ -88,5 +81,6 @@
<classpathentry kind="lib" path="lib/installer-exclude/google-http-client-jackson2-1.20.0.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/google-oauth-client-1.20.0.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/jackson-core-2.5.3.jar"/>
+ <classpathentry kind="lib" path="lib/installer-exclude/dnssecjava-1.1.jar" sourcepath="/dnssecjava"/>
<classpathentry kind="output" path="classes"/>
</classpath>
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..488f808
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+*.java text eol=lf diff=java
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index 4d8c8f3..21f2ae2 100644
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -1,14 +1,15 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index fd63c69..d2e21fe 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -42,10 +42,10 @@ Found a bug and know how to fix it? Great! Please read on.
## Contributor License Agreement
While Jitsi is released under the
-[Apache](https://github.com/jitsi/jitsi/blob/master/LICENSE), the copyright
-holder and principal creator is [Blue Jimp](http://www.bluejimp.com/). To
-ensure that we can continue making Jitsi available under an open source license
-and still pay our bills, we need you to sign our Apache-based contributor
+[Apache License](https://github.com/jitsi/jitsi/blob/master/LICENSE), the copyright
+holder and principal creator is [Atlassian](https://www.atlassian.com/). To
+ensure that we can continue making Jitsi available under an open source license,
+we need you to sign our Apache-based contributor
license agreement as either a [corporation](https://jitsi.org/ccla) or an
[individual](https://jitsi.org/icla). If you cannot accept the terms laid out
in the agreement, unfortunately, we cannot accept your contribution.
@@ -54,6 +54,9 @@ in the agreement, unfortunately, we cannot accept your contribution.
- Please read and follow the [code conventions](https://jitsi.org/Documentation/CodeConvention),
especially the limit on 80 characters per line.
- Do not reformat existing code.
+- Command-Line [build instructions](https://jitsi.org/Documentation/RetrievingAndBuildingTheSources)
+- How to set up [Eclipse](https://jitsi.org/Documentation/ConfigureEclipseNew)
+- Read the [tutorials](https://jitsi.org/Documentation/DeveloperDocumentation) (some of this information might be a bit dated, but it is still a very useful resource)
## Creating Pull Requests
- Perform **one** logical change per pull request.
diff --git a/README.md b/README.md
index 1e16f85..c356062 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
Jitsi
=====
-Jitsi is a free open-source audio/video and chat communicator that supports protocols such as SIP, XMPP/Jabber, AIM/ICQ, IRC, Yahoo! and many other useful features.
+Jitsi is a free open-source audio/video and chat communicator that supports protocols such as SIP, XMPP/Jabber, AIM/ICQ, IRC and many other useful features.
Helpful Resources
-----------------
diff --git a/build.xml b/build.xml
index 5bbd81f..c43b7e8 100644
--- a/build.xml
+++ b/build.xml
@@ -11,7 +11,6 @@
<property name="bundles.dest.mac" value="${bundles.dest}/os-specific/macosx"/>
<property name="bundles.dest.win" value="${bundles.dest}/os-specific/windows"/>
<property name="bundles.dest.lin" value="${bundles.dest}/os-specific/linux"/>
- <property name="bundles.dest.sol" value="${bundles.dest}/os-specific/solaris"/>
<property name="bundles.dest.freebsd" value="${bundles.dest}/os-specific/freebsd"/>
<property name="bundles.dest.android" value="${bundles.dest}/os-specific/android"/>
<property name="doc" value="doc"/>
@@ -23,8 +22,6 @@
<property name="lib.lin.noinst" value="${lib}/os-specific/linux/installer-exclude"/>
<property name="lib.mac" value="${lib}/os-specific/mac"/>
<property name="lib.mac.noinst" value="${lib}/os-specific/mac/installer-exclude"/>
- <property name="lib.sol" value="${lib}/os-specific/solaris"/>
- <property name="lib.sol.noinst" value="${lib}/os-specific/solaris/installer-exclude"/>
<property name="lib.freebsd" value="${lib}/os-specific/freebsd"/>
<property name="lib.freebsd.noinst" value="${lib}/os-specific/freebsd/installer-exclude"/>
<property name="lib.noinst" value="${lib}/installer-exclude"/>
@@ -122,31 +119,6 @@
<isset property="is.running.linux"/>
</condition>
- <!-- solaris specific properties -->
- <condition property="is.running.solaris" value="${os.name}">
- <equals arg1="${os.name}" arg2="solaris" casesensitive="false" trim="true"/>
- </condition>
-
- <condition property="is.running.solaris" value="${os.name}">
- <equals arg1="${os.name}" arg2="SunOS" casesensitive="false" trim="true"/>
- </condition>
-
- <condition property="os.lib.home" value="${lib}/os-specific/solaris">
- <and>
- <isset property="is.running.solaris"/>
- <available file="${lib}/os-specific/solaris" type="dir"/>
- </and>
- </condition>
-
- <condition property="ld.library.path"
- value="${lib}/native/solaris:${system.LD_LIBRARY_PATH}">
- <isset property="is.running.solaris"/>
- </condition>
-
- <condition property="bundles.dest.os" value="${bundles.dest.sol}">
- <isset property="is.running.solaris"/>
- </condition>
-
<!-- mac specific properties -->
<condition property="is.running.macos" value="${os.name}">
<os family="mac"/>
@@ -206,10 +178,6 @@
<!-- set the os.lib.home here in case it was not set before -->
<property name="os.lib.home" value="${lib}"/>
- <property name="profiler.args" value="" />
- <property name="profiler.bootdelegation" value="" />
- <property name="profiler.autostart" value="" />
-
<tstamp>
<format property="build.date" pattern="dd-MM-yyyy"/>
</tstamp>
@@ -476,7 +444,7 @@
</target>
<!-- Jitsi Version -->
- <target name="version" depends="-pre-version">
+ <target name="version" depends="bundle-bundles,-pre-version">
<!-- Recompile ant task classes-->
<delete failonerror="false">
<fileset dir="${dest}" includes="net/java/sip/communicator/impl/version/*.class"/>
@@ -497,7 +465,7 @@
<classpath>
<pathelement path="${dest}"/>
- <pathelement location="${lib.noinst}/libjitsi-1.0-SNAPSHOT.jar"/>
+ <pathelement location="${bundles.dest}/libjitsi.jar"/>
</classpath>
</taskdef>
@@ -519,7 +487,6 @@
<mkdir dir="${bundles.dest.lin}"/>
<mkdir dir="${bundles.dest.win}"/>
<mkdir dir="${bundles.dest.freebsd}"/>
- <mkdir dir="${bundles.dest.sol}"/>
<mkdir dir="${bundles.dest.android}"/>
<mkdir dir="${test.reports.dir}"/>
@@ -673,13 +640,12 @@
see its "Build Successful" output line as users might confuse it
for a general build success while this might not be the case.-->
<echo message="Generating HTML test reports ..."/>
- <java fork="true"
- classname="org.apache.tools.ant.launch.Launcher"
- classpath="${java.class.path}:${lib.noinst}/xalan-2.6.0.jar.ant"
- failonerror="true"
- output="${test.html.reports.dir}/output.txt">
- <arg value="htmlreport"/>
- </java>
+ <junitreport todir="${test.reports.dir}">
+ <fileset dir="${test.reports.dir}">
+ <include name="SC-TEST-*.xml"/>
+ </fileset>
+ <report format="frames" todir="${test.html.reports.dir}"/>
+ </junitreport>
<echo message="Done."/>
<echo/><echo/>
<echo message="Test results available in ./test-reports/html/index.html "/>
@@ -696,20 +662,6 @@
<fail if="testing.failed"/>
</target>
- <!-- We use this target from within the test target in order to generate
- a human readable test report. We do not directly use the htmlreport
- target because we need to include xalan in the classpath before we
- do.-->
- <target name="htmlreport">
- <junitreport todir="${test.reports.dir}">
- <fileset dir="${test.reports.dir}">
- <include name="SC-TEST-*.xml"/>
- </fileset>
- <report format="frames" todir="${test.html.reports.dir}"/>
- </junitreport>
- </target>
-
-
<target name="run-simple-tests"
depends="prepare-all-tests,prepare-local-accounts,deploy-os-specific-bundles"
description="runs selected non-felix tests under junit.">
@@ -826,20 +778,14 @@
<!-- pass to SC args that have been specified by the user -->
<arg line="${args}"/>
- <sysproperty key="org.osgi.framework.bootdelegation"
- value="${profiler.bootdelegation}" />
- <sysproperty key="felix.auto.start.68"
- value="${profiler.autostart}" />
-
<jvmarg value="-Xdebug" />
<jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5432" />
- <!-- add some eventual profiler args, prevent server-class
+ <!-- prevent server-class
detection because -server uses much more memory for 32-bit OS
(64-bit always used -server) -->
- <jvmarg line="${profiler.args} ${jvmarg.line}
- -client ${jvm.maxheapsize}"/>
+ <jvmarg line="${jvmarg.line} -client ${jvm.maxheapsize}"/>
<sysproperty key="apple.laf.useScreenMenuBar" value="true" />
</java>
@@ -933,93 +879,22 @@
<!-- pass to SC args that have been specified by the user -->
<arg line="${args}"/>
- <sysproperty key="org.osgi.framework.bootdelegation"
- value="${profiler.bootdelegation}" />
- <sysproperty key="felix.auto.start.68"
- value="${profiler.autostart}" />
-
- <!-- add some eventual profiler args, prevent server-class
+ <!-- prevent server-class
detection because -server uses much more memory for 32-bit OS
(64-bit always used -server) -->
- <jvmarg line="${profiler.args} ${jvmarg.line}
+ <jvmarg line="${jvmarg.line}
-client ${jvm.maxheapsize} ${jvmarg.splash} ${jvmarg.aegeturl}"/>
<sysproperty key="apple.laf.useScreenMenuBar" value="true" />
</java>
</target>
- <!--RUN-JITSI-WITH-INTEGRATED-PROFILER -->
- <target name="run-with-profiler"
- description="Starts felix and runs sip-comunicator gui (use latest build) with the hooked classloader."
- depends="bundle-plugin-profiler4j">
-
- <antcall target="run">
- <param name="profiler.args"
- value="-Xmx128m -javaagent:${lib.noinst}/profiler4j-1.0-beta3-SC.jar" />
- <param name="profiler.bootdelegation"
- value="net.sf.profiler4j.agent.*" />
- <param name="profiler.autostart"
- value="reference:file:sc-bundles/profiler4j.jar" />
- </antcall>
- </target>
-
<target name="run-v4" description="Starts SC with a preference for IPv4.">
<ant target="run">
<property name="java.net.preferIPv6Addresses" value="false"/>
</ant>
</target>
- <!--PROFILE-JITSI-IN-NETBEANS-IDE -->
- <target name="profile" depends="bundle-plugin-profiler4j,deploy-os-specific-bundles"
- description="Profile Project">
- <fail unless="netbeans.home">
- This target can only run inside the NetBeans IDE.
- </fail>
-
- <nbprofiledirect>
- <classpath> <pathelement location="${dest}"/> </classpath>
- </nbprofiledirect>
-
- <java classname="net.java.sip.communicator.launcher.SIPCommunicator"
- fork="true"
- failonerror="true"
- classpathref="project.class.path">
-
- <jvmarg value="${profiler.info.jvmargs.agent}"/>
-
- <!-- Tell felix to run Jitsi -->
- <sysproperty key="felix.config.properties"
- value="file:${lib}/felix.client.run.properties"/>
-
- <!-- Tell java.util.logging about our logging preferences -->
- <sysproperty key="java.util.logging.config.file"
- value="${lib}/logging.properties"/>
-
- <sysproperty key="java.net.preferIPv6Addresses"
- value="false"/>
-
- <sysproperty key="net.java.sip.communicator.SC_HOME_DIR_LOCATION"
- value="${user.home}/schome"/>
-
- <!-- Setting properties necessary for dependencies on native libs-->
- <sysproperty key="java.library.path"
- path="${ld.library.path}:${path}:${dyld.library.path}"/>
-
- <!-- pass l10n properties from ant call for
- easy translation debugging -->
- <sysproperty key="user.language" value="${user.language}" />
- <sysproperty key="user.country" value="${user.country}" />
- <sysproperty key="user.variant" value="${user.variant}" />
-
- <env key="LD_LIBRARY_PATH" path="${ld.library.path}"/>
- <env key="PATH" path="${path}"/>
- <env key="DYLD_LIBRARY_PATH" path="${dyld.library.path}"/>
-
- </java>
-
- <delete file="${bundles.dest}/profiler4j.jar"/>
- </target>
-
<!-- we run this target before we run SC in order to copy os-specific
bundles from sc-bundles/osname to its parent sc-bundles-->
<target name="deploy-os-specific-bundles" if="bundles.dest.os">
@@ -1053,14 +928,13 @@
bundle-protocol,bundle-protocol-media,bundle-icq,
bundle-icq-slick,bundle-mock,bundle-smacklib,bundle-jmdnslib,
bundle-jabber,bundle-jabber-slick,bundle-swing-ui,bundle-ui-service,
- bundle-jnalib,bundle-phonenumbers,
- bundle-irc-api,bundle-irc,bundle-irc-commands,bundle-plugin-ircaccregwizz,
- bundle-yahoo,bundle-yahoo-slick,
+ bundle-phonenumbers,
+ bundle-irc,bundle-irc-commands,bundle-plugin-ircaccregwizz,
bundle-contactlist,meta-contactlist,meta-contactlist-slick,
bundle-plugin-icqaccregwizz,bundle-plugin-jabberaccregwizz,
bundle-plugin-sipaccregwizz,
- bundle-plugin-yahooaccregwizz,bundle-plugin-aimaccregwizz,
- bundle-commons-codec,bundle-commons-lang,bundle-httputil,bundle-plugin-spellcheck,
+ bundle-plugin-aimaccregwizz,
+ bundle-httputil,bundle-plugin-spellcheck,
bundle-version-impl,bundle-shutdown-timeout,bundle-windows-clean-shutdown,
bundle-growlnotification,bundle-swingnotification,bundle-galagonotification,
bundle-sparkle, bundle-plugin-branding,
@@ -1073,13 +947,13 @@
bundle-plugin-blf,
bundle-plugin-contactinfo,bundle-plugin-chatalerter, bundle-keybindings,
bundle-plugin-keybindingChooser,bundle-plugin-globalproxyconfig,
- bundle-jfontchooserlib,bundle-update,bundle-plugin-update,
+ bundle-update,bundle-plugin-update,
bundle-plugin-simpleaccreg,bundle-plugin-generalconfig,
bundle-plugin-googletalkaccregwizz,bundle-argdelegation-service,
- bundle-argdelegation,bundle-zrtp4j,bundle-sdes4j,bundle-json,
+ bundle-argdelegation,bundle-json,
bundle-filehistory,bundle-metahistory,bundle-metahistory-slick,
- bundle-plugin-facebookaccregwizz,bundle-plugin-ippiaccregwizz,
- bundle-bouncycastle,bundle-plugin-otr,bundle-plugin-iptelaccregwizz,
+ bundle-plugin-ippiaccregwizz,
+ bundle-plugin-otr,bundle-plugin-iptelaccregwizz,
bundle-contactsource,bundle-plugin-reconnect,bundle-plugin-securityconfig,
bundle-plugin-advancedconfig,
bundle-credentialsstorage,bundle-credentialsstorage-slick,
@@ -1093,14 +967,47 @@
bundle-provisioning,bundle-addrbook,bundle-plugin-ldap,
bundle-thunderbird,
bundle-plugin-contactsourceconfig,bundle-plugin-certconfig,
- bundle-globalshortcut,bundle-plugin-msofficecomm,bundle-libjitsi,
+ bundle-globalshortcut,bundle-plugin-msofficecomm,
bundle-customcontactactions, bundle-phonenumbercontactsource,
bundle-demuxcontactsource, bundle-muc,
bundle-desktoputil,bundle-globaldisplaydetails,
- bundle-usersearch,
+ bundle-usersearch,
bundle-plugin-propertieseditor,bundle-plugin-accountinfo,
bundle-plugin-connectioninfo,
- bundle-guava,bundle-hsql,bundle-slf4j"/>
+ bundle-bundles"/>
+
+ <!-- Copying of all unmodified libraries that are already bundles -->
+ <target name="bundle-bundles">
+ <copy file="${lib.noinst}/libjitsi-1.0-20170207.194207-242.jar" tofile="${bundles.dest}/libjitsi.jar"/>
+ <copy file="${lib.noinst}/fmj-1.0-SNAPSHOT.jar" tofile="${bundles.dest}/fmj.jar"/>
+ <copy file="${lib.noinst}/jitsi-lgpl-dependencies-1.0-SNAPSHOT.jar" tofile="${bundles.dest}/jitsi-lgpl-dependencies.jar"/>
+ <copy file="${lib.noinst}/jitsi-gpl-dependencies-1.0-SNAPSHOT.jar" tofile="${bundles.dest}/jitsi-gpl-dependencies.jar"/>
+ <copy file="${lib.noinst}/guava-15.0.jar" tofile="${bundles.dest}/guava.jar"/>
+ <copy file="${lib.noinst}/hsqldb.jar" tofile="${bundles.dest}/hsqldb.jar"/>
+ <copy file="${lib.noinst}/irc-api-1.0.jar" tofile="${bundles.dest}/irc-api-1.0.jar"/>
+ <copy file="${lib.noinst}/slf4j-api-1.7.5.jar" tofile="${bundles.dest}/slf4j-api.jar"/>
+ <copy file="${lib.noinst}/slf4j-jdk14-1.7.5.jar" tofile="${bundles.dest}/slf4j-jdk14.jar"/>
+ <copy file="${lib.noinst}/commons-codec-1.6.jar" tofile="${bundles.dest}/commons-codec.jar"/>
+ <copy file="${lib.noinst}/commons-lang3-3.1.jar" tofile="${bundles.dest}/commons-lang.jar"/>
+ <copy file="${lib.noinst}/httpclient-osgi-4.2.3.jar" tofile="${bundles.dest}/httpclient.jar"/>
+ <copy file="${lib.noinst}/httpcore-osgi-4.2.3.jar" tofile="${bundles.dest}/httpcore.jar"/>
+ <copy file="${lib.noinst}/sdes4j-1.1.3.jar" tofile="${bundles.dest}/sdes4j.jar"/>
+ <copy file="${lib.noinst}/bcpkix-jdk15on-1.54.jar" tofile="${bundles.dest}/bcpkix.jar"/>
+ <copy file="${lib.noinst}/bcprov-jdk15on-1.54.jar" tofile="${bundles.dest}/bouncycastle.jar"/>
+ <copy file="${lib.noinst}/bccontrib-1.0.jar" tofile="${bundles.dest}/bccontrib.jar"/>
+ <copy file="${lib.noinst}/jmork-1.0.5.jar" tofile="${bundles.dest}/jmork.jar"/>
+ <copy file="${lib.noinst}/weupnp-0.1.4.jar" tofile="${bundles.dest}/weupnp.jar"/>
+ <copy file="${lib.noinst}/ice4j-2.0-20170111.193659-7.jar" tofile="${bundles.dest}/ice4j.jar"/>
+ <copy file="${lib.noinst}/sdp-api-1.0.jar" tofile="${bundles.dest}/sdp-api.jar"/>
+ <copy file="${lib.noinst}/sip-api-1.2-1.2.jar" tofile="${bundles.dest}/sip-api.jar"/>
+ <copy file="${lib.noinst}/java-sdp-nist-bridge-1.2.jar" tofile="${bundles.dest}/java-sdp-nist-bridge.jar"/>
+ <copy file="${lib.noinst}/jain-sip-ri-ossonly-1.2.279-jitsi-oss1.jar" tofile="${bundles.dest}/jain-sip-ri.jar"/>
+ <copy file="${lib.noinst}/dnsjava-2.1.7.jar" tofile="${bundles.dest}/dnsjava.jar"/>
+ <copy file="${lib.noinst}/dnssecjava-1.1.jar" tofile="${bundles.dest}/dnssecjava.jar"/>
+ <copy file="${lib.noinst}/jna.jar" tofile="${bundles.dest}/jna.jar"/>
+ <copy file="${lib.noinst}/jna-platform.jar" tofile="${bundles.dest}/jna-platform.jar"/>
+ <copy file="${lib.noinst}/zrtp4j-light-4.1.0-jitsi-1-SNAPSHOT.jar" tofile="${bundles.dest}/zrtp4j.jar"/>
+ </target>
<!--BUNDLE-SC-LAUNCHER-->
<target name="bundle-sc-launcher">
@@ -1223,7 +1130,9 @@
<zipfileset dir="${dest}/net/java/sip/communicator/util"
prefix="net/java/sip/communicator/util">
</zipfileset>
- <zipfileset src="${lib.noinst}/dnsjava.jar" prefix=""/>
+ <service
+ type="sun.net.spi.nameservice.NameServiceDescriptor"
+ provider="net.java.sip.communicator.util.JitsiDnsNameServiceDescriptor"/>
</jar>
</target>
@@ -1308,18 +1217,9 @@
</jar>
</target>
- <!--BUNDLE-LIBJITSI -->
- <target name="bundle-libjitsi">
- <copy file="${lib.noinst}/libjitsi-1.0-SNAPSHOT.jar" tofile="${bundles.dest}/libjitsi.jar"/>
- <copy file="${lib.noinst}/fmj-1.0-SNAPSHOT.jar" tofile="${bundles.dest}/fmj.jar"/>
- <copy file="${lib.noinst}/jitsi-lgpl-dependencies-1.0-SNAPSHOT.jar" tofile="${bundles.dest}/jitsi-lgpl-dependencies.jar"/>
- <copy file="${lib.noinst}/bcpkix-jdk15on-151.jar" tofile="${bundles.dest}/bcpkix.jar"/>
- </target>
-
<!--BUNDLE-NEOMEDIA-->
<target name="bundle-neomedia">
- <!-- Creates a bundle containing the impl of the neomedia package and
- FMJ. -->
+ <!-- Creates a bundle containing the impl of the neomedia package -->
<jar
compress="false"
destfile="${bundles.dest}/neomedia.jar"
@@ -1423,14 +1323,6 @@
</jar>
</target>
- <target name="bundle-guava">
- <copy file="${lib.noinst}/guava-15.0.jar" tofile="${bundles.dest}/guava.jar"/>
- </target>
-
- <target name="bundle-hsql">
- <copy file="${lib.noinst}/hsqldb.jar" tofile="${bundles.dest}/hsqldb.jar"/>
- </target>
-
<!--BUNDLE-SERVICEBINDER -->
<target name="bundle-servicebinder">
<jar compress="true" destfile="lib/bundle/servicebinder.jar"
@@ -1460,9 +1352,7 @@ javax.swing.event, javax.swing.border"/>
</target>
<!-- BUNDLE-NETADDR -->
- <target name="bundle-netaddr"
- depends="bundle-netaddr-dynamically,bundle-netaddr-statically" />
- <target name="bundle-netaddr-dynamically" if="dynamic.linking">
+ <target name="bundle-netaddr">
<jar compress="false" destfile="${bundles.dest}/netaddr.jar"
manifest="${src}/net/java/sip/communicator/impl/netaddr/netaddr.manifest.mf">
<zipfileset dir="${dest}/net/java/sip/communicator/service/netaddr"
@@ -1471,17 +1361,6 @@ javax.swing.event, javax.swing.border"/>
prefix="net/java/sip/communicator/impl/netaddr" />
</jar>
</target>
- <target name="bundle-netaddr-statically" unless="dynamic.linking">
- <jar compress="false" destfile="${bundles.dest}/netaddr.jar"
- manifest="${src}/net/java/sip/communicator/impl/netaddr/netaddr.manifest.mf">
- <zipfileset dir="${dest}/net/java/sip/communicator/service/netaddr"
- prefix="net/java/sip/communicator/service/netaddr" />
- <zipfileset dir="${dest}/net/java/sip/communicator/impl/netaddr"
- prefix="net/java/sip/communicator/impl/netaddr" />
- <zipfileset src="${lib.noinst}/ice4j.jar" prefix="" />
- <zipfileset src="${lib.noinst}/weupnp-0.1.2-SNAPSHOT.jar" prefix="" />
- </jar>
- </target>
<!--BUNDLE-NETADDR-SLICK -->
<target name="bundle-netaddr-slick">
@@ -1519,9 +1398,6 @@ javax.swing.event, javax.swing.border"/>
manifest="${src}/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf">
<zipfileset dir="${dest}/net/java/sip/communicator/impl/protocol/sip"
prefix="net/java/sip/communicator/impl/protocol/sip"/>
- <zipfileset src="${lib.noinst}/jain-sip-ri.jar" prefix=""/>
- <zipfileset src="${lib.noinst}/jain-sip-api.jar" prefix=""/>
- <zipfileset src="${lib.noinst}/jain-sdp.jar" prefix=""/>
</jar>
</target>
@@ -1549,9 +1425,7 @@ javax.swing.event, javax.swing.border"/>
prefix="resources/images">
<include name="protocol/icq/**/*"/>
<include name="protocol/googletalk/**/*"/>
- <include name="protocol/facebook/**/*"/>
<include name="protocol/jabber/**/*"/>
- <include name="protocol/yahoo/**/*"/>
<!-- the media package lives in the protocol-media bundle -->
<exclude name="protocol/media/**/*"/>
</zipfileset>
@@ -1599,17 +1473,6 @@ javax.swing.event, javax.swing.border"/>
</jar>
</target>
- <target name="bundle-jnalib">
- <!-- Creates a bundle containing the win jna implementation.-->
- <jar
- compress="false" destfile="${bundles.dest}/jnalib.jar"
- manifest="${lib.noinst}/jna.manifest.mf">
-
- <zipfileset src="${lib.noinst}/jna.jar" prefix=""/>
- <zipfileset src="${lib.noinst}/jna-platform.jar" prefix=""/>
- </jar>
- </target>
-
<!-- BUNDLE-ICQ -->
<target name="bundle-icq">
<!-- Creates a bundle containing the icq impl of the protocol provider.-->
@@ -1673,51 +1536,6 @@ javax.swing.event, javax.swing.border"/>
</jar>
</target>
- <!-- BUNDLE-SSH -->
- <target name="bundle-ssh">
- <!-- Creates a bundle containing the SSH impl of the protocol provider.-->
- <jar compress="false" destfile="${bundles.dest}/protocol-ssh.jar"
- manifest="${src}/net/java/sip/communicator/impl/protocol/ssh/ssh.provider.manifest.mf">
- <zipfileset dir="${dest}/net/java/sip/communicator/impl/protocol/ssh"
- prefix="net/java/sip/communicator/impl/protocol/ssh"/>
- <zipfileset src="${lib.noinst}/jsch-0.1.36.jar" prefix=""/>
- </jar>
- </target>
-
- <!-- BUNDLE-PLUGIN-SSHACCREGWIZZ -->
- <target name="bundle-plugin-sshaccregwizz">
- <!-- Creates a bundle for the plugin SSH Account Registration Wizard.-->
- <jar compress="false" destfile="${bundles.dest}/sshaccregwizz.jar"
- manifest="${src}/net/java/sip/communicator/plugin/sshaccregwizz/sshaccregwizz.manifest.mf">
- <zipfileset dir="${dest}/net/java/sip/communicator/plugin/sshaccregwizz"
- prefix="net/java/sip/communicator/plugin/sshaccregwizz"/>
- </jar>
- </target>
-
- <!-- BUNDLE-YAHOO -->
- <target name="bundle-yahoo">
- <!-- Creates a bundle containing the yahoo impl of the protocol provider.-->
- <jar compress="false" destfile="${bundles.dest}/protocol-yahoo.jar"
- manifest="${src}/net/java/sip/communicator/impl/protocol/yahoo/yahoo.provider.manifest.mf">
- <zipfileset dir="${dest}/net/java/sip/communicator/impl/protocol/yahoo"
- prefix="net/java/sip/communicator/impl/protocol/yahoo"/>
- <zipfileset src="${lib.noinst}/ymsg_network_v0_67.jar" prefix=""/>
- </jar>
- </target>
-
- <!-- BUNDLE-YAHOO-SLICK -->
- <!-- Creates a bundle containing the slick for the Yahoo protocol provider.-->
- <target name="bundle-yahoo-slick">
- <jar compress="false" destfile="${bundles.dest}/protocol-yahoo-slick.jar"
- manifest="${testsrc}/net/java/sip/communicator/slick/protocol/yahoo/yahoo.provider.slick.manifest.mf">
- <zipfileset dir="${dest}/net/java/sip/communicator/slick/protocol/yahoo"
- prefix="net/java/sip/communicator/slick/protocol/yahoo"/>
- <zipfileset src="${lib.noinst}/ymsg_network_v0_67.jar" prefix=""/>
- <zipfileset dir="${dest}/net/java/sip/communicator/slick/protocol/generic"
- prefix="net/java/sip/communicator/slick/protocol/generic"/>
- </jar>
- </target>
-
<!-- BUNDLE-GIBBERISH -->
<target name="bundle-gibberish">
<!-- Creates a bundle containing the Gibberish impl of the protocol provider.-->
@@ -1753,13 +1571,12 @@ javax.swing.event, javax.swing.border"/>
</target>
<!-- BUNDLE-SWING-UI -->
- <target name="bundle-swing-ui" depends="bundle-commons-lang">
+ <target name="bundle-swing-ui">
<!-- Bundle Jitsi's UI.-->
<jar compress="false" destfile="${bundles.dest}/swing-ui.jar"
manifest="${src}/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf">
<zipfileset dir="${dest}/net/java/sip/communicator/impl/gui"
prefix="net/java/sip/communicator/impl/gui"/>
- <zipfileset src="${lib.noinst}/swing-worker-1.2.jar" prefix=""/>
<zipfileset src="${lib.noinst}/mac_widgets-0.9.5.jar" prefix=""/>
<zipfileset src="${lib.noinst}/forms-1.2.1.jar" prefix=""/>
</jar>
@@ -1835,16 +1652,6 @@ javax.swing.event, javax.swing.border"/>
</jar>
</target>
- <!-- BUNDLE-PLUGIN-YAHOOACCREGWIZZ -->
- <target name="bundle-plugin-yahooaccregwizz">
- <!-- Creates a bundle for the plugin Yahoo Account Registration Wizard.-->
- <jar compress="false" destfile="${bundles.dest}/yahooaccregwizz.jar"
- manifest="${src}/net/java/sip/communicator/plugin/yahooaccregwizz/yahooaccregwizz.manifest.mf">
- <zipfileset dir="${dest}/net/java/sip/communicator/plugin/yahooaccregwizz"
- prefix="net/java/sip/communicator/plugin/yahooaccregwizz"/>
- </jar>
- </target>
-
<!-- BUNDLE-PLUGIN-SIPACCREGWIZZ -->
<target name="bundle-plugin-sipaccregwizz">
<!-- Creates a bundle for the plugin SIP Account Registration Wizard.-->
@@ -1865,16 +1672,6 @@ javax.swing.event, javax.swing.border"/>
</jar>
</target>
- <!-- BUNDLE-PLUGIN-SIP2SIPACCREGWIZZ -->
- <target name="bundle-plugin-sip2sipaccregwizz">
- <!-- Creates a bundle for the plugin Sip2Sip Account Registration Wizard.-->
- <jar compress="false" destfile="${bundles.dest}/sip2sipaccregwizz.jar"
- manifest="${src}/net/java/sip/communicator/plugin/sip2sipaccregwizz/sip2sipaccregwizz.manifest.mf">
- <zipfileset dir="${dest}/net/java/sip/communicator/plugin/sip2sipaccregwizz"
- prefix="net/java/sip/communicator/plugin/sip2sipaccregwizz"/>
- </jar>
- </target>
-
<!-- BUNDLE-PLUGIN-IPPIACCREGWIZZ -->
<target name="bundle-plugin-ippiaccregwizz">
<!-- Creates a bundle for the plugin ippi Account Registration Wizard.-->
@@ -1896,17 +1693,6 @@ javax.swing.event, javax.swing.border"/>
</jar>
</target>
- <!-- BUNDLE-PLUGIN-FACEBOOKACCREGWIZZ -->
- <target name="bundle-plugin-facebookaccregwizz">
- <!-- Creates a bundle for the plugin Facebook Account Registration
- Wizard.-->
- <jar compress="false" destfile="${bundles.dest}/facebookaccregwizz.jar"
- manifest="${src}/net/java/sip/communicator/plugin/facebookaccregwizz/facebookaccregwizz.manifest.mf">
- <zipfileset dir="${dest}/net/java/sip/communicator/plugin/facebookaccregwizz"
- prefix="net/java/sip/communicator/plugin/facebookaccregwizz" />
- </jar>
- </target>
-
<!-- BUNDLE-SERVICEIMPL-VERSION -->
<target name="bundle-version-impl">
<!-- Creates a bundle for the version service impl.-->
@@ -2074,28 +1860,8 @@ javax.swing.event, javax.swing.border"/>
</jar>
</target>
- <!-- BUNDLE-ZEROCONF -->
- <target name="bundle-zeroconf">
- <!-- Creates a bundle containing the Zeroconf impl of the protocol provider.-->
- <jar compress="false" destfile="${bundles.dest}/protocol-zeroconf.jar"
- manifest="${src}/net/java/sip/communicator/impl/protocol/zeroconf/zeroconf.provider.manifest.mf">
- <zipfileset dir="${dest}/net/java/sip/communicator/impl/protocol/zeroconf"
- prefix="net/java/sip/communicator/impl/protocol/zeroconf"/>
- </jar>
- </target>
-
- <!-- BUNDLE-PLUGIN-ZEROCONFACCREGWIZZ -->
- <target name="bundle-plugin-zeroconfaccregwizz">
- <!-- Creates a bundle for the plugin Zeroconf Account Registration Wizard.-->
- <jar compress="false" destfile="${bundles.dest}/zeroconfaccregwizz.jar"
- manifest="${src}/net/java/sip/communicator/plugin/zeroconfaccregwizz/zeroconfaccregwizz.manifest.mf">
- <zipfileset dir="${dest}/net/java/sip/communicator/plugin/zeroconfaccregwizz"
- prefix="net/java/sip/communicator/plugin/zeroconfaccregwizz"/>
- </jar>
- </target>
-
<!-- BUNDLE-IRC -->
- <target name="bundle-irc" depends="bundle-irc-api">
+ <target name="bundle-irc">
<!-- Creates a bundle containing the IRC impl of the protocol provider.-->
<jar compress="false" destfile="${bundles.dest}/protocol-irc.jar"
manifest="${src}/net/java/sip/communicator/impl/protocol/irc/irc.provider.manifest.mf">
@@ -2114,17 +1880,6 @@ javax.swing.event, javax.swing.border"/>
</jar>
</target>
- <!-- BUNDLE IRC-API -->
- <target name="bundle-irc-api" depends="bundle-slf4j">
- <copy file="${lib.noinst}/irc-api-1.0.jar" tofile="${bundles.dest}/irc-api-1.0.jar"/>
- </target>
-
- <!-- BUNDLE SLF4J -->
- <target name="bundle-slf4j">
- <copy file="${lib.noinst}/slf4j-api-1.7.5.jar" tofile="${bundles.dest}/slf4j-api.jar"/>
- <copy file="${lib.noinst}/slf4j-jdk14-1.7.5.jar" tofile="${bundles.dest}/slf4j-jdk14.jar"/>
- </target>
-
<!-- BUNDLE-PLUGIN-IRCACCREGWIZZ -->
<target name="bundle-plugin-ircaccregwizz">
<!-- Creates a bundle for the plugin IRC Account Registration
@@ -2136,18 +1891,6 @@ javax.swing.event, javax.swing.border"/>
</jar>
</target>
- <!--BUNDLE-COMMONS-CODEC -->
- <target name="bundle-commons-codec">
- <copy file="${lib.noinst}/commons-codec-1.6.jar"
- tofile="${bundles.dest}/commons-codec.jar"/>
- </target>
-
- <!--BUNDLE-COMMONS-LANG -->
- <target name="bundle-commons-lang">
- <copy file="${lib.noinst}/commons-lang3-3.1.jar"
- tofile="${bundles.dest}/commons-lang.jar"/>
- </target>
-
<!--BUNDLE-HTTPUTIL -->
<target name="bundle-httputil">
<!-- Create the httputil.jar-->
@@ -2156,11 +1899,6 @@ javax.swing.event, javax.swing.border"/>
<zipfileset dir="${dest}/net/java/sip/communicator/service/httputil"
prefix="net/java/sip/communicator/service/httputil"/>
</jar>
-
- <copy file="${lib.noinst}/httpclient-osgi-4.2.3.jar"
- tofile="${bundles.dest}/httpclient.jar"/>
- <copy file="${lib.noinst}/httpcore-osgi-4.2.3.jar"
- tofile="${bundles.dest}/httpcore.jar"/>
</target>
<!-- BUNDLE-NOTIFICATION -->
@@ -2184,7 +1922,7 @@ javax.swing.event, javax.swing.border"/>
</target>
<!-- BUNDLE-NOTIFICATION-WIRING -->
- <target name="bundle-notification-wiring" depends="bundle-commons-lang">
+ <target name="bundle-notification-wiring">
<!-- Creates a bundle for the notifications.-->
<jar compress="false" destfile="${bundles.dest}/notification-wiring.jar"
manifest="${src}/net/java/sip/communicator/plugin/notificationwiring/notificationwiring.manifest.mf">
@@ -2253,27 +1991,6 @@ javax.swing.event, javax.swing.border"/>
</jar>
</target>
- <!-- BUNDLE-DICT -->
- <target name="bundle-dict">
- <jar compress="false" destfile="${bundles.dest}/protocol-dict.jar"
- manifest="${src}/net/java/sip/communicator/impl/protocol/dict/dict.provider.manifest.mf">
- <zipfileset dir="${dest}/net/java/sip/communicator/impl/protocol/dict"
- prefix="net/java/sip/communicator/impl/protocol/dict"/>
- <zipfileset src="${lib.noinst}/dict4j.jar" prefix=""/>
- </jar>
- </target>
-
- <!-- BUNDLE-PLUGIN-DICTACCREGWIZZ -->
- <target name="bundle-plugin-dictaccregwizz">
- <!-- Creates a bundle for the plugin Dict Account Registration
- Wizard.-->
- <jar compress="false" destfile="${bundles.dest}/dictaccregwizz.jar"
- manifest="${src}/net/java/sip/communicator/plugin/dictaccregwizz/dictaccregwizz.manifest.mf">
- <zipfileset dir="${dest}/net/java/sip/communicator/plugin/dictaccregwizz"
- prefix="net/java/sip/communicator/plugin/dictaccregwizz"/>
- </jar>
- </target>
-
<!-- BUNDLE-UPDATE-->
<target name="bundle-update">
<!-- Creates a bundle containing the provisioning discovery service.-->
@@ -2293,21 +2010,6 @@ javax.swing.event, javax.swing.border"/>
</jar>
</target>
- <!--BUNDLE-PLUGIN-PROFILER-->
- <target name="bundle-plugin-profiler4j">
- <jar compress="false" destfile="${bundles.dest}/profiler4j.jar"
- manifest="${src}/net/java/sip/communicator/plugin/profiler4j/profiler4j.manifest.mf">
- <zipfileset dir="${dest}/net/java/sip/communicator/plugin/profiler4j"
- prefix="net/java/sip/communicator/plugin/profiler4j" />
- <zipfileset src="${lib.noinst}/profiler4j-1.0-beta3-SC.jar"
- prefix=""/>
- <zipfileset src="${lib.noinst}/jdom.jar" prefix=""/>
- <zipfileset src="${lib.noinst}/jcommon-1.0.0.jar" prefix=""/>
- <zipfileset src="${lib.noinst}/jfreechart-1.0.1.jar" prefix=""/>
- <fileset file="${lib.noinst}/p4j-exclusions.txt"/>
- </jar>
- </target>
-
<!--BUNDLE-SimpleAccRegPlugin-->
<target name="bundle-plugin-simpleaccreg">
<jar compress="false" destfile="${bundles.dest}/simpleaccreg.jar"
@@ -2425,15 +2127,6 @@ javax.swing.event, javax.swing.border"/>
</jar>
</target>
- <!-- BUNDLE-JFontChooser -->
- <target name="bundle-jfontchooserlib">
- <!-- Creates a bundle containing the jfontchooser lib.-->
- <jar compress="false" destfile="${bundles.dest}/jfontchooserlib.jar"
- manifest="${lib.noinst}/jfontchooser.manifest.mf">
- <zipfileset src="${lib.noinst}/jfontchooser-1.0.5.jar" prefix=""/>
- </jar>
- </target>
-
<!-- BUNDLE Arg Delegation Service -->
<target name="bundle-argdelegation-service">
<!-- Creates a bundle for the notifications.-->
@@ -2454,51 +2147,6 @@ javax.swing.event, javax.swing.border"/>
</jar>
</target>
- <!--BUNDLE-ZRTP4J -->
- <target name="bundle-zrtp4j">
- <jar compress="true" destfile="${bundles.dest}/zrtp4j.jar"
- filesetmanifest="merge">
-
- <zipfileset src="${lib.noinst}/zrtp4j-light.jar" prefix=""/>
- <manifest>
- <attribute name="Export-Package" value="gnu.java.zrtp,
-gnu.java.zrtp.packets,
-gnu.java.zrtp.utils,
-gnu.java.zrtp.zidfile"/>
- <attribute name="Import-Package" value="org.bouncycastle.asn1,
-org.bouncycastle.asn1.nist,
-org.bouncycastle.asn1.sec,
-org.bouncycastle.asn1.x9,
-org.bouncycastle.crypto,
-org.bouncycastle.crypto.agreement,
-org.bouncycastle.crypto.digests,
-org.bouncycastle.crypto.engines,
-org.bouncycastle.crypto.generators,
-org.bouncycastle.crypto.macs,
-org.bouncycastle.crypto.modes,
-org.bouncycastle.crypto.params,
-org.bouncycastle.crypto.prng,
-org.jitsi.bccontrib.digests,
-org.jitsi.bccontrib.engines,
-org.jitsi.bccontrib.macs,
-org.jitsi.bccontrib.params,
-org.jitsi.bccontrib.prng,
-org.bouncycastle.math.ec,
-org.bouncycastle.util.encoders,
-org.bouncycastle.util"/>
- <attribute name="Bundle-Name" value="ZRTP4J"/>
- <attribute name="Bundle-Description" value="ZRTP for Java library."/>
- <attribute name="Bundle-Version" value="1.4.5"/>
- <attribute name="Bundle-SymbolicName" value="gnu.java.zrtp4j"/>
- </manifest>
- </jar>
- </target>
-
- <!--BUNDLE-SDES4J -->
- <target name="bundle-sdes4j">
- <copy file="${lib.noinst}/sdes4j-1.1.3.jar" tofile="${bundles.dest}/sdes4j.jar"/>
- </target>
-
<!--BUNDLE-JSON -->
<target name="bundle-json">
<jar compress="true" destfile="${bundles.dest}/json.jar"
@@ -2534,12 +2182,6 @@ org.bouncycastle.util"/>
</jar>
</target>
- <!--BUNDLE-BOUNCYCASTLE -->
- <target name="bundle-bouncycastle">
- <copy file="${lib.noinst}/bcprov-jdk15on-151.jar" tofile="${bundles.dest}/bouncycastle.jar"/>
- <copy file="${lib.noinst}/bccontrib-1.0-SNAPSHOT.jar" tofile="${bundles.dest}/bccontrib.jar"/>
- </target>
-
<!--BUNDLE-PLUGIN-OTR -->
<target name="bundle-plugin-otr">
<jar compress="false" destfile="${bundles.dest}/otr.jar" manifest="${src}/net/java/sip/communicator/plugin/otr/otr.manifest.mf">
@@ -2548,6 +2190,7 @@ org.bouncycastle.util"/>
<zipfileset src="${lib.noinst}/otr4j.jar"/>
</jar>
</target>
+
<!--BUNDLE-METAHISTORY-SLICK-->
<target name="bundle-metahistory-slick">
<jar compress="false" destfile="${bundles.dest}/metahistory-slick.jar"
@@ -2833,7 +2476,6 @@ org.bouncycastle.util"/>
<zipfileset dir="${dest}/net/java/sip/communicator/plugin/thunderbird"
prefix="net/java/sip/communicator/plugin/thunderbird" />
</jar>
- <copy file="${lib.noinst}/jmork-1.0.5-SNAPSHOT.jar" tofile="${bundles.dest}/jmork.jar"/>
</target>
<target name="bundle-certificate">
diff --git a/jitsi.eml b/jitsi.eml
deleted file mode 100755
index 7a448a0..0000000
--- a/jitsi.eml
+++ /dev/null
@@ -1,192 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<component inheritJdk="true">
- <contentEntry url="file://$MODULE_DIR$"/>
- <lib name="felix.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/felix.jar!/"/>
- </lib>
- <lib name="junit.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/bundle/junit.jar!/"/>
- </lib>
- <lib name="apache-ant-1.7.0.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/apache-ant-1.7.0.jar!/"/>
- </lib>
- <lib name="cglib-nodep.osgi-2.1_3.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/cglib-nodep.osgi-2.1_3.jar!/"/>
- </lib>
- <lib name="commons-logging.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/bundle/commons-logging.jar!/"/>
- </lib>
- <lib name="dhcp4java-1.00.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/dhcp4java-1.00.jar!/"/>
- </lib>
- <lib name="dict4j.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/dict4j.jar!/"/>
- </lib>
- <lib name="dnsjava.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/dnsjava.jar!/"/>
- </lib>
- <lib name="easymock-3.1.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/easymock-3.1.jar!/"/>
- </lib>
- <lib name="fmj.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/fmj.jar!/"/>
- </lib>
- <lib name="forms-1.2.1.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/forms-1.2.1.jar!/"/>
- </lib>
- <lib name="gdata-client-1.0.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/gdata-client-1.0.jar!/"/>
- </lib>
- <lib name="gdata-client-meta-1.0.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/gdata-client-meta-1.0.jar!/"/>
- </lib>
- <lib name="gdata-contacts-3.0.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/gdata-contacts-3.0.jar!/"/>
- </lib>
- <lib name="gdata-contacts-meta-3.0.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/gdata-contacts-meta-3.0.jar!/"/>
- </lib>
- <lib name="gdata-core-1.0.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/gdata-core-1.0.jar!/"/>
- </lib>
- <lib name="google-collect-1.0-rc1.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/google-collect-1.0-rc1.jar!/"/>
- </lib>
- <lib name="hexdump-0.2.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/hexdump-0.2.jar!/"/>
- </lib>
- <lib name="httpclient-osgi-4.2.3.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/httpclient-osgi-4.2.3.jar!/"/>
- </lib>
- <lib name="httpcore-osgi-4.2.3.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/httpcore-osgi-4.2.3.jar!/"/>
- </lib>
- <lib name="ice4j.jar" scope="COMPILE">
- <srcroot url="file://$MODULE_DIR$/../ice4j/src"/>
- <srcroot bind="false" url="file://$MODULE_DIR$/../ice4j/test"/>
- <relative-module-src project-related="file://$PROJECT_DIR$/../ice4j/src"/>
- <relative-module-src project-related="file://$PROJECT_DIR$/../ice4j/test"/>
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/ice4j.jar!/"/>
- </lib>
- <lib name="jain-sdp.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/jain-sdp.jar!/"/>
- </lib>
- <lib name="jain-sip-api.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/jain-sip-api.jar!/"/>
- </lib>
- <lib name="jain-sip-ri.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/jain-sip-ri.jar!/"/>
- </lib>
- <lib name="jdic_misc.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/jdic_misc.jar!/"/>
- </lib>
- <lib name="jfontchooser-1.0.5.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/jfontchooser-1.0.5.jar!/"/>
- </lib>
- <lib name="jmdns.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/jmdns.jar!/"/>
- </lib>
- <lib name="jmyspell-core.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/jmyspell-core.jar!/"/>
- </lib>
- <lib name="jna.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/jna.jar!/"/>
- </lib>
- <lib name="jnsapi.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/jnsapi.jar!/"/>
- </lib>
- <lib name="joscar-client.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/joscar-client.jar!/"/>
- </lib>
- <lib name="joscar-common.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/joscar-common.jar!/"/>
- </lib>
- <lib name="joscar-protocol.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/joscar-protocol.jar!/"/>
- </lib>
- <lib name="jsch-0.1.36.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/jsch-0.1.36.jar!/"/>
- </lib>
- <lib name="jsocks-klea.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/jsocks-klea.jar!/"/>
- </lib>
- <lib name="json-simple-1.1.1.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/json-simple-1.1.1.jar!/"/>
- </lib>
- <lib name="lib/installer-exclude/junit.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/junit.jar!/"/>
- </lib>
- <lib name="laf-widget.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/laf-widget.jar!/"/>
- </lib>
- <lib name="libdbus-java-2.7.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/libdbus-java-2.7.jar!/"/>
- </lib>
- <lib name="libjitsi.jar" scope="COMPILE">
- <srcroot url="file://$MODULE_DIR$/../libjitsi/src"/>
- <relative-module-src project-related="file://$PROJECT_DIR$/../libjitsi/src"/>
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/libjitsi.jar!/"/>
- </lib>
- <lib name="log4j-1.2.8.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/log4j-1.2.8.jar!/"/>
- </lib>
- <lib name="mac_widgets-0.9.5.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/mac_widgets-0.9.5.jar!/"/>
- </lib>
- <lib name="objenesis-1.2.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/objenesis-1.2.jar!/"/>
- </lib>
- <lib name="otr4j.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/otr4j.jar!/"/>
- </lib>
- <lib name="pircbot.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/pircbot.jar!/"/>
- </lib>
- <lib name="profiler4j-1.0-beta3-SC.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/profiler4j-1.0-beta3-SC.jar!/"/>
- </lib>
- <lib name="sdes4j.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/sdes4j.jar!/"/>
- </lib>
- <lib name="smack.jar" scope="COMPILE">
- <srcroot url="file://lib/installer-exclude/smack-src.jar"/>
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/smack.jar!/"/>
- </lib>
- <lib name="smackx.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/smackx.jar!/"/>
- </lib>
- <lib name="swing-worker-1.2.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/swing-worker-1.2.jar!/"/>
- </lib>
- <lib name="jna-platform.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/jna-platform.jar!/"/>
- </lib>
- <lib name="unix-0.5.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/unix-0.5.jar!/"/>
- </lib>
- <lib name="weupnp-0.1.2-SNAPSHOT.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/weupnp-0.1.2-SNAPSHOT.jar!/"/>
- </lib>
- <lib name="ymsg_network_v0_67.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/ymsg_network_v0_67.jar!/"/>
- </lib>
- <lib name="growl4j.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/os-specific/mac/growl4j.jar!/"/>
- </lib>
- <lib name="OrangeExtensions.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/os-specific/mac/OrangeExtensions.jar!/"/>
- </lib>
- <lib name="jmork-1.0.5-SNAPSHOT.jar" scope="COMPILE">
- <srcroot url="file:///jmork"/>
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/jmork-1.0.5-SNAPSHOT.jar!/"/>
- </lib>
- <lib name="bcprov-jdk15on-148.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/bcprov-jdk15on-148.jar!/"/>
- </lib>
- <lib name="bccontrib-1.0-SNAPSHOT.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/bccontrib-1.0-SNAPSHOT.jar!/"/>
- </lib>
- <lib name="zrtp4j-light.jar" scope="COMPILE">
- <relative-module-cls project-related="jar://$PROJECT_DIR$/lib/installer-exclude/zrtp4j-light.jar!/"/>
- </lib>
-</component>
diff --git a/jitsi.iml b/jitsi.iml
deleted file mode 100644
index ca72718..0000000
--- a/jitsi.iml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" name="ice4j" level="application" />
- <orderEntry type="library" name="jitsi-dependencies" level="application" />
- </component>
-</module>
-
diff --git a/jitsi.ipr b/jitsi.ipr
deleted file mode 100644
index 91fd90e..0000000
--- a/jitsi.ipr
+++ /dev/null
@@ -1,314 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="AntConfiguration">
- <buildFile url="file://$PROJECT_DIR$/build.xml">
- <maximumHeapSize value="400" />
- </buildFile>
- </component>
- <component name="CompilerConfiguration">
- <option name="DEFAULT_COMPILER" value="Javac" />
- <resourceExtensions>
- <entry name=".+\.(properties|xml|html|dtd|tld)" />
- <entry name=".+\.(gif|png|jpeg|jpg)" />
- </resourceExtensions>
- <wildcardResourcePatterns>
- <entry name="?*.properties" />
- <entry name="?*.xml" />
- <entry name="?*.gif" />
- <entry name="?*.png" />
- <entry name="?*.jpeg" />
- <entry name="?*.jpg" />
- <entry name="?*.html" />
- <entry name="?*.dtd" />
- <entry name="?*.tld" />
- <entry name="?*.ftl" />
- </wildcardResourcePatterns>
- <annotationProcessing>
- <profile default="true" name="Default" enabled="false">
- <processorPath useClasspath="true" />
- </profile>
- </annotationProcessing>
- </component>
- <component name="CopyrightManager" default="">
- <module2copyright />
- </component>
- <component name="DependencyValidationManager">
- <option name="SKIP_IMPORT_STATEMENTS" value="false" />
- </component>
- <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
- <component name="EntryPointsManager">
- <entry_points version="2.0" />
- </component>
- <component name="JavacSettings">
- <option name="MAXIMUM_HEAP_SIZE" value="512" />
- </component>
- <component name="JavadocGenerationManager">
- <option name="OUTPUT_DIRECTORY" />
- <option name="OPTION_SCOPE" value="protected" />
- <option name="OPTION_HIERARCHY" value="true" />
- <option name="OPTION_NAVIGATOR" value="true" />
- <option name="OPTION_INDEX" value="true" />
- <option name="OPTION_SEPARATE_INDEX" value="true" />
- <option name="OPTION_DOCUMENT_TAG_USE" value="false" />
- <option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" />
- <option name="OPTION_DOCUMENT_TAG_VERSION" value="false" />
- <option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" />
- <option name="OPTION_DEPRECATED_LIST" value="true" />
- <option name="OTHER_OPTIONS" value="" />
- <option name="HEAP_SIZE" />
- <option name="LOCALE" />
- <option name="OPEN_IN_BROWSER" value="true" />
- </component>
- <component name="Palette2">
- <group name="Swing">
- <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
- </item>
- <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
- </item>
- <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
- </item>
- <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
- <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
- </item>
- <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
- <initial-values>
- <property name="text" value="Button" />
- </initial-values>
- </item>
- <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
- <initial-values>
- <property name="text" value="RadioButton" />
- </initial-values>
- </item>
- <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
- <initial-values>
- <property name="text" value="CheckBox" />
- </initial-values>
- </item>
- <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
- <initial-values>
- <property name="text" value="Label" />
- </initial-values>
- </item>
- <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
- <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
- <preferred-size width="150" height="-1" />
- </default-constraints>
- </item>
- <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
- <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
- <preferred-size width="150" height="-1" />
- </default-constraints>
- </item>
- <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
- <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
- <preferred-size width="150" height="-1" />
- </default-constraints>
- </item>
- <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
- <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
- <preferred-size width="150" height="50" />
- </default-constraints>
- </item>
- <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
- <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
- <preferred-size width="150" height="50" />
- </default-constraints>
- </item>
- <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
- <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
- <preferred-size width="150" height="50" />
- </default-constraints>
- </item>
- <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
- <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
- </item>
- <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
- <preferred-size width="150" height="50" />
- </default-constraints>
- </item>
- <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
- <preferred-size width="150" height="50" />
- </default-constraints>
- </item>
- <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
- <preferred-size width="150" height="50" />
- </default-constraints>
- </item>
- <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
- <preferred-size width="200" height="200" />
- </default-constraints>
- </item>
- <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
- <preferred-size width="200" height="200" />
- </default-constraints>
- </item>
- <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
- <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
- </item>
- <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
- </item>
- <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
- </item>
- <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
- </item>
- <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
- <preferred-size width="-1" height="20" />
- </default-constraints>
- </item>
- <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
- </item>
- <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
- <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
- </item>
- </group>
- </component>
- <component name="ProjectCodeStyleSettingsManager">
- <option name="PER_PROJECT_SETTINGS">
- <value>
- <XML>
- <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
- </XML>
- </value>
- </option>
- </component>
- <component name="ProjectInspectionProfilesVisibleTreeState">
- <entry key="Project Default">
- <profile-state />
- </entry>
- </component>
- <component name="ProjectModuleManager">
- <modules>
- <module fileurl="file://$PROJECT_DIR$/../ice4j/Ice4j.iml" filepath="$PROJECT_DIR$/../ice4j/Ice4j.iml" />
- <module fileurl="file://$PROJECT_DIR$/jitsi.iml" filepath="$PROJECT_DIR$/jitsi.iml" />
- <module fileurl="file://$PROJECT_DIR$/../libjitsi/libjitsi.iml" filepath="$PROJECT_DIR$/../libjitsi/libjitsi.iml" />
- </modules>
- </component>
- <component name="ProjectResources">
- <default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype>
- </component>
- <component name="ProjectRootManager" version="2" languageLevel="JDK_1_5" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
- <output url="file://$PROJECT_DIR$/classes" />
- </component>
- <component name="ProjectRunConfigurationManager">
- <configuration default="false" name="run" type="Application" factoryName="Application">
- <option name="MAIN_CLASS_NAME" value="net.java.sip.communicator.launcher.SIPCommunicator" />
- <option name="VM_PARAMETERS" value="-Xdock:name=Jitsi -Xdock:icon=resources/images/logo/sc_logo_128x128.icns -client -Dfelix.config.properties=file:lib/felix.client.run.properties -Djava.util.logging.config.file=lib/logging.properties -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=schome -Djava.library.path=${ld.library.path}:lib/native/mac:${system.DYLD_LIBRARY_PATH} -Djna.library.path=${ld.library.path}:lib/native/mac:${system.DYLD_LIBRARY_PATH} -Dapple.laf.useScreenMenuBar=true" />
- <option name="PROGRAM_PARAMETERS" value="" />
- <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" value="" />
- <option name="ENABLE_SWING_INSPECTOR" value="false" />
- <option name="ENV_VARIABLES" />
- <option name="PASS_PARENT_ENVS" value="true" />
- <module name="jitsi" />
- <envs />
- <RunnerSettings RunnerId="Run" />
- <ConfigurationWrapper RunnerId="Run" />
- <method>
- <option name="Make" enabled="false" />
- <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/build.xml" target="make-and-deploy" />
- </method>
- </configuration>
- <configuration default="false" name="run-v4" type="Application" factoryName="Application">
- <option name="MAIN_CLASS_NAME" value="net.java.sip.communicator.launcher.SIPCommunicator" />
- <option name="VM_PARAMETERS" value="-Xdock:name=Jitsi -Xdock:icon=resources/images/logo/sc_logo_128x128.icns -client -Dfelix.config.properties=file:lib/felix.client.run.properties -Djava.util.logging.config.file=lib/logging.properties -Djava.net.preferIPv6Addresses=false -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=schome -Djava.library.path=${ld.library.path}:lib/native/mac:${system.DYLD_LIBRARY_PATH} -Djna.library.path=${ld.library.path}:lib/native/mac:${system.DYLD_LIBRARY_PATH} -Dapple.laf.useScreenMenuBar=true" />
- <option name="PROGRAM_PARAMETERS" value="" />
- <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" value="" />
- <option name="ENABLE_SWING_INSPECTOR" value="false" />
- <option name="ENV_VARIABLES" />
- <option name="PASS_PARENT_ENVS" value="true" />
- <module name="jitsi" />
- <envs />
- <RunnerSettings RunnerId="Debug">
- <option name="DEBUG_PORT" value="57968" />
- <option name="TRANSPORT" value="0" />
- <option name="LOCAL" value="true" />
- </RunnerSettings>
- <RunnerSettings RunnerId="Run" />
- <ConfigurationWrapper RunnerId="Debug" />
- <ConfigurationWrapper RunnerId="Run" />
- <method>
- <option name="Make" enabled="false" />
- <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/build.xml" target="make-and-deploy" />
- </method>
- </configuration>
- </component>
- <component name="SvnBranchConfigurationManager">
- <option name="mySupportsUserInfoFilter" value="true" />
- </component>
- <component name="VcsDirectoryMappings">
- <mapping directory="$PROJECT_DIR$/../ice4j" vcs="svn" />
- <mapping directory="$PROJECT_DIR$" vcs="Git" />
- <mapping directory="$PROJECT_DIR$/../libjitsi" vcs="Git" />
- </component>
- <component name="libraryTable">
- <library name="cpptasks">
- <CLASSES>
- <root url="jar://$PROJECT_DIR$/../libjitsi/lib/installer-exclude/cpptasks.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
- <library name="ice4j">
- <CLASSES>
- <root url="jar://$PROJECT_DIR$/../ice4j/ice4j.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
- <library name="lib">
- <CLASSES>
- <root url="jar://$PROJECT_DIR$/../ice4j/lib/jain-sdp.jar!/" />
- <root url="jar://$PROJECT_DIR$/../ice4j/lib/xalan-2.6.0.jar!/" />
- <root url="jar://$PROJECT_DIR$/../ice4j/lib/junit.jar!/" />
- <root url="jar://$PROJECT_DIR$/../ice4j/lib/weupnp-0.1.2-SNAPSHOT.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
- <library name="lib">
- <CLASSES>
- <root url="jar://$PROJECT_DIR$/../libjitsi/lib/osgi.core.jar!/" />
- <root url="jar://$PROJECT_DIR$/../libjitsi/lib/sdes4j.jar!/" />
- <root url="jar://$PROJECT_DIR$/../libjitsi/lib/jain-sdp.jar!/" />
- <root url="jar://$PROJECT_DIR$/../libjitsi/lib/fmj.jar!/" />
- <root url="jar://$PROJECT_DIR$/../libjitsi/lib/bccontrib-1.0-SNAPSHOT.jar!/" />
- <root url="jar://$PROJECT_DIR$/../libjitsi/lib/jspeex.jar!/" />
- <root url="jar://$PROJECT_DIR$/../libjitsi/lib/json-simple-1.1.1.jar!/" />
- <root url="jar://$PROJECT_DIR$/../libjitsi/lib/ice4j.jar!/" />
- <root url="jar://$PROJECT_DIR$/../libjitsi/lib/bcprov-jdk15on-148.jar!/" />
- <root url="jar://$PROJECT_DIR$/../libjitsi/lib/zrtp4j-light.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
- <library name="libjitsi">
- <CLASSES>
- <root url="jar://$PROJECT_DIR$/../libjitsi/libjitsi.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
- </component>
-</project>
-
diff --git a/lib/accounts.properties.template b/lib/accounts.properties.template
index 3845c47..3b6b540 100644
--- a/lib/accounts.properties.template
+++ b/lib/accounts.properties.template
@@ -189,47 +189,6 @@ accounts.jabber.CONTACT_LIST=
# list of icq accounts to notify during testing (optional)
accounts.reporting.JABBER_REPORT_LIST=
-# YAHOO PROPERTIES
-
-# YAHOO ACCOUNT 1
-# The username needed to log onto the server
-accounts.yahoo.account1.USER_ID=
-
-# The password (in plain text) needed to log the user specified in USER_ID
-# on the server
-accounts.yahoo.account1.PASSWORD=
-
-# YAHOO ACCOUNT 2
-
-# The username needed to log onto the server
-accounts.yahoo.account2.USER_ID=
-
-# The password (in plain text) needed to log the user specified in USER_ID
-# on the server
-accounts.yahoo.account2.PASSWORD=
-
-# YAHOO ACCOUNT 3
-
-# The username needed to log onto the server
-accounts.yahoo.account3.USER_ID=
-
-# The password (in plain text) needed to log the user specified in USER_ID
-# on the server
-accounts.yahoo.account3.PASSWORD=
-
-# The following describes the contact list that we will store on the yahoo
-# server for the tested account implementation. The value of the CONTACT_LIST
-# property must be a space separated string containing elements each of which
-# is in the format: GroupName.UIN
-
-
-# VERY IMPORTANT!!! All other users in this contact list will be removed and
-# the contacts and contact groups enumerated beneath will be added instead
-accounts.yahoo.CONTACT_LIST=
-
-# list of yahoo accounts to notify during testing (optional)
-accounts.reporting.YAHOO_REPORT_LIST=
-
# GIBBERISH Account 1
# The username to create the first Gibberish account with.
accounts.gibberish.account1.USER_ID=gibacc1
diff --git a/lib/felix.client.run.properties b/lib/felix.client.run.properties
index b1cc220..c9cb60b 100644
--- a/lib/felix.client.run.properties
+++ b/lib/felix.client.run.properties
@@ -2,30 +2,35 @@
# Framework config properties.
#
org.osgi.framework.system.packages.extra= \
- apple.awt; \
- com.apple.cocoa.application; \
- com.apple.cocoa.foundation; \
- com.apple.eawt; \
- com.apple.eio; \
- com.sun.awt; \
- net.java.sip.communicator.util.launchutils; \
- org.apache.xml.serialize; \
- org.growl4j; \
- org.xbill.DNS; \
- quicktime; \
- quicktime.qd; \
- quicktime.std.image; \
- quicktime.std.sg; \
- quicktime.util; \
- sun.awt.shell; \
- sun.lwawt; \
- sun.lwawt.macosx; \
- sun.misc; \
- sun.net.util; \
- sun.net.dns; \
- sun.security.action; \
- sun.security.pkcs11;\
- sun.audio
+ apple.awt, \
+ com.apple.cocoa.application, \
+ com.apple.cocoa.foundation, \
+ com.apple.eawt, \
+ com.apple.eio, \
+ com.sun.awt, \
+ net.java.sip.communicator.util.launchutils, \
+ org.apache.xml.serialize, \
+ org.growl4j, \
+ org.xbill.DNS;version="2.1.7", \
+ org.xbill.DNS.utils;version="2.1.7", \
+ quicktime, \
+ quicktime.qd, \
+ quicktime.std.image, \
+ quicktime.std.sg, \
+ quicktime.util, \
+ sun.awt.shell, \
+ sun.lwawt, \
+ sun.lwawt.macosx, \
+ sun.misc, \
+ sun.net.util, \
+ sun.net.dns, \
+ sun.security.action, \
+ sun.security.pkcs11,\
+ sun.audio,\
+ sun.nio.ch,\
+ com.sun.nio.sctp, \
+ android.os, \
+ sun.net.spi.nameservice
felix.auto.start.5=reference:file:sc-bundles/splash-screen.jar
@@ -34,7 +39,8 @@ felix.auto.start.5=reference:file:sc-bundles/splash-screen.jar
felix.auto.install.10= \
reference:file:sc-bundles/fmj.jar \
reference:file:sc-bundles/slf4j-jdk14.jar \
- reference:file:sc-bundles/jitsi-lgpl-dependencies.jar
+ reference:file:sc-bundles/jitsi-lgpl-dependencies.jar \
+ reference:file:sc-bundles/jitsi-gpl-dependencies.jar
felix.auto.start.10= \
reference:file:lib/bundle/org.apache.felix.bundlerepository-1.6.4.jar \
@@ -42,14 +48,28 @@ felix.auto.start.10= \
reference:file:sc-bundles/bccontrib.jar \
reference:file:sc-bundles/commons-lang.jar \
reference:file:sc-bundles/guava.jar \
- reference:file:sc-bundles/slf4j-api.jar
+ reference:file:sc-bundles/slf4j-api.jar \
+ reference:file:sc-bundles/weupnp.jar \
+ reference:file:sc-bundles/dnssecjava.jar
+
+felix.auto.start.11= \
+ reference:file:sc-bundles/sip-api.jar \
+ reference:file:sc-bundles/sdp-api.jar \
+ reference:file:sc-bundles/jain-sip-ri.jar \
+ reference:file:sc-bundles/java-sdp-nist-bridge.jar \
+ reference:file:sc-bundles/ice4j.jar
+
# file:lib/bundle/shell.jar \
# file:lib/bundle/servicebinder.jar \
# file:lib/bundle/tablelayout.jar
-felix.auto.start.14= \
+felix.auto.start.13= \
reference:file:sc-bundles/commons-codec.jar
+
+#warning: felix.auto.start.14 is injected by the windows build
+# for the clean-shutdown-bundle
+
felix.auto.start.15= \
reference:file:sc-bundles/zrtp4j.jar \
reference:file:sc-bundles/sdes4j.jar
@@ -86,9 +106,9 @@ felix.auto.start.35= \
felix.auto.start.40= \
reference:file:sc-bundles/jmdnslib.jar \
- reference:file:sc-bundles/jnalib.jar \
+ reference:file:sc-bundles/jna.jar \
+ reference:file:sc-bundles/jna-platform.jar \
reference:file:sc-bundles/provdisc.jar \
- reference:file:sc-bundles/jfontchooserlib.jar \
reference:file:sc-bundles/netaddr.jar \
reference:file:sc-bundles/sysactivitynotifications.jar \
reference:file:sc-bundles/browserlauncher.jar \
@@ -133,7 +153,6 @@ felix.auto.start.52= \
reference:file:sc-bundles/protocol-sip.jar \
reference:file:sc-bundles/smacklib.jar \
reference:file:sc-bundles/protocol-jabber.jar \
- reference:file:sc-bundles/protocol-yahoo.jar \
reference:file:sc-bundles/protocol-irc.jar \
reference:file:sc-bundles/reconnectplugin.jar
@@ -174,7 +193,6 @@ felix.auto.start.67= \
reference:file:sc-bundles/sipaccregwizz.jar \
reference:file:sc-bundles/jabberaccregwizz.jar \
reference:file:sc-bundles/googletalkaccregwizz.jar \
- reference:file:sc-bundles/yahooaccregwizz.jar \
reference:file:sc-bundles/ircaccregwizz.jar \
reference:file:sc-bundles/contacteventhandler.jar \
reference:file:sc-bundles/notificationconfig.jar \
@@ -185,7 +203,6 @@ felix.auto.start.67= \
reference:file:sc-bundles/keybindingChooser.jar \
reference:file:sc-bundles/generalconfig.jar \
reference:file:sc-bundles/otr.jar \
- reference:file:sc-bundles/facebookaccregwizz.jar \
reference:file:sc-bundles/spellChecker.jar \
reference:file:sc-bundles/advancedconfig.jar \
reference:file:sc-bundles/plugin-loggingutils.jar \
@@ -214,7 +231,8 @@ felix.auto.start.67= \
reference:file:sc-bundles/phonenumbercontactsource.jar \
reference:file:sc-bundles/demuxcontactsource.jar \
reference:file:sc-bundles/usersearch.jar \
- reference:file:sc-bundles/propertieseditor.jar
+ reference:file:sc-bundles/propertieseditor.jar \
+ reference:file:sc-bundles/plugin-blf.jar
# Level 68 is for profiler4j. Either don't use it or change the build.xml file
# accordingly.
diff --git a/lib/felix.jar b/lib/felix.jar
index ec4e81a..c91e86b 100644
--- a/lib/felix.jar
+++ b/lib/felix.jar
Binary files differ
diff --git a/lib/felix.unit.test.properties b/lib/felix.unit.test.properties
index 415af6d..e97d3b1 100644
--- a/lib/felix.unit.test.properties
+++ b/lib/felix.unit.test.properties
@@ -4,35 +4,38 @@
# and Service Implementation Compatibility Kits
#
org.osgi.framework.system.packages.extra= \
- apple.awt; \
- com.apple.cocoa.application; \
- com.apple.cocoa.foundation; \
- com.apple.eawt; \
- com.apple.eio; \
- gnu.java.zrtp; \
- gnu.java.zrtp.packets; \
- gnu.java.zrtp.utils; \
- gnu.java.zrtp.zidfile; \
- net.java.stun4j;\
- net.java.stun4j.client;\
- org.apache.xml.serialize;\
- quicktime; \
- quicktime.qd; \
- quicktime.std.image; \
- quicktime.std.sg; \
- quicktime.util; \
- com.sun.awt; \
- sun.lwawt; \
- sun.lwawt.macosx; \
- sun.awt.shell; \
- sun.misc; \
- sun.net.util; \
- sun.net.dns; \
- sun.security.action; \
- sun.security.pkcs11; \
- sun.reflect; \
- org.xbill.DNS;\
- sun.audio
+ apple.awt, \
+ com.apple.cocoa.application, \
+ com.apple.cocoa.foundation, \
+ com.apple.eawt, \
+ com.apple.eio, \
+ gnu.java.zrtp, \
+ gnu.java.zrtp.packets, \
+ gnu.java.zrtp.utils, \
+ gnu.java.zrtp.zidfile, \
+ net.java.stun4j,\
+ net.java.stun4j.client,\
+ org.apache.xml.serialize,\
+ quicktime, \
+ quicktime.qd, \
+ quicktime.std.image, \
+ quicktime.std.sg, \
+ quicktime.util, \
+ com.sun.awt, \
+ sun.lwawt, \
+ sun.lwawt.macosx, \
+ sun.awt.shell, \
+ sun.misc, \
+ sun.net.util, \
+ sun.net.dns, \
+ sun.security.action, \
+ sun.security.pkcs11, \
+ sun.reflect, \
+ org.xbill.DNS;version="2.1.7", \
+ org.xbill.DNS.utils;version="2.1.7", \
+ sun.audio,\
+ sun.nio.ch,\
+ com.sun.nio.sctp
#
@@ -47,7 +50,9 @@ org.osgi.framework.system.packages.extra= \
#install (but don't start) OSGi fragments
felix.auto.install.10= \
reference:file:sc-bundles/fmj.jar \
- reference:file:sc-bundles/jitsi-lgpl-dependencies.jar
+ reference:file:sc-bundles/slf4j-jdk14.jar \
+ reference:file:sc-bundles/jitsi-lgpl-dependencies.jar \
+ reference:file:sc-bundles/jitsi-gpl-dependencies.jar
felix.auto.start.10= \
reference:file:lib/bundle/junit.jar \
@@ -58,7 +63,18 @@ felix.auto.start.10= \
reference:file:sc-bundles/bccontrib.jar \
reference:file:sc-bundles/hsqldb.jar \
reference:file:sc-bundles/commons-lang.jar \
- reference:file:sc-bundles/guava.jar
+ reference:file:sc-bundles/guava.jar \
+ reference:file:sc-bundles/weupnp.jar \
+ reference:file:sc-bundles/slf4j-api.jar \
+ reference:file:sc-bundles/dnssecjava.jar
+
+felix.auto.start.11= \
+ reference:file:sc-bundles/sip-api.jar \
+ reference:file:sc-bundles/sdp-api.jar \
+ reference:file:sc-bundles/jain-sip-ri.jar \
+ reference:file:sc-bundles/java-sdp-nist-bridge.jar \
+ reference:file:sc-bundles/ice4j.jar
+
# file:lib/bundle/shell.jar \
# file:lib/bundle/bundlerepository.jar \
# file:lib/bundle/servicebinder.jar \
@@ -94,10 +110,10 @@ felix.auto.start.40= \
reference:file:sc-bundles/argdelegation-service.jar \
reference:file:sc-bundles/resourcemanager.jar \
reference:file:sc-bundles/defaultresources.jar \
- reference:file:sc-bundles/jfontchooserlib.jar \
reference:file:sc-bundles/version-impl.jar \
reference:file:sc-bundles/keybindings.jar \
- reference:file:sc-bundles/jnalib.jar \
+ reference:file:sc-bundles/jna.jar \
+ reference:file:sc-bundles/jna-platform.jar \
reference:file:sc-bundles/netaddr.jar \
reference:file:sc-bundles/sysactivitynotifications.jar \
reference:file:sc-bundles/browserlauncher.jar \
@@ -126,7 +142,6 @@ felix.auto.start.60= \
reference:file:sc-bundles/neomedia.jar \
reference:file:sc-bundles/protocol-jabber.jar \
reference:file:sc-bundles/protocol-sip.jar \
- reference:file:sc-bundles/protocol-yahoo.jar \
reference:file:sc-bundles/protocol-mock.jar \
reference:file:sc-bundles/meta-cl.jar \
reference:file:sc-bundles/msghistory.jar \
@@ -150,7 +165,6 @@ felix.auto.start.70= \
reference:file:sc-bundles/meta-cl-slick.jar \
reference:file:sc-bundles/protocol-sip-slick.jar \
reference:file:sc-bundles/protocol-jabber-slick.jar \
- reference:file:sc-bundles/protocol-yahoo-slick.jar \
reference:file:sc-bundles/protocol-icq-slick.jar \
reference:file:sc-bundles/msghistory-slick.jar \
reference:file:sc-bundles/metahistory-slick.jar \
diff --git a/lib/installer-exclude/bccontrib-1.0-SNAPSHOT.jar b/lib/installer-exclude/bccontrib-1.0-SNAPSHOT.jar
deleted file mode 100644
index 719078e..0000000
--- a/lib/installer-exclude/bccontrib-1.0-SNAPSHOT.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/bccontrib-1.0.jar b/lib/installer-exclude/bccontrib-1.0.jar
new file mode 100644
index 0000000..47a6a89
--- /dev/null
+++ b/lib/installer-exclude/bccontrib-1.0.jar
Binary files differ
diff --git a/lib/installer-exclude/bcpkix-jdk15on-1.54.jar b/lib/installer-exclude/bcpkix-jdk15on-1.54.jar
new file mode 100644
index 0000000..86f7f0b
--- /dev/null
+++ b/lib/installer-exclude/bcpkix-jdk15on-1.54.jar
Binary files differ
diff --git a/lib/installer-exclude/bcpkix-jdk15on-151.jar b/lib/installer-exclude/bcpkix-jdk15on-151.jar
deleted file mode 100755
index 57e0080..0000000
--- a/lib/installer-exclude/bcpkix-jdk15on-151.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/bcprov-jdk15on-1.54.jar b/lib/installer-exclude/bcprov-jdk15on-1.54.jar
new file mode 100644
index 0000000..bd95185
--- /dev/null
+++ b/lib/installer-exclude/bcprov-jdk15on-1.54.jar
Binary files differ
diff --git a/lib/installer-exclude/bcprov-jdk15on-151.jar b/lib/installer-exclude/bcprov-jdk15on-151.jar
deleted file mode 100755
index 4076e11..0000000
--- a/lib/installer-exclude/bcprov-jdk15on-151.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/dict4j.jar b/lib/installer-exclude/dict4j.jar
deleted file mode 100755
index 7eb9813..0000000
--- a/lib/installer-exclude/dict4j.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/dnsjava.jar b/lib/installer-exclude/dnsjava-2.1.7.jar
index 8158168..6e85e30 100644
--- a/lib/installer-exclude/dnsjava.jar
+++ b/lib/installer-exclude/dnsjava-2.1.7.jar
Binary files differ
diff --git a/lib/installer-exclude/dnssecjava-1.1.jar b/lib/installer-exclude/dnssecjava-1.1.jar
new file mode 100644
index 0000000..57ad85a
--- /dev/null
+++ b/lib/installer-exclude/dnssecjava-1.1.jar
Binary files differ
diff --git a/lib/installer-exclude/fmj-1.0-SNAPSHOT.jar b/lib/installer-exclude/fmj-1.0-SNAPSHOT.jar
index a9757b3..9e56a31 100644
--- a/lib/installer-exclude/fmj-1.0-SNAPSHOT.jar
+++ b/lib/installer-exclude/fmj-1.0-SNAPSHOT.jar
Binary files differ
diff --git a/lib/installer-exclude/httpclient.manifest.mf b/lib/installer-exclude/httpclient.manifest.mf
deleted file mode 100644
index bbd83f0..0000000
--- a/lib/installer-exclude/httpclient.manifest.mf
+++ /dev/null
@@ -1,41 +0,0 @@
-Bundle-Name: Apache Http Client
-Bundle-Description: Apache Http Client
-Bundle-Vendor: jitsi.org
-Bundle-Version: 4.2.3
-Bundle-SymbolicName: org.apache.http
-Import-Package: org.apache.commons.logging,
- javax.security.auth.x500,
- javax.net.ssl
-Export-Package: org.apache.http,
- org.apache.http.entity,
- org.apache.http.entity.mime,
- org.apache.http.entity.mime.content,
- org.apache.http.impl,
- org.apache.http.impl.auth,
- org.apache.http.impl.client,
- org.apache.http.impl.conn,
- org.apache.http.impl.entity,
- org.apache.http.impl.io,
- org.apache.http.io,
- org.apache.http.message,
- org.apache.http.params,
- org.apache.http.protocol,
- org.apache.http.util,
- org.apache.http.annotation,
- org.apache.http.auth,
- org.apache.http.auth.params,
- org.apache.http.client,
- org.apache.http.client.entity,
- org.apache.http.client.methods,
- org.apache.http.client.params,
- org.apache.http.client.protocol,
- org.apache.http.client.utils,
- org.apache.http.conn,
- org.apache.http.conn.params,
- org.apache.http.conn.routing,
- org.apache.http.conn.scheme,
- org.apache.http.conn.ssl,
- org.apache.http.conn.util,
- org.apache.http.impl.client
-
-
diff --git a/lib/installer-exclude/ice4j-2.0-20170111.193659-7.jar b/lib/installer-exclude/ice4j-2.0-20170111.193659-7.jar
new file mode 100644
index 0000000..752334b
--- /dev/null
+++ b/lib/installer-exclude/ice4j-2.0-20170111.193659-7.jar
Binary files differ
diff --git a/lib/installer-exclude/ice4j.jar b/lib/installer-exclude/ice4j.jar
deleted file mode 100644
index 0bdde1c..0000000
--- a/lib/installer-exclude/ice4j.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/jain-sdp.jar b/lib/installer-exclude/jain-sdp.jar
deleted file mode 100644
index 8f4b7a6..0000000
--- a/lib/installer-exclude/jain-sdp.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/jain-sip-api.jar b/lib/installer-exclude/jain-sip-api.jar
deleted file mode 100644
index 3ed1a74..0000000
--- a/lib/installer-exclude/jain-sip-api.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/jain-sip-ri-ossonly-1.2.279-jitsi-oss1.jar b/lib/installer-exclude/jain-sip-ri-ossonly-1.2.279-jitsi-oss1.jar
new file mode 100644
index 0000000..f19d986
--- /dev/null
+++ b/lib/installer-exclude/jain-sip-ri-ossonly-1.2.279-jitsi-oss1.jar
Binary files differ
diff --git a/lib/installer-exclude/jain-sip-ri.jar b/lib/installer-exclude/jain-sip-ri.jar
deleted file mode 100644
index e5298b6..0000000
--- a/lib/installer-exclude/jain-sip-ri.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/java-sdp-nist-bridge-1.2.jar b/lib/installer-exclude/java-sdp-nist-bridge-1.2.jar
new file mode 100644
index 0000000..2efa7fc
--- /dev/null
+++ b/lib/installer-exclude/java-sdp-nist-bridge-1.2.jar
Binary files differ
diff --git a/lib/installer-exclude/jcommon-1.0.0.jar b/lib/installer-exclude/jcommon-1.0.0.jar
deleted file mode 100644
index c5d23f4..0000000
--- a/lib/installer-exclude/jcommon-1.0.0.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/jdom.jar b/lib/installer-exclude/jdom.jar
deleted file mode 100644
index 288e64c..0000000
--- a/lib/installer-exclude/jdom.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/jfontchooser-1.0.5.jar b/lib/installer-exclude/jfontchooser-1.0.5.jar
deleted file mode 100644
index 769c8f1..0000000
--- a/lib/installer-exclude/jfontchooser-1.0.5.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/jfontchooser.manifest.mf b/lib/installer-exclude/jfontchooser.manifest.mf
deleted file mode 100644
index 6ad2b73..0000000
--- a/lib/installer-exclude/jfontchooser.manifest.mf
+++ /dev/null
@@ -1,10 +0,0 @@
-Bundle-Name: JFontChooser
-Bundle-Description: A library containing a Java Font Chooser
-Bundle-Vendor: sip-communicator.org
-Bundle-Version: 0.0.1
-Bundle-SymbolicName: say.swing
-Import-Package: javax.swing,
- javax.swing.border,
- javax.swing.event,
- javax.swing.text
-Export-Package: say.swing
diff --git a/lib/installer-exclude/jfreechart-1.0.1.jar b/lib/installer-exclude/jfreechart-1.0.1.jar
deleted file mode 100644
index 3e4f9cd..0000000
--- a/lib/installer-exclude/jfreechart-1.0.1.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/jitsi-gpl-dependencies-1.0-SNAPSHOT.jar b/lib/installer-exclude/jitsi-gpl-dependencies-1.0-SNAPSHOT.jar
new file mode 100644
index 0000000..39091c8
--- /dev/null
+++ b/lib/installer-exclude/jitsi-gpl-dependencies-1.0-SNAPSHOT.jar
Binary files differ
diff --git a/lib/installer-exclude/jitsi-lgpl-dependencies-1.0-SNAPSHOT.jar b/lib/installer-exclude/jitsi-lgpl-dependencies-1.0-SNAPSHOT.jar
index ec93db9..07d4ec4 100644
--- a/lib/installer-exclude/jitsi-lgpl-dependencies-1.0-SNAPSHOT.jar
+++ b/lib/installer-exclude/jitsi-lgpl-dependencies-1.0-SNAPSHOT.jar
Binary files differ
diff --git a/lib/installer-exclude/jmork-1.0.5-SNAPSHOT.jar b/lib/installer-exclude/jmork-1.0.5-SNAPSHOT.jar
deleted file mode 100644
index 671c474..0000000
--- a/lib/installer-exclude/jmork-1.0.5-SNAPSHOT.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/jmork-1.0.5.jar b/lib/installer-exclude/jmork-1.0.5.jar
new file mode 100644
index 0000000..f87ee11
--- /dev/null
+++ b/lib/installer-exclude/jmork-1.0.5.jar
Binary files differ
diff --git a/lib/installer-exclude/jna.manifest.mf b/lib/installer-exclude/jna.manifest.mf
deleted file mode 100644
index 0c32920..0000000
--- a/lib/installer-exclude/jna.manifest.mf
+++ /dev/null
@@ -1,12 +0,0 @@
-Bundle-Name: JNA Lib Provider
-Bundle-Description: JNA Lib Provider
-Bundle-Vendor: sip-communicator.org
-Bundle-Version: 0.0.1
-Bundle-SymbolicName: com.sun.jna
-Export-Package: com.sun.jna.win32,
- com.sun.jna,
- com.sun.jna.ptr,
- com.sun.jna.platform,
- com.sun.jna.platform.win32
-
-
diff --git a/lib/installer-exclude/jsch-0.1.36.jar b/lib/installer-exclude/jsch-0.1.36.jar
deleted file mode 100644
index fde92b4..0000000
--- a/lib/installer-exclude/jsch-0.1.36.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/libjitsi-1.0-SNAPSHOT.jar b/lib/installer-exclude/libjitsi-1.0-20170207.194207-242.jar
index cf37b9e..a8ca832 100644
--- a/lib/installer-exclude/libjitsi-1.0-SNAPSHOT.jar
+++ b/lib/installer-exclude/libjitsi-1.0-20170207.194207-242.jar
Binary files differ
diff --git a/lib/installer-exclude/p4j-exclusions.txt b/lib/installer-exclude/p4j-exclusions.txt
deleted file mode 100644
index 7b76523..0000000
--- a/lib/installer-exclude/p4j-exclusions.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# This file lists those classes that should be ignored by
-# the agent during instrumentation. In most cases these
-# classes trigger JVM internal errors and should be simply
-# ignored. Notice that some classes are ignored even if
-# not listed here (they may cause your JVM to crash
-# seriously so I hard-coded exclusions for those within
-# the agent)
-#
-# The agent will ignore all classes STARTING WITH the string
-# indicated. So, you can exclude a whole package by ending
-# with '.'
-#
-
-org.apache.tomcat.jni.OS
-org.jboss.util.xml.DOMWriter
-org.jboss.mq.il.uil2.ServerSocketManagerHandler
-org.hsqldb.jdbc.jdbcConnection
-org.hsqldb.Index
-bsh.ParserTokenManager
-org.eclipse.jdt.internal.compiler.lookup.TypeBinding
-org.eclipse.jdt.internal.compiler.ast.Expression
-org.eclipse.jdt.internal.compiler.problem.ProblemReporter
-org.eclipse.jdt.internal.compiler.impl.Constant
-com.arjuna.ats.internal.arjuna.objectstore.ShadowingStore
-sun.reflect. \ No newline at end of file
diff --git a/lib/installer-exclude/profiler4j-1.0-beta3-SC.jar b/lib/installer-exclude/profiler4j-1.0-beta3-SC.jar
deleted file mode 100644
index 1212cb8..0000000
--- a/lib/installer-exclude/profiler4j-1.0-beta3-SC.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/sdp-api-1.0.jar b/lib/installer-exclude/sdp-api-1.0.jar
new file mode 100644
index 0000000..fc50919
--- /dev/null
+++ b/lib/installer-exclude/sdp-api-1.0.jar
Binary files differ
diff --git a/lib/installer-exclude/sip-api-1.2-1.2.jar b/lib/installer-exclude/sip-api-1.2-1.2.jar
new file mode 100644
index 0000000..3adf4c3
--- /dev/null
+++ b/lib/installer-exclude/sip-api-1.2-1.2.jar
Binary files differ
diff --git a/lib/installer-exclude/smack.jar b/lib/installer-exclude/smack.jar
index b0cc856..80bd5c7 100644
--- a/lib/installer-exclude/smack.jar
+++ b/lib/installer-exclude/smack.jar
Binary files differ
diff --git a/lib/installer-exclude/smackx-debug.jar b/lib/installer-exclude/smackx-debug.jar
index 3311681..45bcaaf 100644
--- a/lib/installer-exclude/smackx-debug.jar
+++ b/lib/installer-exclude/smackx-debug.jar
Binary files differ
diff --git a/lib/installer-exclude/smackx.jar b/lib/installer-exclude/smackx.jar
index ba590ca..6362497 100644
--- a/lib/installer-exclude/smackx.jar
+++ b/lib/installer-exclude/smackx.jar
Binary files differ
diff --git a/lib/installer-exclude/swing-worker-1.2.jar b/lib/installer-exclude/swing-worker-1.2.jar
deleted file mode 100644
index 6953042..0000000
--- a/lib/installer-exclude/swing-worker-1.2.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/weupnp-0.1.2-SNAPSHOT.jar b/lib/installer-exclude/weupnp-0.1.2-SNAPSHOT.jar
deleted file mode 100644
index 5051f8f..0000000
--- a/lib/installer-exclude/weupnp-0.1.2-SNAPSHOT.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/weupnp-0.1.4.jar b/lib/installer-exclude/weupnp-0.1.4.jar
new file mode 100644
index 0000000..a03b9e2
--- /dev/null
+++ b/lib/installer-exclude/weupnp-0.1.4.jar
Binary files differ
diff --git a/lib/installer-exclude/xalan-2.6.0.jar.ant b/lib/installer-exclude/xalan-2.6.0.jar.ant
deleted file mode 100755
index c307040..0000000
--- a/lib/installer-exclude/xalan-2.6.0.jar.ant
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/ymsg_network_v0_67.jar b/lib/installer-exclude/ymsg_network_v0_67.jar
deleted file mode 100644
index 998358a..0000000
--- a/lib/installer-exclude/ymsg_network_v0_67.jar
+++ /dev/null
Binary files differ
diff --git a/lib/installer-exclude/zrtp4j-light-4.1.0-jitsi-1-SNAPSHOT.jar b/lib/installer-exclude/zrtp4j-light-4.1.0-jitsi-1-SNAPSHOT.jar
new file mode 100644
index 0000000..a7819d2
--- /dev/null
+++ b/lib/installer-exclude/zrtp4j-light-4.1.0-jitsi-1-SNAPSHOT.jar
Binary files differ
diff --git a/lib/installer-exclude/zrtp4j-light.jar b/lib/installer-exclude/zrtp4j-light.jar
deleted file mode 100644
index 72797c6..0000000
--- a/lib/installer-exclude/zrtp4j-light.jar
+++ /dev/null
Binary files differ
diff --git a/lib/jitsi-defaults.properties b/lib/jitsi-defaults.properties
index 417bd00..ff21e05 100644
--- a/lib/jitsi-defaults.properties
+++ b/lib/jitsi-defaults.properties
@@ -37,7 +37,7 @@ net.java.sip.communicator.service.protocol.jabber.GOOGLE_CONTACTS_ENABLED=true
net.java.sip.communicator.plugin.spellcheck.SYSTEM_HUNSPELL_DIR=/usr/share/hunspell
# protocol order for the simple initial account registration wizard
-plugin.simpleaccreg.PROTOCOL_ORDER=SIP|Jabber|Facebook|Google Talk
+plugin.simpleaccreg.PROTOCOL_ORDER=SIP|Jabber|Google Talk
#provisioning defaults
net.java.sip.communicator.plugin.provisioning.MANDATORY=false
@@ -75,7 +75,6 @@ net.java.sip.communicator.plugin.pluginmanager.SYSTEM_BUNDLES=\
net.java.sip.communicator.plugin.defaultresourcepack,\
net.java.sip.communicator.plugin.demuxcontactsource,\
net.java.sip.communicator.replacement.directimage,\
- net.java.sip.communicator.plugin.facebookaccregwizz,\
net.java.sip.communicator.fileaccess,\
net.java.sip.communicator.filehistory,\
net.java.sip.communicator.replacement.flickr,\
@@ -152,8 +151,6 @@ net.java.sip.communicator.plugin.pluginmanager.SYSTEM_BUNDLES=\
net.java.sip.communicator.version,\
net.java.sip.communicator.replacement.viddler,\
net.java.sip.communicator.replacement.vimeo,\
- net.java.sip.communicator.protocol.yahoo,\
- net.java.sip.communicator.plugin.yahooaccregwizz,\
net.java.sip.communicator.replacement.youtube,\
net.java.sip.communicator.libjitsi,\
net.java.sip.communicator.provdisc.mdns,\
diff --git a/lib/native/linux-64/libjunbound.so b/lib/native/linux-64/libjunbound.so
deleted file mode 100644
index 323403b..0000000
--- a/lib/native/linux-64/libjunbound.so
+++ /dev/null
Binary files differ
diff --git a/lib/native/linux/libjunbound.so b/lib/native/linux/libjunbound.so
deleted file mode 100644
index 274d9dd..0000000
--- a/lib/native/linux/libjunbound.so
+++ /dev/null
Binary files differ
diff --git a/lib/native/mac/libjunbound.jnilib b/lib/native/mac/libjunbound.jnilib
deleted file mode 100644
index fcc1428..0000000
--- a/lib/native/mac/libjunbound.jnilib
+++ /dev/null
Binary files differ
diff --git a/lib/native/solaris/libCvidPro.so b/lib/native/solaris/libCvidPro.so
deleted file mode 100644
index dcad6f9..0000000
--- a/lib/native/solaris/libCvidPro.so
+++ /dev/null
Binary files differ
diff --git a/lib/native/solaris/soundbank.gm b/lib/native/solaris/soundbank.gm
deleted file mode 100644
index 1b3f8dc..0000000
--- a/lib/native/solaris/soundbank.gm
+++ /dev/null
Binary files differ
diff --git a/lib/native/windows-64/jmsofficecomm.dll b/lib/native/windows-64/jmsofficecomm.dll
index 974b617..6ce3901 100755
--- a/lib/native/windows-64/jmsofficecomm.dll
+++ b/lib/native/windows-64/jmsofficecomm.dll
Binary files differ
diff --git a/lib/native/windows-64/jmsoutlookaddrbook.dll b/lib/native/windows-64/jmsoutlookaddrbook.dll
index 70095cb..85be249 100755
--- a/lib/native/windows-64/jmsoutlookaddrbook.dll
+++ b/lib/native/windows-64/jmsoutlookaddrbook.dll
Binary files differ
diff --git a/lib/native/windows-64/jmsoutlookaddrbookcomserver32.exe b/lib/native/windows-64/jmsoutlookaddrbookcomserver32.exe
index 6cfa4f0..8415e77 100755
--- a/lib/native/windows-64/jmsoutlookaddrbookcomserver32.exe
+++ b/lib/native/windows-64/jmsoutlookaddrbookcomserver32.exe
Binary files differ
diff --git a/lib/native/windows-64/jmsoutlookaddrbookcomserver64.exe b/lib/native/windows-64/jmsoutlookaddrbookcomserver64.exe
index 4202f2d..66d3db2 100755
--- a/lib/native/windows-64/jmsoutlookaddrbookcomserver64.exe
+++ b/lib/native/windows-64/jmsoutlookaddrbookcomserver64.exe
Binary files differ
diff --git a/lib/native/windows-64/junbound.dll b/lib/native/windows-64/junbound.dll
deleted file mode 100644
index 0a27298..0000000
--- a/lib/native/windows-64/junbound.dll
+++ /dev/null
Binary files differ
diff --git a/lib/native/windows/IeEmbed.exe b/lib/native/windows/IeEmbed.exe
deleted file mode 100644
index 1e83d21..0000000
--- a/lib/native/windows/IeEmbed.exe
+++ /dev/null
Binary files differ
diff --git a/lib/native/windows/jmsofficecomm.dll b/lib/native/windows/jmsofficecomm.dll
index 7d59f64..e51bc3b 100755
--- a/lib/native/windows/jmsofficecomm.dll
+++ b/lib/native/windows/jmsofficecomm.dll
Binary files differ
diff --git a/lib/native/windows/jmsoutlookaddrbook.dll b/lib/native/windows/jmsoutlookaddrbook.dll
index b8445de..a976aea 100755
--- a/lib/native/windows/jmsoutlookaddrbook.dll
+++ b/lib/native/windows/jmsoutlookaddrbook.dll
Binary files differ
diff --git a/lib/native/windows/jmsoutlookaddrbookcomserver32.exe b/lib/native/windows/jmsoutlookaddrbookcomserver32.exe
index 849a90e..22fdb2a 100755
--- a/lib/native/windows/jmsoutlookaddrbookcomserver32.exe
+++ b/lib/native/windows/jmsoutlookaddrbookcomserver32.exe
Binary files differ
diff --git a/lib/native/windows/jmsoutlookaddrbookcomserver64.exe b/lib/native/windows/jmsoutlookaddrbookcomserver64.exe
index a9dc028..dfb52de 100755
--- a/lib/native/windows/jmsoutlookaddrbookcomserver64.exe
+++ b/lib/native/windows/jmsoutlookaddrbookcomserver64.exe
Binary files differ
diff --git a/lib/native/windows/junbound.dll b/lib/native/windows/junbound.dll
deleted file mode 100644
index b1b8da8..0000000
--- a/lib/native/windows/junbound.dll
+++ /dev/null
Binary files differ
diff --git a/lib/testing.properties b/lib/testing.properties
index 850a47c..7b5c1b8 100644
--- a/lib/testing.properties
+++ b/lib/testing.properties
@@ -35,10 +35,6 @@ net.java.sip.communicator.slick.runner.TEST_LIST=ConfigurationServiceLick \
# GenericProtocolProviderServiceLick because it does not add any tests.
#
# IcqProtocolProviderSlick because 2 of its 25 tests fail.
-#
-# Temporally disabling failing test
-# MsnProtocolProviderSlick
-# YahooProtocolProviderSlick
# define all the test classes that can be run standalone, or by the
diff --git a/m2/jitsi-argdelegation/pom.xml b/m2/jitsi-argdelegation/pom.xml
new file mode 100644
index 0000000..7dfb648
--- /dev/null
+++ b/m2/jitsi-argdelegation/pom.xml
@@ -0,0 +1,57 @@
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jitsi</groupId>
+ <artifactId>jitsi</artifactId>
+ <version>2.9-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>jitsi-argdelegation</artifactId>
+ <packaging>jar</packaging>
+
+ <name>jitsi-argdelegation</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jitsi-util</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>net/java/sip/communicator/impl/argdelegation/**</include>
+ <include>net/java/sip/communicator/service/argdelegation/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.sourceDirectory}/net/java/sip/communicator/impl/argdelegation/argdelegation.manifest.mf</manifestFile>
+ </archive>
+ <includes>
+ <include>net/java/sip/communicator/impl/argdelegation/**</include>
+ <include>net/java/sip/communicator/service/argdelegation/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/m2/jitsi-certificate/pom.xml b/m2/jitsi-certificate/pom.xml
new file mode 100644
index 0000000..a486b92
--- /dev/null
+++ b/m2/jitsi-certificate/pom.xml
@@ -0,0 +1,73 @@
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jitsi</groupId>
+ <artifactId>jitsi</artifactId>
+ <version>2.9-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>jitsi-certificate</artifactId>
+ <packaging>jar</packaging>
+
+ <name>jitsi-certificate</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk15on</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore</artifactId>
+ <version>4.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpmime</artifactId>
+ <version>4.4</version>
+ </dependency>
+ <!-- org.jitsi -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jitsi-configuration</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>net/java/sip/communicator/service/certificate/**</include>
+ <include>net/java/sip/communicator/impl/certificate/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.sourceDirectory}/net/java/sip/communicator/impl/certificate/certificate.manifest.mf</manifestFile>
+ </archive>
+ <includes>
+ <include>net/java/sip/communicator/service/certificate/**</include>
+ <include>net/java/sip/communicator/impl/certificate/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/m2/jitsi-desktoputil/pom.xml b/m2/jitsi-desktoputil/pom.xml
new file mode 100644
index 0000000..701559c
--- /dev/null
+++ b/m2/jitsi-desktoputil/pom.xml
@@ -0,0 +1,57 @@
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jitsi</groupId>
+ <artifactId>jitsi</artifactId>
+ <version>2.9-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>jitsi-desktoputil</artifactId>
+ <packaging>jar</packaging>
+
+ <name>jitsi-desktoputil</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>net.java.dev.laf-widget</groupId>
+ <artifactId>laf-widget</artifactId>
+ <version>4.0</version>
+ </dependency>
+ <!-- org.jitsi -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jitsi-configuration</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>net/java/sip/communicator/plugin/desktoputil/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.sourceDirectory}/net/java/sip/communicator/plugin/desktoputil/desktoputil.manifest.mf</manifestFile>
+ </archive>
+ <includes>
+ <include>net/java/sip/communicator/plugin/desktoputil/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/m2/jitsi-dns/pom.xml b/m2/jitsi-dns/pom.xml
new file mode 100644
index 0000000..bbedef9
--- /dev/null
+++ b/m2/jitsi-dns/pom.xml
@@ -0,0 +1,61 @@
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jitsi</groupId>
+ <artifactId>jitsi</artifactId>
+ <version>2.9-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>jitsi-dns</artifactId>
+ <packaging>jar</packaging>
+
+ <name>jitsi-dns</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>dnsjava</groupId>
+ <artifactId>dnsjava</artifactId>
+ </dependency>
+ <!-- org.jitsi -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>dnssecjava</artifactId>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jitsi-protocol</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>net/java/sip/communicator/impl/dns/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.sourceDirectory}/net/java/sip/communicator/impl/dns/dns.manifest.mf</manifestFile>
+ </archive>
+ <includes>
+ <include>net/java/sip/communicator/impl/dns/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/m2/jitsi-globaldisplaydetails/pom.xml b/m2/jitsi-globaldisplaydetails/pom.xml
new file mode 100644
index 0000000..0e3a828
--- /dev/null
+++ b/m2/jitsi-globaldisplaydetails/pom.xml
@@ -0,0 +1,54 @@
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jitsi</groupId>
+ <artifactId>jitsi</artifactId>
+ <version>2.9-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>jitsi-globaldisplaydetails</artifactId>
+ <packaging>jar</packaging>
+
+ <name>jitsi-globaldisplaydetails</name>
+
+ <dependencies>
+ <!-- org.jitsi -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jitsi-configuration</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>net/java/sip/communicator/service/globaldisplaydetails/**</include>
+ <include>net/java/sip/communicator/impl/globaldisplaydetails/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.sourceDirectory}/net/java/sip/communicator/impl/globaldisplaydetails/globaldisplaydetails.manifest.mf</manifestFile>
+ </archive>
+ <includes>
+ <include>net/java/sip/communicator/service/globaldisplaydetails/**</include>
+ <include>net/java/sip/communicator/impl/globaldisplaydetails/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/m2/jitsi-hid/pom.xml b/m2/jitsi-hid/pom.xml
new file mode 100644
index 0000000..7b0da97
--- /dev/null
+++ b/m2/jitsi-hid/pom.xml
@@ -0,0 +1,51 @@
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jitsi</groupId>
+ <artifactId>jitsi</artifactId>
+ <version>2.9-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>jitsi-hid</artifactId>
+ <packaging>jar</packaging>
+
+ <name>jitsi-hid</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>net/java/sip/communicator/service/hid/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.sourceDirectory}/net/java/sip/communicator/service/hid/hid.manifest.mf</manifestFile>
+ </archive>
+ <includes>
+ <include>net/java/sip/communicator/service/hid/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/m2/jitsi-muc/pom.xml b/m2/jitsi-muc/pom.xml
new file mode 100644
index 0000000..952ddd8
--- /dev/null
+++ b/m2/jitsi-muc/pom.xml
@@ -0,0 +1,52 @@
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jitsi</groupId>
+ <artifactId>jitsi</artifactId>
+ <version>2.9-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>jitsi-muc</artifactId>
+ <packaging>jar</packaging>
+
+ <name>jitsi-muc</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jitsi-protocol</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>net/java/sip/communicator/service/muc/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.sourceDirectory}/net/java/sip/communicator/impl/muc/muc.manifest.mf</manifestFile>
+ </archive>
+ <includes>
+ <include>net/java/sip/communicator/service/muc/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/m2/jitsi-neomedia/pom.xml b/m2/jitsi-neomedia/pom.xml
new file mode 100644
index 0000000..e63f8e0
--- /dev/null
+++ b/m2/jitsi-neomedia/pom.xml
@@ -0,0 +1,52 @@
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jitsi</groupId>
+ <artifactId>jitsi</artifactId>
+ <version>2.9-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>jitsi-neomedia</artifactId>
+ <packaging>jar</packaging>
+
+ <name>jitsi-neomedia</name>
+
+ <dependencies>
+ <!-- org.jitsi -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jitsi-util</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>net/java/sip/communicator/impl/neomedia/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.sourceDirectory}/net/java/sip/communicator/impl/neomedia/neomedia.manifest.mf</manifestFile>
+ </archive>
+ <includes>
+ <include>net/java/sip/communicator/impl/neomedia/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/m2/jitsi-notification-service/pom.xml b/m2/jitsi-notification-service/pom.xml
new file mode 100644
index 0000000..7ad123e
--- /dev/null
+++ b/m2/jitsi-notification-service/pom.xml
@@ -0,0 +1,52 @@
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jitsi</groupId>
+ <artifactId>jitsi</artifactId>
+ <version>2.9-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>jitsi-notification-service</artifactId>
+ <packaging>jar</packaging>
+
+ <name>jitsi-notification-service</name>
+
+ <dependencies>
+ <!-- org.jitsi -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jitsi-configuration</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>net/java/sip/communicator/service/notification/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.sourceDirectory}/net/java/sip/communicator/service/notification/notification.manifest.mf</manifestFile>
+ </archive>
+ <includes>
+ <include>net/java/sip/communicator/service/notification/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/m2/jitsi-packetlogging/pom.xml b/m2/jitsi-packetlogging/pom.xml
index 5f0ce33..bcd42f1 100644
--- a/m2/jitsi-packetlogging/pom.xml
+++ b/m2/jitsi-packetlogging/pom.xml
@@ -23,6 +23,14 @@
<artifactId>libjitsi</artifactId>
</dependency>
<dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jitsi-util</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
</dependency>
diff --git a/m2/jitsi-protocol-sip/pom.xml b/m2/jitsi-protocol-sip/pom.xml
new file mode 100644
index 0000000..4f1ec6e
--- /dev/null
+++ b/m2/jitsi-protocol-sip/pom.xml
@@ -0,0 +1,92 @@
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jitsi</groupId>
+ <artifactId>jitsi</artifactId>
+ <version>2.9-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>jitsi-protocol-sip</artifactId>
+ <packaging>jar</packaging>
+
+ <name>jitsi-protocol-sip</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opentelecoms.sip</groupId>
+ <artifactId>sip-api-1.2</artifactId>
+ <version>1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opentelecoms.sdp</groupId>
+ <artifactId>java-sdp-nist-bridge</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jitsi</groupId>
+ <artifactId>jain-sip-ri-ossonly</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>dnsjava</groupId>
+ <artifactId>dnsjava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore</artifactId>
+ <version>4.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpmime</artifactId>
+ <version>4.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.igniterealtime.smack</groupId>
+ <artifactId>smack</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jitsi-version</artifactId>
+ <version>2.9-20160511.122033-1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>net/java/sip/communicator/impl/protocol/sip/**.java</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.sourceDirectory}/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf</manifestFile>
+ </archive>
+ <includes>
+ <include>net/java/sip/communicator/impl/protocol/sip/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/m2/jitsi-protocol/pom.xml b/m2/jitsi-protocol/pom.xml
index e045b56..d97e083 100644
--- a/m2/jitsi-protocol/pom.xml
+++ b/m2/jitsi-protocol/pom.xml
@@ -61,11 +61,9 @@
</excludes>
<includes>
<include>net/java/sip/communicator/service/protocol/**</include>
- <include>resources/images/protocol/facebook/**</include>
<include>resources/images/protocol/googletalk/**</include>
<include>resources/images/protocol/icq/**</include>
<include>resources/images/protocol/jabber/**</include>
- <include>resources/images/protocol/yahoo/**</include>
</includes>
</configuration>
</plugin>
@@ -77,11 +75,9 @@
<exclude>resources/images/protocol/media/**</exclude>
</excludes>
<includes>
- <include>resources/images/protocol/facebook/**</include>
<include>resources/images/protocol/googletalk/**</include>
<include>resources/images/protocol/icq/**</include>
<include>resources/images/protocol/jabber/**</include>
- <include>resources/images/protocol/yahoo/**</include>
</includes>
</resource>
</resources>
diff --git a/m2/jitsi-reconnect/pom.xml b/m2/jitsi-reconnect/pom.xml
new file mode 100644
index 0000000..8eaf4f1
--- /dev/null
+++ b/m2/jitsi-reconnect/pom.xml
@@ -0,0 +1,52 @@
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jitsi</groupId>
+ <artifactId>jitsi</artifactId>
+ <version>2.9-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>jitsi-reconnect</artifactId>
+ <packaging>jar</packaging>
+
+ <name>jitsi-reconnect</name>
+
+ <dependencies>
+ <!-- org.jitsi -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jitsi-configuration</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>net/java/sip/communicator/plugin/reconnectplugin/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.sourceDirectory}/net/java/sip/communicator/plugin/reconnectplugin/reconnectplugin.manifest.mf</manifestFile>
+ </archive>
+ <includes>
+ <include>net/java/sip/communicator/plugin/reconnectplugin/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/m2/jitsi-sysactivity/pom.xml b/m2/jitsi-sysactivity/pom.xml
new file mode 100644
index 0000000..0f45f4d
--- /dev/null
+++ b/m2/jitsi-sysactivity/pom.xml
@@ -0,0 +1,128 @@
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jitsi</groupId>
+ <artifactId>jitsi</artifactId>
+ <version>2.9-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>jitsi-sysactivity</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>jitsi-sysactivity</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.freedesktop.dbus</groupId>
+ <artifactId>dbus-java</artifactId>
+ <version>2.7</version>
+ </dependency>
+ <dependency>
+ <groupId>org.abstractj.libmatthew</groupId>
+ <artifactId>hexdump</artifactId>
+ <version>0.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.abstractj.libmatthew</groupId>
+ <artifactId>unix</artifactId>
+ <version>0.5.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.abstractj.libmatthew</groupId>
+ <artifactId>libunix</artifactId>
+ <version>0.5.1</version>
+ <type>so</type>
+ </dependency>
+ <!-- org.jitsi -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jitsi-util</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>net/java/sip/communicator/service/sysactivity/**</include>
+ <include>net/java/sip/communicator/impl/sysactivity/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.framework,
+ org.jitsi.service.version,
+ org.jitsi.service.configuration,
+ org.jitsi.util,
+ org.jitsi.service.resources, net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.util
+ </Import-Package>
+ <Export-Package>net.java.sip.communicator.service.sysactivity,
+ net.java.sip.communicator.service.sysactivity.event
+ </Export-Package>
+ <Private-Package>net.java.sip.communicator.impl.sysactivity.*</Private-Package>
+ <Bundle-Activator>net.java.sip.communicator.impl.sysactivity.SysActivityActivator</Bundle-Activator>
+ <Bundle-NativeCode>
+ darwin/libsysactivitynotifications.jnilib;osname=Mac OS X;processor=x86-64,
+ linux-x86/libsysactivitynotifications.so;osname=Linux;processor=x86,
+ linux-x86-64/libsysactivitynotifications.so;osname=Linux;processor=x86-64,
+ win32-x86/sysactivitynotifications.dll;osname=Win32;processor=x86,
+ win32-x86-64/sysactivitynotifications.dll;osname=Win32;processor=x86-64
+ </Bundle-NativeCode>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ <resources>
+ <resource>
+ <targetPath>darwin</targetPath>
+ <directory>../../lib/native/mac</directory>
+ <includes>
+ <include>**/*sysactivitynotifications.*</include>
+ </includes>
+ </resource>
+ <resource>
+ <targetPath>linux-x86</targetPath>
+ <directory>../../lib/native/linux</directory>
+ <includes>
+ <include>**/*sysactivitynotifications.*</include>
+ </includes>
+ </resource>
+ <resource>
+ <targetPath>linux-x86-64</targetPath>
+ <directory>../../lib/native/linux-64</directory>
+ <includes>
+ <include>**/*sysactivitynotifications.*</include>
+ </includes>
+ </resource>
+ <resource>
+ <targetPath>win32-x86-64</targetPath>
+ <directory>../../lib/native/windows-64</directory>
+ <includes>
+ <include>**/*sysactivitynotifications.*</include>
+ </includes>
+ </resource>
+ <resource>
+ <targetPath>win32-x86</targetPath>
+ <directory>../../lib/native/windows</directory>
+ <includes>
+ <include>**/*sysactivitynotifications.*</include>
+ </includes>
+ </resource>
+ </resources>
+
+ </build>
+</project>
diff --git a/m2/jitsi-systray-service/pom.xml b/m2/jitsi-systray-service/pom.xml
new file mode 100644
index 0000000..3965173
--- /dev/null
+++ b/m2/jitsi-systray-service/pom.xml
@@ -0,0 +1,52 @@
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jitsi</groupId>
+ <artifactId>jitsi</artifactId>
+ <version>2.9-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>jitsi-systray-service</artifactId>
+ <packaging>jar</packaging>
+
+ <name>jitsi-systray-service</name>
+
+ <dependencies>
+ <!-- org.jitsi -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jitsi-configuration</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>net/java/sip/communicator/service/systray/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.sourceDirectory}/net/java/sip/communicator/service/systray/systray.manifest.mf</manifestFile>
+ </archive>
+ <includes>
+ <include>net/java/sip/communicator/service/systray/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/m2/jitsi-util/pom.xml b/m2/jitsi-util/pom.xml
index a17620f..1a01006 100644
--- a/m2/jitsi-util/pom.xml
+++ b/m2/jitsi-util/pom.xml
@@ -60,9 +60,27 @@
</archive>
<includes>
<include>net/java/sip/communicator/util/**</include>
+ <include>META-INF/services/**</include>
</includes>
</configuration>
</plugin>
+ <plugin>
+ <groupId>eu.somatik.serviceloader-maven-plugin</groupId>
+ <artifactId>serviceloader-maven-plugin</artifactId>
+ <version>1.0.7</version>
+ <configuration>
+ <services>
+ <param>sun.net.spi.nameservice.NameServiceDescriptor</param>
+ </services>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
</project>
diff --git a/m2/jitsi-version/pom.xml b/m2/jitsi-version/pom.xml
new file mode 100644
index 0000000..6531000
--- /dev/null
+++ b/m2/jitsi-version/pom.xml
@@ -0,0 +1,57 @@
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jitsi</groupId>
+ <artifactId>jitsi</artifactId>
+ <version>2.9-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>jitsi-version</artifactId>
+ <packaging>jar</packaging>
+
+ <name>jitsi-version</name>
+
+ <dependencies>
+ <!-- org.jitsi -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jitsi-configuration</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>net/java/sip/communicator/impl/version/**</include>
+ </includes>
+ <excludes>
+ <exclude>**/*.tmpl</exclude>
+ <exclude>**/version.impl.manifest.mf</exclude>
+ <exclude>**/SipCommunicatorVersionTask.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.sourceDirectory}/net/java/sip/communicator/impl/version/version.impl.manifest.mf</manifestFile>
+ </archive>
+ <includes>
+ <include>net/java/sip/communicator/impl/version/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/m2/pom.xml b/m2/pom.xml
index e8fd64d..931a7eb 100644
--- a/m2/pom.xml
+++ b/m2/pom.xml
@@ -7,8 +7,7 @@
<parent>
<groupId>org.jitsi</groupId>
<artifactId>jitsi-universe</artifactId>
- <version>1.0-SNAPSHOT</version>
- <relativePath>../../jitsi-universe/pom.xml</relativePath>
+ <version>1.0-20161228.135522-20</version>
</parent>
<artifactId>jitsi</artifactId>
@@ -19,21 +18,50 @@
<url>https://jitsi.org</url>
<modules>
+ <module>jitsi-argdelegation</module>
+ <module>jitsi-certificate</module>
<module>jitsi-configuration</module>
<module>jitsi-contactlist</module>
<module>jitsi-credentialsstorage</module>
+ <module>jitsi-desktoputil</module>
+ <module>jitsi-dns</module>
<module>jitsi-dnsservice</module>
<module>jitsi-fileaccess</module>
+ <module>jitsi-globaldisplaydetails</module>
+ <module>jitsi-hid</module>
+ <module>jitsi-muc</module>
+ <module>jitsi-neomedia</module>
<module>jitsi-netaddr</module>
+ <module>jitsi-notification-service</module>
<module>jitsi-packetlogging</module>
<module>jitsi-protocol</module>
<module>jitsi-protocol-jabber</module>
+ <module>jitsi-protocol-sip</module>
<module>jitsi-protocol-media</module>
+ <module>jitsi-reconnect</module>
<module>jitsi-resourcemanager</module>
+ <module>jitsi-sysactivity</module>
+ <module>jitsi-systray-service</module>
<module>jitsi-ui-service</module>
<module>jitsi-util</module>
+ <module>jitsi-version</module>
</modules>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>libjitsi</artifactId>
+ <version>1.0-20170207.194207-242</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>ice4j</artifactId>
+ <version>2.0-20170111.193659-7</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
<build>
<sourceDirectory>../../src</sourceDirectory>
<pluginManagement>
diff --git a/nbproject/project.xml b/nbproject/project.xml
index 939c825..719b909 100644
--- a/nbproject/project.xml
+++ b/nbproject/project.xml
@@ -116,7 +116,7 @@
<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/2">
<compilation-unit>
<package-root>src</package-root>
- <classpath mode="compile">lib/felix.jar:lib/bundle/commons-logging.jar:lib/bundle/junit.jar:lib/bundle/log4j.jar:lib/installer-exclude/apache-ant-1.7.0.jar:lib/installer-exclude/dhcp4java-1.00.jar:lib/installer-exclude/dict4j.jar:lib/installer-exclude/dnsjava.jar:lib/installer-exclude/fmj.jar:lib/installer-exclude/forms-1.2.1.jar:lib/installer-exclude/gdata-client-1.0.jar:lib/installer-exclude/gdata-client-meta-1.0.jar:lib/installer-exclude/gdata-contacts-3.0.jar:lib/installer-exclude/gdata-contacts-meta-3.0.jar:lib/installer-exclude/gdata-core-1.0.jar:lib/installer-exclude/google-collect-1.0-rc1.jar:lib/installer-exclude/hexdump-0.2.jar:lib/installer-exclude/httpclient-osgi-4.2.3.jar:lib/installer-exclude/httpcore-osgi-4.2.3.jar:lib/installer-exclude/ice4j.jar:lib/installer-exclude/irc-api-1.0.jar:lib/installer-exclude/jain-sdp.jar:lib/installer-exclude/jain-sip-api.jar:lib/installer-exclude/jain-sip-ri.jar:lib/installer-exclude/jdic_misc.jar:lib/installer-exclude/jfontchooser-1.0.5.jar:lib/installer-exclude/jmdns.jar:lib/installer-exclude/jmyspell-core.jar:lib/installer-exclude/jna.jar:lib/installer-exclude/jnsapi.jar:lib/installer-exclude/joscar-client.jar:lib/installer-exclude/joscar-common.jar:lib/installer-exclude/joscar-protocol.jar:lib/installer-exclude/jsch-0.1.36.jar:lib/installer-exclude/jsocks-klea.jar:lib/installer-exclude/json-simple-1.1.1.jar:lib/installer-exclude/jspeex.jar:lib/installer-exclude/junit.jar:lib/installer-exclude/laf-widget.jar:lib/installer-exclude/lcrypto-jdk16-143.jar:lib/installer-exclude/libdbus-java-2.7.jar:lib/installer-exclude/libjitsi.jar:lib/installer-exclude/log4j-1.2.8.jar:lib/installer-exclude/lti-civil-no_s_w_t.jar:lib/installer-exclude/mac_widgets-0.9.5.jar:lib/installer-exclude/nist-sdp-1.0.jar:lib/installer-exclude/otr4j.jar:lib/installer-exclude/pircbot.jar:lib/installer-exclude/profiler4j-1.0-beta3-SC.jar:lib/installer-exclude/sdes4j.jar:lib/installer-exclude/smack.jar:lib/installer-exclude/smackx.jar:lib/installer-exclude/swing-worker-1.2.jar:lib/installer-exclude/jna-platform.jar:lib/installer-exclude/unix-0.5.jar:lib/installer-exclude/weupnp-0.1.2-SNAPSHOT.jar:lib/installer-exclude/ymsg_network_v0_67.jar:lib/installer-exclude/zrtp4j-light.jar:lib/installer-exclude/jcalendar-1.4.jar:lib/installer-exclude/bcpkix-jdk15on-151.jar:lib/installer-exclude/bcprov-jdk15on-151.jar:lib/installer-exclude/guava-15.0.jar:lib/installer-exclude/libphonenumber-5.9.jar:lib/installer-exclude/commons-lang3-3.1.jar:lib/installer-exclude/jmork-1.0.5-SNAPSHOT.jar:lib/os-specific/mac/growl4j.jar:lib/os-specific/mac/OrangeExtensions.jar:lib/os-specific/mac/installer-exclude/dock.jar</classpath>
+ <classpath mode="compile">lib/felix.jar:lib/bundle/commons-logging.jar:lib/bundle/junit.jar:lib/bundle/log4j.jar:lib/installer-exclude/apache-ant-1.7.0.jar:lib/installer-exclude/dhcp4java-1.00.jar:lib/installer-exclude/dict4j.jar:lib/installer-exclude/dnsjava.jar:lib/installer-exclude/fmj.jar:lib/installer-exclude/forms-1.2.1.jar:lib/installer-exclude/gdata-client-1.0.jar:lib/installer-exclude/gdata-client-meta-1.0.jar:lib/installer-exclude/gdata-contacts-3.0.jar:lib/installer-exclude/gdata-contacts-meta-3.0.jar:lib/installer-exclude/gdata-core-1.0.jar:lib/installer-exclude/google-collect-1.0-rc1.jar:lib/installer-exclude/hexdump-0.2.jar:lib/installer-exclude/httpclient-osgi-4.2.3.jar:lib/installer-exclude/httpcore-osgi-4.2.3.jar:lib/installer-exclude/ice4j-2.0-20170111.193659-7.jar:lib/installer-exclude/irc-api-1.0.jar:lib/installer-exclude/jain-sdp.jar:lib/installer-exclude/jain-sip-api.jar:lib/installer-exclude/jain-sip-ri.jar:lib/installer-exclude/jdic_misc.jar:lib/installer-exclude/jmdns.jar:lib/installer-exclude/jmyspell-core.jar:lib/installer-exclude/jna.jar:lib/installer-exclude/jnsapi.jar:lib/installer-exclude/joscar-client.jar:lib/installer-exclude/joscar-common.jar:lib/installer-exclude/joscar-protocol.jar:lib/installer-exclude/jsch-0.1.36.jar:lib/installer-exclude/jsocks-klea.jar:lib/installer-exclude/json-simple-1.1.1.jar:lib/installer-exclude/jspeex.jar:lib/installer-exclude/junit.jar:lib/installer-exclude/laf-widget.jar:lib/installer-exclude/lcrypto-jdk16-143.jar:lib/installer-exclude/libdbus-java-2.7.jar:lib/installer-exclude/libjitsi-1.0-20170201.212655-235.jar:lib/installer-exclude/log4j-1.2.8.jar:lib/installer-exclude/lti-civil-no_s_w_t.jar:lib/installer-exclude/mac_widgets-0.9.5.jar:lib/installer-exclude/nist-sdp-1.0.jar:lib/installer-exclude/otr4j.jar:lib/installer-exclude/pircbot.jar:lib/installer-exclude/profiler4j-1.0-beta3-SC.jar:lib/installer-exclude/sdes4j.jar:lib/installer-exclude/smack.jar:lib/installer-exclude/smackx.jar:lib/installer-exclude/swing-worker-1.2.jar:lib/installer-exclude/jna-platform.jar:lib/installer-exclude/unix-0.5.jar:lib/installer-exclude/weupnp-0.1.4.jar:lib/installer-exclude/zrtp4j-light-4.1.0-jitsi-1-SNAPSHOT.jar:lib/installer-exclude/jcalendar-1.4.jar:lib/installer-exclude/bcpkix-jdk15on-151.jar:lib/installer-exclude/bcprov-jdk15on-151.jar:lib/installer-exclude/guava-15.0.jar:lib/installer-exclude/libphonenumber-5.9.jar:lib/installer-exclude/commons-lang3-3.1.jar:lib/installer-exclude/jmork-1.0.5-SNAPSHOT.jar:lib/os-specific/mac/growl4j.jar:lib/os-specific/mac/OrangeExtensions.jar:lib/os-specific/mac/installer-exclude/dock.jar</classpath>
<built-to>classes</built-to>
<source-level>1.5</source-level>
</compilation-unit>
diff --git a/resources/config/defaults.properties b/resources/config/defaults.properties
index f126476..38bb564 100644
--- a/resources/config/defaults.properties
+++ b/resources/config/defaults.properties
@@ -54,14 +54,9 @@ net.java.sip.communicator.service.msghistory.IS_MESSAGE_HISTORY_ENABLED=true
plugin.branding.ABOUT_LOGO_FONT_SIZE=14
plugin.branding.ABOUT_TEXT_INDENT=180
plugin.branding.SPLASH_SCREEN_TEXT_INDENT=190
-plugin.branding.LOADING_BUNDLE_PANEL_HEIGHT=40
plugin.branding.LOADING_BUNDLE_PANEL_BORDER=10
plugin.branding.ABOUT_PARAGRAPH_GAP=10
-# Application name could be present in the background image and in this case
-# we may not want to show it again.
-plugin.branding.IS_APPLICATION_NAME_SHOWN=true
-
# jabber accregwizz
plugin.jabberaccregwizz.SERVER_COMMENTS=net/java/sip/communicator/plugin/jabberaccregwizz/resources/servercomments.xml
diff --git a/resources/config/spellcheck/parameters.xml b/resources/config/spellcheck/parameters.xml
index 1d3e1e2..3c1cf87 100644
--- a/resources/config/spellcheck/parameters.xml
+++ b/resources/config/spellcheck/parameters.xml
@@ -117,6 +117,7 @@
<locale label="Occitan (France)" isoCode="oc,fr" dictionaryUrl="http://dictionaries.jitsi.net/oc_FR.zip" flagIcon="fr"/>
<locale label="Persian (Iran)" isoCode="fa,ir" dictionaryUrl="http://dictionaries.jitsi.net/fa_IR.zip" flagIcon="ir"/>
<locale label="Polish (Poland)" isoCode="pl,pl" dictionaryUrl="http://dictionaries.jitsi.net/pl_PL.zip" flagIcon="pl"/>
+ <locale label="Portuguese (Brazil)" isoCode="pt,br" dictionaryUrl="http://dictionaries.jitsi.net/pt_BR.zip" flagIcon="br"/>
<locale label="Portuguese (Portugal)" isoCode="pt,pt" dictionaryUrl="http://dictionaries.jitsi.net/pt_PT.zip" flagIcon="pt"/>
<locale label="Punjabi (India)" isoCode="xx,in" dictionaryUrl="http://dictionaries.jitsi.net/xx_IN.zip" flagIcon="in"/>
<locale label="Romanian (Romania)" isoCode="ro,ro" dictionaryUrl="http://dictionaries.jitsi.net/ro_RO.zip" flagIcon="ro"/>
diff --git a/resources/images/images.properties b/resources/images/images.properties
index d0ff14c..e9ac9ea 100644
--- a/resources/images/images.properties
+++ b/resources/images/images.properties
@@ -408,20 +408,9 @@ service.systray.DOCK_ICON_EXTENDED_AWAY=resources/images/impl/systray/dock-exten
service.systray.DOCK_ICON_FFC=resources/images/impl/systray/dock-chatty.png
service.systray.DOCK_ICON_DND=resources/images/impl/systray/dock-dnd.png
service.systray.STATUS_MENU_ICON=resources/images/impl/systray/statusIcon.png
-service.systray.MESSAGE_ICON=resources/images/impl/systray/envelope.png
-service.systray.MESSAGE_ICON_WINDOWS=resources/images/impl/systray/envelopeWindows.png
-service.systray.MESSAGE_ICON_MACOSX=resources/images/impl/systray/envelopeMacOSX.png
-service.systray.MESSAGE_ICON_MACOSX_WHITE=resources/images/impl/systray/envelopeMacOSXWhite.png
service.systray.QUIT_MENU_ICON=resources/images/impl/gui/common/quit16x16.png
service.systray.CONFIGURE_ICON=resources/images/impl/gui/common/configureIcon.png
-# dict protocol icons
-service.protocol.dict.DICT_16x16=resources/images/protocol/dict/dict-16x16.png
-service.protocol.dict.DICT_32x32=resources/images/protocol/dict/dict-32x32.png
-service.protocol.dict.DICT_48x48=resources/images/protocol/dict/dict-48x48.png
-service.protocol.dict.DICT_64x64=resources/images/protocol/dict/dict-64x64.png
-service.protocol.dict.OFFLINE_STATUS_ICON=resources/images/protocol/dict/dict-16x16-offline.png
-
# icq protocol icons
service.protocol.icq.ICQ_16x16=resources/images/protocol/icq/icq16x16-online.png
service.protocol.icq.ICQ_32x32=resources/images/protocol/icq/icq32x32.png
@@ -429,33 +418,6 @@ service.protocol.icq.ICQ_48x48=resources/images/protocol/icq/icq48x48.png
service.protocol.icq.ICQ_64x64=resources/images/protocol/icq/icq64x64.png
service.protocol.icq.CONNECTING=resources/images/protocol/icq/cr16-action-icq_connecting-1.gif
-# yahoo protocol icons
-service.protocol.yahoo.YAHOO_16x16=resources/images/protocol/yahoo/yahoo16x16.png
-service.protocol.yahoo.YAHOO_32x32=resources/images/protocol/yahoo/yahoo32x32.png
-service.protocol.yahoo.YAHOO_48x48=resources/images/protocol/yahoo/yahoo48x48.png
-service.protocol.yahoo.YAHOO_64x64=resources/images/protocol/yahoo/yahoo64x64.png
-
-# zeroconf protocol icons
-service.protocol.zeroconf.ZEROCONF_16x16=resources/images/protocol/zeroconf/zeroconf16x16.png
-service.protocol.zeroconf.ZEROCONF_32x32=resources/images/protocol/zeroconf/zeroconf32x32.png
-service.protocol.zeroconf.ZEROCONF_48x48=resources/images/protocol/zeroconf/zeroconf48x48.png
-service.protocol.zeroconf.ZEROCONF_64x64=resources/images/protocol/zeroconf/zeroconf64x64.png
-service.protocol.zeroconf.ONLINE_STATUS_ICON=resources/images/protocol/zeroconf/zeroconf-online.png
-service.protocol.zeroconf.OFFLINE_STATUS_ICON=resources/images/protocol/zeroconf/zeroconf-offline.png
-service.protocol.zeroconf.DND_STATUS_ICON=resources/images/protocol/zeroconf/zeroconf-dnd.png
-service.protocol.zeroconf.INVISIBLE_STATUS_ICON=resources/images/protocol/zeroconf/zeroconf-invisible.png
-
-# ssh protocol icons
-service.protocol.ssh.SSH_16x16=resources/images/protocol/ssh/ssh-online.png
-service.protocol.ssh.SSH_32x32=resources/images/protocol/ssh/ssh32x32.png
-service.protocol.ssh.SSH_48x48=resources/images/protocol/ssh/ssh48x48.png
-service.protocol.ssh.SSH_64x64=resources/images/protocol/ssh/ssh64x64.png
-service.protocol.ssh.OFFLINE_STATUS_ICON=resources/images/protocol/ssh/ssh-offline.png
-service.protocol.ssh.NA_STATUS_ICON=resources/images/protocol/ssh/ssh-na.png
-service.protocol.ssh.CONNECTING_ICON=resources/images/protocol/ssh/ssh-connecting.png
-service.protocol.ssh.CONNECTED_ICON=resources/images/protocol/ssh/ssh-connected.png
-service.protocol.ssh.FILE_TRANSFER_ICON=resources/images/protocol/ssh/ssh-filetransfer.png
-
# sip protocol icons
service.protocol.sip.SIP_16x16=resources/images/protocol/sip/sip16x16.png
service.protocol.sip.SIP_64x64=resources/images/protocol/sip/sip64x64.png
@@ -503,21 +465,12 @@ service.protocol.googletalk.GTALK_64x64=resources/images/protocol/googletalk/log
service.protocol.iptel.IPTEL_16x16=resources/images/protocol/iptel/sip16x16.png
service.protocol.iptel.IPTEL_64x64=resources/images/protocol/iptel/sip64x64.png
-# sip2sip accregwizz
-service.protocol.sip2sip.SIP2SIP_16x16=resources/images/protocol/sip2sip/sip16x16.png
-service.protocol.sip2sip.SIP2SIP_64x64=resources/images/protocol/sip2sip/sip64x64.png
-
# ippi accregwizz
service.protocol.ippi.IPPI_16x16=resources/images/protocol/ippi/sip16x16.png
service.protocol.ippi.IPPI_64x64=resources/images/protocol/ippi/sip64x64.png
-# facebook accregwizz
-service.protocol.facebook.FACEBOOK_16x16=resources/images/protocol/facebook/facebook-online.png
-service.protocol.facebook.FACEBOOK_48x48=resources/images/protocol/facebook/facebook48.png
-
# branding plugin images
plugin.branding.ABOUT_WINDOW_BACKGROUND=resources/images/plugin/branding/aboutWindowBackground.png
-plugin.branding.SPLASH_SCREEN_BACKGROUND=resources/images/plugin/branding/splashScreenBackground.png
#plugin busylampfield
plugin.busylampfield.PICKUP_CALL=resources/images/impl/gui/buttons/pickupCall.png
@@ -625,4 +578,4 @@ plugin.spellcheck.PERSONAL_DIR=resources/images/plugin/spellcheck/personalDictio
plugin.spellcheck.WORD_INCLUDE=resources/images/plugin/spellcheck/wordInclude.png
plugin.spellcheck.WORD_EXCLUDE=resources/images/plugin/spellcheck/wordExclude.png
plugin.spellcheck.ENABLE=resources/images/plugin/spellcheck/enableSpellchecker.png
-plugin.spellcheck.DISABLE=resources/images/plugin/spellcheck/disableSpellchecker.png \ No newline at end of file
+plugin.spellcheck.DISABLE=resources/images/plugin/spellcheck/disableSpellchecker.png
diff --git a/resources/images/impl/systray/envelope.png b/resources/images/impl/systray/envelope.png
deleted file mode 100644
index 1d6b70a..0000000
--- a/resources/images/impl/systray/envelope.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/impl/systray/envelopeMacOSX.png b/resources/images/impl/systray/envelopeMacOSX.png
deleted file mode 100644
index a19704b..0000000
--- a/resources/images/impl/systray/envelopeMacOSX.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/impl/systray/envelopeMacOSXWhite.png b/resources/images/impl/systray/envelopeMacOSXWhite.png
deleted file mode 100644
index 2a11957..0000000
--- a/resources/images/impl/systray/envelopeMacOSXWhite.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/impl/systray/envelopeWindows.png b/resources/images/impl/systray/envelopeWindows.png
deleted file mode 100644
index c0886c2..0000000
--- a/resources/images/impl/systray/envelopeWindows.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/plugin/branding/splashScreenBackground.png b/resources/images/plugin/branding/splashScreenBackground.png
deleted file mode 100644
index 5754b26..0000000
--- a/resources/images/plugin/branding/splashScreenBackground.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/dict/dict-16x16-offline.png b/resources/images/protocol/dict/dict-16x16-offline.png
deleted file mode 100755
index f450b04..0000000
--- a/resources/images/protocol/dict/dict-16x16-offline.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/dict/dict-16x16.png b/resources/images/protocol/dict/dict-16x16.png
deleted file mode 100644
index 0c79371..0000000
--- a/resources/images/protocol/dict/dict-16x16.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/dict/dict-32x32.png b/resources/images/protocol/dict/dict-32x32.png
deleted file mode 100644
index 8009db2..0000000
--- a/resources/images/protocol/dict/dict-32x32.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/dict/dict-48x48.png b/resources/images/protocol/dict/dict-48x48.png
deleted file mode 100644
index 1a33a27..0000000
--- a/resources/images/protocol/dict/dict-48x48.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/dict/dict-64x64.png b/resources/images/protocol/dict/dict-64x64.png
deleted file mode 100644
index 8230e15..0000000
--- a/resources/images/protocol/dict/dict-64x64.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/facebook/facebook-online.png b/resources/images/protocol/facebook/facebook-online.png
deleted file mode 100644
index eef81e3..0000000
--- a/resources/images/protocol/facebook/facebook-online.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/facebook/facebook48.png b/resources/images/protocol/facebook/facebook48.png
deleted file mode 100644
index 2501aca..0000000
--- a/resources/images/protocol/facebook/facebook48.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/facebook/logo32x32.png b/resources/images/protocol/facebook/logo32x32.png
deleted file mode 100644
index 96da001..0000000
--- a/resources/images/protocol/facebook/logo32x32.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/facebook/logo48x48.png b/resources/images/protocol/facebook/logo48x48.png
deleted file mode 100644
index 7c887f8..0000000
--- a/resources/images/protocol/facebook/logo48x48.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/facebook/logo64x64.png b/resources/images/protocol/facebook/logo64x64.png
deleted file mode 100644
index 1c4da39..0000000
--- a/resources/images/protocol/facebook/logo64x64.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-away.png b/resources/images/protocol/facebook/status16x16-away.png
deleted file mode 100644
index 51fc2ed..0000000
--- a/resources/images/protocol/facebook/status16x16-away.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-connecting.gif b/resources/images/protocol/facebook/status16x16-connecting.gif
deleted file mode 100644
index 84b16f1..0000000
--- a/resources/images/protocol/facebook/status16x16-connecting.gif
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-connecting.png b/resources/images/protocol/facebook/status16x16-connecting.png
deleted file mode 100644
index 1fae81e..0000000
--- a/resources/images/protocol/facebook/status16x16-connecting.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-dnd.png b/resources/images/protocol/facebook/status16x16-dnd.png
deleted file mode 100644
index 34f3615..0000000
--- a/resources/images/protocol/facebook/status16x16-dnd.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-ffc.png b/resources/images/protocol/facebook/status16x16-ffc.png
deleted file mode 100644
index f9848fe..0000000
--- a/resources/images/protocol/facebook/status16x16-ffc.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-invisible.png b/resources/images/protocol/facebook/status16x16-invisible.png
deleted file mode 100644
index 05bcba2..0000000
--- a/resources/images/protocol/facebook/status16x16-invisible.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-meeting.png b/resources/images/protocol/facebook/status16x16-meeting.png
deleted file mode 100644
index 6d939ee..0000000
--- a/resources/images/protocol/facebook/status16x16-meeting.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-offline.png b/resources/images/protocol/facebook/status16x16-offline.png
deleted file mode 100644
index ddfaf6f..0000000
--- a/resources/images/protocol/facebook/status16x16-offline.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-online.png b/resources/images/protocol/facebook/status16x16-online.png
deleted file mode 100644
index eef81e3..0000000
--- a/resources/images/protocol/facebook/status16x16-online.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-phone.png b/resources/images/protocol/facebook/status16x16-phone.png
deleted file mode 100644
index 2d19f7b..0000000
--- a/resources/images/protocol/facebook/status16x16-phone.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-xa.png b/resources/images/protocol/facebook/status16x16-xa.png
deleted file mode 100644
index d6eb195..0000000
--- a/resources/images/protocol/facebook/status16x16-xa.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/sip2sip/sip16x16-away.png b/resources/images/protocol/sip2sip/sip16x16-away.png
deleted file mode 100644
index cc2d146..0000000
--- a/resources/images/protocol/sip2sip/sip16x16-away.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/sip2sip/sip16x16-busy.png b/resources/images/protocol/sip2sip/sip16x16-busy.png
deleted file mode 100644
index b3e14e2..0000000
--- a/resources/images/protocol/sip2sip/sip16x16-busy.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/sip2sip/sip16x16-meeting.png b/resources/images/protocol/sip2sip/sip16x16-meeting.png
deleted file mode 100644
index 20b191a..0000000
--- a/resources/images/protocol/sip2sip/sip16x16-meeting.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/sip2sip/sip16x16-offline.png b/resources/images/protocol/sip2sip/sip16x16-offline.png
deleted file mode 100644
index ca74f64..0000000
--- a/resources/images/protocol/sip2sip/sip16x16-offline.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/sip2sip/sip16x16-online.png b/resources/images/protocol/sip2sip/sip16x16-online.png
deleted file mode 100644
index cd05e31..0000000
--- a/resources/images/protocol/sip2sip/sip16x16-online.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/sip2sip/sip16x16-phone.png b/resources/images/protocol/sip2sip/sip16x16-phone.png
deleted file mode 100644
index 0babceb..0000000
--- a/resources/images/protocol/sip2sip/sip16x16-phone.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/sip2sip/sip16x16.png b/resources/images/protocol/sip2sip/sip16x16.png
deleted file mode 100644
index cd05e31..0000000
--- a/resources/images/protocol/sip2sip/sip16x16.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/sip2sip/sip32x32.png b/resources/images/protocol/sip2sip/sip32x32.png
deleted file mode 100644
index 2b77182..0000000
--- a/resources/images/protocol/sip2sip/sip32x32.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/sip2sip/sip48x48.png b/resources/images/protocol/sip2sip/sip48x48.png
deleted file mode 100644
index ffcaeeb..0000000
--- a/resources/images/protocol/sip2sip/sip48x48.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/sip2sip/sip64x64.png b/resources/images/protocol/sip2sip/sip64x64.png
deleted file mode 100644
index 9c7babe..0000000
--- a/resources/images/protocol/sip2sip/sip64x64.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/ssh/ssh-connected.png b/resources/images/protocol/ssh/ssh-connected.png
deleted file mode 100644
index ac168e0..0000000
--- a/resources/images/protocol/ssh/ssh-connected.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/ssh/ssh-connecting.png b/resources/images/protocol/ssh/ssh-connecting.png
deleted file mode 100644
index 5ae7f03..0000000
--- a/resources/images/protocol/ssh/ssh-connecting.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/ssh/ssh-filetransfer.png b/resources/images/protocol/ssh/ssh-filetransfer.png
deleted file mode 100644
index 50eca81..0000000
--- a/resources/images/protocol/ssh/ssh-filetransfer.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/ssh/ssh-na.png b/resources/images/protocol/ssh/ssh-na.png
deleted file mode 100644
index 90e5028..0000000
--- a/resources/images/protocol/ssh/ssh-na.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/ssh/ssh-offline.png b/resources/images/protocol/ssh/ssh-offline.png
deleted file mode 100644
index c8c429a..0000000
--- a/resources/images/protocol/ssh/ssh-offline.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/ssh/ssh-online.png b/resources/images/protocol/ssh/ssh-online.png
deleted file mode 100644
index e67f418..0000000
--- a/resources/images/protocol/ssh/ssh-online.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/ssh/ssh32x32.png b/resources/images/protocol/ssh/ssh32x32.png
deleted file mode 100644
index c873cb5..0000000
--- a/resources/images/protocol/ssh/ssh32x32.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/ssh/ssh48x48.png b/resources/images/protocol/ssh/ssh48x48.png
deleted file mode 100644
index a53f740..0000000
--- a/resources/images/protocol/ssh/ssh48x48.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/ssh/ssh64x64.png b/resources/images/protocol/ssh/ssh64x64.png
deleted file mode 100644
index 2a62b39..0000000
--- a/resources/images/protocol/ssh/ssh64x64.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-away.png b/resources/images/protocol/yahoo/yahoo16x16-away.png
deleted file mode 100644
index fc853f0..0000000
--- a/resources/images/protocol/yahoo/yahoo16x16-away.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-busy.png b/resources/images/protocol/yahoo/yahoo16x16-busy.png
deleted file mode 100644
index 4f30abc..0000000
--- a/resources/images/protocol/yahoo/yahoo16x16-busy.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-connecting.gif b/resources/images/protocol/yahoo/yahoo16x16-connecting.gif
deleted file mode 100644
index 4f07cb7..0000000
--- a/resources/images/protocol/yahoo/yahoo16x16-connecting.gif
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-connecting.png b/resources/images/protocol/yahoo/yahoo16x16-connecting.png
deleted file mode 100644
index 189c45e..0000000
--- a/resources/images/protocol/yahoo/yahoo16x16-connecting.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-idle.png b/resources/images/protocol/yahoo/yahoo16x16-idle.png
deleted file mode 100644
index 2c81b77..0000000
--- a/resources/images/protocol/yahoo/yahoo16x16-idle.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-invisible.png b/resources/images/protocol/yahoo/yahoo16x16-invisible.png
deleted file mode 100644
index 8c8bc0c..0000000
--- a/resources/images/protocol/yahoo/yahoo16x16-invisible.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-lunch.png b/resources/images/protocol/yahoo/yahoo16x16-lunch.png
deleted file mode 100644
index 3cfa10f..0000000
--- a/resources/images/protocol/yahoo/yahoo16x16-lunch.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-na.png b/resources/images/protocol/yahoo/yahoo16x16-na.png
deleted file mode 100644
index 9a1f8ad..0000000
--- a/resources/images/protocol/yahoo/yahoo16x16-na.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-offline.png b/resources/images/protocol/yahoo/yahoo16x16-offline.png
deleted file mode 100644
index 851bb54..0000000
--- a/resources/images/protocol/yahoo/yahoo16x16-offline.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-online.png b/resources/images/protocol/yahoo/yahoo16x16-online.png
deleted file mode 100644
index eaea8e2..0000000
--- a/resources/images/protocol/yahoo/yahoo16x16-online.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-phone.png b/resources/images/protocol/yahoo/yahoo16x16-phone.png
deleted file mode 100644
index c037ad1..0000000
--- a/resources/images/protocol/yahoo/yahoo16x16-phone.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-vacation.png b/resources/images/protocol/yahoo/yahoo16x16-vacation.png
deleted file mode 100644
index 02e8b1f..0000000
--- a/resources/images/protocol/yahoo/yahoo16x16-vacation.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16.png b/resources/images/protocol/yahoo/yahoo16x16.png
deleted file mode 100644
index eaea8e2..0000000
--- a/resources/images/protocol/yahoo/yahoo16x16.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo32x32.png b/resources/images/protocol/yahoo/yahoo32x32.png
deleted file mode 100644
index eed8b25..0000000
--- a/resources/images/protocol/yahoo/yahoo32x32.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo48x48.png b/resources/images/protocol/yahoo/yahoo48x48.png
deleted file mode 100644
index 132a990..0000000
--- a/resources/images/protocol/yahoo/yahoo48x48.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo64x64.png b/resources/images/protocol/yahoo/yahoo64x64.png
deleted file mode 100644
index 827133f..0000000
--- a/resources/images/protocol/yahoo/yahoo64x64.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/zeroconf/zeroconf-away.png b/resources/images/protocol/zeroconf/zeroconf-away.png
deleted file mode 100644
index 8265d5a..0000000
--- a/resources/images/protocol/zeroconf/zeroconf-away.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/zeroconf/zeroconf-dnd.png b/resources/images/protocol/zeroconf/zeroconf-dnd.png
deleted file mode 100644
index fa1b70b..0000000
--- a/resources/images/protocol/zeroconf/zeroconf-dnd.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/zeroconf/zeroconf-invisible.png b/resources/images/protocol/zeroconf/zeroconf-invisible.png
deleted file mode 100644
index e3bd0cf..0000000
--- a/resources/images/protocol/zeroconf/zeroconf-invisible.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/zeroconf/zeroconf-offline.png b/resources/images/protocol/zeroconf/zeroconf-offline.png
deleted file mode 100644
index de37240..0000000
--- a/resources/images/protocol/zeroconf/zeroconf-offline.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/zeroconf/zeroconf-online.png b/resources/images/protocol/zeroconf/zeroconf-online.png
deleted file mode 100644
index be66b1b..0000000
--- a/resources/images/protocol/zeroconf/zeroconf-online.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/zeroconf/zeroconf16x16.png b/resources/images/protocol/zeroconf/zeroconf16x16.png
deleted file mode 100644
index be66b1b..0000000
--- a/resources/images/protocol/zeroconf/zeroconf16x16.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/zeroconf/zeroconf32x32.png b/resources/images/protocol/zeroconf/zeroconf32x32.png
deleted file mode 100644
index 58754b6..0000000
--- a/resources/images/protocol/zeroconf/zeroconf32x32.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/zeroconf/zeroconf48x48.png b/resources/images/protocol/zeroconf/zeroconf48x48.png
deleted file mode 100644
index fbae916..0000000
--- a/resources/images/protocol/zeroconf/zeroconf48x48.png
+++ /dev/null
Binary files differ
diff --git a/resources/images/protocol/zeroconf/zeroconf64x64.png b/resources/images/protocol/zeroconf/zeroconf64x64.png
deleted file mode 100644
index 6db9d49..0000000
--- a/resources/images/protocol/zeroconf/zeroconf64x64.png
+++ /dev/null
Binary files differ
diff --git a/resources/install/build.xml b/resources/install/build.xml
index 64fd24b..c1087c3 100644
--- a/resources/install/build.xml
+++ b/resources/install/build.xml
@@ -131,6 +131,42 @@
<mkdir dir="${generic.app.dir}"/>
</target>
+ <target name="strip-multi-platform-jar">
+ <condition property="win64">
+ <equals arg1="${platform}" arg2="windows-64" />
+ </condition>
+ <condition property="win32">
+ <equals arg1="${platform}" arg2="windows-32" />
+ </condition>
+ <condition property="linux64">
+ <equals arg1="${platform}" arg2="linux-64" />
+ </condition>
+ <condition property="linux32">
+ <equals arg1="${platform}" arg2="linux-32" />
+ </condition>
+ <condition property="macos">
+ <equals arg1="${platform}" arg2="osx" />
+ </condition>
+ <zip destfile="${jar}.tmp">
+ <zipfileset src="${jar}">
+ <exclude name="**/darwin/*.jnilib" unless="${macos}"/>
+ <exclude name="**/linux-x86/*.so" unless="${linux32}"/>
+ <exclude name="**/linux-x86-64/*.so" unless="${linux64}"/>
+ <exclude name="**/win32-x86/*.dll" unless="${win32}"/>
+ <exclude name="**/win32-x86-64/*.dll" unless="${win64}"/>
+
+ <exclude name="**/freebsd-x86/*.so"/>
+ <exclude name="**/freebsd-x86-64/*.so"/>
+ <exclude name="**/linux-arm/*.so"/>
+ <exclude name="**/openbsd-x86/*.so"/>
+ <exclude name="**/openbsd-x86-64/*.so"/>
+ <exclude name="**/sunos-*/*.so"/>
+ <exclude name="**/w32ce-arm/*.dll"/>
+ </zipfileset>
+ </zip>
+ <move file="${jar}.tmp" tofile="${jar}"/>
+ </target>
+
<target name="build-installation-generic"
depends="clean-install-generic,define-izpack-task,version,load-properties">
@@ -539,6 +575,22 @@
<exclude name="*slick.jar" />
</fileset>
</copy>
+ <antcall target="strip-multi-platform-jar">
+ <param name="jar" value="${light.dir}/sc-bundles/libjitsi.jar"/>
+ <param name="platform" value="windows-${windows.arch}" />
+ </antcall>
+ <antcall target="strip-multi-platform-jar">
+ <param name="jar" value="${light.dir}/sc-bundles/jitsi-gpl-dependencies.jar"/>
+ <param name="platform" value="windows-${windows.arch}" />
+ </antcall>
+ <antcall target="strip-multi-platform-jar">
+ <param name="jar" value="${light.dir}/sc-bundles/jitsi-lgpl-dependencies.jar"/>
+ <param name="platform" value="windows-${windows.arch}" />
+ </antcall>
+ <antcall target="strip-multi-platform-jar">
+ <param name="jar" value="${light.dir}/sc-bundles/jna.jar"/>
+ <param name="platform" value="windows-${windows.arch}" />
+ </antcall>
<!--
Include a private Java Runtime Environment if it has been specified.
@@ -1006,6 +1058,25 @@
<arg value="${sign.cert.password}" />
<arg value="${file.to.sign}" />
</exec>
+
+ <exec executable="${inst.resrc}/windows/signtool.exe"
+ failonerror="false">
+ <arg value="sign" />
+ <arg value="/d" />
+ <arg value="${application.name}" />
+ <arg value="/fd" />
+ <arg value="sha256" />
+ <arg value="/tr" />
+ <arg value="http://tsa.starfieldtech.com" />
+ <arg value="/td" />
+ <arg value="sha256" />
+ <arg value="/as" />
+ <arg value="/f" />
+ <arg value="${sign.cert.file}" />
+ <arg value="/p" />
+ <arg value="${sign.cert.password}" />
+ <arg value="${file.to.sign}" />
+ </exec>
</target>
<!-- signs all dll files in folder - $folder.to.sign
@@ -1128,6 +1199,22 @@
<include name="**/*.jar"/>
</fileset>
</copy>
+ <antcall target="strip-multi-platform-jar">
+ <param name="jar" value="${bundles.dest}/libjitsi.jar"/>
+ <param name="platform" value="osx" />
+ </antcall>
+ <antcall target="strip-multi-platform-jar">
+ <param name="jar" value="${bundles.dest}/jitsi-gpl-dependencies.jar"/>
+ <param name="platform" value="osx" />
+ </antcall>
+ <antcall target="strip-multi-platform-jar">
+ <param name="jar" value="${bundles.dest}/jitsi-lgpl-dependencies.jar"/>
+ <param name="platform" value="osx" />
+ </antcall>
+ <antcall target="strip-multi-platform-jar">
+ <param name="jar" value="${bundles.dest}/jna.jar"/>
+ <param name="platform" value="osx" />
+ </antcall>
<!-- Delete the old .app if it exists -->
<delete dir="${macosx.app.dir}/${application.name}.app"
@@ -1267,6 +1354,8 @@
<key>CFBundleURLSchemes</key>
<array>
<string>sip</string>
+ <string>tel</string>
+ <string>callto</string>
</array>
</dict>
<dict>
@@ -1677,7 +1766,7 @@
<!-- the designated param value is taken after executing the command
on already installed and signed application
$ codesign -d -r- /Applications/Jitsi.app -->
- <arg value="=designated => identifier &quot;org.${package.name}&quot; and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = &quot;BE8738ZVRM&quot;"/>
+ <arg value="=designated => identifier &quot;org.${package.name}&quot; and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = &quot;9J46G85C89&quot;"/>
<arg value="${macosx.app.dir}/${application.name}.app"/>
</exec>
@@ -2254,9 +2343,6 @@
todir="${debianize.dir}"
overwrite="true"/>
- <!-- use postinst and postrm files only if used from deb target -->
- <antcall target="-deb-post-files-update"/>
-
<copy todir="${debianize.dir}/source">
<fileset dir="${inst.resrc}/debian/source"/>
</copy>
@@ -2392,7 +2478,7 @@
and libjdic.so to deb and i386 package fail to build -->
<replace file="${debianize.dir}/rules"
token="get-orig-source:"
- value="override_dh_shlibdeps:&#010;&#009;dh_shlibdeps -Xlibjunbound.so -Xlibsysactivitynotifications.so&#010;&#010;get-orig-source:"/>
+ value="override_dh_shlibdeps:&#010;&#009;dh_shlibdeps -Xlibsysactivitynotifications.so&#010;&#010;get-orig-source:"/>
<!-- removes the rule override_dh_auto_clean -->
<replace file="${debianize.dir}/rules"
@@ -2459,16 +2545,6 @@
token="/usr/lib/jni"
value="$SCDIR/lib/native"/>
</target>
- <!-- use postinst and postrm files only if used from deb target -->
- <target name="-deb-post-files-update"
- unless="debianize.src.pkg">
- <copy file="${inst.resrc}/debian/postinst"
- tofile="${debianize.dir}/postinst"
- overwrite="true"/>
- <copy file="${inst.resrc}/debian/postrm"
- tofile="${debianize.dir}/postrm"
- overwrite="true"/>
- </target>
<!-- Prepare to deploy the Debian package - This needs dpkg utilities -->
<target name="deb-rel" depends="deb,dpkg-scan-warning"
@@ -2534,7 +2610,6 @@
<exclude name="**/ssh/**"/>
<exclude name="**/sshaccregwizz/**"/>
<exclude name="**/profiler4j/**"/>
- <exclude name="**/windows/**"/>
<exclude name="**/windows32/**"/>
<exclude name="**/windows64/**"/>
<exclude name="**/native/addrbook/macosx/**"/>
@@ -2687,10 +2762,6 @@
<unzip src="${sc.basedir}/../libsrc/jmyspell-core-src.zip"
dest="${debian.src.dir}/lib/src/jmyspell"/>
- <!-- jfontchooser -->
- <unzip src="${sc.basedir}/../libsrc/jfontchooser-src.zip"
- dest="${debian.src.dir}/lib/src/jfontchooser"/>
-
<!-- gdata
<unzip src="${sc.basedir}/../libsrc/gdata-src.java-1.43.0.zip"
dest="${debian.src.dir}/lib/src">
@@ -2752,8 +2823,6 @@
failonerror="false"/>
<delete dir="${debian.src.dir}/lib/src/jmyspell/classes"
failonerror="false"/>
- <delete dir="${debian.src.dir}/lib/src/jfontchooser/classes"
- failonerror="false"/>
<delete dir="${debian.src.dir}/lib/src/OrangeExtensions/classes"
failonerror="false"/>
<!--ant dir="${debian.src.dir}/lib/src/gdata-java-client/java"
@@ -2825,7 +2894,7 @@
<symlink resource="/usr/share/java/weupnp.jar"
overwrite="true"
- link="${debian.src.dir}/lib/installer-exclude/weupnp-0.1.2-SNAPSHOT.jar"/>
+ link="${debian.src.dir}/lib/installer-exclude/weupnp-0.1.4.jar"/>
<!-- swingworker -->
<ant dir="${debian.src.dir}/lib/src/swingworker"
@@ -2969,15 +3038,6 @@
overwrite="true"
link="${debian.src.dir}/lib/installer-exclude/json-simple-1.1.1.jar"/>
- <!-- jymsg -->
- <ant dir="${debian.src.dir}/lib/src/jymsg"
- inheritAll="false"
- target="jars">
- </ant>
- <symlink resource="../src/jymsg/classes/ymsg_network_v0_67.jar"
- overwrite="true"
- link="${debian.src.dir}/lib/installer-exclude"/>
-
<!-- dhcp4j -->
<mkdir dir="${debian.src.dir}/lib/src/dhcp4java/classes"/>
<javac debug="true"
@@ -3057,23 +3117,6 @@
<symlink resource="../src/jmyspell/jmyspell-core.jar" overwrite="true"
link="${debian.src.dir}/lib/installer-exclude"/>
- <!-- jfontchooser -->
- <mkdir dir="${debian.src.dir}/lib/src/jfontchooser/classes"/>
- <javac debug="true"
- deprecation="true" destdir="${debian.src.dir}/lib/src/jfontchooser/classes"
- nowarn="false"
- source="1.5" target="1.5" fork="true">
- <src path="${debian.src.dir}/lib/src/jfontchooser/src"/>
- <include name="**/*.java" />
- </javac>
- <jar compress="true"
- destfile="${debian.src.dir}/lib/src/jfontchooser/jfontchooser-1.0.5.jar">
- <zipfileset dir="${debian.src.dir}/lib/src/jfontchooser/classes"/>
- </jar>
- <symlink resource="../src/jfontchooser/jfontchooser-1.0.5.jar"
- overwrite="true"
- link="${debian.src.dir}/lib/installer-exclude"/>
-
<!-- libcommons-codec-java -->
<symlink resource="/usr/share/java/commons-codec.jar"
overwrite="true"
@@ -3212,6 +3255,10 @@
<symlink resource="/usr/share/libjitsi/lib/ice4j.jar"
overwrite="true"
link="${debian.src.dir}/lib/installer-exclude"/>
+ <!-- jitsi-gpl-dependencies -->
+ <symlink resource="/usr/share/libjitsi/lib/jitsi-gpl-dependencies.jar"
+ overwrite="true"
+ link="${debian.src.dir}/lib/installer-exclude/"/>
<!-- jitsi-lgpl-dependencies -->
<symlink resource="/usr/share/libjitsi/lib/jitsi-lgpl-dependencies.jar"
overwrite="true"
@@ -3285,7 +3332,6 @@
<antcall target="globalshortcut"/>
<antcall target="hid"/>
<antcall target="sysactivity"/>
- <antcall target="unbound"/>
<antcall target="hwaddressretriever"/>
</target>
@@ -3733,6 +3779,8 @@
link="${debian.bundles.common.dest}/libjitsi.jar/"/>
<symlink resource="/usr/share/libjitsi/libjitsi.jar"
link="${debian.bundles.common.dest}/libjitsi.jar/"/>
+ <symlink resource="/usr/share/libjitsi/lib/jitsi-gpl-dependencies.jar"
+ link="${debian.bundles.common.dest}/libjitsi.jar/"/>
<symlink resource="/usr/share/libjitsi/lib/jitsi-lgpl-dependencies.jar"
link="${debian.bundles.common.dest}/libjitsi.jar/"/>
<symlink resource="/usr/share/libjitsi/lib/fmj.jar"
@@ -3759,7 +3807,7 @@
destfile="${debian.bundles.common.dest}/libjitsi.jar/META-INF/MANIFEST.MF"
append="true"
eol="crlf"
- fixlastline="true">Bundle-ClassPath: .,libjitsi-impl.jar,fmj.jar,jitsi-lgpl-dependencies.jar,libjitsi.jar,bcpkix.jar&#013;&#010;&#013;&#010;</concat>
+ fixlastline="true">Bundle-ClassPath: .,libjitsi-impl.jar,fmj.jar,jitsi-gpl-dependencies.jar,jitsi-lgpl-dependencies.jar,libjitsi.jar,bcpkix.jar&#013;&#010;&#013;&#010;</concat>
<replace file="${debian.bundles.dest}/../lib/felix.client.run.properties"
token="reference:file:sc-bundles/libjitsi.jar">
<replacevalue>reference:file:/usr/share/jitsi-common/libjitsi.jar</replacevalue>
diff --git a/resources/install/debian/README.embedded-libraries b/resources/install/debian/README.embedded-libraries
index d4457de..6ecff8a 100644
--- a/resources/install/debian/README.embedded-libraries
+++ b/resources/install/debian/README.embedded-libraries
@@ -7,21 +7,11 @@ Note 2: We have indicated when Jitsi community members are also somehow affiliat
Java DHCP API.
Reason: No Debian package.
-- jfontchooser http://sourceforge.net/projects/jfontchooser/
-This projects tries to provide an easy JFontChooser in the form of the JColorChooser.
-Reason: No Debian package.
-
- jnsapi http://code.google.com/p/jinglenodes/
Jingle Nodes is an XMPP Extension that enable users to share and discover
P2P Media Relays that can be used to enable Voice and Video Chat via Jingle.
Reason: No Debian package.
-- jymsg http://jymsg9.sourceforge.net/
-This API provides a way for Java applications to connect and
-use the Yahoo Instant Messenger protocol.
-Damian Minkov from Jitsi team is contributor and has commit right in the project.
-Reason: No Debian package.
-
- OrangeExtensions http://ymasory.github.com/OrangeExtensions/
A pluggable jar containing stubs for the Apple Java Extensions.
Reason: No Debian package.
diff --git a/resources/install/debian/control-src.tmpl b/resources/install/debian/control-src.tmpl
index fdf1456..cb9b08d 100644
--- a/resources/install/debian/control-src.tmpl
+++ b/resources/install/debian/control-src.tmpl
@@ -6,7 +6,7 @@ Uploaders: Emil Ivov <emcho@jitsi.org>, Damian Minkov <damencho@jitsi.org>
Homepage: _APP_WEB_
Build-Depends: debhelper (>= 9), javahelper,
dpkg-dev (>= 1.16.1),
- default-jdk,
+ default-jdk | java7-sdk,
ant,
ant-optional,
ant-contrib-cpptasks,
@@ -42,14 +42,11 @@ Build-Depends: debhelper (>= 9), javahelper,
libxtst-dev,
libxv-dev,
libdbus-1-dev,
- libunbound-dev,
libxss-dev,
libgtk2.0-dev,
libglib2.0-dev,
libguava-java,
libhsqldb-java,
- glassfish-activation,
- glassfish-mail,
libjcalendar-java,
libphonenumber6-java,
libslf4j-java
@@ -62,7 +59,8 @@ Depends: ${misc:Depends},
_PACKAGE_NAME_-common (= ${source:Version}),
libjitsi (= ${libjitsi:version}),
libjitsi-jni (= ${libjitsi:version}),
- default-jre,
+ default-jre | java7-runtime,
+ libappindicator1,
libunixsocket-java,
libhttpcore-java,
liblog4j1.2-java,
@@ -93,7 +91,7 @@ Description: VoIP and Instant Messaging client
_APP_NAME_ is an application that allows you to do audio/video
conversations over the Internet through the SIP and XMPP/Jabber protocol,
as well as chat with your friends using some of the most popular instant
- messaging protocols such as SIP/SIMPLE, XMPP/Jabber, AIM/ICQ, Yahoo and others.
+ messaging protocols such as SIP/SIMPLE, XMPP/Jabber, AIM/ICQ and others.
Package: _PACKAGE_NAME_-jni
Replaces: libjitsi-jni (<< 415)
@@ -111,7 +109,7 @@ Package: _PACKAGE_NAME_-common
Section: libs
Architecture: all
Depends: ${misc:Depends}, ${shlibs:Depends},
- libdnsjava-java (>= 2.1.7~),
+ libdnsjava-java (>= 2.1.7),
libxpp3-java,
libjzlib-java,
libbcpkix-java
diff --git a/resources/install/debian/control.tmpl b/resources/install/debian/control.tmpl
index f717416..b780bb4 100644
--- a/resources/install/debian/control.tmpl
+++ b/resources/install/debian/control.tmpl
@@ -6,7 +6,7 @@ Uploaders: Emil Ivov <emcho@jitsi.org>
Homepage: _APP_WEB_
Build-Depends: debhelper (>= 9), javahelper,
dpkg-dev (>= 1.16.1),
- default-jdk,
+ default-jdk | java7-sdk,
ant,
ant-optional,
ant-contrib-cpptasks,
@@ -48,22 +48,24 @@ Build-Depends: debhelper (>= 9), javahelper,
libasound2-dev,
libspeexdsp-dev,
libspeex-dev,
- libunbound-dev,
libxss-dev,
libgtk2.0-dev,
libglib2.0-dev,
libpulse-dev,
libgoogle-collections-java,
- glassfish-activation,
- glassfish-mail,
libbcpkix-java
Standards-Version: 3.9.5
Package: _PACKAGE_NAME_
Architecture: i386 amd64
-Depends: default-jre, libxss1
+Depends: default-jre | java7-runtime,
+ libappindicator1,
+ libxss1,
+ libspeex1,
+ libspeexdsp1,
+ jitsi-archive-keyring
Description: VoIP and Instant Messaging client
_APP_NAME_ is an application that allows you to do audio/video
conversations over the Internet through the SIP and XMPP/Jabber protocol,
as well as chat with your friends using some of the most popular instant
- messaging protocols such as SIP/SIMPLE, XMPP/Jabber, AIM/ICQ, Yahoo and others.
+ messaging protocols such as SIP/SIMPLE, XMPP/Jabber, AIM/ICQ and others.
diff --git a/resources/install/debian/jitsi.1.tmpl b/resources/install/debian/jitsi.1.tmpl
index 5608d63..d09beb5 100644
--- a/resources/install/debian/jitsi.1.tmpl
+++ b/resources/install/debian/jitsi.1.tmpl
@@ -26,7 +26,7 @@ _PACKAGE_NAME_ \- the Java VoIP and Instant Messaging client
.\" respectively.
\fB_APP_NAME_\fP is an audio/video Internet phone and instant messenger
that supports some of the most popular instant messaging and telephony
-protocols such as SIP, Jabber, AIM/ICQ, Yahoo! Messenger, Bonjour, IRC
+protocols such as SIP, Jabber/XMPP, AIM/ICQ, IRC
and soon others like IAX.
.PP
.RI "An optional " uri-to-call " expression can be specified to start a call from the command-line. If _APP_NAME_ is already running then the call is handled by the running application, except when it is explicitly told to allow multiple instance launch."
diff --git a/resources/install/debian/jitsi.sh.tmpl b/resources/install/debian/jitsi.sh.tmpl
index de159db..5e8677d 100644
--- a/resources/install/debian/jitsi.sh.tmpl
+++ b/resources/install/debian/jitsi.sh.tmpl
@@ -30,7 +30,7 @@ javabin=`which java`
SCDIR=/usr/share/_PACKAGE_NAME_
JITSI_COMMON_DIR=/usr/share/_PACKAGE_NAME_-common
LIBPATH=$SCDIR/lib
-CLASSPATH=/usr/share/java/org.apache.felix.framework.jar:/usr/share/java/org.apache.felix.main.jar:$SCDIR/sc-bundles/sc-launcher.jar:$JITSI_COMMON_DIR/util.jar/launchutils.jar:$LIBPATH
+CLASSPATH=/usr/share/java/org.apache.felix.framework.jar:/usr/share/java/org.apache.felix.main.jar:$SCDIR/sc-bundles/dnsjava.jar:$SCDIR/sc-bundles/sc-launcher.jar:$JITSI_COMMON_DIR/util.jar/launchutils.jar:$LIBPATH
FELIX_CONFIG=$LIBPATH/felix.client.run.properties
LOG_CONFIG=$LIBPATH/logging.properties
COMMAND="$javabin $CLIENTARGS -classpath $CLASSPATH -Djna.library.path=/usr/lib/jni -Dfelix.config.properties=file:$FELIX_CONFIG -Djava.util.logging.config.file=$LOG_CONFIG $SPLASH_ARG net.java.sip.communicator.launcher.SIPCommunicator"
diff --git a/resources/install/debian/patches/encoding.patch b/resources/install/debian/patches/encoding.patch
deleted file mode 100644
index 09176fd..0000000
--- a/resources/install/debian/patches/encoding.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-Description: Set encoding for javadoc to fix errors with Java 7
-Author: Colin Watson <cjwatson@ubuntu.com>
-Bug-Debian: https://bugs.debian.org/759835
-Forwarded: no
-Last-Update: 2014-09-05
-
---- jitsi.orig/lib/src/swingworker/build.xml
-+++ jitsi/lib/src/swingworker/build.xml
-@@ -63,7 +63,7 @@ reserved. Use is subject to license term
- <javadoc access="protected" link=""
- packagenames="org.jdesktop.swingworker" author="true" destdir="${javadoc.dir}"
- nodeprecated="false" nodeprecatedlist="false" noindex="false"
-- nonavbar="false" notree="false" use="true" version="true">
-+ nonavbar="false" notree="false" use="true" version="true" encoding="iso-8859-1">
- <link href="${external.doc}" />
- <sourcepath>
- <pathelement path="${src.dir}" />
diff --git a/resources/install/debian/postinst b/resources/install/debian/postinst
deleted file mode 100644
index 997155a..0000000
--- a/resources/install/debian/postinst
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/bin/sh
-#
-# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
-#
-# Copyright @ 2015 Atlassian Pty Ltd
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# sources.list setting for Jitsi updates.
-REPOCONFIG="deb http://download.jitsi.org/deb unstable/"
-
-APT_CONFIG="`which apt-config 2> /dev/null`"
-
-
-# Parse apt configuration and return requested variable value.
-apt_config_val() {
- APTVAR="$1"
- if [ -x "$APT_CONFIG" ]; then
- "$APT_CONFIG" dump | sed -e "/^$APTVAR /"'!d' -e "s/^$APTVAR \"\(.*\)\".*/\1/"
- fi
-}
-
-# Set variables for the locations of the apt sources lists.
-find_apt_sources() {
- APTDIR=$(apt_config_val Dir)
- APTETC=$(apt_config_val 'Dir::Etc')
- APT_SOURCES="$APTDIR$APTETC$(apt_config_val 'Dir::Etc::sourcelist')"
- APT_SOURCESDIR="$APTDIR$APTETC$(apt_config_val 'Dir::Etc::sourceparts')"
-}
-
-# Remove our custom sources list file.
-# Returns:
-# 0 - successfully removed, or not configured
-# !0 - failed to remove
-clean_sources_lists() {
- if [ ! "$REPOCONFIG" ]; then
- return 0
- fi
-
- find_apt_sources
-
- rm -f "$APT_SOURCESDIR/jitsi.list"
-}
-
-remove_key() {
- APT_KEY="`which apt-key 2> /dev/null`"
- if [ -x "$APT_KEY" ]; then
- "$APT_KEY" del EB0AB654
- fi
-}
-
-## MAIN ##
-# Remove any Jitsi repository added by the package previously.
-clean_sources_lists
-# Remove jitsi repository key
-remove_key
diff --git a/resources/install/debian/postrm b/resources/install/debian/postrm
deleted file mode 100644
index 66317be..0000000
--- a/resources/install/debian/postrm
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/sh
-#
-# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
-#
-# Copyright @ 2015 Atlassian Pty Ltd
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# sources.list setting for Jitsi updates.
-REPOCONFIG="deb http://download.jitsi.org/deb unstable/"
-
-APT_CONFIG="`which apt-config 2> /dev/null`"
-
-# Parse apt configuration and return requested variable value.
-apt_config_val() {
- APTVAR="$1"
- if [ -x "$APT_CONFIG" ]; then
- "$APT_CONFIG" dump | sed -e "/^$APTVAR /"'!d' -e "s/^$APTVAR \"\(.*\)\".*/\1/"
- fi
-}
-
-# Set variables for the locations of the apt sources lists.
-find_apt_sources() {
- APTDIR=$(apt_config_val Dir)
- APTETC=$(apt_config_val 'Dir::Etc')
- APT_SOURCES="$APTDIR$APTETC$(apt_config_val 'Dir::Etc::sourcelist')"
- APT_SOURCESDIR="$APTDIR$APTETC$(apt_config_val 'Dir::Etc::sourceparts')"
-}
-
-# Remove our custom sources list file.
-# Returns:
-# 0 - successfully removed, or not configured
-# !0 - failed to remove
-clean_sources_lists() {
- if [ ! "$REPOCONFIG" ]; then
- return 0
- fi
-
- find_apt_sources
-
- rm -f "$APT_SOURCESDIR/jitsi.list"
-}
-
-# Remove any Jitsi repository added by the package.
-clean_sources_lists
diff --git a/resources/install/doc/License.rtf b/resources/install/doc/License.rtf
index 941293b..aaae7af 100644
--- a/resources/install/doc/License.rtf
+++ b/resources/install/doc/License.rtf
@@ -1,491 +1,35 @@
-{\rtf1\ansi\deff1\adeflang1025
-{\fonttbl{\f0\froman\fprq2\fcharset0 Nimbus Roman No9 L{\*\falt Times New Roman};}{\f1\fmodern\fprq1\fcharset0 Courier New;}{\f2\fswiss\fprq2\fcharset0 Nimbus Sans L{\*\falt Arial};}{\f3\fmodern\fprq1\fcharset0 Courier New;}{\f4\fnil\fprq2\fcharset0 DejaVu Sans;}}
-{\colortbl;\red0\green0\blue0;\red128\green128\blue128;}
-{\stylesheet{\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs24\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs24\lang1036\loch\f1\fs24\lang1036\snext1 Normal;}
-{\s2\sb240\sa120\keepn\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af4\afs28\lang255\ltrch\dbch\af4\langfe255\hich\f2\fs28\lang1036\loch\f2\fs28\lang1036\sbasedon1\snext3 Heading;}
-{\s3\sa120\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs24\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs24\lang1036\loch\f1\fs24\lang1036\sbasedon1\snext3 Body Text;}
-{\s4\sa120\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs24\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs24\lang1036\loch\f1\fs24\lang1036\sbasedon3\snext4 List;}
-{\s5\sb120\sa120\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs24\lang255\ai\ltrch\dbch\af1\langfe255\hich\f1\fs24\lang1036\i\loch\f1\fs24\lang1036\i\sbasedon1\snext5 caption;}
-{\s6\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs24\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs24\lang1036\loch\f1\fs24\lang1036\sbasedon1\snext6 Index;}
-}
-{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment StarWriter}{\vern6800}}\deftab720
-{\*\pgdsctbl
-{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}}
-{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc
-\pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 \tab \tab GNU LESSER GENERAL PUBLIC LICENSE}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 \tab \tab Version 2.1, February 1999}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.]}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 \tab \tab \tab Preamble}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for al
-l its users.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think care
-fully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you rece
-ive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or i
-f you modify it.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the libr
-ary, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so tha
-t the original author's reputation will not be affected by problems that might be introduced by others.}
-\par \page\pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Finally, software patents pose a constant threat to the existence of}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 any free program. We wish to make sure that a company cannot}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 effectively restrict the users of a free program by obtaining a}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 restrictive license from a patent holder. Therefore, we insist that}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 any patent license obtained for a version of the library must be}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 consistent with the full freedom of use specified in this license.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Most GNU software, including some libraries, is covered by the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 ordinary GNU General Public License. This license, the GNU Lesser}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 General Public License, applies to certain designated libraries, and}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 is quite different from the ordinary General Public License. We use}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 this license for certain libraries in order to permit linking those}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 libraries into non-free programs.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 When a program is linked with a library, whether statically or using}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 a shared library, the combination of the two is legally speaking a}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 combined work, a derivative of the original library. The ordinary}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 General Public License therefore permits such linking only if the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 entire combination fits its criteria of freedom. The Lesser General}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Public License permits more lax criteria for linking other code with}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 the library.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 We call this license the "Lesser" General Public License because it}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 does Less to protect the user's freedom than the ordinary General}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Public License. It also provides other free software developers Less}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 of an advantage over competing non-free programs. These disadvantages}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 are the reason we use the ordinary General Public License for many}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 libraries. However, the Lesser license provides advantages in certain}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 special circumstances.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 For example, on rare occasions, there may be a special need to}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 encourage the widest possible use of a certain library, so that it becomes}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 a de-facto standard. To achieve this, non-free programs must be}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 allowed to use the library. A more frequent case is that a free}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 library does the same job as widely used non-free libraries. In this}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 case, there is little to gain by limiting the free library to free}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 software only, so we use the Lesser General Public License.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 In other cases, permission to use a particular library in non-free}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 programs enables a greater number of people to use a large body of}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 free software. For example, permission to use the GNU C Library in}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 non-free programs enables many more people to use the whole GNU}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 operating system, as well as its variant, the GNU/Linux operating}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 system.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Although the Lesser General Public License is Less protective of the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 users' freedom, it does ensure that the user of a program that is}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 linked with the Library has the freedom and the wherewithal to run}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 that program using a modified version of the Library.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 The precise terms and conditions for copying, distribution and}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 modification follow. Pay close attention to the difference between a}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 "work based on the library" and a "work that uses the library". The}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 former contains code derived from the library, whereas the latter must}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 be combined with the library in order to run.}
-\par \page\pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 \tab \tab GNU LESSER GENERAL PUBLIC LICENSE}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 0. This License Agreement applies to any software library or other}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 program which contains a notice placed by the copyright holder or}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 other authorized party saying it may be distributed under the terms of}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 this Lesser General Public License (also called "this License").}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Each licensee is addressed as "you".}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 A "library" means a collection of software functions and/or data}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 prepared so as to be conveniently linked with application programs}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 (which use some of those functions and data) to form executables.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 The "Library", below, refers to any such software library or work}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 which has been distributed under these terms. A "work based on the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Library" means either the Library or any derivative work under}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 copyright law: that is to say, a work containing the Library or a}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 portion of it, either verbatim or with modifications and/or translated}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 straightforwardly into another language. (Hereinafter, translation is}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 included without limitation in the term "modification".)}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 "Source code" for a work means the preferred form of the work for}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 making modifications to it. For a library, complete source code means}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 all the source code for all modules it contains, plus any associated}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 interface definition files, plus the scripts used to control compilation}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 and installation of the library.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Activities other than copying, distribution and modification are not}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 covered by this License; they are outside its scope. The act of}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 running a program using the Library is not restricted, and output from}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 such a program is covered only if its contents constitute a work based}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 on the Library (independent of the use of the Library in a tool for}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 writing it). Whether that is true depends on what the Library does}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 and what the program that uses the Library does.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}{\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 1. You may copy and distribute verbatim copies of the Library's}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 complete source code as you receive it, in any medium, provided that}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 you conspicuously and appropriately publish on each copy an}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 appropriate copyright notice and disclaimer of warranty; keep intact}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 all the notices that refer to this License and to the absence of any}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 warranty; and distribute a copy of this License along with the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Library.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 You may charge a fee for the physical act of transferring a copy,}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 and you may at your option offer warranty protection in exchange for a}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 fee.}
-\par \page\pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 2. You may modify your copy or copies of the Library or any portion}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 of it, thus forming a work based on the Library, and copy and}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 distribute such modifications or work under the terms of Section 1}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 above, provided that you also meet all of these conditions:}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 a) The modified work must itself be a software library.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 b) You must cause the files modified to carry prominent notices}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 stating that you changed the files and the date of any change.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 c) You must cause the whole of the work to be licensed at no}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 charge to all third parties under the terms of this License.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 d) If a facility in the modified Library refers to a function or a}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 table of data to be supplied by an application program that uses}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 the facility, other than as an argument passed when the facility}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 is invoked, then you must make a good faith effort to ensure that,}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 in the event an application does not supply such function or}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 table, the facility still operates, and performs whatever part of}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 its purpose remains meaningful.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 (For example, a function in a library to compute square roots has}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 a purpose that is entirely well-defined independent of the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 application. Therefore, Subsection 2d requires that any}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 application-supplied function or table used by this function must}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 be optional: if the application does not supply it, the square}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 root function must still compute square roots.)}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 These requirements apply to the modified work as a whole. If}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 identifiable sections of that work are not derived from the Library,}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 and can be reasonably considered independent and separate works in}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 themselves, then this License, and its terms, do not apply to those}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 sections when you distribute them as separate works. But when you}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 distribute the same sections as part of a whole which is a work based}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 on the Library, the distribution of the whole must be on the terms of}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 this License, whose permissions for other licensees extend to the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 entire whole, and thus to each and every part regardless of who wrote}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 it.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Thus, it is not the intent of this section to claim rights or contest}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 your rights to work written entirely by you; rather, the intent is to}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 exercise the right to control the distribution of derivative or}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 collective works based on the Library.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 In addition, mere aggregation of another work not based on the Library}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 with the Library (or with a work based on the Library) on a volume of}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 a storage or distribution medium does not bring the other work under}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 the scope of this License.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 3. You may opt to apply the terms of the ordinary GNU General Public}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 License instead of this License to a given copy of the Library. To do}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 this, you must alter all the notices that refer to this License, so}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 that they refer to the ordinary GNU General Public License, version 2,}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 instead of to this License. (If a newer version than version 2 of the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 ordinary GNU General Public License has appeared, then you can specify}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 that version instead if you wish.) Do not make any other change in}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 these notices.}
-\par \page\pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Once this change is made in a given copy, it is irreversible for}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 that copy, so the ordinary GNU General Public License applies to all}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 subsequent copies and derivative works made from that copy.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 This option is useful when you wish to copy part of the code of}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 the Library into a program that is not a library.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 4. You may copy and distribute the Library (or a portion or}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 derivative of it, under Section 2) in object code or executable form}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 under the terms of Sections 1 and 2 above provided that you accompany}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 it with the complete corresponding machine-readable source code, which}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 must be distributed under the terms of Sections 1 and 2 above on a}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 medium customarily used for software interchange.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 If distribution of object code is made by offering access to copy}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 from a designated place, then offering equivalent access to copy the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 source code from the same place satisfies the requirement to}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 distribute the source code, even though third parties are not}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 compelled to copy the source along with the object code.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 5. A program that contains no derivative of any portion of the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Library, but is designed to work with the Library by being compiled or}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 linked with it, is called a "work that uses the Library". Such a}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 work, in isolation, is not a derivative work of the Library, and}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 therefore falls outside the scope of this License.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 However, linking a "work that uses the Library" with the Library}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 creates an executable that is a derivative of the Library (because it}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 contains portions of the Library), rather than a "work that uses the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 library". The executable is therefore covered by this License.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Section 6 states terms for distribution of such executables.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 When a "work that uses the Library" uses material from a header file}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 that is part of the Library, the object code for the work may be a}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 derivative work of the Library even though the source code is not.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Whether this is true is especially significant if the work can be}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 linked without the Library, or if the work is itself a library. The}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 threshold for this to be true is not precisely defined by law.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 If such an object file uses only numerical parameters, data}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 structure layouts and accessors, and small macros and small inline}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 functions (ten lines or less in length), then the use of the object}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 file is unrestricted, regardless of whether it is legally a derivative}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 work. (Executables containing this object code plus portions of the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Library will still fall under Section 6.)}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Otherwise, if the work is a derivative of the Library, you may}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 distribute the object code for the work under the terms of Section 6.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Any executables containing that work also fall under Section 6,}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 whether or not they are linked directly with the Library itself.}
-\par \page\pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 6. As an exception to the Sections above, you may also combine or}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 link a "work that uses the Library" with the Library to produce a}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 work containing portions of the Library, and distribute that work}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 under terms of your choice, provided that the terms permit}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 modification of the work for the customer's own use and reverse}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 engineering for debugging such modifications.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 You must give prominent notice with each copy of the work that the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Library is used in it and that the Library and its use are covered by}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 this License. You must supply a copy of this License. If the work}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 during execution displays copyright notices, you must include the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 copyright notice for the Library among them, as well as a reference}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 directing the user to the copy of this License. Also, you must do one}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 of these things:}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 a) Accompany the work with the complete corresponding}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 machine-readable source code for the Library including whatever}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 changes were used in the work (which must be distributed under}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Sections 1 and 2 above); and, if the work is an executable linked}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 with the Library, with the complete machine-readable "work that}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 uses the Library", as object code and/or source code, so that the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 user can modify the Library and then relink to produce a modified}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 executable containing the modified Library. (It is understood}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 that the user who changes the contents of definitions files in the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Library will not necessarily be able to recompile the application}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 to use the modified definitions.)}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 b) Use a suitable shared library mechanism for linking with the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Library. A suitable mechanism is one that (1) uses at run time a}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 copy of the library already present on the user's computer system,}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 rather than copying library functions into the executable, and (2)}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 will operate properly with a modified version of the library, if}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 the user installs one, as long as the modified version is}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 interface-compatible with the version that the work was made with.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 c) Accompany the work with a written offer, valid for at}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 least three years, to give the same user the materials}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 specified in Subsection 6a, above, for a charge no more}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 than the cost of performing this distribution.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 d) If distribution of the work is made by offering access to copy}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 from a designated place, offer equivalent access to copy the above}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 specified materials from the same place.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 e) Verify that the user has already received a copy of these}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 materials or that you have already sent this user a copy.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 For an executable, the required form of the "work that uses the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Library" must include any data and utility programs needed for}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 reproducing the executable from it. However, as a special exception,}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 the materials to be distributed need not include anything that is}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 normally distributed (in either source or binary form) with the major}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 components (compiler, kernel, and so on) of the operating system on}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 which the executable runs, unless that component itself accompanies}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 the executable.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 It may happen that this requirement contradicts the license}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 restrictions of other proprietary libraries that do not normally}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 accompany the operating system. Such a contradiction means you cannot}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 use both them and the Library together in an executable that you}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 distribute.}
-\par \page\pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 7. You may place library facilities that are a work based on the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Library side-by-side in a single library together with other library}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 facilities not covered by this License, and distribute such a combined}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 library, provided that the separate distribution of the work based on}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 the Library and of the other library facilities is otherwise}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 permitted, and provided that you do these two things:}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 a) Accompany the combined library with a copy of the same work}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 based on the Library, uncombined with any other library}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 facilities. This must be distributed under the terms of the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Sections above.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 b) Give prominent notice with the combined library of the fact}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 that part of it is a work based on the Library, and explaining}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 where to find the accompanying uncombined form of the same work.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 8. You may not copy, modify, sublicense, link with, or distribute}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 the Library except as expressly provided under this License. Any}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 attempt otherwise to copy, modify, sublicense, link with, or}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 distribute the Library is void, and will automatically terminate your}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 rights under this License. However, parties who have received copies,}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 or rights, from you under this License will not have their licenses}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 terminated so long as such parties remain in full compliance.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 9. You are not required to accept this License, since you have not}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 signed it. However, nothing else grants you permission to modify or}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 distribute the Library or its derivative works. These actions are}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 prohibited by law if you do not accept this License. Therefore, by}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 modifying or distributing the Library (or any work based on the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Library), you indicate your acceptance of this License to do so, and}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 all its terms and conditions for copying, distributing or modifying}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 the Library or works based on it.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 10. Each time you redistribute the Library (or any work based on the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Library), the recipient automatically receives a license from the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 original licensor to copy, distribute, link with or modify the Library}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 subject to these terms and conditions. You may not impose any further}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 restrictions on the recipients' exercise of the rights granted herein.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 You are not responsible for enforcing compliance by third parties with}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 this License.}
-\par \page\pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 11. If, as a consequence of a court judgment or allegation of patent}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 infringement or for any other reason (not limited to patent issues),}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 conditions are imposed on you (whether by court order, agreement or}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 otherwise) that contradict the conditions of this License, they do not}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 excuse you from the conditions of this License. If you cannot}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 distribute so as to satisfy simultaneously your obligations under this}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 License and any other pertinent obligations, then as a consequence you}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 may not distribute the Library at all. For example, if a patent}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 license would not permit royalty-free redistribution of the Library by}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 all those who receive copies directly or indirectly through you, then}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 the only way you could satisfy both it and this License would be to}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 refrain entirely from distribution of the Library.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 If any portion of this section is held invalid or unenforceable under any}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 particular circumstance, the balance of the section is intended to apply,}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 and the section as a whole is intended to apply in other circumstances.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 It is not the purpose of this section to induce you to infringe any}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 patents or other property right claims or to contest validity of any}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 such claims; this section has the sole purpose of protecting the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 integrity of the free software distribution system which is}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 implemented by public license practices. Many people have made}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 generous contributions to the wide range of software distributed}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 through that system in reliance on consistent application of that}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 system; it is up to the author/donor to decide if he or she is willing}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 to distribute software through any other system and a licensee cannot}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 impose that choice.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 This section is intended to make thoroughly clear what is believed to}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 be a consequence of the rest of this License.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 12. If the distribution and/or use of the Library is restricted in}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 certain countries either by patents or by copyrighted interfaces, the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 original copyright holder who places the Library under this License may add}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 an explicit geographical distribution limitation excluding those countries,}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 so that distribution is permitted only in or among countries not thus}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 excluded. In such case, this License incorporates the limitation as if}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 written in the body of this License.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 13. The Free Software Foundation may publish revised and/or new}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 versions of the Lesser General Public License from time to time.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Such new versions will be similar in spirit to the present version,}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 but may differ in detail to address new problems or concerns.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Each version is given a distinguishing version number. If the Library}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 specifies a version number of this License which applies to it and}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 "any later version", you have the option of following the terms and}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 conditions either of that version or of any later version published by}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 the Free Software Foundation. If the Library does not specify a}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 license version number, you may choose any version ever published by}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 the Free Software Foundation.}
-\par \page\pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 14. If you wish to incorporate parts of the Library into other free}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 programs whose distribution conditions are incompatible with these,}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 write to the author to ask for permission. For software which is}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 copyrighted by the Free Software Foundation, write to the Free}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Software Foundation; we sometimes make exceptions for this. Our}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 decision will be guided by the two goals of preserving the free status}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 of all derivatives of our free software and of promoting the sharing}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 and reuse of software generally.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 \tab \tab \tab NO WARRANTY}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 DAMAGES.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 \tab \tab END OF TERMS AND CONDITIONS}
-\par \page\pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 How to Apply These Terms to Your New Libraries}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 If you develop a new library, and you want it to be of the greatest}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 possible use to the public, we recommend making it free software that}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 everyone can redistribute and change. You can do so by permitting}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 redistribution under these terms (or, alternatively, under the terms of the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 ordinary General Public License).}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 To apply these terms, attach the following notices to the library. It is}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 safest to attach them to the start of each source file to most effectively}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 convey the exclusion of warranty; and each file should have at least the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 "copyright" line and a pointer to where the full notice is found.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 <one line to give the library's name and a brief idea of what it does.>}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Copyright (C) <year> <name of author>}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 This library is free software; you can redistribute it and/or}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 modify it under the terms of the GNU Lesser General Public}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 License as published by the Free Software Foundation; either}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 version 2.1 of the License, or (at your option) any later version.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 This library is distributed in the hope that it will be useful,}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 but WITHOUT ANY WARRANTY; without even the implied warranty of}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Lesser General Public License for more details.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 You should have received a copy of the GNU Lesser General Public}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 License along with this library; if not, write to the Free Software}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Also add information on how to contact you by electronic and paper mail.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 You should also get your employer (if you work as a programmer) or your}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 school, if any, to sign a "copyright disclaimer" for the library, if}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 necessary. Here is a sample; alter the names:}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Yoyodyne, Inc., hereby disclaims all copyright interest in the}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 library `Frob' (a library for tweaking knobs) written by James Random Hacker.}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 <signature of Ty Coon>, 1 April 1990}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 Ty Coon, President of Vice}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b0 That's all there is to it!}
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par \pard\plain \ltrpar\s1\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang255\ltrch\dbch\af1\langfe255\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033
-\par } \ No newline at end of file
+{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fprq2\fcharset0 Georgia;}}
+{\colortbl ;\red51\green51\blue51;\red0\green0\blue255;\red88\green90\blue194;\red255\green255\blue255;}
+{\*\generator Riched20 10.0.10586}{\*\mmathPr\mnaryLim0\mdispDef1\mwrapIndent1440 }\viewkind4\uc1
+\pard\cbpat4\widctlpar\sa150\sl300\slmult0\cf1\f0\fs28 Apache License\line Version 2.0, January 2004\line\fs21\line {\cf0{\field{\*\fldinst{HYPERLINK http://www.apache.org/licenses/ }}{\fldrslt{http://www.apache.org/licenses/\ul0\cf0}}}}\f0\fs21\par
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\par
+\cf3\b 1. Definitions\cf1\b0 .\par
+"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.\par
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\par
+"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.\par
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.\par
+"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.\par
+"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.\par
+"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\par
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.\par
+"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."\par
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.\par
+\cf3\b 2. Grant of Copyright License\cf1\b0 . Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\par
+\cf3\b 3. Grant of Patent License\cf1\b0 . Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.\par
+\cf3\b 4. Redistribution\cf1\b0 . You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:\par
+
+\pard\cbpat4
+{\pntext\f0 1.\tab}{\*\pn\pnlvlbody\pnf0\pnindent360\pnstart1\pndec{\pntxta.}}
+\widctlpar\fi-360\li720\sb100\sa100\sl300\slmult0 You must give any other recipients of the Work or Derivative Works a copy of this License; and\par
+{\pntext\f0 2.\tab}You must cause any modified files to carry prominent notices stating that You changed the files; and\par
+{\pntext\f0 3.\tab}You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\par
+{\pntext\f0 4.\tab}If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.\~\line\line You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.\par
+
+\pard\cbpat4\widctlpar\sa150\sl300\slmult0\cf3\b 5. Submission of Contributions\cf1\b0 . Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.\par
+\cf3\b 6. Trademarks\cf1\b0 . This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.\par
+\cf3\b 7. Disclaimer of Warranty\cf1\b0 . Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.\par
+\cf3\b 8. Limitation of Liability\cf1\b0 . In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.\par
+\cf3\b 9. Accepting Warranty or Additional Liability\cf1\b0 . While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.\par
+END OF TERMS AND CONDITIONS\par
+}
+
diff --git a/resources/install/doc/License.txt b/resources/install/doc/License.txt
deleted file mode 100644
index 5ab7695..0000000
--- a/resources/install/doc/License.txt
+++ /dev/null
@@ -1,504 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/resources/install/doc/readme.txt b/resources/install/doc/readme.txt
index 199d6aa..101ade0 100644
--- a/resources/install/doc/readme.txt
+++ b/resources/install/doc/readme.txt
@@ -1,5 +1,5 @@
-The SIP Communicator is currently under active development.
-The version you are running is only experimental and WILL NOT
+Jitsi is currently under active development.
+The version you are running is only experimental and may not
work as expected. Please refer to
-<a href="http://jitsi.org/">http://jitsi.org/</a>
+<a href="https://jitsi.org/">https://jitsi.org/</a>
for more information.
diff --git a/resources/install/generic/installer-generic.xml b/resources/install/generic/installer-generic.xml
index b505ff3..26ee42f 100755
--- a/resources/install/generic/installer-generic.xml
+++ b/resources/install/generic/installer-generic.xml
@@ -52,7 +52,7 @@
</locale>
<resources>
<res id="InfoPanel.info" src="resources/install/doc/readme.txt" parse="yes"/>
- <res id="LicencePanel.licence" src="resources/install/doc/License.txt"/>
+ <res id="LicencePanel.licence" src="LICENSE"/>
<res src="@DEST_DIR@/generic/tmp-linux_shortcut_specification.xml" id="Unix_shortcutSpec.xml"/>
<res id="Installer.image.0" src="resources/install/doc/welcome.png" />
</resources>
diff --git a/resources/install/generic/run.sh b/resources/install/generic/run.sh
index a9bf1cc..bbc6306 100644
--- a/resources/install/generic/run.sh
+++ b/resources/install/generic/run.sh
@@ -6,7 +6,7 @@ ARCH=`uname -m | sed -e s/x86_64/64/ -e s/i.86/32/`
# Additionnal JVM arguments
CLIENTARGS=""
-if [ $ARCH -eq 32 ]
+if [ $ARCH = 32 ]
then
CLIENTARGS="-client -Xmx256m"
fi
diff --git a/resources/install/installers.properties b/resources/install/installers.properties
index 4526b4b..05701e5 100644
--- a/resources/install/installers.properties
+++ b/resources/install/installers.properties
@@ -13,7 +13,7 @@ windows.jre64.file=C:\\Install\\jre-7u17-windows-x64.exe
# Paths to the ZIP files of private extracted Windows JRE setups to be deployed
# as part of the respective setups of SIP Communicator.
-windows.jre.zip=C:\\Install\\jre-8u40-windows-i586.zip
-windows.jre64.zip=C:\\Install\\jre-8u40-windows-x64.zip
+windows.jre.zip=C:\\Install\\jre-8u121-windows-i586.zip
+windows.jre64.zip=C:\\Install\\jre-8u121-windows-x64.zip
-macosx.jre=${user.home}/bin/jre1.8.0_40.jre
+macosx.jre=${user.home}/bin/jre1.8.0_121.jre
diff --git a/resources/install/linux/installer-linux.xml b/resources/install/linux/installer-linux.xml
index b24ab49..c4f9dcb 100755
--- a/resources/install/linux/installer-linux.xml
+++ b/resources/install/linux/installer-linux.xml
@@ -53,7 +53,7 @@
<resources>
<res id="InfoPanel.info" src="resources/install/doc/readme.txt" parse="yes"/>
- <res id="LicencePanel.licence" src="resources/install/doc/License.txt"/>
+ <res id="LicencePanel.licence" src="LICENSE"/>
<res src="@DEST_DIR@/linux/tmp-linux_shortcut_specification.xml" id="Unix_shortcutSpec.xml"/>
<res id="Installer.image.0" src="resources/install/doc/welcome.png" />
</resources>
diff --git a/resources/install/linux/run.sh b/resources/install/linux/run.sh
index ef3e9ff..bd74b1a 100755
--- a/resources/install/linux/run.sh
+++ b/resources/install/linux/run.sh
@@ -2,4 +2,4 @@ mkdir -p $HOME/.sip-communicator/log
export PATH=$PATH:native
export JAVA_HOME=jre
-${JAVA_HOME}/bin/java -classpath "lib/felix.jar:sc-bundles/sc-launcher.jar:sc-bundles/util.jar:lib/" -Djna.library.path=native -Djava.library.path=native -Dfelix.config.properties=file:./lib/felix.client.run.properties -Djava.util.logging.config.file=lib/logging.properties net.java.sip.communicator.launcher.SIPCommunicator
+${JAVA_HOME}/bin/java -classpath "lib/felix.jar:sc-bundles/sc-launcher.jar:sc-bundles/dnsjava.jar:sc-bundles/util.jar:lib/" -Djna.library.path=native -Djava.library.path=native -Dfelix.config.properties=file:./lib/felix.client.run.properties -Djava.util.logging.config.file=lib/logging.properties net.java.sip.communicator.launcher.SIPCommunicator
diff --git a/resources/install/rpm/Readme.txt b/resources/install/rpm/Readme.txt
deleted file mode 100644
index 03903da..0000000
--- a/resources/install/rpm/Readme.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Packages needed subversion rpm-build java-devel ant.
-Create folder ~/rpmbuild.
-Copy or link the SPECS folder there.
-To create rpm packages just need to call build-jitsi-rpm.sh script, like:
-~/rpmbuild/SPECS/build-jitsi-rpm.sh 1.1 4454.10414 10414
-
diff --git a/resources/install/rpm/SPECS/build-jitsi-rpm.sh b/resources/install/rpm/SPECS/build-jitsi-rpm.sh
index f501d51..ca0af7a 100755
--- a/resources/install/rpm/SPECS/build-jitsi-rpm.sh
+++ b/resources/install/rpm/SPECS/build-jitsi-rpm.sh
@@ -5,11 +5,13 @@ cd $SCRIPT_DIR
#exec > "${0%.*}.log" 2>&1
if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "-?" || $# -lt 1 ]]; then
- echo "Usage $0 BUILD_NUMBER"
+ echo "Usage: $0 BUILD_NUMBER GOOGLE_API_ID GOOGLE_API_SECRET"
exit 1
fi
buildNumber=$1
+googleApiId=$2
+googleApiSecret=$3
# Deletes everything but the newest files matching the specified pattern
clean_oldies() {
@@ -24,6 +26,7 @@ clean_oldies() {
ls -t $pattern | tail -$tailCount | xargs rm -f
}
+[[ ! -d SOURCES ]] && mkdir SOURCES
cd SOURCES
[[ ! -d jitsi ]] && git clone https://github.com/jitsi/jitsi.git
@@ -43,11 +46,13 @@ rm -f jitsi-src*.zip
zipFileName=jitsi-src-${version}-${buildNumber/./-}.zip
zip -rq $zipFileName jitsi -x 'jitsi/.git/* jitsi/.gitignore'
+[[ ! -d $SCRIPT_DIR/SPECS/ ]] && mkdir $SCRIPT_DIR/SPECS/
+cp jitsi/resources/install/rpm/SPECS/jitsi.spec $SCRIPT_DIR/SPECS/
sed -i \
-e "s@Version:\( *\).*@Version:\1$version@" \
-e "s@Release:\( *\).*@Release:\1$buildNumber@" \
--e "s@Source0:\( *\).*@Source0:\1http://download.jitsi.org/jitsi/nightly/src/$zipFileName@" \
--e "s@ant -Dlabel=.* rebuild@ant -Dlabel=$buildNumber rebuild@" \
+-e "s@Source0:\( *\).*@Source0:\1https://download.jitsi.org/jitsi/nightly/src/$zipFileName@" \
+-e "s@ant -Dlabel=.* rebuild@ant rebuild -Dlabel=$buildNumber -Dgoogle.api.client.id=$googleApiId -Dgoogle.api.client.secret=$googleApiSecret@" \
$SCRIPT_DIR/SPECS/jitsi.spec
rm -f $SCRIPT_DIR/RPMS/i686/jitsi*.rpm
diff --git a/resources/install/rpm/SPECS/jitsi.spec b/resources/install/rpm/SPECS/jitsi.spec
index 0998303..38aa215 100644
--- a/resources/install/rpm/SPECS/jitsi.spec
+++ b/resources/install/rpm/SPECS/jitsi.spec
@@ -1,28 +1,31 @@
Name: jitsi
-Version: 2.5
-Release: 5267
+Version: 2.9
+Release: 5537
Summary: Jitsi - Open Source Video Calls and Chat
Packager: Damian Minkov <damencho@jitsi.org>
Group: Applications/Internet
-License: GNU Lesser General Public License
-URL: https://www.jitsi.org
-Source0: http://download.jitsi.org/jitsi/nightly/src/%{name}-src-%{version}-%{release}.zip
+License: Apache License 2.0
+URL: https://jitsi.org
+Source0: https://download.jitsi.org/jitsi/nightly/src/%{name}-src-%{version}-%{release}.zip
BuildRoot: %{_topdir}/buildroot
AutoReqProv: no
-BuildRequires: java-devel >= 0:1.6
+BuildRequires: java-devel >= 1:1.7
BuildRequires: ant
BuildRequires: ant-nodeps
BuildRequires: gzip
-BuildRequires: git-core
+BuildRequires: git
-Requires: java >= 0:1.6
+Requires: java >= 1:1.7
+Requires: libappindicator
+Requires: speex
+Requires: speexdsp
+Requires: libXScrnSaver
%description
-Jitsi (formerly SIP Communicator) is an audio/video and chat communicator
-that supports protocols such as SIP, XMPP/Jabber, AIM/ICQ, Windows Live,
-Yahoo! and many other useful features.
+Jitsi is an audio/video and chat communicator that supports protocols
+such as SIP, XMPP/Jabber, AIM/ICQ, IRC and many other useful features.
%define debug_package %{nil}
@@ -113,6 +116,7 @@ sed -i -e "s/\/usr\/lib\/jni/\$LIBPATH\/native/" $RPM_BUILD_ROOT/usr/bin/jitsi
sed -i -e "s/\/usr\/share\/java\/jdic\.jar/\$LIBPATH\/jdic_stub\.jar:\$LIBPATH\/jdic-all\.jar/" $RPM_BUILD_ROOT/usr/bin/jitsi
sed -i -e "s/\/usr\/share\/java\/org\.apache\.felix\.framework\.jar/\$LIBPATH\/felix\.jar/" $RPM_BUILD_ROOT/usr/bin/jitsi
sed -i -e "s/\/usr\/share\/java\/org\.apache\.felix\.main\.jar://" $RPM_BUILD_ROOT/usr/bin/jitsi
+sed -i -e "s/\/usr\/share\/java\/dnsjava\.jar://" $RPM_BUILD_ROOT/usr/bin/jitsi
sed -i -e "s/\/launchutils.jar//" $RPM_BUILD_ROOT/usr/bin/jitsi
%clean
diff --git a/resources/install/rpm/readme.txt b/resources/install/rpm/readme.txt
new file mode 100644
index 0000000..16d6b14
--- /dev/null
+++ b/resources/install/rpm/readme.txt
@@ -0,0 +1,6 @@
+Packages needed: git, rpm-build, java-devel, ant
+
+1) Create folder ~/rpmbuild
+2) Copy build-jitsi-rpm.sh there
+3) Call build-jitsi-rpm.sh script, like:
+ ~/rpmbuild/build-jitsi-rpm.sh VERSION GOOGLE_API_ID GOOGLE_API_SECRET
diff --git a/resources/install/windows/Microsoft.Windows.Build.Signing.mssign32.dll.manifest b/resources/install/windows/Microsoft.Windows.Build.Signing.mssign32.dll.manifest
new file mode 100644
index 0000000..422623c
--- /dev/null
+++ b/resources/install/windows/Microsoft.Windows.Build.Signing.mssign32.dll.manifest
@@ -0,0 +1,11 @@
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+
+<assemblyIdentity
+ name="Microsoft.Windows.Build.Signing.mssign32.dll"
+ version="0.0.0.0"
+/>
+
+ <file name="mssign32.dll">
+ </file>
+
+</assembly>
diff --git a/resources/install/windows/Microsoft.Windows.Build.Signing.wintrust.dll.manifest b/resources/install/windows/Microsoft.Windows.Build.Signing.wintrust.dll.manifest
new file mode 100644
index 0000000..651475f
--- /dev/null
+++ b/resources/install/windows/Microsoft.Windows.Build.Signing.wintrust.dll.manifest
@@ -0,0 +1,11 @@
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+
+<assemblyIdentity
+ name="Microsoft.Windows.Build.Signing.wintrust.dll"
+ version="0.0.0.0"
+/>
+
+ <file name="wintrust.dll">
+ </file>
+
+</assembly>
diff --git a/resources/install/windows/SCRegistrySpec.wxi b/resources/install/windows/SCRegistrySpec.wxi
index cf07c53..36069de 100644
--- a/resources/install/windows/SCRegistrySpec.wxi
+++ b/resources/install/windows/SCRegistrySpec.wxi
@@ -20,6 +20,31 @@
<Fragment>
<ComponentGroup Id="ComponentGroup_RegistryEntries">
+ <Component
+ Id="Component_UrlCapabilities"
+ Directory="TARGETDIR"
+ Guid="5798BE9D-AEA5-4DA8-992E-EEAD03D7E4CB"
+ Win64="no">
+ <RegistryKey Key="Software\Jitsi\Capabilities" Root="HKLM">
+ <RegistryValue Name="ApplicationDescription" Type="string" Value="Jitsi, the Open Source VoIP and Instant Messaging client." />
+ </RegistryKey>
+ <RegistryKey Key="Software\RegisteredApplications" Root="HKLM">
+ <RegistryValue Name="Jitsi" Type="string" Value="Software\Jitsi\Capabilities" />
+ </RegistryKey>
+ <RegistryKey Key="Software\Jitsi\Capabilities\UrlAssociations" Root="HKLM">
+ <RegistryValue Name="callto" Type="string" Value="Jitsi.Url" />
+ <RegistryValue Name="sip" Type="string" Value="Jitsi.Url" />
+ <RegistryValue Name="tel" Type="string" Value="Jitsi.Url" />
+ <RegistryValue Name="xmpp" Type="string" Value="Jitsi.Url" />
+ </RegistryKey>
+ <RegistryKey Key="Software\Classes\Jitsi.Url" Root="HKLM">
+ <RegistryValue
+ Key="shell\open\command"
+ KeyPath="yes"
+ Type="string"
+ Value='"[INSTALLDIR]@APP_LAUNCHER_NAME@.exe" "%1"' />
+ </RegistryKey>
+ </Component>
<Component
Id="Component_SipRegistryEntries"
@@ -93,7 +118,7 @@
</RegistryKey>
<RegistryKey
Key="SOFTWARE\IM Providers\@APP_NAME@"
- Root="HKLM" Action="createAndRemoveOnUninstall">
+ Root="HKLM">
<RegistryValue
Name="FriendlyName"
Type="string"
@@ -143,6 +168,32 @@
<?if $(var.Platform) = x64 ?>
<Component
+ Id="Component_UrlCapabilities64"
+ Directory="TARGETDIR"
+ Guid="3de76b6b-90b9-403d-82ac-51d841ea95af"
+ Win64="yes">
+ <RegistryKey Key="Software\Jitsi\Capabilities" Root="HKLM">
+ <RegistryValue Name="ApplicationDescription" Type="string" Value="Jitsi, the Open Source VoIP and Instant Messaging client." />
+ </RegistryKey>
+ <RegistryKey Key="Software\RegisteredApplications" Root="HKLM">
+ <RegistryValue Name="Jitsi" Type="string" Value="Software\Jitsi\Capabilities" />
+ </RegistryKey>
+ <RegistryKey Key="Software\Jitsi\Capabilities\UrlAssociations" Root="HKLM">
+ <RegistryValue Name="callto" Type="string" Value="Jitsi.Url" />
+ <RegistryValue Name="sip" Type="string" Value="Jitsi.Url" />
+ <RegistryValue Name="tel" Type="string" Value="Jitsi.Url" />
+ <RegistryValue Name="xmpp" Type="string" Value="Jitsi.Url" />
+ </RegistryKey>
+ <RegistryKey Key="Software\Classes\Jitsi.Url" Root="HKLM">
+ <RegistryValue
+ Key="shell\open\command"
+ KeyPath="yes"
+ Type="string"
+ Value='"[INSTALLDIR]@APP_LAUNCHER_NAME@.exe" "%1"' />
+ </RegistryKey>
+ </Component>
+
+ <Component
Id="Component_MsOfficeCommRegistryEntries_X64"
Directory="TARGETDIR"
Guid="ce3c9a0f-1876-470e-823c-a29d7b7fcb26"
@@ -159,7 +210,7 @@
</RegistryKey>
<RegistryKey
Key="SOFTWARE\IM Providers\@APP_NAME@"
- Root="HKLM" Action="createAndRemoveOnUninstall">
+ Root="HKLM">
<RegistryValue
Name="FriendlyName"
Type="string"
diff --git a/resources/install/windows/makecat.exe b/resources/install/windows/makecat.exe
new file mode 100755
index 0000000..d232107
--- /dev/null
+++ b/resources/install/windows/makecat.exe
Binary files differ
diff --git a/resources/install/windows/makecat.exe.manifest b/resources/install/windows/makecat.exe.manifest
new file mode 100644
index 0000000..4db4536
--- /dev/null
+++ b/resources/install/windows/makecat.exe.manifest
@@ -0,0 +1,21 @@
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity
+ name=" "
+ version="0.0.0.0"
+ />
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ name="Microsoft.Windows.Build.Signing.wintrust.dll"
+ version="0.0.0.0"
+ />
+ </dependentAssembly>
+ </dependency>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker" />
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
diff --git a/resources/install/windows/mssign32.dll b/resources/install/windows/mssign32.dll
new file mode 100755
index 0000000..9905900
--- /dev/null
+++ b/resources/install/windows/mssign32.dll
Binary files differ
diff --git a/resources/install/windows/signtool.exe b/resources/install/windows/signtool.exe
index e631c35..f2aa67e 100755
--- a/resources/install/windows/signtool.exe
+++ b/resources/install/windows/signtool.exe
Binary files differ
diff --git a/resources/install/windows/signtool.exe.manifest b/resources/install/windows/signtool.exe.manifest
new file mode 100644
index 0000000..78e470d
--- /dev/null
+++ b/resources/install/windows/signtool.exe.manifest
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+
+ <assemblyIdentity
+ name=" "
+ version="0.0.0.0"
+ />
+
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ name="Microsoft.Windows.Build.Signing.mssign32.dll"
+ version="0.0.0.0"
+ />
+ </dependentAssembly>
+ </dependency>
+
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ name="Microsoft.Windows.Build.Signing.wintrust.dll"
+ version="0.0.0.0"
+ />
+ </dependentAssembly>
+ </dependency>
+</assembly>
diff --git a/resources/install/windows/wintrust.dll b/resources/install/windows/wintrust.dll
new file mode 100755
index 0000000..ad0c061
--- /dev/null
+++ b/resources/install/windows/wintrust.dll
Binary files differ
diff --git a/resources/languages/resources.properties b/resources/languages/resources.properties
index cafbe93..bc39d06 100644
--- a/resources/languages/resources.properties
+++ b/resources/languages/resources.properties
@@ -43,7 +43,6 @@ service.gui.ACCOUNT_ME=Me
service.gui.ACCOUNT_REGISTRATION_WIZARD=Account Registration Wizard
service.gui.ACCOUNTS=Accounts
service.gui.ADD=&Add
-service.gui.ADD_ACCOUNT=Add account
service.gui.ADD_CONTACT=&Add contact
service.gui.ADD_AUTHORIZED_CONTACT=Add {0} to your contact list
service.gui.ADD_CONTACT_TO_CONTACTLIST=Add the contact to your contact list
@@ -53,20 +52,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Add contact Error
service.gui.ADD_CONTACT_EXIST_ERROR=The contact {0} already exists in your contact list.
service.gui.ADD_CONTACT_NETWORK_ERROR=Server did not respond to our request adding contact with id: {0}.
service.gui.ADD_CONTACT_NOT_SUPPORTED=Failed to add contact with id: {0}. Operation not supported.
-service.gui.ADD_CONTACT_IDENTIFIER=In the field below enter the identifier of the contact you would like to add.
-service.gui.ADD_CONTACT_WIZARD=Add contact wizard
service.gui.ADD_CONTACT_NOT_CONNECTED=You need to be connected in in order to add a contact. Please sign in to the selected provider and try again.
service.gui.ADD_GROUP_LOCAL_ERROR=Failed to add group with name: {0}. The problem occurred during a local IO operation.
service.gui.ADD_GROUP_EXIST_ERROR=The group {0} already exists in your contact list. Please choose another name.
service.gui.ADD_GROUP_NET_ERROR=Failed to add group with name: {0}. The problem occurred due to a network failure. Please check your network connection and try again.
service.gui.ADD_GROUP_ERROR=Failed to add group with name: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=The group name must not be empty.
-service.gui.ADD_GROUP=Create group
-service.gui.ADD_SUBCONTACT=&Add subcontact
service.gui.ADDRESS=Address
service.gui.ADMINISTRATOR=administrator
service.gui.ADVANCED=&Advanced
-service.gui.ALL=&All
service.gui.ALL_CONTACTS=&All contacts
service.gui.ALTERNATE_ADDRESS=Alternate address
service.gui.APPLY=&Apply
@@ -76,7 +70,6 @@ service.gui.AT=at
service.gui.AUTHORIZE=&Authorize
service.gui.AUTHORIZATION_ACCEPTED={0} has accepted your authorization request.
service.gui.AUTHENTICATION_FAILED=Authentication failed for {0}. The password you entered is not valid.
-service.gui.AUTHENTICATION_REQUESTED=Authentication requested
service.gui.AUTHENTICATION_REQUESTED_SERVER=The {0} server has requested your authentication.
service.gui.AUTHENTICATION_REJECTED={0} has rejected your authorization request.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} authentication
@@ -118,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=In the field below, you can enter your new nic
service.gui.CHANGE_NICKNAME_ERROR=Error changing nickname
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Nickname already exists
service.gui.CHANGE_VIDEO_QUALITY=Change remote video quality
-service.gui.CHAT_CONFERENCE_LABEL=Conferences
service.gui.CHAT_CONFERENCE_ITEM_LABEL={0}''s conference
service.gui.CHAT_ROOM_ALREADY_JOINED=The {0} chat room is already joined.
service.gui.CHAT_ROOM_CONFIGURATION={0} chat room configuration
@@ -132,18 +124,14 @@ service.gui.CHAT_ROOM_USER_LEFT=has left {0}
service.gui.CHAT_ROOM_USER_KICKED=has been kicked from {0}
service.gui.CHAT_ROOM_USER_QUIT=has quit {0}
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=Message sending is forbidden (voice revoked)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Saves the chat room for future use
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Removes the selected room from the list of saved rooms
service.gui.CHAT_ROOM_NAME=Chat room name
service.gui.CLEAR_CUSTOM_MESSAGES=Clear custom messages
service.gui.ROOM_NAME=Chat Room
-service.gui.AUTOJOIN=Autojoin
service.gui.CHANGE_PASSWORD=Change password
service.gui.CHAT_ROOM_NAME_INFO=In the field below enter the name of the chat room that you would like to create.
service.gui.CHAT_ROOM_NOT_EXIST=The {0} room was not found in the {1} server. Please verify if the name you typed is correct.
service.gui.CHAT_ROOM_NOT_CONNECTED=You need to be logged in in order to join the {0} chat room.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=You need to be logged in in order to leave a chat room.
-service.gui.CHAT_ROOM_NOT_JOINED=You need to be joined to the chat room in order to do further operations with it.
service.gui.CHAT_ROOM_OPTIONS=Chat room options
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=The {0} chat room requires registration to be joined.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=The {0} chat room has requested a password.
@@ -168,16 +156,15 @@ service.gui.CONNECTING=Connecting...
service.gui.CONNECTING_STATUS=Connecting
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Connecting*
service.gui.CONNECTION=Connection
-service.gui.CONNECTION_FAILED_MSG=Connection failed for the following account: User name: {0}, Server name: {1}. Please check your network connection or contact your network administrator for more information.
service.gui.CONNECTION_EXPIRED_MSG=You are currently disconnected from the {0} server.
service.gui.CONTACT_NAME=ID or Number
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=The chosen {0} contact doesn''t support telephony.
+service.gui.CONTACT_NAME_PROMPT=jane.doe@example.com
+service.gui.CONTACT_NAME_INFO=Add either an instant messaging address (such as jane.doe@example.com) or a VoIP number
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=The chosen {0} contact doesn''t support chat conferencing.
service.gui.CONTACT_PAUSED_TYPING={0} paused typing the message
service.gui.CONTACT_TYPING={0} is typing a message
service.gui.CONTACT_TYPING_SEND_FAILED=uh-oh...we couldn''t tell {0} that you were writing
service.gui.CONTACT_INFO=&Contact info
-service.gui.CONTACTLIST=Contactlist
service.gui.CONTACTS=Contacts
service.gui.COPY=&Copy
service.gui.COPY_LINK=Copy &link
@@ -187,28 +174,26 @@ service.gui.CREATE_CHAT_ROOM=&Create chat room...
service.gui.CREATE_CHAT_ROOM_ERROR=Failed to create {0} chat room.
service.gui.CREATE_CHAT_ROOM_WIZARD=Create chat room wizard
service.gui.CREATE_CONFERENCE_CALL=&Create a conference call...
-service.gui.CREATE_CONFERENCE_CHAT=&Create a conference chat...
service.gui.CREATE_GROUP=&Create group...
service.gui.CREATE_GROUP_NAME=In the field below enter the name of the group you would like to create.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Your contact list doesn't contain any groups. Please create a group first (File/Create group).
service.gui.CREATE_VIDEO_BRIDGE=Create a &video bridge...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Create a &video bridge
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Create / Join video conference
service.gui.CREATE_VIDEO_CONFERENCE=Create a new video conference for this chat room
service.gui.CONTACT_INFO_NOT_SUPPORTED=This contact doesn't support web contact info
service.gui.CUT=C&ut
-service.gui.DATE=Date
service.gui.DELETE=Delete
service.gui.DENY=&Deny
service.gui.DESKTOP_SHARING_WARNING=<b>Are you sure you want to start screen sharing?</b> <br> Clicking OK will let people on this call see your screen.
service.gui.DESKTOP_SHARING_DIALOG_INDICATE=You are sharing your screen
service.gui.DIALPAD=Dial Pad
service.gui.DISPLAY_NAME=Display name
+service.gui.DISPLAY_NAME_PROMPT=Jane Doe
+service.gui.DISPLAY_NAME_INFO=Add a name for this contact. If left blank the IM address or VoIP number will be used. (Optional)
service.gui.DISCONNECTED_STATUS=Disconnected
service.gui.DND_STATUS=Do not disturb
service.gui.DO_NOT_ASK_AGAIN=Don't ask again
service.gui.DO_NOT_SHOW_AGAIN=Don't show this message again
-service.gui.DOWNLOAD_NOW=&Download now
service.gui.DRAG_FOR_SHARING=Drag here anything you want to share...
service.gui.DURATION=duration
service.gui.DESTROY_CHATROOM=Destroy chat room
@@ -229,7 +214,6 @@ service.gui.ERROR_RECEIVED_FROM=Error received from {0}
service.gui.ESTIMATED_TIME=Estimated time:
service.gui.EVENTS=Events
service.gui.EXIT=E&xit
-service.gui.EXTENDED_CRITERIA=Extended criteria
service.gui.GENERAL=General
service.gui.GENERAL_ERROR=General error
service.gui.GROUP_NAME=Group name
@@ -271,7 +255,6 @@ service.gui.FONT_ITALIC=Italic
service.gui.FONT_SIZE=Size
service.gui.FONT_STYLE=Style
service.gui.FONT_UNDERLINE=Underline
-service.gui.FROM={0} from {1}
service.gui.GRANT_OWNERSHIP=Grant ownership...
service.gui.GRANT_ADMIN=Grant administrator...
service.gui.GRANT_MODERATOR=Grant moderator
@@ -298,7 +281,6 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=Are you sure you want to permanently remo
service.gui.HISTORY_REMOVE_ERROR=Error removing locally stored messages.
service.gui.HOME=Home
service.gui.HOME_PAGE=Home page
-service.gui.HOUR=Hour
service.gui.ICE=ICE
service.gui.IDENTIFIER=Identifier
service.gui.IGNORE=&Ignore
@@ -322,16 +304,10 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Invite contacts to video bridge
service.gui.INVITE_REASON=Invite reason
service.gui.IS_CALLING={0} is calling...
service.gui.IS_NOW={0} is now {1}
-service.gui.JITSI_WARNING=SIP Communicator has recently been renamed to Jitsi.<br/>\
- If you want your version to remain up-to-date, then please download Jitsi now.\
-<br/><br/>We are sorry for any inconvenience that this may be causing you.\
-<br/><br/>The Jitsi Dev Team
-service.gui.JITSI_WARNING_TITLE=SIP Communicator becomes Jitsi
service.gui.JOIN=&Join
service.gui.JOIN_AS=J&oin as
service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=Join an existing video conference
service.gui.JOIN_VIDEO=Join video
-service.gui.CLOSE_CHAT_ROOM_DIALOG=C&lose
service.gui.JOB_TITLE=Job title
service.gui.JOIN_CHAT_ROOM=&Join chat room...
service.gui.JOIN_CHAT_ROOM_TITLE=Join chat room
@@ -344,7 +320,6 @@ service.gui.KICK_FAILED=Kick failed
service.gui.KICK_FAILED_GENERAL_ERROR=Failed to kick {0}. A general server error occurred.
service.gui.KICK_FAILED_NOT_ALLOWED=Failed to kick {0}. The owner and the administrator of the room could not be kicked.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Failed to kick {0}. You don''t have enough privileges to do that.
-service.gui.LAST=Last
service.gui.LAST_NAME=Last name
service.gui.LEAVE=&Leave
service.gui.LIMIT_REACHED_FOR_IP=You have too many existing registrations from the local IP address and the {0} server doesn''t allow to open any more of them.
@@ -364,7 +339,6 @@ service.gui.MESSAGE=Message
service.gui.MISSED_CALLS_TOOL_TIP=Missed calls from:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= and {0} more
service.gui.MODERATOR=moderator
-service.gui.MORE=See more
service.gui.MORE_LABEL=More
service.gui.MOVE=Move
service.gui.MOVE_SUBCONTACT=M&ove contact
@@ -373,7 +347,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=The contact you have chosen is the same as \n
service.gui.MOVE_SUBCONTACT_QUESTION=Are you sure you want to move {0} to {1}?
service.gui.MOVE_TO_GROUP=&Move to group
service.gui.MOVE_CONTACT=Move Contact
-service.gui.MOVE_CONTACT_ERROR=&Contact cannot be moved
service.gui.MSG_DELIVERY_FAILURE=The above message could not be delivered
service.gui.MSG_DELIVERY_NOT_SUPPORTED=The protocol you are using doesn''t \
support offline messages. You could try to reach {0} through another \
@@ -389,7 +362,6 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=You should be connected to be able to se
service.gui.MULTIPLE_LOGINS=You have logged in more than once with the same account. The following account: User name: {0}, Server name: {1} is currently disconnected.
service.gui.MY_CHAT_ROOMS=Add chat room
service.gui.MY_CHAT_ROOMS_TITLE=Add chat room
-service.gui.MUTE=Mute
service.gui.MUTUALLY_ON_HOLD_STATUS=Mutually On Hold
service.gui.NAME=Name
service.gui.NETWORK=Network
@@ -421,7 +393,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=NotInContactList
service.gui.SD_QUALITY=Standard quality
service.gui.OFFLINE=Offline
service.gui.OK=&OK
-service.gui.OLDER_CALLS=Older calls
service.gui.ONLINE=Online
service.gui.OPEN=Open
service.gui.OPEN_FILE_FROM_IMAGE=Double click to open file.
@@ -433,7 +404,6 @@ service.gui.OPEN_ON_ACTIVITY=Open on activity
service.gui.OPEN_ON_MESSAGE=Open on message only
service.gui.OPEN_ON_IMPORTANT_MESSAGE=Open on important messages only
service.gui.OR=or
-service.gui.OR_ENTER_PHONE_NUMBER=Or enter phone number here...
service.gui.ORGANIZATION=Organization
service.gui.OTHER=Other
service.gui.chat.role.OWNER=Owner
@@ -459,7 +429,6 @@ service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Enter' for suggestions
service.gui.PRESS_FOR_CALL_INFO=Press for call info
service.gui.PRESS_TO_OPEN_CRM=Press to open CRM application
service.gui.PREVIOUS=Previous
-service.gui.PREVIOUS_TOOLTIP=Browse older conversations
service.gui.PRINT=&Print
service.gui.PROACTIVE_NOTIFICATION=is writing a message
service.gui.PROBLEMS_ENCOUNTERED=Problems encountered
@@ -475,7 +444,6 @@ service.gui.RECONNECTION_LIMIT_EXCEEDED=You have have been disconnecting and rec
service.gui.RE_REQUEST_AUTHORIZATION=Re-request authorization
service.gui.REFERRED_STATUS=Referred
service.gui.REJECT=&Reject
-service.gui.REMIND_ME_LATER=Remind me later
service.gui.REMEMBER_PASSWORD=Remember password
service.gui.REMOVE=&Remove
service.gui.REMOVE_ACCOUNT=&Remove account
@@ -501,29 +469,23 @@ service.gui.REVOKE_ADMIN=Revoke admin
service.gui.REVOKE_MODERATOR=Revoke moderator
service.gui.REVOKE_MEMBERSHIP=Revoke membership
service.gui.REVOKE_VOICE=Revoke voice
-service.gui.ROOT_GROUP=Root group
service.gui.SAVE=&Save
-service.gui.SAVE_AS_DEFAULT=Save as default
service.gui.SEARCH=&Search
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Click the below button to show all chat rooms existing in the selected server. Then select the one you would like to join and click the join button.
service.gui.SEARCH_STRING_CONTACT_SOURCE=Searched contact
service.gui.SECURITY=Security
service.gui.SELECT_ACCOUNT=Select account
+service.gui.SELECT_ACCOUNT_INFO=Which account do you want to use to communicate with this contact?
service.gui.SELECT_COLOR=Select color
service.gui.SELECT_GROUP=Select group
-service.gui.SELECT_GROUP_WIZARD_MSG=The list below contains all groups in your Contact List. Select the one, where you would like to add the new contact.
+service.gui.SELECT_GROUP_INFO=Which group do you want to display this contact under? (Optional)
service.gui.SELECT_NO_GROUP=No group
-service.gui.SELECT_GROUP_WIZARD=Specify group
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=The list below contains all accounts that support the multi user chat feature. Select the one you would like to use to create your chat room.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=The list below contains all registered accounts. Select the one you would like to use to communicate with the new contact.
-service.gui.SELECT_PROVIDERS_WIZARD=Select account
service.gui.SELECT_VIDEO_CONFERENCE=Select video conference
service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Select chat room from the list and press OK to add it.
service.gui.SEND=&Send
service.gui.SEND_FILE=Send &file
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=There is no info for this contact.
service.gui.SEND_MESSAGE=&Send a message
-service.gui.SEND_AS_SMS=Send as SMS
service.gui.SEND_PRIVATE_MESSAGE=Send private message
service.gui.SEND_SMS=S&end SMS
service.gui.SEND_SMS_DETAILS=Remember that you need to enter the number in international \
@@ -563,7 +525,6 @@ service.gui.STREET=Street
service.gui.SUBJECT=Subject
service.gui.SUMMARY=Summary
service.gui.TELEPHONY=Telephony
-service.gui.TODAY=Today
service.gui.TOOLS=&Tools
service.gui.TRANSFER=Trans&fer
service.gui.TO=&To:
@@ -573,7 +534,6 @@ service.gui.TRANSFER_CALL_TO=Transfer to:
service.gui.TRANSPARENCY_NOT_ENABLED=Transparency is not supported by your current configuration.
service.gui.TYPE_YOUR_REQUEST=Type your request here
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=We were not able to change video quality for this call.
-service.gui.UNMUTE=Unmute
service.gui.USER_IDENTIFIER=User identifier:
service.gui.USER_EXISTS_ERROR=This user already exists on the selected network. Please choose another user or network.
service.gui.USERNAME_NULL=Please fill your username and password.
@@ -586,7 +546,6 @@ service.gui.USE_PROVISIONING=Use online provisioning
service.gui.VALUE=Value
service.gui.VIDEO_CALL=&Video call
service.gui.VIA=via
-service.gui.VIA_SMS=Via SMS
service.gui.VIEW=&View
service.gui.VIEW_HISTORY=View &history
service.gui.VIEW_SMILEYS=View &smileys
@@ -606,9 +565,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=Adjust volume
service.gui.WAITING_AUTHORIZATION=Waiting for authorization
service.gui.WARNING=Warning
service.gui.YES=Yes
-service.gui.YESTERDAY=Yesterday
-service.gui.EXISTING_ACCOUNT_ERROR=The account you entered is already installed.
-service.gui.NEW_MAIL=<b>You have one new Mail!</b><br/><b>From:</b> {0} {1} <br/><b>Subject:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=You have received a new mail message in your {0} <a href="{1}">inbox</a>:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=You have received {2} new mail messages in your {0} <a href="{1}">inbox</a>:<br/>
service.gui.NEW_GMAIL_FOOTER=one more unread conversation in your <a href="{0}">inbox</a>.<br/>
@@ -635,7 +591,6 @@ service.gui.SECURITY_ERROR=Security error
service.gui.SPEED=Speed:
service.gui.SILENT_MEMBER=silent member
service.gui.NON_SECURE_CONNECTION=No secure connection can be made for account {0}. If you want to connect to non-secure server, please check \"Allow non-secure connections\" in your account configuration
-service.gui.UPDATE=Update
service.gui.MOBILE_PHONE=Mobile
service.gui.VIDEO_PHONE=Video
service.gui.WORK_PHONE=Work
@@ -672,12 +627,10 @@ service.gui.callinfo.CALL_INFORMATION=Call information
service.gui.callinfo.CALL_IDENTITY=Identity
service.gui.callinfo.PEER_COUNT=Participant count
service.gui.callinfo.IS_CONFERENCE_FOCUS=Conference focus
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Encryption enabled
service.gui.callinfo.CALL_TRANSPORT=Signalling call transport
service.gui.callinfo.CALL_DURATION=Call duration
service.gui.callinfo.TLS_PROTOCOL=TLS protocol
service.gui.callinfo.TLS_CIPHER_SUITE=TLS cipher suite
-service.gui.callinfo.TLS_SERVER_CERTIFICATE_CHAIN=TLS server certificate chain
service.gui.callinfo.TLS_CERTIFICATE_CONTENT=The content of the TLS server \
certificate is displayed below.
service.gui.callinfo.VIEW_CERTIFICATE=View certificate
@@ -688,7 +641,7 @@ service.gui.callinfo.AUDIO_INFO=Audio info
service.gui.callinfo.VIDEO_INFO=Video info
service.gui.callinfo.LOCAL_IP=Local IP / Port
service.gui.callinfo.REMOTE_IP=Remote IP / Port
-service.gui.callinfo.BANDWITH=Bandwith
+service.gui.callinfo.BANDWITH=Bandwidth
service.gui.callinfo.LOSS_RATE=Loss rate
service.gui.callinfo.RTT=RTT
service.gui.callinfo.JITTER=Jitter
@@ -698,10 +651,14 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=Key exchange protocol
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=ICE candidate extended type
service.gui.callinfo.ICE_STATE=ICE Processing State
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=Gather candidates
service.gui.callinfo.ICE_STATE.RUNNING=Connectivity checks
service.gui.callinfo.ICE_STATE.COMPLETED=Completed
service.gui.callinfo.ICE_STATE.FAILED=Failed
+service.gui.callinfo.ICE_STATE.TERMINATED=Terminated
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=Local host IP / Port
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=Local reflexive IP / Port
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=Local relayed IP / Port
@@ -733,12 +690,6 @@ The certificate is not trusted, which means that the server''s \
identity cannot<br> be automatically verified. \
Do you want to continue connecting?<br><br> \
For more information, click "Show Certificate".</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} can''t verify the identity \
-of the connecting client.<br><br> \
-The certificate is not trusted, which means that the client''s \
-identity cannot<br> be automatically verified. \
-Do you want to accept the connection?<br><br> \
-For more information, click "Show Certificate".</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} can''t verify the identity \
of the peer {1}.<br><br> \
The certificate is not trusted, which means that the peer''s \
@@ -748,6 +699,8 @@ For more information, click "Show Certificate".</html>
service.gui.CONTINUE_ANYWAY=Continue anyway
service.gui.CERT_INFO_CHAIN=Certificate Chain:
service.gui.CERT_INFO_ISSUED_TO=Issued To
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Common Name:
service.gui.CERT_INFO_O=Organization:
service.gui.CERT_INFO_C=Country Name:
@@ -766,12 +719,10 @@ service.gui.CERT_INFO_SIGN_ALG=Signature Algorithm:
service.gui.CERT_INFO_PUB_KEY_INFO=Public Key Info
service.gui.CERT_INFO_ALG=Algorithm:
service.gui.CERT_INFO_PUB_KEY=Public Key:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} bytes: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} bits
service.gui.CERT_INFO_EXP=Exponent:
service.gui.CERT_INFO_KEY_SIZE=Key Size:
service.gui.CERT_INFO_SIGN=Signature:
-service.gui.CONTINUE=Continue
service.gui.SHOW_CERT=Show Certificate
service.gui.HIDE_CERT=Hide Certificate
@@ -794,12 +745,9 @@ service.gui.security.SECURE_AUDIO=Secure audio
service.gui.security.AUDIO_NOT_SECURED=Audio not secure
service.gui.security.SECURE_VIDEO=Secure video
service.gui.security.VIDEO_NOT_SECURED=Video not secure
-service.gui.security.NO_VIDEO=No video
-service.gui.security.CIPHER=Cipher: {0}
service.gui.security.CALL_SECURED_TOOLTIP=Call secured. For more information click here.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Call not secure.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Press here to compare security secret with your partner.
-service.gui.security.COMPARE_WITH_PARTNER=Compare with partner and click the padlock to confirm.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Compare with partner:
service.gui.security.STRING_COMPARED=String compared!
@@ -824,20 +772,22 @@ service.gui.avatar.imagepicker.CLICK=Click and Smile
service.gui.avatar.imagepicker.IMAGE_FILES=Image files
service.gui.avatar.imagepicker.IMAGE_PICKER=Picture
service.gui.avatar.imagepicker.IMAGE_SIZE=Image size
-service.gui.avatar.imagepicker.INITIALIZING=Initializing
service.gui.avatar.imagepicker.RESET=Reset
service.gui.avatar.imagepicker.SET=Set
service.gui.avatar.imagepicker.TAKE_PHOTO=Take a photo
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Webcam error
service.gui.security.encryption.required=Encryption required!
service.protocol.ICE_FAILED=Could not establish connection (ICE failed and no relay found)
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
+service.systray.MODE=Tray implementation
+service.systray.mode.NATIVE=Default
+service.systray.mode.DISABLED=Disabled
+service.systray.mode.APPINDICATOR=AppIndicator (Unity, KDE, not plain Gnome 3; may crash on Debian)
+service.systray.mode.APPINDICATOR_STATIC=AppIndicator Static (no account status menus)
+service.systray.CLI_NOTE=If your choice does not work, you can start {0} with the "--notray" option. \
+ This forces the mode to "Disabled" and shows the GUI. \
+ Changing the tray implementation requires a restart.
impl.protocol.sip.XCAP_ERROR_TITLE=Error in SIP contact list storage
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=Resource cannot be read {0}. For {1}
@@ -867,9 +817,7 @@ impl.ldap.QUERY_CUSTOM=Custom query
impl.ldap.QUERY_CUSTOM_HINT=Use {0} as a placeholder for the search term.
impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=Automatically add wildcards to the query term
impl.ldap.QUERY_PHOTO_INLINE=Fetch photo along with other attributes
-impl.ldap.NEW=New
impl.ldap.EDIT=edit
-impl.ldap.REMOVE=Remove
impl.ldap.ENABLED=Enabled
impl.ldap.SERVER_NAME=Server name
impl.ldap.SERVER_NAME_EXAMPLE=My LDAP server
@@ -902,14 +850,21 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=homePhone
impl.ldap.PHONE_PREFIX=Phone prefix
impl.ldap.PHONE_PREFIX_EXAMPLE=Ex.: 00
+# SIP Protocol
+impl.protocol.sip.INVALID_ADDRESS=''{0}'' is not a valid SIP address.
+
+#Jabber Protocol
+impl.protocol.jabber.INVALID_ADDRESS=''{0}'' is not a valid XMPP JID.
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=Address book
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=Enable MacOSX Address Book search
plugin.addrbook.ENABLE_MICROSOFT_OUTLOOK=Enable Microsoft Outlook search
+plugin.addrbook.ENABLE_OUTLOOK_CALENDAR=Disable setting presence using the Microsoft Outlook Calendar
plugin.addrbook.DESCRIPTION=If enabled everything you type in the search field \
of the contact list will be also searched in your system address book and all \
matching contacts from your address book will appear in your contact list.
- plugin.addrbook.DEFAULT_IM_APP=Make Jitsi the default Instant Messaging Provider (Outlook integration)
+plugin.addrbook.DEFAULT_IM_APP=Make Jitsi the default Instant Messaging Provider (Outlook integration)
plugin.addrbook.PREFIX=Specific phone number prefix
plugin.addrbook.PREFIX_EXAMPLE=Ex.: 00
plugin.addrbook.OUTLOOK_IS_NOT_DEFAULT_MAIL_CLIENT_TITLE=Error accessing your Microsoft Outlook contacts.
@@ -918,9 +873,7 @@ plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT=Make Outlook default mail clien
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Google Contacts
-impl.googlecontacts.NEW=New
impl.googlecontacts.EDIT=edit
-impl.googlecontacts.REMOVE=Remove
impl.googlecontacts.ENABLED=Enabled
impl.googlecontacts.ACCOUNT_NAME=Account name
impl.googlecontacts.SAVE=Save
@@ -963,11 +916,8 @@ plugin.accountinfo.ORGANIZATION=Organization Name:
plugin.accountinfo.JOB_TITLE=Job Title:
plugin.accountinfo.ABOUT_ME=About Me:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
-plugin.accountinfo.USER_PICTURES=User Pictures
plugin.accountinfo.GLOBAL_ICON=Use global icon
plugin.accountinfo.LOCAL_ICON=Use this icon:
-plugin.accountinfo.CHANGE=Change
-plugin.accountinfo.ONLY_MESSAGE=Only messages
# connection info
plugin.connectioninfo.TITLE=Connection Info
@@ -987,61 +937,18 @@ plugin.aimaccregwizz.USERNAME=AIM Screenname:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Screen Name and Password
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Register new account
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=In case you don't have an AIM account, click on this button to create a new one.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Override server default options
# branding
plugin.branding.ABOUT_WINDOW_TITLE=About {0}
plugin.branding.LOGO_MESSAGE=Open Source VoIP && Instant Messaging
-plugin.branding.LOADING=Loading
plugin.branding.ABOUT_MENU_ENTRY=&About
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>The {1} is currently under active development. \
- The version you are running is only experimental and MAY NOT \
- work as expected. Please refer to {2} for more information.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 Copyright \
- <b>jitsi.org</b>. All rights reserved. Visit \
- <a href="https://jitsi.org">https://jitsi.org</a>.\
- </font></DIV>
-plugin.branding.LICENSE=<DIV color={0}><b>Jitsi</b> is distributed under \
- the terms of the Apache \
- (<a href=\"http://www.apache.org/licenses/LICENSE-2.0\">\
- http://www.apache.org/licenses/LICENSE-2.0</a>).</DIV>
+plugin.branding.COPYRIGHT_LICENSE=<DIV><font size=3 color={0}>Copyright 2003-{1} \
+ <a href="{2}"><b>{3}</b></a>, All rights reserved.\
+ </font><br><br>{4} is distributed under \
+ the terms of the <a href=\"{5}\">{6}</a>.</DIV>
plugin.busylampfield.PICKUP=Pickup call
-# Dict protocol
-service.protocol.DICTIONARIES=Dictionaries
-plugin.dictaccregwizz.ANY_DICTIONARY=Any Dictionary
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Any Dictionary from {0}
-plugin.dictaccregwizz.FIRST_MATCH=First Match
-plugin.dictaccregwizz.NO_MATCH=No match
-plugin.dictaccregwizz.MATCH_RESULT=No definitions found for "{0}", perhaps you mean:\n
-plugin.dictaccregwizz.INVALID_DATABASE=The current dictionary "{0}" doesn''t exist anymore on the server.
-plugin.dictaccregwizz.INVALID_STRATEGY=The current strategy isn't available on the server.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=The Dict service protocol
-plugin.dictaccregwizz.HOST=Host
-plugin.dictaccregwizz.SERVER_INFO=Server informations
-plugin.dictaccregwizz.STRATEGY_SELECTION=Strategy selection
-plugin.dictaccregwizz.STRATEGY_LIST=List of strategies:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Search strategies
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=Strategy is use to search similar words,if a translation was not found, thanks to different approaches. For example the Prefix strategies will search words which begin like the word you would translate.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Dict Account Information
-plugin.dictaccregwizz.FIRST_ACCOUNT=This wizard will create your first Dict Account for you on dict.org.\n\n\
-You can add new dictionary by going on Account Registration Wizard. Fill the host Field with dictionary you would like to add.
-plugin.dictaccregwizz.THREAD_CONNECT=Trying to connect to server
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=Connexion attempt failed, this isn't a dict server or the server is offline
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=Retrieving strategies
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=No strategy found on the server
-plugin.dictaccregwizz.POPULATE_LIST=Populating list
-plugin.dictaccregwizz.CLOSING_CONNECTION=Closing connection
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">In order to use Facebook Chat you need to create a "Username" <br>from your "Account Settings" page on Facebook.</a><br><br>Note: When you create username you must logout from the webpage <br>and it can take a while before you are able to login with your new username!</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=The Facebook Chat protocol
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Username:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Username and Password
-
# generalconfig
plugin.generalconfig.AUTO_START=Auto-start {0} when computer restarts or reboots
plugin.generalconfig.CHATALERTS_ON_MESSAGE=Use task bar / dock alerts on incoming calls and chats
@@ -1051,9 +958,6 @@ plugin.generalconfig.SHOW_HISTORY=Show
plugin.generalconfig.HISTORY_SIZE=recent messages in new chats
plugin.generalconfig.SEND_MESSAGES_WITH=Send messages with:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=Bring chat window to front
-plugin.generalconfig.ERROR_PERMISSION=You don't have enough privileges to remove autostart
-plugin.generalconfig.TRANSPARENCY=Transparency
-plugin.generalconfig.ENABLE_TRANSPARENCY=Enable transparency
plugin.generalconfig.DEFAULT_LANGUAGE=Interface Language
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Your changes will take effect on next restart.
plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0}% translated
@@ -1069,6 +973,8 @@ plugin.generalconfig.REMOVE_SPECIAL_PHONE_SYMBOLS=Remove special symbols before
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS=Convert letters in phone numbers
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS_EXAMPLE=e.g. +1-800-MYPHONE -> +1-800-694663
plugin.generalconfig.SIP_CALL_CONFIG=SIP
+plugin.generalconfig.XMPP_CONFIG=XMPP
+plugin.generalconfig.XMPP_USE_ALL_RESOURCES=Use all resources when detecting a contact's features
plugin.generalconfig.OPUS_CONFIG=Opus
plugin.generalconfig.OPUS_AUDIO_BANDWIDTH=Sampling rate:
plugin.generalconfig.OPUS_BITRATE=Encoder average bitrate (kbps):
@@ -1082,6 +988,7 @@ plugin.generalconfig.SILK_ALWAYS_ASSUME_PACKET_LOSS=Always assume packet loss:
plugin.generalconfig.SILK_SAT=Speech activity threshold (0-1):
plugin.generalconfig.SILK_ADVERTISE_FEC=Advertise FEC support in SDP:
plugin.generalconfig.RESTORE=Restore defaults
+plugin.generalconfig.MINIMIZE_NOT_HIDE=Minimize the main window instead of closing or hiding it
# gibberish accregwizz
plugin.gibberishaccregwizz.PROTOCOL_NAME=Gibberish
@@ -1140,13 +1047,10 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Comment
plugin.jabberaccregwizz.RESOURCE=Resource
plugin.jabberaccregwizz.AUTORESOURCE=Auto generate resource
plugin.jabberaccregwizz.PRIORITY=Priority
-plugin.jabberaccregwizz.XMPP_ERROR=XMPP Error
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Unknown XMPP error ({0}). Verify that the server name is correct.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Your passwords did not match.
plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Override server default options
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Advanced options
plugin.jabberaccregwizz.USE_ICE=Use ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=Use Google's Jingle/ICE (experimental)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=Auto discover STUN/TURN servers
plugin.jabberaccregwizz.SUPPORT_TURN=Support TURN
plugin.jabberaccregwizz.TURN_USERNAME=TURN username
@@ -1174,11 +1078,8 @@ plugin.jabberaccregwizz.DISABLE_CARBON=Disable message carbons
plugin.jabberaccregwizz.DTMF_AUTO=Auto: Choose automatically between RTP and Inband
plugin.jabberaccregwizz.SERVER_OPTIONS=Server options
plugin.jabberaccregwizz.CHANGE_PASSWORD=Change account password
-plugin.jabberaccregwizz.NEW_PASSWORD=New password
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Confirm new password
plugin.jabberaccregwizz.PORT_FIELD_INVALID=Please fill a valid port number in order to continue.
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=The account has to be signed in before changing a password.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=The password is empty.
plugin.jabberaccregwizz.TLS_REQUIRED=The connection does not use TLS, will not attempt a password change.
plugin.jabberaccregwizz.PASSWORD_CHANGED=The password has been successfully changed
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=Your XMPP server does not support password changes.
@@ -1192,15 +1093,6 @@ plugin.jabberaccregwizz.RESET=Reset
plugin.jabberaccregwizz.RESET_DESCRIPTION=Reset to the global settings
plugin.jabberaccregwizz.DISABLE_JINGLE=Disable Jingle (audio and video calls with XMPP).
-# mailbox
-plugin.mailbox.OUTGOING=Outgoing Message:
-plugin.mailbox.INCOMING=Incoming Messages:
-plugin.mailbox.WAIT_TIME=Delay Until Call Sent to Voicemail
-plugin.mailbox.MAX_MESSAGE_TIME=Maximum Incoming Message Duration
-plugin.mailbox.CONFIRM=Confirm
-plugin.mailbox.DEFAULTS=Defaults
-plugin.mailbox.MAILBOX=Mailbox
-
# plugin manager
plugin.pluginmanager.INSTALL=Install
plugin.pluginmanager.UNINSTALL=Uninstall
@@ -1229,7 +1121,6 @@ plugin.sipaccregwizz.SERVER_PORT=Server port
plugin.sipaccregwizz.PROXY=Proxy
plugin.sipaccregwizz.PROXY_PORT=Proxy port
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Preferred transport
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Advanced options
plugin.sipaccregwizz.PROXY_OPTIONS=Proxy options
plugin.sipaccregwizz.PROXY_AUTO=Configure proxy automatically
plugin.sipaccregwizz.PROXY_FORCE_BYPASS=Bypass proxy security check for HA scenarios (use only if needed)
@@ -1250,8 +1141,6 @@ plugin.sipaccregwizz.DTMF_AUTO=Auto: Choose automatically between RTP and Inband
plugin.sipaccregwizz.DTMF_RTP=RTP ( RFC2833 / RFC 4733 )
plugin.sipaccregwizz.DTMF_SIP_INFO=SIP INFO
plugin.sipaccregwizz.DTMF_INBAND=Inband
-plugin.sipaccregwizz.REGISTER=REGISTER
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Override server default options
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Enable support to encrypt calls
plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=Indicate support of ZRTP in signalling protocol
plugin.sipaccregwizz.AUTH_NAME=Authorization name
@@ -1272,10 +1161,10 @@ plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=Voicemail check URI
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Your passwords did not match.
plugin.sipaccregwizz.NO_CERTIFICATE=<none> (use regular authentication)
plugin.sipaccregwizz.SAVP_OPTION=RTP/SAVP indication
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=Off (indicate RTP/AVP only)
plugin.sipaccregwizz.SAVP_OPTION_1=Mandatory (offer and accept only RTP/SAVP)
plugin.sipaccregwizz.SAVP_OPTION_2=Optional (offer RTP/SAVP first, then RTP/AVP)
-plugin.sipaccregwizz.ENABLE_SDES_ATTRIBUTE=Enable S-Descriptor (also known as SDES or SRTP)
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=Choose enabled encryption protocols and their priority (top protocol first):
plugin.sipaccregwizz.CIPHER_SUITES=Enabled cipher suites:
plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>{0} will automatically try to secure all \
@@ -1292,15 +1181,6 @@ plugin.skinmanager.DEFAULT_SKIN=Default skin
plugin.skinmanager.ADD_NEW_SKIN=Add new skin...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=The default skin of the application.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=A Protocol to connect to remote machines over SSH.
-plugin.sshaccregwizz.USERNAME=Account ID:
-plugin.sshaccregwizz.IDENTITY_FILE=Identity File:
-plugin.sshaccregwizz.KNOWN_HOSTS=Known Hosts:
-plugin.sshaccregwizz.OPTIONAL=Optional
-plugin.sshaccregwizz.ACCOUNT_DETAILS=Account details
-
# status update
plugin.autoaway.AUTO_STATUS=Auto Away
plugin.autoaway.ENABLE_CHANGE_STATUS=Change status while away
@@ -1348,22 +1228,6 @@ plugin.whiteboard.DESELECT=Deselect
plugin.whiteboard.DELETE=Delete
plugin.whiteboard.PROPERTIES=Properties
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=A protocol to connect and chat on the Yahoo! Service.
-plugin.yahooaccregwizz.USERNAME=Username:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=ID and Password
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=The Zeroconf (Bonjour) service protocol.
-plugin.zeroaccregwizz.FIRST_NAME=First name:
-plugin.zeroaccregwizz.LAST_NAME=Last name:
-plugin.zeroaccregwizz.EMAIL=Email:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=Remember Bonjour contacts?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=ID and Password
-plugin.zeroaccregwizz.USERID=User ID
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=The Google Talk protocol
@@ -1377,19 +1241,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, the IP Telecommunications
plugin.iptelaccregwizz.USERNAME=User name
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=Subscribe to iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIP and chat
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Username
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Retype password
plugin.sip2sipaccregwizz.EMAIL=Email address
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=For help about this service visit<br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>The email address is used to send voicemail messages, <br>missed calls notifications and to recover a lost password</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>For help about this service visit <a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=Existing sip2sip.info account
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Create a free sip2sip.info account
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP && Instant Messaging
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=For help about this service visit<br>http://ippi.fr
@@ -1398,6 +1254,8 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=Existing ippi account
plugin.ippiaccregwizz.CREATE_ACCOUNT=Create a free ippi account
# key binding chooser
+plugin.keybindings.WAITING=Press shortcut...
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Close Chat Window
plugin.keybindings.CHAT_COPY=Copy
plugin.keybindings.CHAT_CUT=Cut
@@ -1420,10 +1278,10 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=Name
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=Primary shortcut
plugin.keybindings.globalchooser.SHORTCUT_SECOND=Second shortcut
plugin.keybindings.globalchooser.PRESS_BTN=Press to set shortcut
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=Waiting
plugin.keybindings.globalchooser.PUSH_TO_TALK=Push to talk
plugin.keybindings.globalchooser.ENABLE_SPECIAL=Enable special key detection
plugin.keybindings.PLUGIN_NAME=Keybindings
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Chat
plugin.keybindings.MAIN=Main
plugin.keybindings.GLOBAL=Global shortcuts
@@ -1451,6 +1309,7 @@ plugin.notificationconfig.tableheader.SOUND=Play a sound through notification de
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=Play a sound through playback device
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=Play a sound through PC speaker device
plugin.notificationconfig.tableheader.DESCRIPTION=Description of event
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Incoming Call
plugin.notificationconfig.event.SecurityMessage=Security Message
plugin.notificationconfig.event.IncomingFile=Incoming File
@@ -1557,6 +1416,7 @@ impl.neomedia.configform.VIDEO=Video
impl.neomedia.configform.H264=H.264
impl.neomedia.configform.H264.defaultIntraRefresh=Periodic Intra Refresh
impl.neomedia.configform.H264.defaultProfile=Default profile to encode into:
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=Baseline
impl.neomedia.configform.H264.defaultProfile.high=High
impl.neomedia.configform.H264.defaultProfile.main=Main
@@ -1587,7 +1447,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=Current password:
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Enter new password:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Re-enter password:
plugin.securityconfig.masterpassword.MP_TITLE=Master Password
-plugin.securityconfig.masterpassword.MP_NOT_SET=(not set)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=You did not enter the correct current Master Password. Please try again.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=The Master Password is not correct!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Password Change Failed
@@ -1718,8 +1577,6 @@ Proxy support is currently experimental and only works with some protocols. \
Check out the table below for more details:
plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> \
<tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr>\
-<tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr>\
-<tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr>\
<tr><td>XMPP</td><td>+</td><td>+</td><td>+</td><td>+</td></tr>\
<tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr>\
</table></html>
@@ -1760,7 +1617,6 @@ plugin.provisioning.RESTART_WARNING=Note that your changes will only take effect
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=Copy UUID to clipboard
plugin.provisioning.CLIPBOARD_FAILED=Failed to copy UUID to clipboard
-plugin.provisioning.EXIT_ON_FAIL=Exit the application if the provisioning fails
plugin.provisioning.CREDENTIALS=Last stored provisioning credentials
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=Are you sure you want to remove provisioning password?
plugin.provisioning.PROV_FAILED=Provisioning failed
@@ -1842,8 +1698,6 @@ inform them about the issue. \
#plugin spellcheck
plugin.spellcheck.TITLE=Spelling and Grammar
plugin.spellcheck.MENU=Show Spelling and Grammar
-plugin.spellcheck.LANG=Language
-plugin.spellcheck.EDIT_PERSONAL_DICT=Edit
plugin.spellcheck.ENABLE_SPELL_CHECK=Enable spell check
plugin.spellcheck.dialog.FIND=Find Next
plugin.spellcheck.dialog.REPLACE=Replace
diff --git a/resources/languages/resources_ar.properties b/resources/languages/resources_ar.properties
index 9583582..deee731 100644
--- a/resources/languages/resources_ar.properties
+++ b/resources/languages/resources_ar.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,29 +43,24 @@ service.gui.ACCOUNT_ME=أنا (خاص بي)
service.gui.ACCOUNT_REGISTRATION_WIZARD=المساعدة ÙÙŠ تسجيل الحساب
service.gui.ACCOUNTS=حسابات
service.gui.ADD=&إضاÙØ©
-service.gui.ADD_ACCOUNT=إضاÙØ© حساب
service.gui.ADD_CONTACT=إضاÙØ© عضو (مستخدم)
-service.gui.ADD_AUTHORIZED_CONTACT=إض٠{0} إلى قائمة المستخدمين لديك
+service.gui.ADD_AUTHORIZED_CONTACT=أضÙÙ {0} إلى قائمة جهات الاتصال
+service.gui.ADD_CONTACT_TO_CONTACTLIST=أض٠الإسم هذه إلى قائمة جهات اتصالك
service.gui.ADD_CONTACT_TO=إضاÙØ© عضو إلى
service.gui.ADD_CONTACT_ERROR=خطأ عند إضاÙØ© المستخدم التالي : {0}
service.gui.ADD_CONTACT_ERROR_TITLE=حدث خطأ لدى إضاÙØ© مستخدم
service.gui.ADD_CONTACT_EXIST_ERROR=اسم المستخدم {0} موجود بالÙعل ÙÙŠ قائمة المستخدمين لديك.
service.gui.ADD_CONTACT_NETWORK_ERROR=الخادم لم يستجب لطلب إضاÙØ© الصديق ذات الرقم {0}
service.gui.ADD_CONTACT_NOT_SUPPORTED=Ùشل ÙÙŠ إضاÙØ© المستخدم:{0}. عملية غير مدعومة.
-service.gui.ADD_CONTACT_IDENTIFIER=أكتب ÙÙŠ الخانة التي ÙÙŠ الأسÙÙ„ اسم العضو (المستخدم) الذي تريد إضاÙته.
-service.gui.ADD_CONTACT_WIZARD=المساعد ÙÙŠ إضاÙØ© مشترك (عضو أو مستخدم).
service.gui.ADD_CONTACT_NOT_CONNECTED=يجب أن تكون متصل لكي تضي٠اسم مستخدم الى قائمة الأصدقاء, رجاءا سجل دخولك و جرب مرة اخرى.
service.gui.ADD_GROUP_LOCAL_ERROR=لم تتم إضاÙØ© المجموعة :{0}. السبب : مشكلة حدثت اثناء عملية إدخال-إخراج محلية.
service.gui.ADD_GROUP_EXIST_ERROR=المجموعة {0} موجودة بالÙعل ÙÙŠ قائمة المستخدمين لديك. من Ùضلك اختر إسما آخر.
service.gui.ADD_GROUP_NET_ERROR=لم تتم إضاÙØ© المجموعة بإسم {0}. السبب : حدوث مشكلة ÙÙŠ الشبكة. من Ùضلك تأكد من اتصال الشبكة لديك ثم حاول مرة اخرى.
service.gui.ADD_GROUP_ERROR=لم تتم إضاÙØ© المجموعة بإسم : {0}.
service.gui.ADD_GROUP_EMPTY_NAME=إسم المجموعة يحب أن لا يكون Ùارغا.
-service.gui.ADD_GROUP=إنشاء مجموعة
-service.gui.ADD_SUBCONTACT=&إضاÙØ© مستخدم Ùرعي.
service.gui.ADDRESS=عنوان
service.gui.ADMINISTRATOR=المسؤول
service.gui.ADVANCED=&متقدم
-service.gui.ALL=&الكل
service.gui.ALL_CONTACTS=&جميع المستخدمين.
service.gui.APPLY=&تطبيق
service.gui.ARE_CALLING={0} يتصل بك...
@@ -63,7 +69,6 @@ service.gui.AT=عند
service.gui.AUTHORIZE=&ترخيص
service.gui.AUTHORIZATION_ACCEPTED={0} واÙÙ‚ على طلب تÙويضك.
service.gui.AUTHENTICATION_FAILED=Ùشل التحقق Ù„{0} . كلمة السر التي ادخلتها غير صالحة.
-service.gui.AUTHENTICATION_REQUESTED=طلب التحقق
service.gui.AUTHENTICATION_REQUESTED_SERVER=الخادم {0} يطلب منك معلومات الدخول (التحقق).
service.gui.AUTHENTICATION_REJECTED={0} رÙض طلب تÙويضك .
service.gui.AUTHENTICATION_WINDOW_TITLE=التحقق أو التأكد من الهوية لـ {0}.
@@ -102,7 +107,6 @@ service.gui.CHANGE_NICKNAME_LABEL=ÙÙ‰ الحقل ÙÙ‰ الأسÙÙ„ØŒ يمكنك
service.gui.CHANGE_NICKNAME_ERROR=خطأ ÙÙŠ تغير الإسم المستعار
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=الاسم موجود مسبقاً
service.gui.CHANGE_VIDEO_QUALITY=تغيير جودة الÙيديو
-service.gui.CHAT_CONFERENCE_LABEL=مأتمرات
service.gui.CHAT_ROOM_ALREADY_JOINED=تم دخول الغرÙØ© {0} مسبقا.
service.gui.CHAT_ROOM_CONFIGURATION=إعدادات غرÙØ© الدردشة {0}
service.gui.CHAT_ROOM_CONFIGURATION_FAILED=Ùشل ÙÙ‰ الحصول على إعدادات غرÙØ© الدردشة {0}. Ùقط مالك صالون الدردشة قادر على تغير الإعدادات .
@@ -114,13 +118,11 @@ service.gui.CHAT_ROOM_USER_QUIT=خرج من {0}
service.gui.CHAT_ROOM_NAME=إسم غرÙÙ‡ الدردشة
service.gui.CLEAR_CUSTOM_MESSAGES=احذ٠الرسائل المخصصة
service.gui.ROOM_NAME=غرÙØ© الدردشة
-service.gui.AUTOJOIN=دخول تلقائي
service.gui.CHANGE_PASSWORD=تغيير كلمة المرور
service.gui.CHAT_ROOM_NAME_INFO=ÙÙ‰ الحقل الأسÙÙ„ إدخل أسم الغرÙØ© التى تريد إنشاءها.
service.gui.CHAT_ROOM_NOT_EXIST=الغرÙØ© {0} غير موجودة لدى الخادم {1}. الرجاء التحقق من الإسم المدخل.
service.gui.CHAT_ROOM_NOT_CONNECTED=يجب أن تكون مسجلا لكي تدخل غرÙØ© الدردشة{0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=يجب أن تكون مسجلا لكي تخرج من غرÙØ© الدردشة.
-service.gui.CHAT_ROOM_NOT_JOINED=يجب ان تكون داخل غرÙØ© الدردشة لكى تقوم ببعض الإجراءات.
service.gui.CHAT_ROOM_OPTIONS=خيارات غرÙØ© الدردشة
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=غرÙØ© الدردشة {0} تتطلب تسجيلا قبل دخولها.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=غرÙØ© الدردشة {0} تتطلب كلمة سر.
@@ -136,21 +138,17 @@ service.gui.CLEAR=مسح
service.gui.CLOSE=غلق&
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=لقد وصلتك رسالة جديدة منذ أقل من ثانيتين. هل تود أن تغلق هذا الحوار أو النقاش؟
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=لديك ملÙات تنقل حاليا Ùˆ غير مكتملة. هل أنت متأكد من رغبتك ÙÙŠ إلغائها؟
-service.gui.CONFIRM=أكÙّد
service.gui.CONNECTED_STATUS=متصل
service.gui.CONNECTING=الاتصال جار...
service.gui.CONNECTING_STATUS=جاري الإتصال
service.gui.CONNECTING_EARLY_MEDIA_STATUS=جاري الإتصال*
service.gui.CONNECTION=الإتصال
-service.gui.CONNECTION_FAILED_MSG=لم يتم الاتصال من الحساب : إسم المستخدم: {0} إسم الخادم : {1}. يرجى التأكد من الاتصال بالشبكة أو الاتصال بمسؤول الشبكة لديك لمزيد من المعلومات.
service.gui.CONNECTION_EXPIRED_MSG=أنت غير متصل عبر الخادم {0}.
service.gui.CONTACT_NAME=معرً٠أو رقم
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=المستخدم {0} الذي تم إختياره لا يمكنه الاتصال بالهاتÙ.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=المستخدم {0} الذي تم إختياره لا يمكنه استخدام الدردشة عديدة المستخدمين.
service.gui.CONTACT_PAUSED_TYPING=لقد توق٠{0} لحظة عن كتابة الرسالة.
service.gui.CONTACT_TYPING=المستخدم {0} يكتب رسالة الآن.
service.gui.CONTACT_INFO=&معلومات جهة الإتصال
-service.gui.CONTACTLIST=قائمة جهات الإتصال
service.gui.CONTACTS=المستخدمين (الأعضاء)
service.gui.COPY=&نسخ
service.gui.COPY_LINK=نسخ &ربط
@@ -160,15 +158,12 @@ service.gui.CREATE_CHAT_ROOM=&إنشاء غرÙØ© دردشة ...
service.gui.CREATE_CHAT_ROOM_ERROR=Ùشل إنشاء غرÙØ© الدردشة {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=مساعدة لإنشاء غرÙØ© دردشة
service.gui.CREATE_CONFERENCE_CALL=&إنشاء اتصال حوار متعدد (مكالمة)...
-service.gui.CREATE_CONFERENCE_CHAT=&إنشاء حوار متعدد (اتصال دردشة)...
service.gui.CREATE_GROUP=&إنشاء مجموعة...
service.gui.CREATE_GROUP_NAME=ÙÙ‰ الحقل ÙÙ‰ الأسÙÙ„ أدخل أسم المجموعة التى تريد إنشاءها.
-service.gui.CREATE_FIRST_GROUP_WIZARD=قائمة المستخدمين لديك ليس Ùيها أي مجموعة. لطÙا، بادر بإنشاء مجموعة (مل٠/إنشاء مجموعة).
service.gui.CREATE_VIDEO_BRIDGE=إنشاء &جسر Ùيديو...
service.gui.CREATE_VIDEO_BRIDGE_MENU=إنشاء &جسر Ùيديو
service.gui.CONTACT_INFO_NOT_SUPPORTED=هذا المستخدم لا يمكنه التعامل مع معلومات المستخدم ÙÙŠ الشبكة العنكبوتية
service.gui.CUT=&قص
-service.gui.DATE=تاريخ
service.gui.DELETE=حذÙ
service.gui.DENY=&رÙض
service.gui.DESKTOP_SHARING_WARNING=<b>هل أنت متأكد من أنك تريد بدء مشاركة الشاشة؟<br></b>عند المواÙقة سيتمكن البعض من رؤية ما تراه أمامك على الشاشة.
@@ -178,7 +173,6 @@ service.gui.DISCONNECTED_STATUS=Ù…Ùصول
service.gui.DND_STATUS=لا تزعجني
service.gui.DO_NOT_ASK_AGAIN=لا تسألني مرة ثانية
service.gui.DO_NOT_SHOW_AGAIN=لا تعرض هذه الرسالة مرة ثانية
-service.gui.DOWNLOAD_NOW=&تنزيل الآن
service.gui.DRAG_FOR_SHARING=اسحب هنا كل ما تريد مشاركته...
service.gui.DURATION=مدة
service.gui.EDIT=&تعديل
@@ -195,7 +189,6 @@ service.gui.ERROR_RECEIVED_FROM=خطأ مستقبل من
service.gui.ESTIMATED_TIME=الوقت المخمن :
service.gui.EVENTS=أحداث
service.gui.EXIT=خ&روج
-service.gui.EXTENDED_CRITERIA=معايير مطولة
service.gui.GENERAL=عام
service.gui.GENERAL_ERROR=خطأ عام
service.gui.GROUP_NAME=إسم المجموعة
@@ -253,12 +246,12 @@ service.gui.HISTORY=&السجل
service.gui.HISTORY_CONTACT=سجل - {0}
service.gui.HOME=الرئيسية
service.gui.HOME_PAGE=الصÙحة الرئيسية
-service.gui.HOUR=ساعة
service.gui.ICE=ICE
service.gui.IDENTIFIER=معرÙ
service.gui.IGNORE=&تجاهل
service.gui.INSERT_SMILEY=أدخل وجها تعبيريا
service.gui.INCOMING_CALL=مكالمة واردة من : {0}
+service.gui.INCOMING_SCREEN_SHARE=مكالمة واردة من : {0}
service.gui.INCOMING_CALL_STATUS=مكالمة واردة
service.gui.INSTANT_MESSAGINGS=IMs
service.gui.INITIATING_CALL_STATUS=التحضير للمكالمة
@@ -273,11 +266,8 @@ service.gui.INVITE_CONTACT_TO_CALL=أرسل دعوة إلى المستخدمين
service.gui.INVITE_REASON=سبب الدعوة
service.gui.IS_CALLING=يتصل ....
service.gui.IS_NOW={0} هو {1} الآن
-service.gui.JITSI_WARNING=لقد تم تسمية سيب كومينيكاتور بـ جيتسي مؤخرا.<br> لجعل نسختك حديثة دوما، بادر بتنزيل جيتسي الآن. <br> نأس٠لما قد يسببه ذلك لكم.<br> مع تحيات Ùريق تطوير جيتسي
-service.gui.JITSI_WARNING_TITLE=سيب كومينيكاتور أصبح يعر٠بـ جيتسي
service.gui.JOIN=&إنضم أو شارك
service.gui.JOIN_AS=إ&نضم كـ
-service.gui.CLOSE_CHAT_ROOM_DIALOG=غ&لق
service.gui.JOB_TITLE=عنوان الوظيÙØ©
service.gui.JOIN_CHAT_ROOM=&أدخل غرÙØ© الدردشة...
service.gui.JOIN_CHAT_ROOM_TITLE=أدخل غرÙØ© الدردشة
@@ -288,7 +278,6 @@ service.gui.KICK_FAILED=Ùشل الصد
service.gui.KICK_FAILED_GENERAL_ERROR=Ùشل صد {0}. حدث خطأ عام ÙÙ‰ الخادم.
service.gui.KICK_FAILED_NOT_ALLOWED=Ùشل صد{0}. مالك ومدير الغرÙØ© لا يمكن صد (إخراجه)
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Ùشل صد{0}. ليس لديك صلاحيات كاÙيه Ù„Ùعل ذلك.
-service.gui.LAST=آخر
service.gui.LAST_NAME=اسم العائلة
service.gui.LEAVE=&أترك
service.gui.LIMIT_REACHED_FOR_IP=لديك العديد من التسجيلات من عنوان انترنت واحد و الخادم {0} لا يسمح لك بعمل المزيد منها.
@@ -308,7 +297,6 @@ service.gui.MESSAGE=رسالة
service.gui.MISSED_CALLS_TOOL_TIP=مكالمات لم يتم الرد عليها واردة من:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= Ùˆ بالاضاÙØ© إلى {0}
service.gui.MODERATOR=منسق
-service.gui.MORE=رؤية المزيد
service.gui.MORE_LABEL=أنقل
service.gui.MOVE=أنقل
service.gui.MOVE_SUBCONTACT=أن&قل مستخدم
@@ -317,7 +305,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=المستخدم الذي اخترت هو Ù†Ù
service.gui.MOVE_SUBCONTACT_QUESTION=متأكد من نقل {0} إلى {1}؟
service.gui.MOVE_TO_GROUP=&أنقل إلى مجموعة
service.gui.MOVE_CONTACT=نقل مستخدم
-service.gui.MOVE_CONTACT_ERROR=&لا يمكن نقل المستخدم
service.gui.MSG_DELIVERY_FAILURE=الرسالة ÙÙŠ أعلاه لم يتمكن من إرسالها
service.gui.MSG_DELIVERY_NOT_SUPPORTED=نظام الاتصال (بروتوكول) المستخدم لا يتعامل مع الرسائل المبيتة. حاول أن تستخدم {0} نظاما آخر أو أن تنتظر حتى يكون المستخدم متصلا,
service.gui.MSG_DELIVERY_INTERNAL_ERROR=حصل خلل داخلي. أغلب الظن بسبب خلل. يرجى الإعلام عنه هنا: http://www.jitsi.org/index.php/Development/BugsAndIssues
@@ -328,7 +315,6 @@ service.gui.MSG_NOT_POSSIBLE=الرسائل غير ممكنة مع هذا الم
service.gui.MSG_RECEIVED={0} كتب
service.gui.MSG_SEND_CONNECTION_PROBLEM=عليك أن تكون مسجلا حتى تبعث رسائلا.
service.gui.MULTIPLE_LOGINS=لقد سجلت دخولك أكثر من مرة بهذا الحساب. الحساب التالي غير موصول حاليا: اسم المستخدم: {0}، اسم الخادم: {1}.
-service.gui.MUTE=بدون صوت
service.gui.MUTUALLY_ON_HOLD_STATUS=ÙÙŠ وضع الانتظار من الجهتين.
service.gui.NAME=اسم
service.gui.NETWORK=شبكة
@@ -339,6 +325,7 @@ service.gui.NEW_MESSAGE=رسالة جديدة
service.gui.NEW_NAME=اسم جديد
service.gui.NEW_STATUS_MESSAGE=رسالة جديدة للدلالة على الحالة
service.gui.NEW_STATUS_MESSAGE_SAVE=أحÙظ كرسالة مخصصة
+service.gui.NICKNAME=لقب
service.gui.NO=لا
service.gui.NONE=لا أحد
service.gui.NO_CAMERA_AVAILABLE=لا توجد كاميرا
@@ -355,7 +342,6 @@ service.gui.NON_EXISTING_USER_ID=الخادم {0} لا يعر٠هوية المØ
service.gui.SD_QUALITY=جودة قياسية
service.gui.OFFLINE=غير متصل
service.gui.OK=&مواÙÙ‚
-service.gui.OLDER_CALLS=المكالمات السابقة
service.gui.ONLINE=متصل (مسجل)
service.gui.OPEN=Ùتح
service.gui.OPEN_FILE_FROM_IMAGE=اضغط مرتين Ù„Ùتح الملÙ.
@@ -363,9 +349,12 @@ service.gui.OPEN_FOLDER=Ùتح المجلد
service.gui.OPEN_IN_BROWSER=Ùتح ÙÙŠ &مستعرض
service.gui.OPTIONS=خيارات
service.gui.OR=أو
-service.gui.OR_ENTER_PHONE_NUMBER=أو أدخل رقم الهات٠هنا...
service.gui.ORGANIZATION=منظمة
service.gui.OTHER=أخرى
+service.gui.chat.role.ADMINISTRATOR=المسؤول
+service.gui.chat.role.MODERATOR=منسق
+service.gui.chat.role.MEMBER=عضو أو مشترك
+service.gui.chat.role.SILENT_MEMBER=عضو صامت
service.gui.OWNER=مالك الغرÙØ©
service.gui.PASSWORD=كلمة السر
service.gui.PASSWORD_CHANGE_FAILURE=Ùشل تغيير كلمة المرور
@@ -380,7 +369,6 @@ service.gui.PRESENCE=حضور
service.gui.PRESS_ENTER_FOR_SUGGESTIONS="إدخال" للمقترحات
service.gui.PRESS_FOR_CALL_INFO=إضغط للحصول على معلومات المكالمة
service.gui.PREVIOUS=سابق
-service.gui.PREVIOUS_TOOLTIP=استعراض الحوارات السابقة
service.gui.PRINT=&طباعة
service.gui.PROACTIVE_NOTIFICATION=يكتب رسالة
service.gui.PROTOCOL=نظام (بروتوكول)
@@ -393,7 +381,6 @@ service.gui.RECONNECTION_LIMIT_EXCEEDED=لقد قمت بقطع الاتصال و
service.gui.RE_REQUEST_AUTHORIZATION=(أعد) طلب التصريح
service.gui.REFERRED_STATUS=مشار إليه
service.gui.REJECT=&رÙض
-service.gui.REMIND_ME_LATER=ذكرًني لاحقا
service.gui.REMEMBER_PASSWORD=Ø­Ùظ كلمة السر
service.gui.REMOVE=&حذÙ
service.gui.REMOVE_ACCOUNT=&حذ٠حساب
@@ -417,27 +404,18 @@ service.gui.REVOKE_ADMIN=إخلاء المسؤولية
service.gui.REVOKE_MODERATOR=التخلي عن واجب التنسيق
service.gui.REVOKE_MEMBERSHIP=التخلي عن العضوية
service.gui.REVOKE_VOICE=التخلي عن الكلام
-service.gui.ROOT_GROUP=مجموعة رئيسة
service.gui.SAVE=&احÙظ
-service.gui.SAVE_AS_DEFAULT=احÙظ كاÙتراضي
service.gui.SEARCH=&ابحث
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=اضغط على الزر ÙÙŠ الأسÙÙ„ لإظهار جميع غر٠الحوار على الخادم الذي اخترت. ثم اختر ما تريد منها للدخول إليها Ùˆ اضغط على دخول أو انضمام.
service.gui.SEARCH_STRING_CONTACT_SOURCE=بحث جهة إتصال
service.gui.SECURITY=حماية
-service.gui.SELECT_ACCOUNT=اختر حسابا
service.gui.SELECT_COLOR=اختر لونا
service.gui.SELECT_GROUP=اختر مجموعة
-service.gui.SELECT_GROUP_WIZARD_MSG=القائمة ÙÙŠ الأسÙÙ„ تحتوي على جميع أسماء مجموعات المستخدمين لديك. اختر ما شئت منها لتحديد مكان إضاÙØ© المستخدم الجديد.
service.gui.SELECT_NO_GROUP=و لا مجموعة
-service.gui.SELECT_GROUP_WIZARD=حدد المجموعة
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=القائمة ÙÙŠ الأسÙÙ„ تحتوي على جميع أسماء المستخدمين الذين لديهم خدمة الحوار المتعدد. اختر ما شئت منها لإنشاء غرÙØ© حوار لك.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=القائمة ÙÙŠ الأسÙÙ„ تحتوي على جميع الحسابات المسجلة. اختر ما شئت منها للإتصال بالمستخدم الجديد.
-service.gui.SELECT_PROVIDERS_WIZARD=اختر حسابا
service.gui.SEND=&أرسل
service.gui.SEND_FILE=أرسل ملÙا
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=لا توجد معلومات عن هذا المستخدم.
service.gui.SEND_MESSAGE=&أرسل رسالة
-service.gui.SEND_AS_SMS=أرسل رسالة قصيرة (خدمة SMS)
service.gui.SEND_SMS=أ&رسل رسالة قصيرة (خدمة SMS)
service.gui.SEND_SMS_DETAILS=تذكًر أن عليك إدخال الرقم كاملا. مثال ، بـدءا بـ 44+ لبريطانيا، كما يلي : 447777000000+.
service.gui.SEND_SMS_NOT_SUPPORTED=البروتوكول الذي اخترت لا يتعامل مع خدمة الرسائل القصيرة.
@@ -472,7 +450,6 @@ service.gui.STREET=الشارع
service.gui.SUBJECT=موضوع
service.gui.SUMMARY=خلاصة
service.gui.TELEPHONY=هاتÙ
-service.gui.TODAY=اليوم
service.gui.TOOLS=&أداوات
service.gui.TRANSFER=&تحويل
service.gui.TO=&إلى:
@@ -482,7 +459,6 @@ service.gui.TRANSFER_CALL_TO=تحويل إلى :
service.gui.TRANSPARENCY_NOT_ENABLED=الشÙاÙية غير متاحة حسب الاعدادات الحالية لديك.
service.gui.TYPE_YOUR_REQUEST=أدخل طلبك هنا
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=لم نستطع تغييرجودة Ùيديوهذه المكالمة.
-service.gui.UNMUTE=تÙعيل الصوت
service.gui.USER_IDENTIFIER=معر٠المستخدم :
service.gui.USER_EXISTS_ERROR=هذا المستخدم موجود أصلا على الشبكة التي اخترت. لطÙا، اختر شبكة أخرى.
service.gui.USERNAME_NULL=إملأ اسم المستخدم و كلمة السر.
@@ -494,7 +470,6 @@ service.gui.USE_PROVISIONING=استخدم التزود (بخدمة أو بعنو
service.gui.VALUE=قيمة:
service.gui.VIDEO_CALL=&مكالمة بالصوت Ùˆ الصورة (Ùيديو)
service.gui.VIA=عبر
-service.gui.VIA_SMS=باستخدام خدمة الرسائل القصيرة
service.gui.VIEW=&عرض
service.gui.VIEW_HISTORY=عرض &السجل
service.gui.VIEW_SMILEYS=أظهر الرسوم &التعبيرية
@@ -512,9 +487,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=عدّل مستوى الصوت
service.gui.WAITING_AUTHORIZATION=جاري انتظار تصريح
service.gui.WARNING=تحذير
service.gui.YES=نعم
-service.gui.YESTERDAY=يوم أمس
-service.gui.EXISTING_ACCOUNT_ERROR=الحساب الذي أدخلت موجود أصلا.
-service.gui.NEW_MAIL=<b>لديك بريد جديد واحد ! </b><br/><b>من:</b> {0} {1} <br/><b>الموضوع</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=لديك رسالة جديدة ÙÙŠ {0} <a href="{1}">صندوق البريد</a>:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=عدد الرسائل الجديدة هو {2} ÙÙŠ <a href="{1}">صندوق البريد</a>:{0} <br/>
service.gui.NEW_GMAIL_FOOTER=لديك حوارا واحدا لم يقرأ بعد ÙÙŠ <a href="{0}">صندوقك</a>.<br/>
@@ -536,7 +508,6 @@ service.gui.SECURITY_WARNING=تحذير حماية
service.gui.SECURITY_ERROR=خلل حماية
service.gui.SPEED=السرعة:
service.gui.SILENT_MEMBER=عضو صامت
-service.gui.UPDATE=تجديد أو تحديث
service.gui.MOBILE_PHONE=محمول
service.gui.VIDEO_PHONE=Ùيديو
service.gui.WORK_PHONE=العمل
@@ -563,7 +534,6 @@ service.gui.callinfo.TECHNICAL_CALL_INFO=معلومة تقنية عن الإتص
service.gui.callinfo.CALL_INFORMATION=معلومات الطلب
service.gui.callinfo.CALL_IDENTITY=هوية
service.gui.callinfo.PEER_COUNT=عدد المشاركين
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=تÙعيل التشÙير
service.gui.callinfo.CALL_DURATION=مدة المكالمة
service.gui.callinfo.VIEW_CERTIFICATE=أظهر الشهادة
service.gui.callinfo.CODEC=برنامج ترميز / تردد
@@ -578,8 +548,11 @@ service.gui.callinfo.JITTER=Jitter
service.gui.callinfo.MEDIA_STREAM_RTP=RTP
service.gui.callinfo.MEDIA_STREAM_SRTP=RTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=بروتوكول Ù…Ùتاح التبادل
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.COMPLETED=إكتمل
service.gui.callinfo.ICE_STATE.FAILED=Ùشل
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=مضي٠محلي / مدخل
service.gui.callinfo.ICE_REMOTE_HOST_ADDRESS=IP عن بعد / مدخل
service.gui.callinfo.HARVESTING_MS_FOR=ms (Ù„
@@ -588,9 +561,10 @@ service.gui.ALWAYS_TRUST=الوثوق دوما بهذه الشهادة
service.gui.CERT_DIALOG_TITLE=تحقق من الشهادة
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0}لا يمكن التحقق من هوية الخادم عند الاتصال <br>بـ {1}:{2}.<br><br> الشهادة غير موثوق بها، يعني أن هوية الخادم لا يمكن <br> التحقق منها تلقائيا. هل تريد الاستمرار بالاتصال؟<br><br> للمزيد من المعلومات اضغط على "إظهار الشهادة".</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0}لا يمكن التحقق من هوية الخادم عند الاتصال <br>بـ {1}:{2}.<br><br> الشهادة غير موثوق بها، يعني أن هوية الخادم لا يمكن <br> التحقق منها تلقائيا. هل تريد الاستمرار بالاتصال؟<br><br> للمزيد من المعلومات اضغط على "إظهار الشهادة".</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} لا يمكن التحقق من هوية المستخدم.<br><br> الشهادة غير موثوق بها، يعني أن هوية المستخدم لا يمكن <br> التحقق منها تلقائيا. هل تريد الاستمرار بالاتصال؟<br><br> للمزيد من المعلومات اضغط على "إظهار الشهادة".</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} لا يمكن التحقق من هوية المستخدم.<br><br> الشهادة غير موثوق بها، يعني أن هوية المستخدم لا يمكن <br> التحقق منها تلقائيا. هل تريد الاستمرار بالاتصال؟<br><br> للمزيد من المعلومات اضغط على "إظهار الشهادة".</html>
service.gui.CONTINUE_ANYWAY=واصل على أي حال
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=اسم الشهرة:
service.gui.CERT_INFO_O=منظمة :
service.gui.CERT_INFO_C=اسم البلد:
@@ -599,17 +573,16 @@ service.gui.CERT_INFO_L=المكان أو المنطقة:
service.gui.CERT_INFO_OU=الوحدة التنظيمية:
service.gui.CERT_INFO_ISSUED_ON=أصدرت بتاريخ:
service.gui.CERT_INFO_EXPIRES_ON=تاريخ انتهاء الصلاحية:
+service.gui.CERT_INFO_FINGERPRINTS=بصمة
service.gui.CERT_INFO_SER_NUM=الرقم التسلسلي:
service.gui.CERT_INFO_VER=نسخة:
service.gui.CERT_INFO_SIGN_ALG=نوع نمط التوقيع:
service.gui.CERT_INFO_ALG=النمط المستخدم:
service.gui.CERT_INFO_PUB_KEY=المÙتاح العام:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} بايت: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} بت
service.gui.CERT_INFO_EXP=الأس:
service.gui.CERT_INFO_KEY_SIZE=طول المÙتاح
service.gui.CERT_INFO_SIGN=التوقيع:
-service.gui.CONTINUE=تابع
service.gui.SHOW_CERT=أظهر الشهادة
service.gui.HIDE_CERT=إخÙاء الشهادة
@@ -630,10 +603,8 @@ service.gui.security.SECURE_AUDIO=صوت أمن
service.gui.security.AUDIO_NOT_SECURED=صوت غير أمن
service.gui.security.SECURE_VIDEO=Ùيديو أمن
service.gui.security.VIDEO_NOT_SECURED=Ùيديو غير أمن
-service.gui.security.NO_VIDEO=لا يوجد Ùيديو
-service.gui.security.CIPHER=تشÙير: {0}
+service.gui.security.CALL_SECURED_TOOLTIP=مكالمة أمنة. لمعلومات أكثر إضغط هنا.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=مكالمة غير أمنة.
-service.gui.security.COMPARE_WITH_PARTNER=قارن مع رÙيق (أو شريك) Ùˆ اضغط على القÙÙ„ للتÙعيل.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=قارن مع الرÙيق أو الشريك : {0}
service.gui.security.STRING_COMPARED=سلسلة حرÙية مقارنة!
@@ -650,19 +621,13 @@ service.gui.avatar.imagepicker.CLICK=اضغط و ابتسم
service.gui.avatar.imagepicker.IMAGE_FILES=ملÙات الصور
service.gui.avatar.imagepicker.IMAGE_PICKER=صورة
service.gui.avatar.imagepicker.IMAGE_SIZE=حجم الصورة
-service.gui.avatar.imagepicker.INITIALIZING=تجهيز
service.gui.avatar.imagepicker.RESET=إعادة لوضع البدء
service.gui.avatar.imagepicker.SET=جهÙّز
service.gui.avatar.imagepicker.TAKE_PHOTO=تصور
-service.gui.avatar.imagepicker.WEBCAM_ERROR=خطأ ÙÙŠ الكاميرا
service.gui.security.encryption.required=تشÙير ملزم!
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
impl.protocol.sip.XCAP_ERROR_TITLE=خطأ ÙÙŠ تخزين قائمة الإتصال SIP
impl.protocol.sip.XCAP_ERROR_UNAUTHORIZED=اسم المستخدم أو كلمة السر خاطئة بإستخدام xcap. ل {0}.
@@ -684,9 +649,7 @@ impl.gui.main.account.DUMMY_PROTOCOL_DESCRIPTION=اختر شبكة
# LDAP
impl.ldap.CONFIG_FORM_TITLE=إعداد LDAP
impl.ldap.GENERAL=عام
-impl.ldap.NEW=جديد
impl.ldap.EDIT=تعديل
-impl.ldap.REMOVE=احذÙ
impl.ldap.ENABLED=تم تÙعيله
impl.ldap.SERVER_NAME=اسم الخادم
impl.ldap.SERVER_NAME_EXAMPLE=خادمي LDAP
@@ -719,6 +682,10 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=هات٠البيت
impl.ldap.PHONE_PREFIX=بادئة هاتÙ
impl.ldap.PHONE_PREFIX_EXAMPLE=مثال: 00
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=كتاب العناوين
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=تÙعيل البحث ÙÙŠ كتاب العناوين لنظام ماكنتوش أوو أس إكس
@@ -729,9 +696,7 @@ plugin.addrbook.PREFIX_EXAMPLE=مثال: 00
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=مستخدمي غوغل
-impl.googlecontacts.NEW=جديد
impl.googlecontacts.EDIT=حرر
-impl.googlecontacts.REMOVE=حذÙ
impl.googlecontacts.ENABLED=تم تÙعيله
impl.googlecontacts.ACCOUNT_NAME=اسم الحساب
impl.googlecontacts.SAVE=احÙظ
@@ -760,9 +725,6 @@ plugin.accountinfo.EMAIL=بريد ألكتروني:
plugin.accountinfo.PHONE=هاتÙ:
plugin.accountinfo.MOBILE_PHONE=هات٠جوال
plugin.accountinfo.JOB_TITLE=عنوان الوظيÙØ©
-plugin.accountinfo.USER_PICTURES=صور المستخدم
-plugin.accountinfo.CHANGE=غيÙّر
-plugin.accountinfo.ONLY_MESSAGE=رسائل Ùقط
# connection info
@@ -781,49 +743,12 @@ plugin.aimaccregwizz.USERNAME=اسم مستخدم AIM:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=اسم المستخدم و كلمة السر
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=التسجيل بحساب جديد
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=إذا لم يكن لديك حساب من AIM ، اضغط على هذا الزر لإنشاء حساب جديد.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=تخطي خيارات الخادم الاÙتراضية
# branding
plugin.branding.ABOUT_WINDOW_TITLE=عن {0}
plugin.branding.LOGO_MESSAGE=نقل الصوت عبر الانترنت و الرسائل المباشرة، تقنية مجانية
-plugin.branding.LOADING=تحميل
plugin.branding.ABOUT_MENU_ENTRY=&عن البرنامج
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}> {1} حاليا تحت التطوير المستمر‫.‬ النسخة التي لديك نسخة تجريبية و قد لا تعمل كما تتوقع‫.‬ لمزيد من المعلومات بإمكانك زيارة {2} .</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 حقوق النشر <b>jitsi.org</b>. الحقوق محÙوظة. بالإمكان زيارة <a href="http://jitsi.org">http://jitsi.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}> <b>جيتسي</b> يوزع حسب اتÙاقية LGPL ""(<a href=\\"http://www.gnu.org\\">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=القواميس
-plugin.dictaccregwizz.ANY_DICTIONARY=أي قاموس
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=أي قاموس من {0}
-plugin.dictaccregwizz.FIRST_MATCH=أول تطابق
-plugin.dictaccregwizz.NO_MATCH=لا تطابق
-plugin.dictaccregwizz.MATCH_RESULT=لا توجد تعريÙات لـ "{0}"ØŒ ربما أنك تقصد:\n
-plugin.dictaccregwizz.INVALID_DATABASE=القاموس الحالي "{0}" لم يعد موجودا لدى الخادم.
-plugin.dictaccregwizz.INVALID_STRATEGY=Ùنون التخطيط الحالية غير موجودة لدى الخادم.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=بروتوكول خدمة Dict
-plugin.dictaccregwizz.HOST=المضيÙ
-plugin.dictaccregwizz.SERVER_INFO=معلومات الخادم
-plugin.dictaccregwizz.STRATEGY_SELECTION=اختيار ÙÙ† التخطيط
-plugin.dictaccregwizz.STRATEGY_LIST=قائمة بÙنون التخطيط:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Ùنون تخطيط البحث
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=أساليب البحث تبحث عن التشابه ÙÙŠ الكلمات، إذا لم يوجد تطابق، بÙضل عدة حلول. مثلا أساليب البحث حسب البداية تبحث عن الكلمات التي تبدأ بالمقطع الذي تحدده.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=معلومات حساب Dict
-plugin.dictaccregwizz.FIRST_ACCOUNT=هذا المساعد سينشئ لك حساب Dict من dict.org.\n\nيمكنك أن تضي٠قاموسا جديدا باستخدام "المساعد ÙÙŠ تسجيل حساب جديد". املأ حقل اسم المضي٠باسم القاموس الذي تود اضاÙته.
-plugin.dictaccregwizz.THREAD_CONNECT=محاولة الاتصال بالخادم
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=Ùشل الاتصال، هذا ليس خادم Dict أو أن الخادم غير متصل.
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=عرض Ùنون التخطيط
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=لا توجد Ùنون للتخطيط على الخادم
-plugin.dictaccregwizz.POPULATE_LIST=ملء القائمة
-plugin.dictaccregwizz.CLOSING_CONNECTION=إنهاء الإتصال
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">لاستخدام الدردشة على الÙيس بوك يجب إنشاء "اسم مستخدم<br>من صÙحة إعدادات الحساب على الÙيس بوك.</a><br><br>Nملاحظة: عندما تنشئ اسم مستخدم عليك أن تسجل خروجك من الصÙحة<br>ØŒ قد يتطلب وقتا قبل أن تسجل دخولك باستخدام اسم المستخدم الجديد! </center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=بروتوكول الدردشة Ù„Ùيس بوك
-plugin.facebookaccregwizz.PROTOCOL_NAME=Ùيس بوك
-plugin.facebookaccregwizz.USERNAME=اسم المستخدم:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=اسم المستخدم و كلمة السر
+
# generalconfig
plugin.generalconfig.AUTO_START=إعادة تشغيل {0} تلقائيا عند بدء تشغيل أو إعادة تشغيل الحاسوب
@@ -833,9 +758,6 @@ plugin.generalconfig.SHOW_HISTORY=أظهر
plugin.generalconfig.HISTORY_SIZE=الرسائل الحديثة ÙÙŠ الحوارات الجديدة
plugin.generalconfig.SEND_MESSAGES_WITH=ابعث الرسائل مع:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=لجعل ناÙذة الحوار Ùوق الأخريات
-plugin.generalconfig.ERROR_PERMISSION=ليس لديك صلاحيات كاÙية لإلغاء إعادة التشغيل تلقائيا
-plugin.generalconfig.TRANSPARENCY=Ø´ÙاÙية أو صراحة
-plugin.generalconfig.ENABLE_TRANSPARENCY=تÙعيل الشÙاÙية
plugin.generalconfig.DEFAULT_LANGUAGE=لغة الواجهة البينية
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=التغييرات سو٠تÙعَّل لدى اعادة التشغيل التالي.
plugin.generalconfig.SIP_CLIENT_PORT=ميناء عميل سيب SIP
@@ -873,19 +795,20 @@ plugin.icqaccregwizz.REGISTER_NEW_ACCOUNT=تسجيل حساب جديد
plugin.ircaccregwizz.PROTOCOL_NAME=IRC
plugin.ircaccregwizz.PROTOCOL_DESCRIPTION=بروتوكول IRC.
plugin.ircaccregwizz.USERNAME_AND_PASSWORD=رمز المستخدم و كلمة السر
+plugin.ircaccregwizz.USERNAME=لقب
plugin.ircaccregwizz.INFO_PASSWORD=أغلب خوادم IRC لا تتطلب كلمة سر.
plugin.ircaccregwizz.AUTO_NICK_CHANGE=غيÙّر تلقائيا اللقب إذا كان مستعملا أصلا
plugin.ircaccregwizz.USE_DEFAULT_PORT=استعمل الميناء الاÙتراضي
plugin.ircaccregwizz.PASSWORD_NOT_REQUIRED=لقبي لا يحتاج إلى تعريÙ
plugin.ircaccregwizz.HOST=اسم المضيÙ:
plugin.ircaccregwizz.IRC_SERVER=خادم
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE=التحقق أو التأكد من الهوية لـ {0}.
+plugin.ircaccregwizz.SASL_USERNAME=اسم المستخدم:
# jabber accregwizz
-plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=بروتوكول XMPP
plugin.jabberaccregwizz.USERNAME=XMPP إسم المستخدم
plugin.jabberaccregwizz.PASSWORD_CONFIRM=أكد كلمة السر
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=اسم المستخدم و كلمة السر
plugin.jabberaccregwizz.CSERVER=خادم
plugin.jabberaccregwizz.SERVER=الاتصال بالخادم
plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=تÙعيل "إبقاء الاتصال"
@@ -901,13 +824,9 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=تعقيب أو ملاحظة
plugin.jabberaccregwizz.RESOURCE=وسيلة أو مورد
plugin.jabberaccregwizz.AUTORESOURCE=أنتج تلقائيا وسيلة
plugin.jabberaccregwizz.PRIORITY=أولوية
-plugin.jabberaccregwizz.XMPP_ERROR=خطأ XMPP
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=خطأ XMPP غير معروÙ. تأكد من اسم الخادم.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=كلمة السر غير مطابقة
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=تخطي خيارات الخادم الاÙتراضية
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=خيارات متقدمة
plugin.jabberaccregwizz.USE_ICE=استعمل ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=إستعمل Google's Jingle/ICE (تجريبي)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=استكش٠تلقائيا خادم STUN/TURN
plugin.jabberaccregwizz.SUPPORT_TURN=دعم لـ TURN
plugin.jabberaccregwizz.TURN_USERNAME=اسم المستخدم لـ TURN
@@ -933,9 +852,6 @@ plugin.jabberaccregwizz.TELEPHONY_DOMAIN=نطاق الهاتÙ
plugin.jabberaccregwizz.ALLOW_NON_SECURE=إسمح لإتصالات غير أمنة
plugin.jabberaccregwizz.SERVER_OPTIONS=خيارات الخادم
plugin.jabberaccregwizz.CHANGE_PASSWORD=تغيير حساب كلمة المرور
-plugin.jabberaccregwizz.NEW_PASSWORD=كلمة مرور جديدة
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=أكد كلمة السر
-plugin.jabberaccregwizz.PASSWORD_EMPTY=كلمة المرور Ùارغة
plugin.jabberaccregwizz.PASSWORD_CHANGED=لقد تمّ تغيير كلمة المرور بنجاح
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=خادمك XMPP لا يدعم تغيير كلمة المرور.
plugin.jabberaccregwizz.ENTER_NEW_PASSWORD=الرجاء إدخال كلمة المرور ÙÙŠ كلا الحقلين
@@ -944,25 +860,9 @@ plugin.jabberaccregwizz.AUDIO=سمعي
plugin.jabberaccregwizz.VIDEO=Ùيديو (عرض بالصور)
plugin.jabberaccregwizz.RESET=إعادة لوضع البدء
-# mailbox
-plugin.mailbox.OUTGOING=رسالة صادرة:
-plugin.mailbox.INCOMING=رسائل واردة:
-plugin.mailbox.WAIT_TIME=المدة حتى ترسل المكالمة إلى البريد الصوتي
-plugin.mailbox.MAX_MESSAGE_TIME=أقصى Ùترة للرسالة الواردة
-plugin.mailbox.CONFIRM=أكÙّد
-plugin.mailbox.DEFAULTS=اÙتراضيات
-plugin.mailbox.MAILBOX=صندوق البريد
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=بروتوكول للوصول إلى الدردشة ÙÙŠ خدمة MSN
-plugin.msnaccregwizz.USERNAME=بريد الكتروني:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=اسم المستخدم و كلمة السر
-
# plugin manager
plugin.pluginmanager.INSTALL=تثبيت
plugin.pluginmanager.UNINSTALL=إزالة
-plugin.pluginmanager.UPDATE=تجديد أو تحديث
plugin.pluginmanager.PLUGINS=إضاÙات مدمجة
plugin.pluginmanager.URL=عنوان وحيد لكائن مصدري
plugin.pluginmanager.CHOOSE_FILE=اختر ملÙا
@@ -987,7 +887,6 @@ plugin.sipaccregwizz.SERVER_PORT=ميناء الخادم
plugin.sipaccregwizz.PROXY=بروكسي (خادم يقوم مقام عميل أو خادم)
plugin.sipaccregwizz.PROXY_PORT=ميناء البروكسي
plugin.sipaccregwizz.PREFERRED_TRANSPORT=وسيلة النقل المÙضلة
-plugin.sipaccregwizz.ADVANCED_OPTIONS=خيارات متقدمة
plugin.sipaccregwizz.PROXY_OPTIONS=خيارات البروكسي
plugin.sipaccregwizz.PROXY_AUTO=إعداد البروكسي تلقائيا
plugin.sipaccregwizz.ENABLE_PRESENCE=تÙعيل الحضور (بسيط)
@@ -1003,8 +902,6 @@ plugin.sipaccregwizz.DTMF=DTMF
plugin.sipaccregwizz.DTMF_METHOD=طريقة DTMF
plugin.sipaccregwizz.DTMF_RTP=(RTP ( RFC2833 / RFC 4733
plugin.sipaccregwizz.DTMF_SIP_INFO=معلومات SIP
-plugin.sipaccregwizz.REGISTER=سجَّل
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=تجاهل خيارات الخادم الاÙتراضية
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=تÙعيل تشÙير المكالمات
plugin.sipaccregwizz.AUTH_NAME=اسم السماح بالدخول
plugin.sipaccregwizz.DISPLAY_NAME=الإسم المعروض
@@ -1021,6 +918,7 @@ plugin.sipaccregwizz.VOICEMAIL=بريد صوتي
plugin.sipaccregwizz.MWI=جاري إنتطار رسالة (MWI)
plugin.sipaccregwizz.NOT_SAME_PASSWORD=كلمة السر غير مطابقة
plugin.sipaccregwizz.SAVP_OPTION=إشارة RTP/SAVP
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_1=إجباري (عرض Ùˆ اقبل Ùقط RTP/SAVP)
plugin.sipaccregwizz.SAVP_OPTION_2=أختياري (عرض أولا RTP/SAVP, و بعدها RTP/AVP)
plugin.sipaccregwizz.SHOW_ADVANCED=إعدادات متقدمة للتشÙير
@@ -1033,15 +931,6 @@ plugin.skinmanager.DEFAULT_SKIN=المظهَر الاÙتراضي
plugin.skinmanager.ADD_NEW_SKIN=أض٠مظهَراً جديداً...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=المظهَر الاÙتراضي للتطبيق
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=بروتوكول آمن للاتصال بالحواسيب البعيدة باستخدام SSH
-plugin.sshaccregwizz.USERNAME=معرÙّ٠الحساب:
-plugin.sshaccregwizz.IDENTITY_FILE=مل٠الهوية:
-plugin.sshaccregwizz.KNOWN_HOSTS=الحواسيب أو المضيÙات المعروÙØ©:
-plugin.sshaccregwizz.OPTIONAL=اختياري
-plugin.sshaccregwizz.ACCOUNT_DETAILS=تÙاصيل الحساب
-
# status update
plugin.autoaway.AUTO_STATUS=غائب تلقائياً
plugin.autoaway.ENABLE_CHANGE_STATUS=غيÙّر الحالة أثناء غيابك
@@ -1087,22 +976,6 @@ plugin.whiteboard.DESELECT=إلغاء الاختيار
plugin.whiteboard.DELETE=حذÙ
plugin.whiteboard.PROPERTIES=خصائص
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=بروتوكول للاتصال و الدردشة مع خدمة ياهوو.
-plugin.yahooaccregwizz.USERNAME=اسم المستخدم:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=اسم المستخدم و كلمة السر
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=خدمة الـ"من دون تعريÙ"
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=نظام الـ"بدون تعريÙ" أو بونجور.
-plugin.zeroaccregwizz.FIRST_NAME=الاسم الأول:
-plugin.zeroaccregwizz.LAST_NAME=اسم العائلة:
-plugin.zeroaccregwizz.EMAIL=بريد ألكتروني:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=تذكر مستخدمي بونجور ؟
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=المعرÙÙ‘Ù Ùˆ كلمة السر
-plugin.zeroaccregwizz.USERID=معرÙّ٠المستخدم :
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=بروتوكول نقاش غوغل
@@ -1116,19 +989,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.orgØŒ بوابة الاتصاÙ
plugin.iptelaccregwizz.USERNAME=اسم المستخدم:
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=اشترك مع iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=الاتصال بالصوت (و الصورة) و التحاور عبر الانترنت
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=اسم المستخدم:
plugin.sip2sipaccregwizz.RETYPE_PASSWORD= أعد كتابة كلمة السر
plugin.sip2sipaccregwizz.EMAIL=بريد ألكتروني
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=للمزيد عن هذه الخدمة تÙضل بزيارة<br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>عنوان البريد الالكتروني يستعمل لارسال بريد صوتي<br>Ùˆ للتنبيه عند وجود مكالمات Ùائتة Ùˆ لاسترجاع كلمة السر Ù…Ùقودة</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>للمساعدة حول هذه الخدمة، تÙضل بزيارة<a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=حساب sip2sip.info موجود أصلا
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=أنشئ حساب sip2sip.info مجانا
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=نقل الصوت عبر الانترنت و الرسائل المباشرة
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=للمزيد عن هذه الخدمة تÙضل بزيارة<br>http://ippi.fr
@@ -1137,6 +1002,7 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=حساب ippi موجود أصلا
plugin.ippiaccregwizz.CREATE_ACCOUNT=أنشئ حساب ippi مجانا
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=إغلاق ناÙذة الدردشة
plugin.keybindings.CHAT_COPY=نسخ
plugin.keybindings.CHAT_CUT=قص
@@ -1158,14 +1024,15 @@ plugin.keybindings.globalchooser.MUTE_CALLS=كتم المكالمات
plugin.keybindings.globalchooser.SHORTCUT_NAME=اسم
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=إختصار أوّلي
plugin.keybindings.globalchooser.SHORTCUT_SECOND=إختصار ثانوي
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=جاري الإنتظار
plugin.keybindings.globalchooser.ENABLE_SPECIAL=تÙعيل Ù…Ùتاح التحقق الخاص
plugin.keybindings.PLUGIN_NAME=ارتباط المÙاتيح
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=دردشة
plugin.keybindings.MAIN=رئيسي
plugin.keybindings.GLOBAL=اختصارات عامة
# Notification Configuration Form
+plugin.notificationconfig.ENABLE_NOTIF=تÙعيل
plugin.notificationconfig.DESCRIPTION=وصÙ
plugin.notificationconfig.TURN_ON_ALL=تشغيل الكل
plugin.notificationconfig.TURN_OFF_ALL=إيقا٠الكل
@@ -1182,6 +1049,7 @@ plugin.notificationconfig.BROWSE_SOUND=اختر مل٠الصوت
plugin.notificationconfig.BROWSE_PROGRAM=إختر برنامج
plugin.notificationconfig.tableheader.EXECUTE=تنÙيذ برنامج:
plugin.notificationconfig.tableheader.DESCRIPTION=وص٠الحدث
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=مكالمة واردة
plugin.notificationconfig.event.SecurityMessage=رسالة أمنة
plugin.notificationconfig.event.IncomingFile=مكالمة واردة
@@ -1275,6 +1143,7 @@ impl.neomedia.configform.VIDEO=Ùيديو
impl.neomedia.configform.H264=H.264
impl.neomedia.configform.H264.defaultProfile=تشÙير التخطيط الاÙتراضي للخيارات للمستخدم إلى:
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=خط أساس
impl.neomedia.configform.H264.defaultProfile.high=عالي
impl.neomedia.configform.H264.defaultProfile.main=رئيسي
@@ -1303,7 +1172,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=كلمة السر الحا
plugin.securityconfig.masterpassword.ENTER_PASSWORD=أدخل كلمة سر جديدة:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=أعد كتابة كلمة السر:
plugin.securityconfig.masterpassword.MP_TITLE=كلمة السر الرئيسة
-plugin.securityconfig.masterpassword.MP_NOT_SET=(غير مجهز)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=لم تقم بإدخال كلمة السر الرئيسة الحالية كما يجب. لطÙا، حاول مرة أخزى.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=كلمة السر الرئيسة غير صحيحة !
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Ùشل تغيير كلمة السر
@@ -1319,7 +1187,6 @@ plugin.securityconfig.masterpassword.COL_PASSWORD=كلمة السر
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(مجهول)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(لا يمكن ÙÙƒ الترميز)
plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=كلمات مرور محÙوظة
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=حذÙ
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=احذ٠الكل
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=أمتأكد من أنك تريد حذ٠كل كلمات السر؟
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=حذ٠كل كلمات السر
@@ -1381,7 +1248,6 @@ plugin.globalproxy.PROXY_PORT=ميناء البروكسي
plugin.globalproxy.PROXY_USERNAME=اسم المستخدم للبروكسي
plugin.globalproxy.PROXY_PASSWORD=كلمة السر للبروكسي
plugin.globalproxy.DESCRIPTION={0} سيستخدم إعدادات البروكسي أعلاه لجميع الشبكات التي ستتصل بها أو منها منذ الآن.\nإن دعم البروكسي هو تجريبي حاليا Ùˆ يعمل مع عدد من البروتوكولات. تأكد من الجدول ÙÙŠ الأسÙÙ„ لمزيد من المعلومات:
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>JABBER</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
# plugin reconnect
@@ -1394,6 +1260,8 @@ plugin.reconnectplugin.NETWORK_DOWN=قطع الاتصال بالشبكة !
plugin.chatconfig.TITLE=دردشة أو حوار
plugin.chatconfig.replacement.TITLE=صورة/Ùيديو
plugin.chatconfig.replacement.ENABLE_SMILEY_STATUS=تÙعيل تبديل الوجوه التعبيرية
+plugin.chatconfig.replacement.REPLACEMENT_TITLE=تÙعيل تبديل الصورة أو الÙيديو
+plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS=تÙعيل
plugin.chatconfig.replacement.REPLACEMENT_SOURCES=مصادر:
plugin.chatconfig.spellcheck.TITLE=تدقيق إملاء
@@ -1461,8 +1329,6 @@ net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult
#plugin spellcheck
plugin.spellcheck.TITLE=هجاء و قواعد
plugin.spellcheck.MENU=أظهر هجاء و قواعد
-plugin.spellcheck.LANG=لغة
-plugin.spellcheck.EDIT_PERSONAL_DICT=تعديل
plugin.spellcheck.ENABLE_SPELL_CHECK=مكن التدقيق الإملائي
plugin.spellcheck.dialog.FIND=ابحث عن التالي
plugin.spellcheck.dialog.REPLACE=بدّل
diff --git a/resources/languages/resources_ast.properties b/resources/languages/resources_ast.properties
index 980daac..bfba5d9 100644
--- a/resources/languages/resources_ast.properties
+++ b/resources/languages/resources_ast.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Yo
service.gui.ACCOUNT_REGISTRATION_WIZARD=Encontu pal rexistru de cuentes
service.gui.ACCOUNTS=Cuentes
service.gui.ADD=&Amestar
-service.gui.ADD_ACCOUNT=Amestar cuenta
service.gui.ADD_CONTACT=&Amestar contautu
service.gui.ADD_AUTHORIZED_CONTACT=Amestar a {0} a la to llista contautos
service.gui.ADD_CONTACT_TO_CONTACTLIST=Amestar el contautu a la to llista contautos
@@ -42,20 +52,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Fallu al amestar el contautu
service.gui.ADD_CONTACT_EXIST_ERROR=El contautu {0} yá esiste na to llista contautos.
service.gui.ADD_CONTACT_NETWORK_ERROR=El sirvidor nun respondió la nuesa petición d'amestar el contautu cola ID: {0} .
service.gui.ADD_CONTACT_NOT_SUPPORTED=Fallu al amestar contautu cola ID: {0} . Operación non sofitada.
-service.gui.ADD_CONTACT_IDENTIFIER=Nel campu d'embaxo, pon l'identificador del contautu que te prestaría amestar.
-service.gui.ADD_CONTACT_WIZARD=Encontu p'amestar contautos
service.gui.ADD_CONTACT_NOT_CONNECTED=Necesites tar coneutáu p'amestar un contautu. Por favor, rexístrate nel fornidor esbilláu ya intentalo de nueves.
service.gui.ADD_GROUP_LOCAL_ERROR=Fallu al amestar el grupu col nome: {0} . La torga asocedió nuna operación E/S llocal.
service.gui.ADD_GROUP_EXIST_ERROR=El grupu {0} yá esiste na to llista contautos. Por favor, escueyi otru nome.
service.gui.ADD_GROUP_NET_ERROR=Fallu al amestar el grupu col nome: {0} . El problema asocedió pola mor d'un fallu de rede. Por favor, comprueba la to conexón ya intentalo de nueves.
service.gui.ADD_GROUP_ERROR=Fallu al amestar el grupu col nome: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=El nome del grupu nun tien de tar baleru.
-service.gui.ADD_GROUP=Crear grupu
-service.gui.ADD_SUBCONTACT=&Amestar socontautu
service.gui.ADDRESS=Direición
service.gui.ADMINISTRATOR=alministrador
service.gui.ADVANCED=&Avanzáu
-service.gui.ALL=&Too
service.gui.ALL_CONTACTS=&Tolos contautos
service.gui.ALTERNATE_ADDRESS=Alternar direición
service.gui.APPLY=&Aplicar
@@ -65,7 +70,6 @@ service.gui.AT=a les
service.gui.AUTHORIZE=&Autorizar
service.gui.AUTHORIZATION_ACCEPTED={0} aceutó la to solicitú d'autorización.
service.gui.AUTHENTICATION_FAILED=Falló l''autenticación pa {0} . La contraseña que punxesti nun ye válida.
-service.gui.AUTHENTICATION_REQUESTED=Autenticación riquida
service.gui.AUTHENTICATION_REQUESTED_SERVER=El sirvidor {0} solicitó la to autenticación.
service.gui.AUTHENTICATION_REJECTED={0} refugó la to solicitú d'autorización.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} autenticación
@@ -107,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=Nel campu d'embaxo, pues poner el to nomatu nu
service.gui.CHANGE_NICKNAME_ERROR=Fallu camudando'l nomatu
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Yá esiste'l nomatu
service.gui.CHANGE_VIDEO_QUALITY=Camudar calidá de vidéu remota
-service.gui.CHAT_CONFERENCE_LABEL=Conferencies
service.gui.CHAT_CONFERENCE_ITEM_LABEL=Conferencia de {0}
service.gui.CHAT_ROOM_ALREADY_JOINED=Yá s'alcuentra na sala de charra {0} .
service.gui.CHAT_ROOM_CONFIGURATION=Configuración de la sala de charra {0}
@@ -121,18 +124,14 @@ service.gui.CHAT_ROOM_USER_LEFT={0} coló
service.gui.CHAT_ROOM_USER_KICKED=fosti espulsáu de {0}
service.gui.CHAT_ROOM_USER_QUIT=coló {0}
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=Ta prohibíu'l dunviu de mensaxes (voz revocada)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Atroxa la sala de charra pa un usu futuru
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Desanicia la sala esbillada de la llista de sales atroxaes
service.gui.CHAT_ROOM_NAME=Nome de la sala de charra
service.gui.CLEAR_CUSTOM_MESSAGES=Llimpiar mensaxes personalizaos
service.gui.ROOM_NAME=Sala de charra
-service.gui.AUTOJOIN=Xunise automáticamente
service.gui.CHANGE_PASSWORD=Camudar contraseña
service.gui.CHAT_ROOM_NAME_INFO=Nel campu d'embaxo pon el nome de la sala de charra que te prestaría crear.
service.gui.CHAT_ROOM_NOT_EXIST=La sala {0} nun fo alcontrada nel sirvidor {1}. Por favor, verifica si'l nome qu'escribiesti ye'l correutu.
service.gui.CHAT_ROOM_NOT_CONNECTED=Necesites aniciar sesión pa xunite a la sala de charra {0} .
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Necesites aniciar sesión pa colar de la sala de charra.
-service.gui.CHAT_ROOM_NOT_JOINED=Necesites xunite a la sala de charra pa cola fin de faer operaciones con ella.
service.gui.CHAT_ROOM_OPTIONS=Opciones de la sala de charra
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=La sala de charra {0} rique d'un rexistru pa xunise.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=La sala de charra {0} solicitó una contraseña.
@@ -151,22 +150,18 @@ service.gui.CLEAR=Llimpiar
service.gui.CLOSE=Za&rrar
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Recibiesti fai menos de 2 segundos un mensax nuevu. ¿De xuru quies zarrar esta charra?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=Tienes tresferencies de ficheros actives. ¿De xuru quies encaboxales toes?
-service.gui.CONFIRM=Confirmar
service.gui.CONNECTED_STATUS=Coneutáu
service.gui.CONNECTING=Coneutando…
service.gui.CONNECTING_STATUS=Coneutando
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Coneutando*
service.gui.CONNECTION=Conexón
-service.gui.CONNECTION_FAILED_MSG=Conexón fallida cola siguiente cuenta: Nome d'usuariu: {0} , Nome'l sirvidor: {1} . Por favor, comprueba la to conexón de rede o contauta col to alministrador de redes pa más información.
service.gui.CONNECTION_EXPIRED_MSG=Anguaño tas desconeutáu del sirvidor {0} .
service.gui.CONTACT_NAME=ID o númberu
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=El contautu escoyíu {0} nun sofita telefonía.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=El contautu escoyíu {0} nun sofita conferencies.
service.gui.CONTACT_PAUSED_TYPING={0} posó d''escribir el mensax
service.gui.CONTACT_TYPING={0} ta escribiendo un mensax
service.gui.CONTACT_TYPING_SEND_FAILED=¡Fo!... nun pudimos dici-y a {0} que tabes escribiendo
service.gui.CONTACT_INFO=&Información de contautu
-service.gui.CONTACTLIST=Llista contautos
service.gui.CONTACTS=Contautos
service.gui.COPY=&Copiar
service.gui.COPY_LINK=Copiar &enllaz
@@ -176,27 +171,24 @@ service.gui.CREATE_CHAT_ROOM=&Crear sala de charra...
service.gui.CREATE_CHAT_ROOM_ERROR=Fallu al crear la sala de cahrra {0} .
service.gui.CREATE_CHAT_ROOM_WIZARD=Encontu pa la criación de sales de charra
service.gui.CREATE_CONFERENCE_CALL=&Crear una llamada de conferencia...
-service.gui.CREATE_CONFERENCE_CHAT=&Crear una charra de conferencia...
service.gui.CREATE_GROUP=&Crear grupu...
service.gui.CREATE_GROUP_NAME=Nel campu d'embaxo pon el nome'l grupu que te prestaría crear.
-service.gui.CREATE_FIRST_GROUP_WIZARD=La to llista contautos nun tien dengún grupu. Por favor, crea un grupu primero (Ficheru/Crear grupu).
service.gui.CREATE_VIDEO_BRIDGE=Crear una ponte &vidéu...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Crear una ponte &vidéu
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Crear / Xunise a una conferencia de vidéu
service.gui.CREATE_VIDEO_CONFERENCE=Crear una videoconferencia nueva nesta sala de charra
service.gui.CONTACT_INFO_NOT_SUPPORTED=Esti contautu nun sofita información de contautu web
service.gui.CUT=F&rañir
-service.gui.DATE=Data
service.gui.DELETE=Desaniciar
service.gui.DENY=&Refugar
service.gui.DESKTOP_SHARING_WARNING=<b>¿De xuru quies entamar la compartición de pantalla?</b> <br> Primi Val pa dexar a la xente nesta llamada ver la to pantalla.
+service.gui.DESKTOP_SHARING_DIALOG_INDICATE=Tas compartiendo la to pantalla
service.gui.DIALPAD=Tecláu numbéricu
service.gui.DISPLAY_NAME=Amosar nome
service.gui.DISCONNECTED_STATUS=Desconeutáu
service.gui.DND_STATUS=Nun cafiar
service.gui.DO_NOT_ASK_AGAIN=Nun entrugar más
service.gui.DO_NOT_SHOW_AGAIN=Nun amosar esti mensax más
-service.gui.DOWNLOAD_NOW=&Baxar agora
service.gui.DRAG_FOR_SHARING=Arrastra equí tolo que quies compartir...
service.gui.DURATION=duración
service.gui.DESTROY_CHATROOM=Destruyir sala de charra
@@ -217,7 +209,6 @@ service.gui.ERROR_RECEIVED_FROM=Fallu recibíu de {0}
service.gui.ESTIMATED_TIME=Tiempu estimáu:
service.gui.EVENTS=Eventos
service.gui.EXIT=C&olar
-service.gui.EXTENDED_CRITERIA=Criteriu estendíu
service.gui.GENERAL=Xeneral
service.gui.GENERAL_ERROR=Fallu xeneral
service.gui.GROUP_NAME=Nome del grupu
@@ -259,7 +250,6 @@ service.gui.FONT_ITALIC=Cursiva
service.gui.FONT_SIZE=Tamañu
service.gui.FONT_STYLE=Estilu
service.gui.FONT_UNDERLINE=Solliñar
-service.gui.FROM={0} de {1}
service.gui.GRANT_OWNERSHIP=Faer propietariu...
service.gui.GRANT_ADMIN=Faer alministrador...
service.gui.GRANT_MODERATOR=Faer llendador
@@ -285,7 +275,6 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=¿De xuru quies desaniciar dafechu tolos
service.gui.HISTORY_REMOVE_ERROR=Fallu desaniciando los mensaxes atroxaos llocalmente.
service.gui.HOME=Llar
service.gui.HOME_PAGE=Páxina d'aniciu
-service.gui.HOUR=Hora
service.gui.ICE=ICE
service.gui.IDENTIFIER=Identificador
service.gui.IGNORE=&Inorar
@@ -309,13 +298,10 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Convidar contautos a la ponte de vidÃ
service.gui.INVITE_REASON=Razón d'invitación
service.gui.IS_CALLING={0} ta llamando...
service.gui.IS_NOW={0} ye agora {1}
-service.gui.JITSI_WARNING=SIP Communicator fo renomáu apocayá como Jitsi.<br/>Si quies que la to versión tea anovada, entós baxa Jitsi agora.<br/><br/>Sentimos cualaquier inconveniencia que puea causate ésto.<br/><br/>L'equipu Jitsi Dev
-service.gui.JITSI_WARNING_TITLE=SIP Communicator ye agora Jitsi
service.gui.JOIN=&Xunise
service.gui.JOIN_AS=X&unise como
service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=Xunise a una videoconferencia esistente
service.gui.JOIN_VIDEO=Xunir vidéu
-service.gui.CLOSE_CHAT_ROOM_DIALOG=Z&arrar
service.gui.JOB_TITLE=Títulu'l trabayu
service.gui.JOIN_CHAT_ROOM=&Xunise a la charra de charra...
service.gui.JOIN_CHAT_ROOM_TITLE=Xunise a la sala de charra
@@ -328,7 +314,6 @@ service.gui.KICK_FAILED=Espulsión fallida
service.gui.KICK_FAILED_GENERAL_ERROR=Fallu al espulsar a {0} . Asocedió un fallu xeneral del sirvidor.
service.gui.KICK_FAILED_NOT_ALLOWED=Fallu al espulsar a {0} . Nun puen espulsase al dueñu y l'alministrador la sala.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Fallu al espulsar a {0} . Nun tienes abondos privilexos pa fer esto.
-service.gui.LAST=Caberu
service.gui.LAST_NAME=Apellíos
service.gui.LEAVE=&Colar
service.gui.LIMIT_REACHED_FOR_IP=Tienes milenta rexistros esistentes dende la to direción IP llocal y el sirvidor {0} nun almite abrir dengún más d'ellos.
@@ -348,7 +333,6 @@ service.gui.MESSAGE=Mensax
service.gui.MISSED_CALLS_TOOL_TIP=Llamaes perdíes de:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= y {0} más
service.gui.MODERATOR=llendador
-service.gui.MORE=Ver más
service.gui.MORE_LABEL=Más
service.gui.MOVE=Mover
service.gui.MOVE_SUBCONTACT=M&over contautu
@@ -357,7 +341,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=El contautu qu'escoyesti ye'l mesmu que\nl'or
service.gui.MOVE_SUBCONTACT_QUESTION=¿De xuru quies mover {0} a {1} ?
service.gui.MOVE_TO_GROUP=&Mover al grupu
service.gui.MOVE_CONTACT=Mover contautu
-service.gui.MOVE_CONTACT_ERROR=&El contautu nun pue movese
service.gui.MSG_DELIVERY_FAILURE=Nun pudo entregase'l mensax d'enriba
service.gui.MSG_DELIVERY_NOT_SUPPORTED=El protocolu que tas usando nun sofita mensaxes fuera de llinia. Pues intentar contautar con {0} pente medies d'otru protocolu o esperar fasta qu'elli/ella tea en llinia.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Asocedió un fallu internu. Esto pue ser de xuru un problema. Por favor, repórtalu equí: https://jitsi.org/Development/BugsAndIssues.
@@ -371,7 +354,6 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=Deberíes tar coneutáu pa poder dunviar
service.gui.MULTIPLE_LOGINS=Aniciesti sesión más d'una vegada cola mesma cuenta. La siguiente cuenta: Nome d'usuariu: {0} , Nome'l sirvidor: {1} ta anguaño desconeutada.
service.gui.MY_CHAT_ROOMS=Amestar sala de charra
service.gui.MY_CHAT_ROOMS_TITLE=Amestar sala de charra
-service.gui.MUTE=Silenciar
service.gui.MUTUALLY_ON_HOLD_STATUS=Dambos n'espera
service.gui.NAME=Nome
service.gui.NETWORK=Rede
@@ -403,7 +385,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=Nun ta na llista contautos
service.gui.SD_QUALITY=Calidá estándar
service.gui.OFFLINE=Fuera de llinia
service.gui.OK=&Val
-service.gui.OLDER_CALLS=Llamaes más vieyes
service.gui.ONLINE=En llinia
service.gui.OPEN=Abrir
service.gui.OPEN_FILE_FROM_IMAGE=Clic doblu p'abrir el ficheru.
@@ -415,7 +396,6 @@ service.gui.OPEN_ON_ACTIVITY=Abrir al tar activu
service.gui.OPEN_ON_MESSAGE=Abrir namái nel mensax
service.gui.OPEN_ON_IMPORTANT_MESSAGE=Abrir namái en mensaxes importantes
service.gui.OR=o
-service.gui.OR_ENTER_PHONE_NUMBER=O pon equí'l númberu de teléfonu...
service.gui.ORGANIZATION=Organización
service.gui.OTHER=Otru
service.gui.chat.role.OWNER=Dueñu
@@ -440,7 +420,6 @@ service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Intru' pa suxerencies
service.gui.PRESS_FOR_CALL_INFO=Primi pa información de la llamada
service.gui.PRESS_TO_OPEN_CRM=Primi p'abrir l'aplicación CRM
service.gui.PREVIOUS=Previu
-service.gui.PREVIOUS_TOOLTIP=Restolar charres más vieyes
service.gui.PRINT=&Imprentar
service.gui.PROACTIVE_NOTIFICATION=ta escribiendo un mensax
service.gui.PROBLEMS_ENCOUNTERED=Problemes alcontraos
@@ -456,7 +435,6 @@ service.gui.RECONNECTION_LIMIT_EXCEEDED=Tuviesti desconeutándote y reconeutánd
service.gui.RE_REQUEST_AUTHORIZATION=Solicitar autorización de nueves
service.gui.REFERRED_STATUS=Referíu
service.gui.REJECT=&Refugar
-service.gui.REMIND_ME_LATER=Recuérdamelo sero
service.gui.REMEMBER_PASSWORD=Recordar contraseña
service.gui.REMOVE=&Desaniciar
service.gui.REMOVE_ACCOUNT=&Desaniciar cuenta
@@ -482,29 +460,20 @@ service.gui.REVOKE_ADMIN=Revocar almin
service.gui.REVOKE_MODERATOR=Revocar llendador
service.gui.REVOKE_MEMBERSHIP=Revocar membresía
service.gui.REVOKE_VOICE=Revocar voz
-service.gui.ROOT_GROUP=Grupu raigañu
service.gui.SAVE=&Atroxar
-service.gui.SAVE_AS_DEFAULT=Atroxar como predetermináu
service.gui.SEARCH=&Guetar
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Primi'l botón d'embaxo p'amosar toles sales de charra esistentes nel sirvidor esbilláu. Dempués esbilla a la que te prestaría xunite primiendo nel botón Xunise.
service.gui.SEARCH_STRING_CONTACT_SOURCE=Contautu guetáu
service.gui.SECURITY=Seguranza
-service.gui.SELECT_ACCOUNT=Esbillar cuenta
service.gui.SELECT_COLOR=Esbillar color
service.gui.SELECT_GROUP=Esbillar grupu
-service.gui.SELECT_GROUP_WIZARD_MSG=La llista d'embaxo contien tolos grupos na to llista contautos. Esbilla a la que te prestaría amestar el contautu nuevu.
service.gui.SELECT_NO_GROUP=Ensin grupu
-service.gui.SELECT_GROUP_WIZARD=Especificar grupu
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=La llista d'embaxo contien toles cuentes que sofiten la carauteristica de charra multi usuariu. Esbilla la que te prestaría usar pa criar la to sala de charres.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=La llista d'embaxo contien toles cuentes rexistraes. Esbilla cola que te prestaría comunicate col contautu nuevu.
-service.gui.SELECT_PROVIDERS_WIZARD=Esbillar cuenta
service.gui.SELECT_VIDEO_CONFERENCE=Esbillar conferencia de vidéu
service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Esbilla una sala de charra de la llista y primi Val p'amestala.
service.gui.SEND=&Dunviar
service.gui.SEND_FILE=Dunviar &ficheru
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Nun hai información pa esti contautu.
service.gui.SEND_MESSAGE=&Dunviar un mensax
-service.gui.SEND_AS_SMS=Dunviar como SMS
service.gui.SEND_PRIVATE_MESSAGE=Dunviar un mensax priváu
service.gui.SEND_SMS=D&unviar SMS
service.gui.SEND_SMS_DETAILS=Alcuérdate que necesites poner el númberu en formatu internacional. Exemp.: entamando per +34 pa ES por exemplu, +34999999999
@@ -543,7 +512,6 @@ service.gui.STREET=Cai
service.gui.SUBJECT=Asuntu
service.gui.SUMMARY=Resume
service.gui.TELEPHONY=Telefonía
-service.gui.TODAY=Güei
service.gui.TOOLS=&Ferramientes
service.gui.TRANSFER=Tres&ferir
service.gui.TO=&A:
@@ -553,7 +521,6 @@ service.gui.TRANSFER_CALL_TO=Tresferir a:
service.gui.TRANSPARENCY_NOT_ENABLED=La tresparencia nun ta sofitada anguaño pola to configuración.
service.gui.TYPE_YOUR_REQUEST=Escribi equí la to petición
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Nun podemos camudar la calidá de vidéu d'esta llamada.
-service.gui.UNMUTE=Quitar silenciu
service.gui.USER_IDENTIFIER=Indentificador d'usuariu:
service.gui.USER_EXISTS_ERROR=Esti usuariu yá esiste na rede esbillada. Por favor, escueyi otru usuariu o rede.
service.gui.USERNAME_NULL=Por favor, enllena'l to nome d'usuariu y contraseña.
@@ -566,7 +533,6 @@ service.gui.USE_PROVISIONING=Usar aprovisionamientu en llinia
service.gui.VALUE=Valor
service.gui.VIDEO_CALL=&Llamada de vidéu
service.gui.VIA=per
-service.gui.VIA_SMS=Per SMS
service.gui.VIEW=&Ver
service.gui.VIEW_HISTORY=Ver &historia
service.gui.VIEW_SMILEYS=Ver &fustaxes
@@ -586,9 +552,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=Axustar volume
service.gui.WAITING_AUTHORIZATION=Esperando pola autorización
service.gui.WARNING=Avisu
service.gui.YES=Sí
-service.gui.YESTERDAY=Ayeri
-service.gui.EXISTING_ACCOUNT_ERROR=Yá ta intalada a cuenta que punxesti.
-service.gui.NEW_MAIL=<b>¡Tienes un corréu nuevu!</b><br/><b>De:</b> {0} {1} <br/><b>Asuntu:</b> {2} <br/>{3} ;
service.gui.NEW_GMAIL_HEADER=Recibiesti un corréu nuevu na to <a href="{1}">bandexa d'entrada</a>:<br/> {0}
service.gui.NEW_GMAIL_MANY_HEADER=Recibiesti {2} correos nuevos na to <a href="{1}">bandexa d'entrada</a>:<br/> {0}
service.gui.NEW_GMAIL_FOOTER=ún o más correos ensin lleer na to <a href="{0}">bandexa d'entrada</a>.<br/>
@@ -612,7 +575,6 @@ service.gui.SECURITY_ERROR=Fallu de seguranza
service.gui.SPEED=Velocidá:
service.gui.SILENT_MEMBER=silenciar miembru
service.gui.NON_SECURE_CONNECTION=Nun pue asegurase la conexón pa la cuenta {0} . Si quies coneutate a un sirvidor non seguru, por favor conseña "Almitir conexones non segures" nos axustes de la to cuenta
-service.gui.UPDATE=Anovar
service.gui.MOBILE_PHONE=Móvil
service.gui.VIDEO_PHONE=Vidéu
service.gui.WORK_PHONE=Trabayu
@@ -647,12 +609,10 @@ service.gui.callinfo.CALL_INFORMATION=Información de llamada
service.gui.callinfo.CALL_IDENTITY=Identidá
service.gui.callinfo.PEER_COUNT=Participación
service.gui.callinfo.IS_CONFERENCE_FOCUS=Enfocar charra
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Cifráu habilitáu
service.gui.callinfo.CALL_TRANSPORT=Señalización de tresporte de llamada
service.gui.callinfo.CALL_DURATION=Duración de llamada
service.gui.callinfo.TLS_PROTOCOL=Protocolu TLS
service.gui.callinfo.TLS_CIPHER_SUITE=Suit de cifráu TLS
-service.gui.callinfo.TLS_SERVER_CERTIFICATE_CHAIN=Cadena del certificáu TLS del sirvidor
service.gui.callinfo.TLS_CERTIFICATE_CONTENT=Ta amosáu embaxo'l conteníu'l certificáu TLS.
service.gui.callinfo.VIEW_CERTIFICATE=Ver certificáu
service.gui.callinfo.CODEC=Codificador / Frecuencia
@@ -662,7 +622,6 @@ service.gui.callinfo.AUDIO_INFO=Información d'audiu
service.gui.callinfo.VIDEO_INFO=Información de vidéu
service.gui.callinfo.LOCAL_IP=IP llocal / puertu
service.gui.callinfo.REMOTE_IP=IP remota / puertu
-service.gui.callinfo.BANDWITH=Anchor de banda
service.gui.callinfo.LOSS_RATE=Tasa de perda
service.gui.callinfo.RTT=RTT
service.gui.callinfo.JITTER=Jitter
@@ -672,10 +631,13 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=Protocolu d'intercambéu claves
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=Candidatu ICE de triba estendida
service.gui.callinfo.ICE_STATE=Estáu de procesamientu ICE
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=Axuntando candidatos
service.gui.callinfo.ICE_STATE.RUNNING=Comprobaciones de conectividá
service.gui.callinfo.ICE_STATE.COMPLETED=Completáu
service.gui.callinfo.ICE_STATE.FAILED=Falló
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=IP llocal d'agospiu / Puertu
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=IP llocal reflexiva / Puertu
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=IP llocal tresmitida / Puertu
@@ -696,10 +658,11 @@ service.gui.ALWAYS_TRUST=Confiar siempres nesti certificáu
service.gui.CERT_DIALOG_TITLE=Verificar certificáu
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} nun pue verificar la identidá''l sirvidor al coneutase a<br><b>{1}</b>.<br><br>Nun pue confiase nel certificáu, lo que quier dicir que la identida''l sirvidor nun pue verificase automáticamente.<br><br> ¿Quies siguir coneutándote?<br> Pa más información primi n'"Amosar certificáu".</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0} nun pue verificar la identidá del certificáu del sirvidor.<br><br> Nun pue confiase nel certificáu, lo que quier dicir que la identida''l sirvidor nun pue<br> verificase automáticamente. ¿Quies siguir coneutándote?<br><br> Pa más información primi n''"Amosar certificáu".</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} nun pue verificar la identidá''l veceru coneutáu.<br><br> Nun pue confiase nel certificáu, lo que quier dicir que la identida''l sirvidor nun pue<br> verificase automáticamente. ¿Quies siguir coneutándote?<br><br> Pa más información primi n'"Amosar certificáu".</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} nun pue verificar la identidá''l veceru {1}.<br><br> Nun pue confiase nel certificáu, lo que quier dicir que la identida''l sirvidor nun pue<br> verificase automáticamente. ¿Quies siguir coneutándote?<br><br> Pa más información primi n''"Amosar certificáu".</html>
service.gui.CONTINUE_ANYWAY=Siguir de toes toes
service.gui.CERT_INFO_CHAIN=Cadena del certificáu:
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Nome común:
service.gui.CERT_INFO_O=Organización:
service.gui.CERT_INFO_C=Nome'l país:
@@ -717,12 +680,10 @@ service.gui.CERT_INFO_SIGN_ALG=Algoritmu de robla:
service.gui.CERT_INFO_PUB_KEY_INFO=Información de clave pública
service.gui.CERT_INFO_ALG=Algoritmu:
service.gui.CERT_INFO_PUB_KEY=Clave pública:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} bytes: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} bits
service.gui.CERT_INFO_EXP=Esponente:
service.gui.CERT_INFO_KEY_SIZE=Tamañu la clave:
service.gui.CERT_INFO_SIGN=Robla:
-service.gui.CONTINUE=Siguir
service.gui.SHOW_CERT=Amosar certificáu
service.gui.HIDE_CERT=Anubrir certificáu
@@ -745,12 +706,9 @@ service.gui.security.SECURE_AUDIO=Audiu seguru
service.gui.security.AUDIO_NOT_SECURED=Audiu non seguru
service.gui.security.SECURE_VIDEO=Vidéu seguru
service.gui.security.VIDEO_NOT_SECURED=Vidéu non seguru
-service.gui.security.NO_VIDEO=Ensin vidéu
-service.gui.security.CIPHER=Cifráu: {0}
service.gui.security.CALL_SECURED_TOOLTIP=Llamada asegurada. Pa más información primi equí.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Llamada non asegurada.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Primi equí pa comparar el secretu de seguranza col to collaciu.
-service.gui.security.COMPARE_WITH_PARTNER=Compara col to collaciu y primi nel candáu pa confirmar.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Comparar col collaciu:
service.gui.security.STRING_COMPARED=¡Cadena comparada!
@@ -768,20 +726,14 @@ service.gui.avatar.imagepicker.CLICK=Primi y sorrí
service.gui.avatar.imagepicker.IMAGE_FILES=Ficheros d'imaxes
service.gui.avatar.imagepicker.IMAGE_PICKER=Semeya
service.gui.avatar.imagepicker.IMAGE_SIZE=Tamañu d'imax
-service.gui.avatar.imagepicker.INITIALIZING=Aniciando
service.gui.avatar.imagepicker.RESET=Reafitar
service.gui.avatar.imagepicker.SET=Definir
service.gui.avatar.imagepicker.TAKE_PHOTO=Fer una semeya
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Fallu de cámara web
service.gui.security.encryption.required=¡Cifráu riquíu!
service.protocol.ICE_FAILED=Nun pudo afitase la conexón (nun s'alcontró rempuesta y fallu d'ICE)
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
impl.protocol.sip.XCAP_ERROR_TITLE=Fallu nel almacenamientu de llista contautos SIP
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=Nun puen lleese los recursos {0} . De {1}
@@ -811,9 +763,7 @@ impl.ldap.QUERY_CUSTOM=Consulta automática
impl.ldap.QUERY_CUSTOM_HINT=Usa {0} como un marcador pal terminu de gueta.
impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=Amestar automáticamente comodines al términu de gueta
impl.ldap.QUERY_PHOTO_INLINE=Amesta una foto con otros atributos
-impl.ldap.NEW=Nuevu
impl.ldap.EDIT=editar
-impl.ldap.REMOVE=Desaniciar
impl.ldap.ENABLED=Habilitáu
impl.ldap.SERVER_NAME=Nome'l sirvidor
impl.ldap.SERVER_NAME_EXAMPLE=El mio sirvidor LDAP
@@ -846,6 +796,10 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=TeléfonuLlar
impl.ldap.PHONE_PREFIX=Prefixu de teléfonu
impl.ldap.PHONE_PREFIX_EXAMPLE=Ex.: 00
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=Llibreta de direiciones
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=Habilitar gueta na llibreta de direiciones MacOSX
@@ -860,9 +814,7 @@ plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT=Faer Outlook el to veceru de co
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Google Contacs
-impl.googlecontacts.NEW=Nuevu
impl.googlecontacts.EDIT=editar
-impl.googlecontacts.REMOVE=Desaniciar
impl.googlecontacts.ENABLED=Habilitáu
impl.googlecontacts.ACCOUNT_NAME=Nome de cuenta
impl.googlecontacts.SAVE=Atroxar
@@ -901,11 +853,8 @@ plugin.accountinfo.ORGANIZATION=Nome d'organización:
plugin.accountinfo.JOB_TITLE=Títulu'l trabayu:
plugin.accountinfo.ABOUT_ME=Tocante a min:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
-plugin.accountinfo.USER_PICTURES=Semeyes d'usuariu
plugin.accountinfo.GLOBAL_ICON=Usar iconu global
plugin.accountinfo.LOCAL_ICON=Usar esti iconu:
-plugin.accountinfo.CHANGE=Camudar
-plugin.accountinfo.ONLY_MESSAGE=Namái mensaxes
# connection info
plugin.connectioninfo.TITLE=Información de conexón
@@ -925,49 +874,12 @@ plugin.aimaccregwizz.USERNAME=Usuariu AIM:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Usuariu y contraseña
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Rexistrar cuenta nueva
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Nel casu que nun tengas una cuenta AIM, primi nesti botón pa crear una nueva.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Trocar les opciones predeterminaes del sirvidor
# branding
plugin.branding.ABOUT_WINDOW_TITLE=Tocante a {0}
plugin.branding.LOGO_MESSAGE=VoIP y mensaxeru nel intre de códigu llibre
-plugin.branding.LOADING=Cargando
plugin.branding.ABOUT_MENU_ENTRY=&Tocante a
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>{1} ta anguaño baxo desendolcu activu. La versión que tas executando ye namái esperimental y PUE QUE NUN furrule como s'espera. Por favor, consulta a {2} pa más información.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 Copyright <b>jitsi.org</b>. Tolos drechos reservaos. Visita <a href="https://jitsi.org">https://jitsi.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}><b>Jitsi</b> ta distribuyíu baxo los terminos de llicencia LGPL (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=Diccionarios
-plugin.dictaccregwizz.ANY_DICTIONARY=Cualaquier diccionariu
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Cualaquier diccionariu de {0}
-plugin.dictaccregwizz.FIRST_MATCH=Primera coincidencia
-plugin.dictaccregwizz.NO_MATCH=Nun hai coincidencies
-plugin.dictaccregwizz.MATCH_RESULT=Nun hai definiciones alcontraes pa "{0}", quiciabes quixesti dicir:\n
-plugin.dictaccregwizz.INVALID_DATABASE=El diccionariu "{0}" d'anguaño nun esiste nel sirvidor.
-plugin.dictaccregwizz.INVALID_STRATEGY=La estratexa d'anguaño nun ta disponible nel sirvidor.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=El serviciu de protocolu Dict
-plugin.dictaccregwizz.HOST=Agospiu
-plugin.dictaccregwizz.SERVER_INFO=Informaciones del sirvidor
-plugin.dictaccregwizz.STRATEGY_SELECTION=Esbilla d'estratexa
-plugin.dictaccregwizz.STRATEGY_LIST=Llista d'estratexes:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Guetar estratexa
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=La estratexa úsase pa guetar pallabres asemeyaes, si nun s'alcuentra una torna, ye gracies a los diferentes enfoques. Por exemplu, les estratexes de prefixos guetarán pallabres qu'entamen como la pallabra que te prestaría tornar.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Información de cuenta Dict
-plugin.dictaccregwizz.FIRST_ACCOUNT=Esti encontu creará la primer cuenta Dict pa tigo en dict.org.\n\nPues amestar un diccionariu nuevu diendo al encontu pal rexistru cuentes. Enllena'l campu l'agospiu col diccionariu que te prestaría amestar.
-plugin.dictaccregwizz.THREAD_CONNECT=Intentando coneutase al sirvidor
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=Intentu de conexón fallíu, esti nun ye un sirvidor dict o'l sirvidor ta fuera de llinia
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=Recibiendo estratexes
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Nun s'alcuentra estratexa dala nel sirvidor
-plugin.dictaccregwizz.POPULATE_LIST=Xenerando llista
-plugin.dictaccregwizz.CLOSING_CONNECTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Pa usar el Facebook Chat tienes de crear un "nome d'usuariu" <br>dende la páxina d'"Axustes de cuenta" na páxina de Faceook.</a><br><br>Nota: ¡Cuando crees l'usuariu tienes d'aniciar sesión dende la páxina web <br> y esperar un pocoñín enantes de poder aniciar sesión col to nome d'usuariu nuevu!</center></body></html>
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Pa usar el Facebook Chat tienes de crear un usuariu <br>dende la páxina d'"Axustes de cuenta" en Faceook.</a><br><br>Nota: ¡Cuando crees l'usuariu tienes d'aniciar sesión dende la páxina web <br> y esperar un pocoñín enantes de poder aniciar sesión col to usuariu nuevu!</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=El protocolu Facebook Chat
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Nome d'usuariu:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Nome d'usuariu y contraseña
+
# generalconfig
plugin.generalconfig.AUTO_START=Aniciar {0} cuando l''ordenador se reanicie o prenda
@@ -978,9 +890,6 @@ plugin.generalconfig.SHOW_HISTORY=Amosar
plugin.generalconfig.HISTORY_SIZE=mensaxes recientes en charres nueves
plugin.generalconfig.SEND_MESSAGES_WITH=Dunviar mensaxes con:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=Trayer la ventana la charra al frente
-plugin.generalconfig.ERROR_PERMISSION=Nun tienes abondos premisos pa desaniciar l'aniciu automáticu
-plugin.generalconfig.TRANSPARENCY=Tresparencia
-plugin.generalconfig.ENABLE_TRANSPARENCY=Habilitar tresparencia
plugin.generalconfig.DEFAULT_LANGUAGE=Llingua d'interfaz
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Les tos camudancies fadrán efeutu nel prósimu reaniciu.
plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0}% tornáu
@@ -1037,13 +946,15 @@ plugin.ircaccregwizz.HOST=Nome d'agospiu:
plugin.ircaccregwizz.IRC_SERVER=Sirvidor
plugin.ircaccregwizz.EXAMPLE_SERVER=Exem: chat.freenode.net
plugin.ircaccregwizz.USE_SECURE_CONNECTION=Usar conexón segura
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE={0} autenticación
+plugin.ircaccregwizz.SASL_USERNAME=Nome d'usuariu
+plugin.ircaccregwizz.SASL_IRC_PASSWORD_USED=La contraseña d'IRC d'enriba úsase pa l'autenticación SASL
+plugin.ircaccregwizz.RESOLVE_DNS_THROUGH_PROXY=Resolver siempres nomes DNS pente proxy
# jabber accregwizz
-plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=El protocolu XMPP
plugin.jabberaccregwizz.USERNAME=Nome d'usuariu XMPP
plugin.jabberaccregwizz.PASSWORD_CONFIRM=Confirmar contraseña
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=ID y contraseña
plugin.jabberaccregwizz.CSERVER=Sirvidor
plugin.jabberaccregwizz.SERVER=Coneutar al sirvidor
plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=Habilitar caltener vivu
@@ -1059,13 +970,9 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Comentariu
plugin.jabberaccregwizz.RESOURCE=Recursu
plugin.jabberaccregwizz.AUTORESOURCE=Xenerar recursu automáticamente
plugin.jabberaccregwizz.PRIORITY=Prioridá
-plugin.jabberaccregwizz.XMPP_ERROR=Fallu XMPP
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Fallu XMPP ({0}) desconocíu. Verifica que'l nome'l sirvidor ye correutu.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Les tos contraseñes nun concasen.
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Trocar opciones predeterminaes del sirvidor
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Opciones avanzaes
plugin.jabberaccregwizz.USE_ICE=Usar ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=Usar el Jingle/ICE de Google (esperimental)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=Escubrir sirvidores STUN/TURN automáticamente
plugin.jabberaccregwizz.SUPPORT_TURN=Sofitu TURN
plugin.jabberaccregwizz.TURN_USERNAME=Nome d'usuariu TURN
@@ -1093,11 +1000,8 @@ plugin.jabberaccregwizz.DISABLE_CARBON=Deshabilitar copies de mensaxes
plugin.jabberaccregwizz.DTMF_AUTO=Auto: Escoyer automáticamente ente RTP y en banda
plugin.jabberaccregwizz.SERVER_OPTIONS=Opciones del sirivdor
plugin.jabberaccregwizz.CHANGE_PASSWORD=Camudar contraseña de cuenta
-plugin.jabberaccregwizz.NEW_PASSWORD=Contraseña nueva
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Confirmar contraseña nueva
plugin.jabberaccregwizz.PORT_FIELD_INVALID=Por favor, rellena con un númberu de puertu válidu pa siguir.
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=La cuenta tien de tar roblada enantes de camudar la contraseña.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=La contraseña ta balera.
plugin.jabberaccregwizz.TLS_REQUIRED=La conexón nun utiliza TLS, nun s'intentará una camudancia de contraseña.
plugin.jabberaccregwizz.PASSWORD_CHANGED=La contraseña camudóse con ésitu
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=El to sirvidor XMPP nun sofita camudancies de contraseña.
@@ -1111,25 +1015,9 @@ plugin.jabberaccregwizz.RESET=Reafitar
plugin.jabberaccregwizz.RESET_DESCRIPTION=Reafitar axustes globales
plugin.jabberaccregwizz.DISABLE_JINGLE=Deshabilitar Jingle (audiu y llamaes de vidéu con XMPP).
-# mailbox
-plugin.mailbox.OUTGOING=Mensax saliente:
-plugin.mailbox.INCOMING=Mensaxes entrantes:
-plugin.mailbox.WAIT_TIME=Esperar fasta que la llamada s'unvie al buzón de voz
-plugin.mailbox.MAX_MESSAGE_TIME=Duración másima de mensax entrante
-plugin.mailbox.CONFIRM=Confirmar
-plugin.mailbox.DEFAULTS=Por defeutu
-plugin.mailbox.MAILBOX=Buzón
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Un protocolu pa coneutar y charrar nel serviciu MSN.
-plugin.msnaccregwizz.USERNAME=Corréu:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=ID y contraseña
-
# plugin manager
plugin.pluginmanager.INSTALL=Instalar
plugin.pluginmanager.UNINSTALL=Desinstalar
-plugin.pluginmanager.UPDATE=Anovar
plugin.pluginmanager.PLUGINS=Complementos
plugin.pluginmanager.URL=Enllaz
plugin.pluginmanager.CHOOSE_FILE=Esbillar ficheru
@@ -1154,7 +1042,6 @@ plugin.sipaccregwizz.SERVER_PORT=Puertu'l sirvidor
plugin.sipaccregwizz.PROXY=Proxy
plugin.sipaccregwizz.PROXY_PORT=Puertu'l proxy
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Tresporte preferíu
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Opciones avanzaes
plugin.sipaccregwizz.PROXY_OPTIONS=Opciones de proxy
plugin.sipaccregwizz.PROXY_AUTO=Configurar proxy automáticamente
plugin.sipaccregwizz.ENABLE_PRESENCE=Habilitar presencia (SIMPLE)
@@ -1174,8 +1061,6 @@ plugin.sipaccregwizz.DTMF_AUTO=Auto: Escueyi automáticamente ente RTP y en band
plugin.sipaccregwizz.DTMF_RTP=RTP ( RFC2833 / RFC 4733 )
plugin.sipaccregwizz.DTMF_SIP_INFO=SIP INFO
plugin.sipaccregwizz.DTMF_INBAND=En banda
-plugin.sipaccregwizz.REGISTER=REGISTRU
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Trocar les opciones por defeutu''l sirvidor
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Habilitar sofitu pa llamaes cifraes
plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=Indica'l sofitu de ZRTP nel protocolu de señalización
plugin.sipaccregwizz.AUTH_NAME=Nome d'autorización
@@ -1196,10 +1081,10 @@ plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=Comprobar URI de corréu de voz
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Les tos contraseñes nun concasen.
plugin.sipaccregwizz.NO_CERTIFICATE=<ninguno> (usa autenticación regular)
plugin.sipaccregwizz.SAVP_OPTION=Indicador RTP/SAVP
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=Apagáu (indica RTP/AVP solo)
plugin.sipaccregwizz.SAVP_OPTION_1=Obligatoriu (ufre y aceuta namái RTP/SAVP)
plugin.sipaccregwizz.SAVP_OPTION_2=Opcional (ufre primero RTP/SAVP, y dempués RTP/AVP)
-plugin.sipaccregwizz.ENABLE_SDES_ATTRIBUTE=Habilitar S-Descriptor (conocíu tamién como SDES o SRTP)
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=Escueyi protocolos con cifráu habilitáu y la so prioridá (primero'l protocolu cimeru):
plugin.sipaccregwizz.CIPHER_SUITES=Suits de cifráu habilitaes:
plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>{0} intentará asegurar automáticamente toles tos llamaes con ZRTP. Oyirás y verás una notificación cuando s''asegure la conexón afitada. Deberíes camudar namái los axustes avanzaos d'embaxo si tas bien seguru de lo que tas faciendo.</div></html>
@@ -1213,15 +1098,6 @@ plugin.skinmanager.DEFAULT_SKIN=Tema por defeutu
plugin.skinmanager.ADD_NEW_SKIN=Amestar tema nuevu...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=Tema por defeutu de l'aplicación.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=Un protocolu pa coneutar máquines remotes per SSH.
-plugin.sshaccregwizz.USERNAME=ID de cuenta:
-plugin.sshaccregwizz.IDENTITY_FILE=Ficheru d'identidá:
-plugin.sshaccregwizz.KNOWN_HOSTS=Agospios conocíos:
-plugin.sshaccregwizz.OPTIONAL=Opcional
-plugin.sshaccregwizz.ACCOUNT_DETAILS=Detalles de cuenta
-
# status update
plugin.autoaway.AUTO_STATUS=Ausencia automática
plugin.autoaway.ENABLE_CHANGE_STATUS=Camudar l'estáu entrín nun tea
@@ -1269,22 +1145,6 @@ plugin.whiteboard.DESELECT=Deseleicionar
plugin.whiteboard.DELETE=Desaniciar
plugin.whiteboard.PROPERTIES=Propiedaes
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Un protocolu pa coneutase y charrar nel servicu Yahoo!.
-plugin.yahooaccregwizz.USERNAME=Nome d'usuariu:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=ID y contraseña
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=El protocolu del serviciu Zeroconf (Bonjour).
-plugin.zeroaccregwizz.FIRST_NAME=Nome:
-plugin.zeroaccregwizz.LAST_NAME=Apellíos:
-plugin.zeroaccregwizz.EMAIL=Corréu:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=¿Recordar contautos Bonjour?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=ID y contraseña
-plugin.zeroaccregwizz.USERID=ID d'usuariu
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=El protocolu Google Talk
@@ -1298,19 +1158,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, el portal de telecomunica
plugin.iptelaccregwizz.USERNAME=Nome d'usuariu
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=Soscribise a iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIP y charra
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Nome d'usuariu
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Escribi la contraseña otra vegada
plugin.sip2sipaccregwizz.EMAIL=Direición de corréu
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=P'aida tocante a esti serviciu visita<br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>La direición de corréu úsase pa dunviar mensaxes del corréu de voz, <br>notificaciones de llamaes perdíes y pa recuperar una contraseña escaecida</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>P'aida tocante a esti serviciu visita <a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=Cuenta sip2sip.info esistente
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Crear una cuenta sip2sip.info de baldre
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP y mensaxería nel intre
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=P'aida tocante a esti serviciu visita<br>http://ippi.fr
@@ -1319,6 +1171,7 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=Cuenta ippi esistente
plugin.ippiaccregwizz.CREATE_ACCOUNT=Crear una cuenta ippi de baldre
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Zarrar ventana de charra
plugin.keybindings.CHAT_COPY=Copiar
plugin.keybindings.CHAT_CUT=Frañir
@@ -1341,10 +1194,10 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=Nome
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=Atayu primariu
plugin.keybindings.globalchooser.SHORTCUT_SECOND=Atayu secundariu
plugin.keybindings.globalchooser.PRESS_BTN=Primi p'afitar un atayu
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=Esperando
plugin.keybindings.globalchooser.PUSH_TO_TALK=Primi pa falar
plugin.keybindings.globalchooser.ENABLE_SPECIAL=Habilitar deteición de tecles especiales
plugin.keybindings.PLUGIN_NAME=Combinaciones de tecles
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Charra
plugin.keybindings.MAIN=Principal
plugin.keybindings.GLOBAL=Atayos globales
@@ -1372,6 +1225,7 @@ plugin.notificationconfig.tableheader.SOUND=Reproducir un soníu pente medies d'
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=Repoducir un soníu pente medies d'un preséu de reproducción
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=Reproducir un soníu pente medies d'unos altavoces
plugin.notificationconfig.tableheader.DESCRIPTION=Descripción del eventu
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Llamada entrante
plugin.notificationconfig.event.SecurityMessage=Mensax de seguranza
plugin.notificationconfig.event.IncomingFile=Ficheru entrante
@@ -1473,6 +1327,7 @@ impl.neomedia.configform.VIDEO=Vidéu
impl.neomedia.configform.H264=H.264
impl.neomedia.configform.H264.defaultIntraRefresh=Anovamientu periódicu d'Intra
impl.neomedia.configform.H264.defaultProfile=Perfil por defeutu pa codificar en:
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=Llinia bas
impl.neomedia.configform.H264.defaultProfile.high=Alta
impl.neomedia.configform.H264.defaultProfile.main=Principal
@@ -1503,7 +1358,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=Contraseña d'anguaño:
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Pon la contraseña nueva:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Escribi la contraseña de nueves:
plugin.securityconfig.masterpassword.MP_TITLE=Contraseña maestra
-plugin.securityconfig.masterpassword.MP_NOT_SET=(ensin afitar)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=Nun punxesti la contraseña maesta correuta. Por favor, inténtalo de nueves.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=¡La contraseña maestra nun ye correuta!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Fallu al camudar contraseña
@@ -1519,7 +1373,6 @@ plugin.securityconfig.masterpassword.COL_PASSWORD=Contraseña
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(desconocíu)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(nun pue descifrase)
plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=Contraseñes atroxaes
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=Desaniciar
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=Desaniciar too
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=¿De xuru quies desaniciar toles contraseñes?
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=Desaniciar toles contraseñes
@@ -1615,7 +1468,6 @@ plugin.globalproxy.PROXY_PORT=Puertu proxy
plugin.globalproxy.PROXY_USERNAME=Usuariu proxy
plugin.globalproxy.PROXY_PASSWORD=Contraseña proxy
plugin.globalproxy.DESCRIPTION={0} usará la configuración de proxy d'enriba pa toles redes a les que te coneutes o reconeutes dende agora. \nEl sofitu de proxy ye anguaño esperimental y namái furrula con dalgunos protocolos. Comprueba la tabla pa más detalles:
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>XMPP</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
plugin.globalproxy.FWD_DNS=Tamién proxy DNS
plugin.globalproxy.FWD_DNS_NOTE=Útil con Tor. Aida a evitar fugues de DNS direicionando tol tráficu DNS al proxy Tor. Requier reaniciar.
@@ -1650,7 +1502,6 @@ plugin.provisioning.RESTART_WARNING=¡Alcuerdate que les camudancies fadrán efe
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=Copiar UUID al cartafueyu
plugin.provisioning.CLIPBOARD_FAILED=Fallu al copiar UUID al cartafueyu
-plugin.provisioning.EXIT_ON_FAIL=Colar de l'aplicación si l'aprovisionamientu falla
plugin.provisioning.CREDENTIALS=Caberes credenciales d'aprovisionamientu atroxaes
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=¿De xuru quies desaniciar la contraseña d'aprovisionamientu?
plugin.provisioning.PROV_FAILED=Aprovisionamientu fallíu
@@ -1717,8 +1568,6 @@ util.dns.DNSSEC_WARNING=<html><div width="600">{0} intentó coneutase al sirvido
#plugin spellcheck
plugin.spellcheck.TITLE=Ortografía y gramática
plugin.spellcheck.MENU=Amosar ortografía y gramática
-plugin.spellcheck.LANG=Llingua
-plugin.spellcheck.EDIT_PERSONAL_DICT=Editar
plugin.spellcheck.ENABLE_SPELL_CHECK=Activar revisión ortográfica
plugin.spellcheck.dialog.FIND=Alcontrar siguiente
plugin.spellcheck.dialog.REPLACE=Trocar
diff --git a/resources/languages/resources_bg.properties b/resources/languages/resources_bg.properties
index c61c18e..4c3f380 100644
--- a/resources/languages/resources_bg.properties
+++ b/resources/languages/resources_bg.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Ðз
service.gui.ACCOUNT_REGISTRATION_WIZARD=РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ð° профил
service.gui.ACCOUNTS=Профили
service.gui.ADD=&Добави
-service.gui.ADD_ACCOUNT=Добави профил
service.gui.ADD_CONTACT=&Добави контакт
service.gui.ADD_AUTHORIZED_CONTACT=Добави {0} към ÑпиÑъка Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð¸
service.gui.ADD_CONTACT_TO_CONTACTLIST=ДобавÑне на контакта към ÑпиÑък ви Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð¸
@@ -42,20 +52,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Грешка при добавÑне на к
service.gui.ADD_CONTACT_EXIST_ERROR=Контактът {0} вече ÑъщеÑтвува във вашиÑÑ‚ ÑпиÑък Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð¸.
service.gui.ADD_CONTACT_NETWORK_ERROR=Сървърът не отговори на опита ни да добавим контакт: {0}.
service.gui.ADD_CONTACT_NOT_SUPPORTED=Грешка при добавÑне на {0}. ОперациÑта не Ñе поддържа.
-service.gui.ADD_CONTACT_IDENTIFIER=Ð’ полето по-долу въведете идентификатора на контакта, който бихте иÑкали да добавите.
-service.gui.ADD_CONTACT_WIZARD=ДобавÑне на контакт
service.gui.ADD_CONTACT_NOT_CONNECTED=ТрÑбва да Ñе Ñвържете преди да добавите контакт. ÐœÐ¾Ð»Ñ Ñвържете Ñе и опитайте отново.
service.gui.ADD_GROUP_LOCAL_ERROR=Възникна грешка при добавÑне на група {0}. Проблемът е възникнал по време на входно-изходно операциÑ.
service.gui.ADD_GROUP_EXIST_ERROR=Групата {0} е вече добавена към Ð²Ð°ÑˆÐ¸Ñ ÑпиÑък Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð¸.
service.gui.ADD_GROUP_NET_ERROR=Възникна грешка при добавÑне на група {0}. Проблемът е възникнал по време на мрежова операциÑ. Проверете мрежовите Ñи наÑтройки и опитайте отново.
service.gui.ADD_GROUP_ERROR=ÐеуÑпешно добавÑне на група: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=Името на групата не Ñ‚Ñ€Ñбва да е празно
-service.gui.ADD_GROUP=Грешка при добавÑне на група
-service.gui.ADD_SUBCONTACT=&ДобавÑне на подконтакт
service.gui.ADDRESS=ÐдреÑ
service.gui.ADMINISTRATOR=админиÑтратор
service.gui.ADVANCED=&ЕкÑпертни
-service.gui.ALL=&Ð’Ñички
service.gui.ALL_CONTACTS=&Ð’Ñички контаки
service.gui.ALTERNATE_ADDRESS=Ðлтернативен адреÑ
service.gui.APPLY=&Приложи
@@ -65,7 +70,6 @@ service.gui.AT=от
service.gui.AUTHORIZE=&Разреши
service.gui.AUTHORIZATION_ACCEPTED={0} прие молбата за легитимациÑ.
service.gui.AUTHENTICATION_FAILED=ÐеуÑпешна проверка на ÑамоличноÑтта за {0}. Въвели Ñте невалидна парола.
-service.gui.AUTHENTICATION_REQUESTED=Молба за добавÑне
service.gui.AUTHENTICATION_REQUESTED_SERVER=Ð˜Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð·Ð° Ñървър {0}.
service.gui.AUTHENTICATION_REJECTED={0} отказа молбата за легитимациÑ.
service.gui.AUTHENTICATION_WINDOW_TITLE=Проверка на ÑамоличноÑтта
@@ -107,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=Въдете Ð½Ð¾Ð²Ð¸Ñ Ð¿Ñ€Ñкор.
service.gui.CHANGE_NICKNAME_ERROR=Грешка при ÑмÑната на пÑевдонима
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=ПÑевдонимът вече ÑъщеÑтвува
service.gui.CHANGE_VIDEO_QUALITY=КачеÑтво на видеото от ÑъбеÑедника ви
-service.gui.CHAT_CONFERENCE_LABEL=Конференции
service.gui.CHAT_CONFERENCE_ITEM_LABEL=КонференциÑта на {0}
service.gui.CHAT_ROOM_ALREADY_JOINED=Вече Ñте влезли в ÑÑ‚Ð°Ñ {0}.
service.gui.CHAT_ROOM_CONFIGURATION={0} конфигуриране на ÑтаÑ
@@ -121,18 +124,14 @@ service.gui.CHAT_ROOM_USER_LEFT=напуÑна {0}
service.gui.CHAT_ROOM_USER_KICKED=беше изритан от {0}
service.gui.CHAT_ROOM_USER_QUIT=напуÑна {0}
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=Изпращането на ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ðµ забранено (глаÑÑŠÑ‚ е анулиран)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Запазва чат ÑтаÑта за бъдеща употреба
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Премахва избраната ÑÑ‚Ð°Ñ Ð¾Ñ‚ ÑпиÑъка на запазените Ñтаи
service.gui.CHAT_ROOM_NAME=Име на ÑтаÑ
service.gui.CLEAR_CUSTOM_MESSAGES=Изтрий перÑонализираните ÑтатуÑи
service.gui.ROOM_NAME=Ð¡Ñ‚Ð°Ñ Ð·Ð° разговори
-service.gui.AUTOJOIN=Ðвт. влизане
service.gui.CHANGE_PASSWORD=Промени паролата
service.gui.CHAT_ROOM_NAME_INFO=ÐœÐ¾Ð»Ñ Ð²ÑŠÐ²ÐµÐ´ÐµÑ‚Ðµ името на ÑтаÑта коÑто желаете да Ñъздадете.
service.gui.CHAT_ROOM_NOT_EXIST=Ðе уÑпÑÑ… да Ð½Ð°Ð¼ÐµÑ€Ñ ÑÑ‚Ð°Ñ {0} на Ñървър {1}. ÐœÐ¾Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐµÑ‚Ðµ дали правилно Ñте напиÑали името.
service.gui.CHAT_ROOM_NOT_CONNECTED=ТрÑбва да Ñе Ñвържете към мрежата преди да напуÑнете ÑÑ‚Ð°Ñ {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=ТрÑбва да Ñе Ñвържете преди да напуÑнете ÑтаÑта (парадокÑално, а :) ).
-service.gui.CHAT_ROOM_NOT_JOINED=ТрÑбва да Ñте в ÑтаÑта за да можете да оперирате Ñ Ð½ÐµÑ.
service.gui.CHAT_ROOM_OPTIONS=ÐаÑтройки на ÑтаÑта
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Ðужно е да Ñе региÑтрирате за да влезнете в ÑÑ‚Ð°Ñ {0}.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Ðужна е парола за ÑÑ‚Ð°Ñ {0}.
@@ -157,16 +156,13 @@ service.gui.CONNECTING=Свързване...
service.gui.CONNECTING_STATUS=Свързване
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Свързване...
service.gui.CONNECTION=Връзка
-service.gui.CONNECTION_FAILED_MSG=Връзката към Ñървър {1} е прекъÑната за потребител {0}.
service.gui.CONNECTION_EXPIRED_MSG=Ð’ момента не Ñте Ñвързани Ñ {0}.
service.gui.CONTACT_NAME=ID или номер
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY={0} не поддържа телефонните разговори.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF={0} не поддържа чат конференции.
service.gui.CONTACT_PAUSED_TYPING={0} ÑÐ¿Ñ€Ñ Ð´Ð° пише
service.gui.CONTACT_TYPING={0} пише Ñъобщение
service.gui.CONTACT_TYPING_SEND_FAILED=оп...не уÑпÑхме да предупредим {0}, че пишете
service.gui.CONTACT_INFO=&Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° контакта
-service.gui.CONTACTLIST=Контакт лиÑта
service.gui.CONTACTS=Контакти
service.gui.COPY=&Копирай
service.gui.COPY_LINK=Копирай &връзка
@@ -176,17 +172,14 @@ service.gui.CREATE_CHAT_ROOM=&Създай ÑÑ‚Ð°Ñ Ð·Ð° разговори...
service.gui.CREATE_CHAT_ROOM_ERROR=ÐеуÑпешен опит за Ñъздаване на ÑтаÑ: {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=ÐÑиÑтент по Ñъздаване на ÑÑ‚Ð°Ñ Ð·Ð° разговори
service.gui.CREATE_CONFERENCE_CALL=&Създай телефонна конференциÑ...
-service.gui.CREATE_CONFERENCE_CHAT=&Създай чат конференциÑ
service.gui.CREATE_GROUP=&Създай групa...
service.gui.CREATE_GROUP_NAME=Въведете името на групата, коÑто бихте иÑкали да Ñъздадете.
-service.gui.CREATE_FIRST_GROUP_WIZARD=СпиÑъкът ви Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð¸ не Ñъдържа групи. ÐœÐ¾Ð»Ñ Ð´Ð¾Ð±Ð°Ð²ÐµÑ‚Ðµ група от меню Файл/Добави група.
service.gui.CREATE_VIDEO_BRIDGE=Създай &видео моÑÑ‚...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Създай &видео моÑÑ‚
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Създай / приÑъедини Ñе към видео конференциÑ
service.gui.CREATE_VIDEO_CONFERENCE=Създаване на нова видео-ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ñ Ð·Ð° тази чат ÑтаÑ
service.gui.CONTACT_INFO_NOT_SUPPORTED=Контактът не поддържа уеб информациÑ
service.gui.CUT=О&трежи
-service.gui.DATE=Дата
service.gui.DELETE=Изтрий
service.gui.DENY=&Откажи
service.gui.DESKTOP_SHARING_WARNING=<b>Сигурен ли Ñте че иÑкате да Ñподелите екрана Ñи?</b> <br> Ðко натиÑнете OK оÑтаналите учаÑтници в обаждането ще могат да видÑÑ‚ екрана ви.
@@ -197,7 +190,6 @@ service.gui.DISCONNECTED_STATUS=Край на разговора
service.gui.DND_STATUS=Ðе ме безпокойте
service.gui.DO_NOT_ASK_AGAIN=Ðе ме питай повече
service.gui.DO_NOT_SHOW_AGAIN=Повече не ми показвай това Ñъобщение
-service.gui.DOWNLOAD_NOW=&Свали Ñега
service.gui.DRAG_FOR_SHARING=Довлачете тука прозорците, които иÑкате да покажете
service.gui.DURATION=продължителноÑÑ‚
service.gui.DESTROY_CHATROOM=Унищожаване на чат ÑтаÑта
@@ -218,7 +210,6 @@ service.gui.ERROR_RECEIVED_FROM=Получена грешка от {0}
service.gui.ESTIMATED_TIME=Приблизително време:
service.gui.EVENTS=СъбитиÑ
service.gui.EXIT=И&зход
-service.gui.EXTENDED_CRITERIA=Допълнителни уÑловиÑ
service.gui.GENERAL=Общи
service.gui.GENERAL_ERROR=Обща грешка
service.gui.GROUP_NAME=Име на групата
@@ -260,7 +251,6 @@ service.gui.FONT_ITALIC=КурÑив
service.gui.FONT_SIZE=Размер
service.gui.FONT_STYLE=Стил
service.gui.FONT_UNDERLINE=Подчертан
-service.gui.FROM={0} от {1}
service.gui.GRANT_OWNERSHIP=Даване на ÑобÑтвеноÑÑ‚...
service.gui.GRANT_ADMIN=Даване на админиÑтраторÑки права...
service.gui.GRANT_MODERATOR=Даване на Ñ€Ð¾Ð»Ñ Ð½Ð° модератор
@@ -286,7 +276,6 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=Сигурни ли Ñте, че иÑка
service.gui.HISTORY_REMOVE_ERROR=Грешка при изтриването на локално запазените ÑъобщениÑ.
service.gui.HOME=Домашен
service.gui.HOME_PAGE=Ðачална Ñтраница
-service.gui.HOUR=ЧаÑ
service.gui.ICE=ICE
service.gui.IDENTIFIER=Ключ
service.gui.IGNORE=&Пренебрегни
@@ -310,13 +299,10 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Покани контакти във
service.gui.INVITE_REASON=ТекÑÑ‚ на поканата
service.gui.IS_CALLING={0} Ñе обажда...
service.gui.IS_NOW={0} вече е {1}
-service.gui.JITSI_WARNING=Скоро преименувахме СИП Комуникатор и го нарекохме Жици (Jitsi).<br/>Ðко желаете да продължите да получавате извеÑÑ‚Ð¸Ñ Ð·Ð° нови верÑии ще Ñ‚Ñ€Ñбва да Ñвалите Жици Ñега.<br/><br/>СъжалÑваме ако това ви причинÑва неудобÑтво!<br/><br/>Разработчиците на Жици
-service.gui.JITSI_WARNING_TITLE=СИП Комуникатор Ñе прекръÑтва на Жици
service.gui.JOIN=&Влез
service.gui.JOIN_AS=В&лез като
service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=ПриÑъединÑване към ÑъщеÑтвуваща видео-конференциÑ
service.gui.JOIN_VIDEO=ПриÑъедини видео
-service.gui.CLOSE_CHAT_ROOM_DIALOG=&Затвори
service.gui.JOB_TITLE=ДлъжноÑÑ‚
service.gui.JOIN_CHAT_ROOM=&Влез в ÑÑ‚Ð°Ñ Ð·Ð° разговори...
service.gui.JOIN_CHAT_ROOM_TITLE=Влизане в ÑÑ‚Ð°Ñ Ð·Ð° разговори
@@ -329,7 +315,6 @@ service.gui.KICK_FAILED=ÐеуÑпешен опит за изритване
service.gui.KICK_FAILED_GENERAL_ERROR=При опит за изритване на {0} възникна грешка на Ñървъва. Опитът е неуÑпешен.
service.gui.KICK_FAILED_NOT_ALLOWED=ÐеуÑпешен опит за изритване на {0}. СобÑтвениците и админиÑтраторите на една ÑÑ‚Ð°Ñ Ð½Ðµ могат да бъдат изритвани.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=ÐÑмата правата необходими за изритването на {0}.
-service.gui.LAST=ПоÑледно
service.gui.LAST_NAME=ФамилиÑ
service.gui.LEAVE=&ÐапуÑни
service.gui.LIMIT_REACHED_FOR_IP=Имате прекалено много региÑтрации от Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ Ð²Ð¸ Ð°Ð´Ñ€ÐµÑ Ð¸ Ñървърт на {0} не разрешава отварÑнето на нови.
@@ -349,7 +334,6 @@ service.gui.MESSAGE=Съобщение
service.gui.MISSED_CALLS_TOOL_TIP=ПропуÑнати Ð¾Ð±Ð°Ð¶Ð´Ð°Ð½Ð¸Ñ Ð¾Ñ‚:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= и {0} други
service.gui.MODERATOR=модератор
-service.gui.MORE=Повече
service.gui.MORE_LABEL=Повече
service.gui.MOVE=ПремеÑти
service.gui.MOVE_SUBCONTACT=Пре&меÑти подконтакт
@@ -358,7 +342,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=Подконтактът вече Ñе нам
service.gui.MOVE_SUBCONTACT_QUESTION=Сигурни ли Ñте, че иÑкате да премеÑтите {0} в {1}?
service.gui.MOVE_TO_GROUP=Пре&меÑти в група
service.gui.MOVE_CONTACT=Пре&меÑти контакт
-service.gui.MOVE_CONTACT_ERROR=Контактът не може да бъде премеÑтен
service.gui.MSG_DELIVERY_FAILURE=ДоÑтавката на горното Ñъобщение Ñе провали
service.gui.MSG_DELIVERY_NOT_SUPPORTED=Протоколът който използвате не позволÑва ÑъобщениÑта към не включени потребители. Опитайте да Ñе Ñвържете Ñ {0} чрез друг протокол или изчакайте да Ñе включи.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Възникна грешка в програмата. Това най-вероÑтно е бъг. Ще ви бъдем благодарни ако ни уведомите: http://www.jitsi.org/index.php/Development/BugsAndIssues
@@ -372,7 +355,6 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=ТрÑбва да Ñе Ñвържете
service.gui.MULTIPLE_LOGINS=Свързали Ñте Ñе повече от веднъж Ñ ÐµÐ´Ð¸Ð½ и Ñъщ профил. Потребител {0} на Ñървър {1} ше бъде изключен.
service.gui.MY_CHAT_ROOMS=Добави чат ÑтаÑ
service.gui.MY_CHAT_ROOMS_TITLE=Добави чат ÑтаÑ
-service.gui.MUTE=Спри микрофона
service.gui.MUTUALLY_ON_HOLD_STATUS=Взаимно Ñе изчакваме
service.gui.NAME=Име
service.gui.NETWORK=Мрежа
@@ -404,7 +386,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=Временни контакти
service.gui.SD_QUALITY=Стандартно качеÑтво
service.gui.OFFLINE=Изключен
service.gui.OK=&ОК
-service.gui.OLDER_CALLS=Предишни обажданиÑ
service.gui.ONLINE=Включен
service.gui.OPEN=Отвори
service.gui.OPEN_FILE_FROM_IMAGE=Кликнете два пъти върху файла, за да го отворите.
@@ -416,7 +397,6 @@ service.gui.OPEN_ON_ACTIVITY=При активноÑÑ‚
service.gui.OPEN_ON_MESSAGE=Само на нови ÑъобщениÑ
service.gui.OPEN_ON_IMPORTANT_MESSAGE=Само на важни ÑъобщениÑ
service.gui.OR=или
-service.gui.OR_ENTER_PHONE_NUMBER=Или въведете телефонен номер тук...
service.gui.ORGANIZATION=ОрганизациÑ
service.gui.OTHER=Други
service.gui.chat.role.OWNER=СобÑтвеник
@@ -442,7 +422,6 @@ service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Enter' за предложениÑ
service.gui.PRESS_FOR_CALL_INFO=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° обаждането
service.gui.PRESS_TO_OPEN_CRM=Повече Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ñ‚ външен източник
service.gui.PREVIOUS=Ðа&зад
-service.gui.PREVIOUS_TOOLTIP=Разглеждане на по-ранни разговори
service.gui.PRINT=&Печат
service.gui.PROACTIVE_NOTIFICATION=ви пише
service.gui.PROBLEMS_ENCOUNTERED=Ðамерени Ñа проблеми
@@ -458,7 +437,6 @@ service.gui.RECONNECTION_LIMIT_EXCEEDED=ОÑъщеÑтвихте нÑколко
service.gui.RE_REQUEST_AUTHORIZATION=Ðово иÑкане на оторизациÑ
service.gui.REFERRED_STATUS=Препратен
service.gui.REJECT=&Отказ
-service.gui.REMIND_ME_LATER=Ðапомни ми по-къÑно
service.gui.REMEMBER_PASSWORD=Запомни паролата
service.gui.REMOVE=&Премахни
service.gui.REMOVE_ACCOUNT=&Изтриване на профила
@@ -484,9 +462,7 @@ service.gui.REVOKE_ADMIN=Отнеми админиÑтраторÑките прÐ
service.gui.REVOKE_MODERATOR=Отнеми модераторÑките права
service.gui.REVOKE_MEMBERSHIP=Отнеми членÑтвото
service.gui.REVOKE_VOICE=Отнеми правото на изказване
-service.gui.ROOT_GROUP=Група корен
service.gui.SAVE=&Запази
-service.gui.SAVE_AS_DEFAULT=Запиши по подразбиране
service.gui.SEARCH=&ТърÑи
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Използвайе бутона за да видите вÑички Ñтаи от Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ Ñървър и Ñ Ð±ÑƒÑ‚Ð¾Ð½Ð° Влез, изберете тази, в коÑто иÑкате да влезете.
service.gui.SEARCH_STRING_CONTACT_SOURCE=ТърÑен контакт
@@ -494,19 +470,13 @@ service.gui.SECURITY=СигурноÑÑ‚
service.gui.SELECT_ACCOUNT=Изберете потребител
service.gui.SELECT_COLOR=Изберете цвÑÑ‚
service.gui.SELECT_GROUP=Изберете група
-service.gui.SELECT_GROUP_WIZARD_MSG=СпиÑъкът по-долу Ñъдържа вÑички групи от вашата контакт лиÑта. Изберете тази, в коÑто иÑкате да добавите Ð½Ð¾Ð²Ð¸Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚.
service.gui.SELECT_NO_GROUP=Без група
-service.gui.SELECT_GROUP_WIZARD=Изберете група
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=СпиÑъкът по-долу Ñъдържа вÑички профили, които поддържат разговори Ñ Ð¿Ð¾Ð²ÐµÑ‡Ðµ учаÑтници. Изберете този, в който желаете да Ñъздадете нова ÑтаÑ.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=СпиÑъкът по-долу Ñъдържа вÑички региÑтрирани профили. Изберете този, който желаете да ползвате за разговори Ñ Ð½Ð¾Ð²Ð¸Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚.
-service.gui.SELECT_PROVIDERS_WIZARD=Изберете профил(и)
service.gui.SELECT_VIDEO_CONFERENCE=Избери видео конференциÑ
service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Изберете чат ÑÑ‚Ð°Ñ Ð¾Ñ‚ ÑпиÑъка и натиÑнете ОК да Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ‚Ðµ.
service.gui.SEND=&Изпрати
service.gui.SEND_FILE=Изпрати &файл
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=ÐÑма Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° този контакт.
service.gui.SEND_MESSAGE=&Изпрати Ñъобщение
-service.gui.SEND_AS_SMS=Изпратете като SMS
service.gui.SEND_PRIVATE_MESSAGE=Изпрати поверително Ñъобщение
service.gui.SEND_SMS=И&зпрати SMS
service.gui.SEND_SMS_DETAILS=Ðе забравÑйте да въведете и Ð¼ÐµÐ¶Ð´ÑƒÐ½Ð°Ñ€Ð¾Ð´Ð½Ð¸Ñ Ñ‚ÐµÐ»ÐµÑ„Ð¾Ð½ÐµÐ½ код. За българÑки номера например започнете Ñ +359
@@ -545,7 +515,6 @@ service.gui.STREET=Улица
service.gui.SUBJECT=Тема
service.gui.SUMMARY=Обобщение
service.gui.TELEPHONY=ТелефониÑ
-service.gui.TODAY=ДнеÑ
service.gui.TOOLS=&ИнÑтрументи
service.gui.TRANSFER=ТранÑфер
service.gui.TO=Ðа:
@@ -555,7 +524,6 @@ service.gui.TRANSFER_CALL_TO=Прехвърли към:
service.gui.TRANSPARENCY_NOT_ENABLED=ПрозрачноÑтта не Ñе поддържа от текущата ви конфигурациÑ.
service.gui.TYPE_YOUR_REQUEST=Въведете молбата Ñи тук
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Ðе уÑпÑхме да променим видео качеÑтвото на обаждането.
-service.gui.UNMUTE=Ðктивирай микрофона
service.gui.USER_IDENTIFIER=Ðомер:
service.gui.USER_EXISTS_ERROR=ПотребителÑÑ‚ вече ÑъщеÑтвува на избраната мрежа. ÐœÐ¾Ð»Ñ Ð¸Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ друг потребител или друга мрежа.
service.gui.USERNAME_NULL=ÐœÐ¾Ð»Ñ Ð²ÑŠÐ²ÐµÐ´ÐµÑ‚Ðµ име и парола.
@@ -568,7 +536,6 @@ service.gui.USE_PROVISIONING=Конфигуриране от мрежата (ЗÐ
service.gui.VALUE=СтойноÑÑ‚
service.gui.VIDEO_CALL=&Видео обаждане
service.gui.VIA=през
-service.gui.VIA_SMS=По СМС
service.gui.VIEW=&Преглед
service.gui.VIEW_HISTORY=Преглед на &иÑториÑта
service.gui.VIEW_SMILEYS=Показвай &уÑмивките
@@ -588,9 +555,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=ÐаглаÑÑване Ñилата на зÐ
service.gui.WAITING_AUTHORIZATION=Чакаме на оторизациÑ
service.gui.WARNING=Предупреждение
service.gui.YES=Да
-service.gui.YESTERDAY=Вчера
-service.gui.EXISTING_ACCOUNT_ERROR=ВъведениÑÑ‚ профил е вече инÑталиран.
-service.gui.NEW_MAIL=<b>Имате един нов мейл!</b><br/><b>От:</b> {0} {1} <br/><b>Заглавие:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=Получихте ново пиÑмо във вашата {0} <a href="{1}">кутиÑ</a>:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=Получихте {2} нови пиÑма във вашата {0} <a href="{1}">кутиÑ</a>:<br/>
service.gui.NEW_GMAIL_FOOTER=ОÑтава оше един непрочетен разговор във вашата <a href="{0}">кутиÑ</a>.<br/>
@@ -614,7 +578,6 @@ service.gui.SECURITY_ERROR=Грешка в ÑигурноÑтта
service.gui.SPEED=СкороÑÑ‚:
service.gui.SILENT_MEMBER=тих член
service.gui.NON_SECURE_CONNECTION=Ðевъзможно е да Ñе уÑтанови Ñигурна връзка за профил {0}. Ðко иÑкате да Ñе Ñвържете по незащитен начин, Ð¼Ð¾Ð»Ñ Ð¾Ñ‚Ð¼ÐµÑ‚Ð½ÐµÑ‚Ðµ полето "Разреши незащитено Ñвързване" в наÑтройките на профила Ñи.
-service.gui.UPDATE=ОбновÑване
service.gui.MOBILE_PHONE=Мобилен
service.gui.VIDEO_PHONE=Видео
service.gui.WORK_PHONE=Работен
@@ -649,12 +612,10 @@ service.gui.callinfo.CALL_INFORMATION=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° обаждане
service.gui.callinfo.CALL_IDENTITY=СамоличноÑÑ‚
service.gui.callinfo.PEER_COUNT=Брой учаÑтници
service.gui.callinfo.IS_CONFERENCE_FOCUS=Конферентен фокуÑ
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Ðктивирано криптиране
service.gui.callinfo.CALL_TRANSPORT=Сигнализационен транÑпорт
service.gui.callinfo.CALL_DURATION=ПродължителноÑÑ‚
service.gui.callinfo.TLS_PROTOCOL=TLS протокол
service.gui.callinfo.TLS_CIPHER_SUITE=TLS шифър
-service.gui.callinfo.TLS_SERVER_CERTIFICATE_CHAIN=верига на ÑÑŠÑ€Ð²ÑŠÑ€Ð½Ð¸Ñ TLS Ñертификат
service.gui.callinfo.TLS_CERTIFICATE_CONTENT=Следва Ñъдържанието на ÑÑŠÑ€Ð²ÑŠÑ€Ð½Ð¸Ñ TLS Ñертификат:
service.gui.callinfo.VIEW_CERTIFICATE=Преглед на Ñертификат
service.gui.callinfo.CODEC=Кодек / ЧеÑтота
@@ -664,7 +625,6 @@ service.gui.callinfo.AUDIO_INFO=Ðудио инфо
service.gui.callinfo.VIDEO_INFO=Видео инфо
service.gui.callinfo.LOCAL_IP=Локален IP / Порт
service.gui.callinfo.REMOTE_IP=ОтÑрещен IP / Порт
-service.gui.callinfo.BANDWITH=Дебит
service.gui.callinfo.LOSS_RATE=% Загуба
service.gui.callinfo.RTT=RTT
service.gui.callinfo.JITTER=Джитър
@@ -674,10 +634,13 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=ОбмÑна на ключове
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=ICE кандидати
service.gui.callinfo.ICE_STATE=ICE ÑÑŠÑтоÑние
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=Събиране на кандидати
service.gui.callinfo.ICE_STATE.RUNNING=Connectivity checks
service.gui.callinfo.ICE_STATE.COMPLETED=Завършен
service.gui.callinfo.ICE_STATE.FAILED=Провал
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=Локален IP / Порт
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=ПродължителноÑÑ‚ на жътвата
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=Локален пренаÑочван IP / Порт
@@ -698,11 +661,12 @@ service.gui.ALWAYS_TRUST=Занапред винаги Ñе доверÑвай Ð
service.gui.CERT_DIALOG_TITLE=Проверка на Ñертификата
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} не можа да провери ÑамоличноÑтта на Ñървър<br><b>{1}</b>.<br><br>.Сървърът използва непознат или недоверен Ñертификат, което означава, че ÑамоличноÑтта на Ñървъра не може да бъде автоматично потвърдена.<br><br> Желаете ли да Ñе Ñвържете въпреки това?<br>За повече Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ‚Ð¸Ñнете "Покажи Ñертификата"</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0} не можа да провери ÑамоличноÑтта на Ñървъра.<br><br>Сървърът използва непознат или недоверен Ñертификат, което означава, че ÑамоличноÑтта на Ñървъра не може да бъде автоматично потвърдена. Желаете ли да Ñе Ñвържете въпреки това?<br><br>За повече Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ‚Ð¸Ñнете "Покажи Ñертификата"</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} не можа да провери ÑамоличноÑтта на клиента {1}:{2}.<br><br>СъбеÑедникът ви използва непознат или недоверен Ñертификат, което означава, че ÑамоличноÑтта му не може да бъде автоматично потвърдена. Желаете ли да Ñе Ñвържете въпреки това?<br><br>За повече Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ‚Ð¸Ñнете "Покажи Ñертификата"</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} не можа да провери ÑамоличноÑтта на ÑъбеÑедника {1}.<br><br> Сертификатът е недоверен или непознат , което пречи проверката да бъде<br> извършена автоматично. Желаете ли да Ñе Ñвържете въпреки това?<br><br> За повече Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ‚Ð¸Ñнете "Покажи Ñертификата".</html>
service.gui.CONTINUE_ANYWAY=Продължавам въпреки това
service.gui.CERT_INFO_CHAIN=Верига от Ñертификати:
service.gui.CERT_INFO_ISSUED_TO=Издаден за
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Обичайно име:
service.gui.CERT_INFO_O=ОрганизациÑ:
service.gui.CERT_INFO_C=Държава:
@@ -721,12 +685,10 @@ service.gui.CERT_INFO_SIGN_ALG=Ðлгоритъм на подпиÑа:
service.gui.CERT_INFO_PUB_KEY_INFO=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° публичен ключ
service.gui.CERT_INFO_ALG=Ðлгоритъм:
service.gui.CERT_INFO_PUB_KEY=Публичен ключ:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} байтове: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} битове
service.gui.CERT_INFO_EXP=ЕкÑпонента:
service.gui.CERT_INFO_KEY_SIZE=Размер на ключа:
service.gui.CERT_INFO_SIGN=ПодпиÑ:
-service.gui.CONTINUE=Продължи
service.gui.SHOW_CERT=Покажи Ñертификата
service.gui.HIDE_CERT=Скрий Ñертификата
@@ -749,12 +711,9 @@ service.gui.security.SECURE_AUDIO=Защитено аудио
service.gui.security.AUDIO_NOT_SECURED=Ðезащитено аудио
service.gui.security.SECURE_VIDEO=Защитено видео
service.gui.security.VIDEO_NOT_SECURED=Ðезащитено видео
-service.gui.security.NO_VIDEO=ÐÑма видео
-service.gui.security.CIPHER=Шифър: {0}
service.gui.security.CALL_SECURED_TOOLTIP=Защитено обаждане. За повече Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ‚Ð¸Ñнете тук.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Ðезащитено обаждане.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=ÐатиÑнете тук за да Ñравните тайната парола Ñ Ð¿Ð°Ñ€Ñ‚Ð½ÑŒÐ¾Ñ€Ð° Ñи.
-service.gui.security.COMPARE_WITH_PARTNER=Сравнете ÑÑŠÑ ÑъбеÑедника Ñи и натиÑнете катинарчето ако Ñъвпадат.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Сравнете ÑÑŠÑ ÑъбеÑедника Ñи:
service.gui.security.STRING_COMPARED=Паролата е Ñравнена!
@@ -772,20 +731,14 @@ service.gui.avatar.imagepicker.CLICK=ÐатиÑни и Ñе уÑмихни
service.gui.avatar.imagepicker.IMAGE_FILES=Файлове
service.gui.avatar.imagepicker.IMAGE_PICKER=Картинка
service.gui.avatar.imagepicker.IMAGE_SIZE=Размер на картинката
-service.gui.avatar.imagepicker.INITIALIZING=Инициализиране
service.gui.avatar.imagepicker.RESET=РеинициализациÑ
service.gui.avatar.imagepicker.SET=Сложи
service.gui.avatar.imagepicker.TAKE_PHOTO=Ðаправи Ñнимка
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Проблем Ñ ÐºÐ°Ð¼ÐµÑ€ÐºÐ°Ñ‚Ð°
service.gui.security.encryption.required=ИзиÑква Ñе криптиране!
service.protocol.ICE_FAILED=Ðе може да Ñе оÑъщеÑтви връзка (неуÑпешен ICE, не е намерено реле)
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
impl.protocol.sip.XCAP_ERROR_TITLE=Грешка при ÑъхранÑване на СИП ÑпиÑъка Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð¸
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=Ðе можем да прочетем реÑÑƒÑ€Ñ {0}. За {1}
@@ -815,9 +768,7 @@ impl.ldap.QUERY_CUSTOM=ПерÑонализиране на заÑвката
impl.ldap.QUERY_CUSTOM_HINT=Използвайте <query> като замеÑтител на Ñ‚ÑŠÑ€ÑÐµÐ½Ð¸Ñ Ñ‚ÐµÐºÑÑ‚.
impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=Ðвтоматично разширÑване на заÑвката до вÑички подобни резултати
impl.ldap.QUERY_PHOTO_INLINE=ИзтеглÑне на Ñнимката заедно Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¸Ñ‚Ðµ
-impl.ldap.NEW=&Ðов
impl.ldap.EDIT=промени
-impl.ldap.REMOVE=Премахни
impl.ldap.ENABLED=Ðктивиран
impl.ldap.SERVER_NAME=Име
impl.ldap.SERVER_NAME_EXAMPLE=МоÑÑ‚ LDAP указател
@@ -850,6 +801,10 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=homePhone
impl.ldap.PHONE_PREFIX=Телефонен префикÑ
impl.ldap.PHONE_PREFIX_EXAMPLE=Пр.: 00
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=ÐдреÑник
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=Ðктивирай Ñ‚ÑŠÑ€Ñенето в адреÑника на Mac OS X
@@ -864,9 +819,7 @@ plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT=Outlook приложение п
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Google Контакти
-impl.googlecontacts.NEW=Ðов
impl.googlecontacts.EDIT=промени
-impl.googlecontacts.REMOVE=Премахни
impl.googlecontacts.ENABLED=Ðктивиран
impl.googlecontacts.ACCOUNT_NAME=Име на профил
impl.googlecontacts.SAVE=Запази
@@ -905,11 +858,8 @@ plugin.accountinfo.ORGANIZATION=ОрганизациÑ:
plugin.accountinfo.JOB_TITLE=ДлъжноÑÑ‚:
plugin.accountinfo.ABOUT_ME=За мен:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
-plugin.accountinfo.USER_PICTURES=Снимки:
plugin.accountinfo.GLOBAL_ICON=Използвай глобална иконка
plugin.accountinfo.LOCAL_ICON=Използвай тази иконка:
-plugin.accountinfo.CHANGE=Промени
-plugin.accountinfo.ONLY_MESSAGE=Само ÑъобщениÑ
# connection info
plugin.connectioninfo.TITLE=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° връзката
@@ -929,49 +879,12 @@ plugin.aimaccregwizz.USERNAME=ÐИМ потребилÑко име:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=ПотребителÑко име и парола
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=РегиÑтриране на нов профил
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Ðко нÑмата профил при ÐИМ, натиÑнете тук за да Ñе региÑтрирате.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Използвай ръчни наÑтройки
# branding
plugin.branding.ABOUT_WINDOW_TITLE=ОтноÑно {0}
plugin.branding.LOGO_MESSAGE=Ð¢ÐµÐ»ÐµÑ„Ð¾Ð½Ð¸Ñ Ð¸ ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñ Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½ код
-plugin.branding.LOADING=Зареждане
plugin.branding.ABOUT_MENU_ENTRY=ОтноÑно
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>The {1} е в Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð½Ð° интензивна разработка. ВерÑиÑта коÑто ползвате е екÑпериментална и е ВЪЗМОЖÐО ДРÐЕ РÐБОТИ както бихте очаквали. ÐœÐ¾Ð»Ñ Ð¾Ð±ÑŠÑ€Ð½ÐµÑ‚Ðµ Ñе към {2} за повече информациÑ.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 Copyright <b>jitsi.org</b>. Ð’Ñички права запазени. ПоÑетете <a href="http://jitsi.org">http://jitsi.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}>The <b>Жици</b> Ñе разпроÑтранÑва под лиценз LGPL (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=Речници
-plugin.dictaccregwizz.ANY_DICTIONARY=Ð’Ñички речници
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Ð’Ñички речници от {0}
-plugin.dictaccregwizz.FIRST_MATCH=Първи резултат
-plugin.dictaccregwizz.NO_MATCH=ÐÑма резултати
-plugin.dictaccregwizz.MATCH_RESULT=Ðе Ñа намерени дефиниции за "{0}", може би имахте предвид:\n
-plugin.dictaccregwizz.INVALID_DATABASE=Ð¢ÐµÐºÑƒÑ‰Ð¸Ñ Ñ€ÐµÑ‡Ð½Ð¸Ðº "{0}" вече не ÑъщеÑтвува на Ñървъра.
-plugin.dictaccregwizz.INVALID_STRATEGY=Текущата ÑÑ‚Ñ€Ð°Ñ‚ÐµÐ³Ð¸Ñ Ð½Ðµ Ñе поддържа от Ñървъра.
-plugin.dictaccregwizz.PROTOCOL_NAME=Речник
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=Протокол за доÑтъп до он-лайн речници
-plugin.dictaccregwizz.HOST=ÐдреÑ
-plugin.dictaccregwizz.SERVER_INFO=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ñ‚ Ñървъра
-plugin.dictaccregwizz.STRATEGY_SELECTION=Избор на ÑтратегиÑ
-plugin.dictaccregwizz.STRATEGY_LIST=СпиÑък ÑÑŠÑ Ñтратегиите:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Стратегии на Ñ‚ÑŠÑ€Ñене
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=Стратегиите Ñе използват при Ñ‚ÑŠÑ€Ñене на подобни думи. Това е необходимо когато зададена от Ð²Ð°Ñ Ð´ÑƒÐ¼Ð° не е намерена във вида, в който е зададена и е нужно да Ñе разшири Ñ‚ÑŠÑ€Ñенето. Ð¡Ñ‚Ñ€Ð°Ñ‚ÐµÐ³Ð¸Ñ "ПрефикÑ" например ще Ñ‚ÑŠÑ€Ñи Ñред вÑички думи, които започват ÑÑŠÑ Ð·Ð°Ð´Ð°Ð´ÐµÐ½Ð°Ñ‚Ð° от Ð²Ð°Ñ Ð´ÑƒÐ¼Ð°.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° Речник профила ви
-plugin.dictaccregwizz.FIRST_ACCOUNT=Този аÑиÑтент ще Ñъздаде профил Ñвързан към dict.org.\n\nÐ’ поÑледÑтвие ще можете да добавите нови профили и Ñървъри. Попълнете полето "ÐдреÑ" Ñ Ñ€ÐµÑ‡Ð½Ð¸ÐºÐ° който иÑкате да добавите.
-plugin.dictaccregwizz.THREAD_CONNECT=Свъзване към Ñървъра
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=ÐеуÑпешен опит за Ñвързване. Сървърът не ÑъщеÑтвува или не поддържа протокол Речник
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=ИзтеглÑне на Ñтратегиите
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Ðе Ñа намерени Ñтратегии на Ñървъра
-plugin.dictaccregwizz.POPULATE_LIST=Зареждане на ÑпиÑъка
-plugin.dictaccregwizz.CLOSING_CONNECTION=ЗатварÑне на връзката
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Преди да можете да използвате ФейÑбук Чат, Ñ‚Ñ€Ñбва да Ñъздадете "ПотребителÑко име" (Username) <br>чрез вашата ФейÑбук Ñтраница ("Account Settings").</a><br><br>ÐœÐ¾Ð»Ñ Ð¸Ð¼Ð°Ð¹Ñ‚Ðµ предвид,че Ñлед като Ñъздадете ПотребителÑкото Ñи име ще Ñ‚Ñ€Ñбва да излезате от Ñтраницата. Ð’ нÑкой Ñлучаи е възможно да Ñе наложи да изчакате.</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=ФейÑбук чат протокол
-plugin.facebookaccregwizz.PROTOCOL_NAME=ФейÑбук
-plugin.facebookaccregwizz.USERNAME=ПотребителÑко име:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=ПотребителÑко име и парола
+
# generalconfig
plugin.generalconfig.AUTO_START=Ðвтоматично Ñтартиране на {0} Ñлед включване на компютъра
@@ -982,9 +895,6 @@ plugin.generalconfig.SHOW_HISTORY=Покажи
plugin.generalconfig.HISTORY_SIZE=Скорошни ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð² нови разговори
plugin.generalconfig.SEND_MESSAGES_WITH=Изпращане на ÑъобщениÑта Ñ:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=ОтварÑне на чат прозореца на преден план
-plugin.generalconfig.ERROR_PERMISSION=ÐÑмате привилегиите нужни за премахването на автоматичното Ñтартиране
-plugin.generalconfig.TRANSPARENCY=ПрозрачноÑÑ‚
-plugin.generalconfig.ENABLE_TRANSPARENCY=Ðктивиране на прозрачноÑтта
plugin.generalconfig.DEFAULT_LANGUAGE=Език
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Промените ви ще бъдат отчетени Ñлед реÑтартиране на приложението.
plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0}% преведени
@@ -1065,13 +975,10 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Коментар
plugin.jabberaccregwizz.RESOURCE=РеÑурÑ
plugin.jabberaccregwizz.AUTORESOURCE=Ðвтоматично генериране на реÑурÑ
plugin.jabberaccregwizz.PRIORITY=Приоритет
-plugin.jabberaccregwizz.XMPP_ERROR=XMPP грешка
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Ðепозната XMPP грешка ({0}). Проверете, че името на Ñървъра е правилно.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Паролата ви не ÑъответÑтва.
plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Изрично въвеждане на Ñървърни параметри
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Разширени наÑтройки
plugin.jabberaccregwizz.USE_ICE=Използване на ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=Използване на ICE и Jingle от Google (теÑтово)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=Ðвтоматично откриване на STUN и TURN Ñървъри
plugin.jabberaccregwizz.SUPPORT_TURN=Поддържа TURN
plugin.jabberaccregwizz.TURN_USERNAME=TURN потребителÑко име
@@ -1099,11 +1006,8 @@ plugin.jabberaccregwizz.DISABLE_CARBON=Изключване на копие на
plugin.jabberaccregwizz.DTMF_AUTO=Ðвтоматично: Избор между RTP и Inband
plugin.jabberaccregwizz.SERVER_OPTIONS=ÐаÑтройки на Ñървъра
plugin.jabberaccregwizz.CHANGE_PASSWORD=Смени паролата на Ñметката
-plugin.jabberaccregwizz.NEW_PASSWORD=Ðова парола
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Потвърждаване на паролата
plugin.jabberaccregwizz.PORT_FIELD_INVALID=ÐœÐ¾Ð»Ñ Ð²ÑŠÐ²ÐµÐ´ÐµÑ‚Ðµ валиден номер на порт за да продължите.
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=Сметката Ñ‚Ñ€Ñбва да е включена, за да промените паролата.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=Полето за парола е празно.
plugin.jabberaccregwizz.TLS_REQUIRED=КонекциÑта не използва TLS, ÑмÑната на паролата нÑма да Ñе оÑъщеÑтви.
plugin.jabberaccregwizz.PASSWORD_CHANGED=Паролата беше Ñменена уÑпешно
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=ВашиÑÑ‚ XMPP Ñървър не позволÑва ÑмÑна на паролата.
@@ -1117,21 +1021,6 @@ plugin.jabberaccregwizz.RESET=РеинициализациÑ
plugin.jabberaccregwizz.RESET_DESCRIPTION=Реинициализирай глобалните наÑтройки
plugin.jabberaccregwizz.DISABLE_JINGLE=Изключи Jingle (аудио и видео разговори Ñ XMPP)
-# mailbox
-plugin.mailbox.OUTGOING=ИзходÑщо Ñъобщение
-plugin.mailbox.INCOMING=ВходÑщи ÑъобщениÑ:
-plugin.mailbox.WAIT_TIME=ЗабавÑне преди активиране на глаÑовата поща
-plugin.mailbox.MAX_MESSAGE_TIME=МакÑимална продължителноÑÑ‚ на ÑъобщениÑта
-plugin.mailbox.CONFIRM=Потвърди
-plugin.mailbox.DEFAULTS=По подразбиране
-plugin.mailbox.MAILBOX=ГлаÑова поща
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Протокол за връзка Ñ MSN уÑлугата
-plugin.msnaccregwizz.USERNAME=Е-мейл:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=Име и парола
-
# plugin manager
plugin.pluginmanager.INSTALL=ИнÑталиране
plugin.pluginmanager.UNINSTALL=ДезинÑталациÑ
@@ -1160,7 +1049,6 @@ plugin.sipaccregwizz.SERVER_PORT=Порт на Ñървъра
plugin.sipaccregwizz.PROXY=ПрокÑи
plugin.sipaccregwizz.PROXY_PORT=Порт за прокÑито
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Предпочитан транÑпортен протокол
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Разширени наÑтройки
plugin.sipaccregwizz.PROXY_OPTIONS=ÐаÑтройки на прокÑито
plugin.sipaccregwizz.PROXY_AUTO=Ðвтоматично наÑтройване на прокÑито
plugin.sipaccregwizz.ENABLE_PRESENCE=Ðктивирай чат и ÑтатуÑи на приÑÑŠÑтвие (SIMPLE)
@@ -1180,8 +1068,6 @@ plugin.sipaccregwizz.DTMF_AUTO=Ðвтоматично: Избор между RTP
plugin.sipaccregwizz.DTMF_RTP=RTP ( RFC2833 / RFC 4733 )
plugin.sipaccregwizz.DTMF_SIP_INFO=SIP INFO
plugin.sipaccregwizz.DTMF_INBAND=Inband (в аудио потока)
-plugin.sipaccregwizz.REGISTER=РегиÑтрационни ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ (REGISTER)
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Изрично задаване на Ñървърни наÑтройки
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Ðктивирай поддръжката за кодирани разговори
plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=ОбÑвÑвай ZRTP поддръжката в ÑÐ¸Ð³Ð½Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»
plugin.sipaccregwizz.AUTH_NAME=Име за оторизациÑ
@@ -1202,10 +1088,10 @@ plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=ÐÐ´Ñ€ÐµÑ Ð·Ð° проверка на Ð
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Паролата ви не ÑъответÑтва.
plugin.sipaccregwizz.NO_CERTIFICATE=<none> (използване на регулÑрен израз)
plugin.sipaccregwizz.SAVP_OPTION=ОбÑвÑване на RTP/SAVP
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=Изключено (обÑвÑване Ñамо на RTP/AVP)
plugin.sipaccregwizz.SAVP_OPTION_1=Задължително (предлагане и приемане Ñамо на RTP/SAVP)
plugin.sipaccregwizz.SAVP_OPTION_2=Ðезадължително (предлагане на 1. RTP/SAVP и 2. RTP/AVP)
-plugin.sipaccregwizz.ENABLE_SDES_ATTRIBUTE=Ðктивиране на S-Descriptor (Ñъщо извеÑтно като SDES или SRTP)
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=Избери активните протоколи за криптиране и Ñ‚ÐµÑ…Ð½Ð¸Ñ Ð¿Ñ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚ (най-Ð¿Ñ€ÐµÐ´Ð¿Ð¾Ñ‡Ð¸Ñ‚Ð°Ð½Ð¸Ñ Ð½Ð°Ð¹-отгоре)
plugin.sipaccregwizz.CIPHER_SUITES=Ðктивирани шифри:
plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>{0} ще Ñе опита автоматично да защити вÑичките ви разговори ÑÑŠÑ ZRTP и ще ви уведоми звуково и визуално при уÑтановÑването на Ñигурна връзка. Препоръчваме ви да променÑте наÑтройките по-долу Ñамо ако знаете какво точно правите.</div></html>
@@ -1219,15 +1105,6 @@ plugin.skinmanager.DEFAULT_SKIN=Скин по подразбиране
plugin.skinmanager.ADD_NEW_SKIN=ДобавÑне на нов Ñкин ...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=Скин по подразбиране
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=Модул за Ñвързване към SSH машини
-plugin.sshaccregwizz.USERNAME=Потребител:
-plugin.sshaccregwizz.IDENTITY_FILE=Файл ÑÑŠÑ ÑамоличноÑÑ‚:
-plugin.sshaccregwizz.KNOWN_HOSTS=Познати машини:
-plugin.sshaccregwizz.OPTIONAL=По избор
-plugin.sshaccregwizz.ACCOUNT_DETAILS=ÐаÑтройки на профила
-
# status update
plugin.autoaway.AUTO_STATUS=Ðвтоматично преминаване в режим Далече
plugin.autoaway.ENABLE_CHANGE_STATUS=ПромÑна на ÑтатуÑа докато Ñте далече
@@ -1275,22 +1152,6 @@ plugin.whiteboard.DESELECT=Отмени избор
plugin.whiteboard.DELETE=Изтрий
plugin.whiteboard.PROPERTIES=СвойÑтва
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Протокол за чат на Yahoo!
-plugin.yahooaccregwizz.USERNAME=Потребител:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=Име и парола:
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=Протокол Zeroconf (Бонжур)
-plugin.zeroaccregwizz.FIRST_NAME=Име:
-plugin.zeroaccregwizz.LAST_NAME=ФамилиÑ:
-plugin.zeroaccregwizz.EMAIL=Е-мейл:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=Запазване на бонжур контактите?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=Име и парола
-plugin.zeroaccregwizz.USERID=Потребител
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Протокол за връзка Ñ ÑƒÑлугата Гугъл Толк
@@ -1304,19 +1165,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, Портал за ИнтÐ
plugin.iptelaccregwizz.USERNAME=Потребител
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð² iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=Интернет Ñ‚ÐµÐ»ÐµÑ„Ð¾Ð½Ð¸Ñ Ð¸ чат
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Потребител
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Ðапишете отново
plugin.sip2sipaccregwizz.EMAIL=ÐÐ´Ñ€ÐµÑ Ð½Ð° ел. поща
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=За помощ по тази уÑлуга отидете на <br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>Ð•Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¸Ñ Ð°Ð´Ñ€ÐµÑ Ñе използва при получаване на глаÑова поща, <br>пропуÑнати Ð¿Ð¾Ð²Ð¸ÐºÐ²Ð°Ð½Ð¸Ñ Ð¸ възÑтановÑване на загубена парола</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>За помощ по тази уÑлуга отидете на <a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=СъщеÑтвуващ sip2sip.info потребител
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Създайте безплатно нов sip2sip.info потребител
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=Интернет Ñ‚ÐµÐ»ÐµÑ„Ð¾Ð½Ð¸Ñ Ð¸ чат
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=За помощ по тази уÑлуга отидете на <br>http://ippi.fr
@@ -1325,6 +1178,7 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=СъщеÑтвуващ ippi профил
plugin.ippiaccregwizz.CREATE_ACCOUNT=Създаване на безплатен ippi профил
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=ЗатварÑне на чат прозореца
plugin.keybindings.CHAT_COPY=&Копирай
plugin.keybindings.CHAT_CUT=О&трежи
@@ -1347,10 +1201,10 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=Име
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=ОÑновна комбинациÑ
plugin.keybindings.globalchooser.SHORTCUT_SECOND=Втора комбинациÑ
plugin.keybindings.globalchooser.PRESS_BTN=ÐатиÑнете за да наÑтроите
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=Изчакване
plugin.keybindings.globalchooser.PUSH_TO_TALK=ÐатиÑни за да говориш (режим радио ÑтанциÑ)
plugin.keybindings.globalchooser.ENABLE_SPECIAL=ЗаÑичане на Ñпециални клавиши
plugin.keybindings.PLUGIN_NAME=Клавишни комбинации
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Чат
plugin.keybindings.MAIN=ОÑновни
plugin.keybindings.GLOBAL=Глобални комбинации
@@ -1378,6 +1232,7 @@ plugin.notificationconfig.tableheader.SOUND=Възпроизвеждане на
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=Възпроизвеждане на звук през уÑтройÑтвото за playback
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=Възпроизвеждане на звук през говорителите
plugin.notificationconfig.tableheader.DESCRIPTION=ОпиÑание на Ñъбитие
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=ВходÑщо обаждане
plugin.notificationconfig.event.SecurityMessage=СигурноÑÑ‚
plugin.notificationconfig.event.IncomingFile=ВходÑщ файл
@@ -1479,6 +1334,7 @@ impl.neomedia.configform.VIDEO=Видео
impl.neomedia.configform.H264=H.264
impl.neomedia.configform.H264.defaultIntraRefresh=Периодично вътрешно опреÑнÑване
impl.neomedia.configform.H264.defaultProfile=Подразбиращ Ñе профил на кодиране:
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=Базов (Baseline)
impl.neomedia.configform.H264.defaultProfile.high=ВиÑококачеÑтвен (High)
impl.neomedia.configform.H264.defaultProfile.main=Главен (Main)
@@ -1509,7 +1365,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=ÐаÑтоÑща пароÐ
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Въведете нова парола:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Въведете отново:
plugin.securityconfig.masterpassword.MP_TITLE=Главна парола
-plugin.securityconfig.masterpassword.MP_NOT_SET=(невъведена)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=Въведохте грешна главна парола. Опитайте отново!
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=Грешна главна парола!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=ÐеуÑпешна ÑмÑна на паролата
@@ -1621,7 +1476,6 @@ plugin.globalproxy.PROXY_PORT=ПрокÑи порт
plugin.globalproxy.PROXY_USERNAME=Потребител за прокÑито
plugin.globalproxy.PROXY_PASSWORD=Парола за прокÑито
plugin.globalproxy.DESCRIPTION={0} ще използва прокÑи наÑтройките за вÑички мрежи към които Ñе Ñвързва отÑега нататък.\nПоддръжката на прокÑи Ñървъри в момента е екÑпериментална. За Ñправки таблицата по-долу:
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>JABBER</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
plugin.globalproxy.FWD_DNS=ПоÑредничи Ñъщо и DNS
plugin.globalproxy.FWD_DNS_NOTE=Полезно Ñ Ð¢Ð¾Ñ€. Помага за избÑгване на DNS утечки чрез препредаване на Ñ†ÐµÐ»Ð¸Ñ DNS трафик към Тор прокÑито. ИзиÑква реÑтарт.
@@ -1659,7 +1513,6 @@ plugin.provisioning.RESTART_WARNING=Промените ви ще Ñе отраз
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=Копиране на ÑƒÐ½Ð¸ÐºÐ°Ð»Ð½Ð¸Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€
plugin.provisioning.CLIPBOARD_FAILED=Грешка при копирането
-plugin.provisioning.EXIT_ON_FAIL=Излезте от приложението ако мрежовото наÑтройване Ñе провали
plugin.provisioning.CREDENTIALS=ПоÑледно запаметена парола за наÑтройването
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=Сигурни ли Ñте, че иÑкате да изтриете паролата за мрежово наÑтройване?
plugin.provisioning.PROV_FAILED=Захранването пропадна
@@ -1726,8 +1579,6 @@ util.dns.DNSSEC_WARNING=<html><div width="600">{0} Ñе опита да Ñе вÑ
#plugin spellcheck
plugin.spellcheck.TITLE=ÐŸÑ€Ð°Ð²Ð¾Ð¿Ð¸Ñ Ð¸ граматика
plugin.spellcheck.MENU=Покажи правопиÑа и граматиката
-plugin.spellcheck.LANG=Език
-plugin.spellcheck.EDIT_PERSONAL_DICT=Редактирай
plugin.spellcheck.ENABLE_SPELL_CHECK=Ðктивирай проверката на правопиÑа
plugin.spellcheck.dialog.FIND=Ðамери отново
plugin.spellcheck.dialog.REPLACE=Замени
diff --git a/resources/languages/resources_cs.properties b/resources/languages/resources_cs.properties
index 1a3390f..b2c4347 100644
--- a/resources/languages/resources_cs.properties
+++ b/resources/languages/resources_cs.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Já
service.gui.ACCOUNT_REGISTRATION_WIZARD=Průvodce registrací úÄtu
service.gui.ACCOUNTS=ÚÄty
service.gui.ADD=&Přidat
-service.gui.ADD_ACCOUNT=PÅ™idat úÄet
service.gui.ADD_CONTACT=&Přidat kontakt
service.gui.ADD_AUTHORIZED_CONTACT=Přidat {0} do seznamu kontaktů
service.gui.ADD_CONTACT_TO=&Přidat kontakt do
@@ -41,20 +51,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Chyba při přidávání kontaktu
service.gui.ADD_CONTACT_EXIST_ERROR=Kontakt {0} již existuje ve vašem seznamu kontaktů.
service.gui.ADD_CONTACT_NETWORK_ERROR=Server neodpověděl na požadavek o přidání kontaktu s id: {0}.
service.gui.ADD_CONTACT_NOT_SUPPORTED=Neúspěšné přidání kontaktu s id: {0}. Operace není podporována.
-service.gui.ADD_CONTACT_IDENTIFIER=Do pole níže zadejte identifikátor kontaktu, který chcete přidat.
-service.gui.ADD_CONTACT_WIZARD=Průvodce přidáním kontaktu
service.gui.ADD_CONTACT_NOT_CONNECTED=Pro přidání kontaktu musíte být připojeni. Přihlašte se prosím k vybranému poskytovateli a opakujte akci.
service.gui.ADD_GROUP_LOCAL_ERROR=Nepodařilo se přidat skupinu se jménem: {0}. Chyba při lokální IO operaci.
service.gui.ADD_GROUP_EXIST_ERROR=Skupina jménem {0} již existuje ve vašem seznamu kontaktů. Zvolte prosím jiný název.
service.gui.ADD_GROUP_NET_ERROR=Nepodařilo se přidat skupinu: {0}. Problém byl způsoben chybou sítě. Zkontrolujte prosím síťové připojení a opakujte akci.
service.gui.ADD_GROUP_ERROR=Nepodařilo se přidat skupinu s jménem {0}.
service.gui.ADD_GROUP_EMPTY_NAME=Jméno skupiny musí být zadáno
-service.gui.ADD_GROUP=Přidat skupinu
-service.gui.ADD_SUBCONTACT=&Přidat subkontakt
service.gui.ADDRESS=Adresa
service.gui.ADMINISTRATOR=administrátor
service.gui.ADVANCED=&PokroÄilé
-service.gui.ALL=&VÅ¡e
service.gui.ALL_CONTACTS=&VÅ¡echny kontakty
service.gui.APPLY=&Použij
service.gui.ARE_CALLING={0} volá...
@@ -63,7 +68,6 @@ service.gui.AT=at
service.gui.AUTHORIZE=Autorizovat
service.gui.AUTHORIZATION_ACCEPTED={0} přijal požadavek na autorizaci.
service.gui.AUTHENTICATION_FAILED=Neúspěšné přihlášení ({0}). Zadali jste nesprávné heslo.
-service.gui.AUTHENTICATION_REQUESTED=Požadavek na přihlášení
service.gui.AUTHENTICATION_REQUESTED_SERVER=Server {0} vyžaduje vaši autentifikaci.
service.gui.AUTHENTICATION_REJECTED={0} odmítl váš požadavek na autorizaci.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} autorizace
@@ -103,7 +107,6 @@ service.gui.CHANGE_NICKNAME_LABEL=Do políÄka níže zadejte novou pÅ™ezdívku.
service.gui.CHANGE_NICKNAME_ERROR=Chyba při změně jména
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Přezdívka již existuje
service.gui.CHANGE_VIDEO_QUALITY=Změnit kvalitu vzdáleného videa
-service.gui.CHAT_CONFERENCE_LABEL=Konference
service.gui.CHAT_CONFERENCE_ITEM_LABEL={0} konferencí
service.gui.CHAT_ROOM_ALREADY_JOINED=Místnost {0} je již připojena.
service.gui.CHAT_ROOM_CONFIGURATION=Konfigurace místnosti {0}
@@ -114,18 +117,14 @@ service.gui.CHAT_ROOM_USER_JOINED=se připojil(a) do {0}
service.gui.CHAT_ROOM_USER_LEFT=opustil(a) {0}
service.gui.CHAT_ROOM_USER_KICKED=byl(a) vyhozen(a) od {0}
service.gui.CHAT_ROOM_USER_QUIT=ukonÄil(a) {0}
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Uloží místnost pro budoucí použití
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Odstranit zvolenou místnost ze seznamu uložených místností
service.gui.CHAT_ROOM_NAME=Jméno místnosti
service.gui.CLEAR_CUSTOM_MESSAGES=Vymazat vlastní zprávy
service.gui.ROOM_NAME=Místnost
-service.gui.AUTOJOIN=Automatické připojení
service.gui.CHANGE_PASSWORD=Změnit heslo
service.gui.CHAT_ROOM_NAME_INFO=Do pole níže zadejte jmého místnosti kterou chcete vytvořit.
service.gui.CHAT_ROOM_NOT_EXIST=Místnost {0} nebyla nalezena na serveru {1}. PÅ™esvÄ›dÄte se jestli jste zadali správné jméno.
service.gui.CHAT_ROOM_NOT_CONNECTED=Pro připojení k místnosti {0} musíte být přihlášeni.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Pro opuštění místnosti k ní musíte být přihlášeni.
-service.gui.CHAT_ROOM_NOT_JOINED=Pro provádění akcí v místnosti k ní musíty být přihlášeni.
service.gui.CHAT_ROOM_OPTIONS=Možnosti místnosti
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Místnost {0} vyžaduje abyste se před připojením registrovali.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Místnost {0} požaduje heslo.
@@ -142,22 +141,18 @@ service.gui.CLEAR=Vymazat
service.gui.CLOSE=&Zavřít
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Před méně než 2 ma sekundami jste přijali novou zprávu. Opravdu chcete zavřít chat?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=Právě probíhá přenos souboru. Přejete si jej přerušit?
-service.gui.CONFIRM=Potvrdit
service.gui.CONNECTED_STATUS=Spojeno
service.gui.CONNECTING=Připojuji...
service.gui.CONNECTING_STATUS=Připojuji
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Připojuji...
service.gui.CONNECTION=Spojení
-service.gui.CONNECTION_FAILED_MSG=NepodaÅ™ilo se pÅ™ipojit úÄet {0} k serveru {1}. Zkontrolujte nastavení síťového spojení nebo kontaktujte správce sítÄ›.
service.gui.CONNECTION_EXPIRED_MSG=Nyní jste odpojeni od serveru {0}.
service.gui.CONTACT_NAME=ID nebo Číslo
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Zvolený kontakt {0} nepodporuje telefonování.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Zvolený kontakt {0} nepodporuje konferenÄní chat.
service.gui.CONTACT_PAUSED_TYPING={0} přestal(a) psát...
service.gui.CONTACT_TYPING={0} píše zprávu...
service.gui.CONTACT_TYPING_SEND_FAILED=nemohli jsme {0} informovat že jste mu psali
service.gui.CONTACT_INFO=&Informace o kontaktech
-service.gui.CONTACTLIST=Seznam kontaktů
service.gui.CONTACTS=Kontakty
service.gui.COPY=&Kopírovat
service.gui.COPY_LINK=Kopírovat &odkaz
@@ -167,16 +162,13 @@ service.gui.CREATE_CHAT_ROOM=&Vytvořit místnost...
service.gui.CREATE_CHAT_ROOM_ERROR=Chyba při vytváření místnosti {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=Průvodce vytvořením místnosti
service.gui.CREATE_CONFERENCE_CALL=&VytvoÅ™it konferenÄní hovor...
-service.gui.CREATE_CONFERENCE_CHAT=&ytvoÅ™it konferenÄní chat...
service.gui.CREATE_GROUP=&Vytvořit skupinu
service.gui.CREATE_GROUP_NAME=Do políÄka níže zadejte název skupiny kterou chcete vytvoÅ™it.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Váš seznam kontaktů neobsahuje žádnou skupinu. Prosím nejprve skupinu vytvořte (Soubor/Vytvořit skupinu).
service.gui.CREATE_VIDEO_BRIDGE=Vytvořit &video bridge...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Vytvořit &video bridge
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Vytvořit / Připojit se do video konference
service.gui.CONTACT_INFO_NOT_SUPPORTED=Tento kontakt nepodporuje informace z webu
service.gui.CUT=&Vyjmout
-service.gui.DATE=Datum
service.gui.DELETE=Smazat
service.gui.DENY=&Odmítnout
service.gui.DESKTOP_SHARING_WARNING=<b>Opravdu si pÅ™ejete sdílet obrazovku?</b><br>StlaÄením OK dovolíte ostatním vidÄ›t vaÅ¡i obrazovku
@@ -186,7 +178,6 @@ service.gui.DISCONNECTED_STATUS=Odpojeno
service.gui.DND_STATUS=Nerušit
service.gui.DO_NOT_ASK_AGAIN=Příště se neptat
service.gui.DO_NOT_SHOW_AGAIN=Tuto zprávu víckrát nezobrazovat
-service.gui.DOWNLOAD_NOW=&Stáhnout nyní
service.gui.DRAG_FOR_SHARING=Přetáhněte sem objekty ke sdílení...
service.gui.DURATION=Doba trvání
service.gui.EDIT=&Editovat
@@ -205,7 +196,6 @@ service.gui.ERROR_RECEIVED_FROM=Nelze přijmout zprávu od {0}
service.gui.ESTIMATED_TIME=Odhadovaný Äas:
service.gui.EVENTS=Notifikace
service.gui.EXIT=U&konÄit
-service.gui.EXTENDED_CRITERIA=Rozšířené hledání
service.gui.GENERAL=Obecné
service.gui.GENERAL_ERROR=Obecná chyba
service.gui.GROUP_NAME=Jméno skupiny
@@ -247,7 +237,6 @@ service.gui.FONT_ITALIC=Kurzíva
service.gui.FONT_SIZE=Velikost
service.gui.FONT_STYLE=Styl
service.gui.FONT_UNDERLINE=Podtržené
-service.gui.FROM={0} z {1}
service.gui.GRANT_OWNERSHIP=Přidělit vlastnictví...
service.gui.GRANT_ADMIN=Přidělit práva administrátora...
service.gui.GRANT_MODERATOR=Přidělit práva moderátora
@@ -273,12 +262,12 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=Jste si jisti, že chcete trvale odstrani
service.gui.HISTORY_REMOVE_ERROR=Chyba při odstraňování lokálně uložených zpráv.
service.gui.HOME=Domov
service.gui.HOME_PAGE=Domovská stránka
-service.gui.HOUR=Hodin(a)
service.gui.ICE=ICE
service.gui.IDENTIFIER=Identifikátor
service.gui.IGNORE=&Ignorovat
service.gui.INSERT_SMILEY=Vložit smajlíka
service.gui.INCOMING_CALL=Příchozí hovor od: {0}
+service.gui.INCOMING_SCREEN_SHARE=Příchozí hovor od: {0}
service.gui.INCOMING_CALL_STATUS=Příchozí hovor
service.gui.INSTANT_MESSAGINGS=IM
service.gui.INITIATING_CALL_STATUS=Inicializace spojení
@@ -294,12 +283,9 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Pozvat kontakty do video bridge
service.gui.INVITE_REASON=Důvod pozvání
service.gui.IS_CALLING={0} volá...
service.gui.IS_NOW={0} je nyní {1}
-service.gui.JITSI_WARNING=SIP Communicator byl pÅ™ed Äasem pÅ™ejmenovaný na Jitsi.<br/>Jestliže si pÅ™ejete aby vaÅ¡e verze zůstala aktuální, potom prosím stáhnÄ›te aplikaci Jitsi.<br/><br/>Omlouváme se za jakékoli způsobené nepÅ™ijemnosti.<br/><br/>Vývojový tým Jitsi
-service.gui.JITSI_WARNING_TITLE=SIP Communicator se přejmenuje na Jitsi
service.gui.JOIN=&Připojit
service.gui.JOIN_AS=PÅ™&ipojen jako
service.gui.JOIN_VIDEO=Připojit video
-service.gui.CLOSE_CHAT_ROOM_DIALOG=&Zavřít
service.gui.JOB_TITLE=Pozice
service.gui.JOIN_CHAT_ROOM=&Připojit místnost...
service.gui.JOIN_CHAT_ROOM_TITLE=Připojit místnost
@@ -312,7 +298,6 @@ service.gui.KICK_FAILED=Vyhození selhalo
service.gui.KICK_FAILED_GENERAL_ERROR=Nepodařilo se vyhodit uživatele {0}. Nastala obecná chyba serveru.
service.gui.KICK_FAILED_NOT_ALLOWED=Nepodařilo se vyhodit uživatele {0}. Vlastník ani správce místnosti nemůžou být vyhozeni.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=NepodaÅ™ilo se vyhodit uživatele {0}. Nemáte dostateÄná oprávnÄ›ní.
-service.gui.LAST=Poslední
service.gui.LAST_NAME=Příjmení
service.gui.LEAVE=&Odejít
service.gui.LIMIT_REACHED_FOR_IP=Máte otevřeno příliš mnoho spojení z lokální IP adresy a server {0} odmítl z této adresy otevřít další spojení.
@@ -332,7 +317,6 @@ service.gui.MESSAGE=Zprávy
service.gui.MISSED_CALLS_TOOL_TIP=Ztracená volání od:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= a {0} další(ch)
service.gui.MODERATOR=moderátor
-service.gui.MORE=Více (See more)
service.gui.MORE_LABEL=Více
service.gui.MOVE=Přesunout
service.gui.MOVE_SUBCONTACT=Pře&místit kontakt
@@ -341,7 +325,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=Vybraný kontakt je stejný jako ten,\nkterý
service.gui.MOVE_SUBCONTACT_QUESTION=Opravdu si přejete přesunout kontakt {0} do {1}?
service.gui.MOVE_TO_GROUP=&Přesunout do skupiny
service.gui.MOVE_CONTACT=Přesunout kontakt
-service.gui.MOVE_CONTACT_ERROR=&Kontakt nelze přesunout
service.gui.MSG_DELIVERY_FAILURE=Zprávu nelze doruÄit
service.gui.MSG_DELIVERY_NOT_SUPPORTED=Protokol nepodporuje offline doruÄování zpráv. Můžete se zkusit s {0} spojit pomocí jiného protokolu, nebo poÄkat až bude kontakt online.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Vnitřní chyba programu. Prosím oznamte chybu zde: https://jitsi.org/Development/BugsAndIssues.
@@ -354,7 +337,6 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=Abyste mohli zprávu odeslat, musít bá
service.gui.MULTIPLE_LOGINS=Jste pÅ™ihlášeni víckrát pod stejným úÄtem. Tento úÄet: Jméno: {0}, server: {1} je nyní odpojen.
service.gui.MY_CHAT_ROOMS=Přidat chatovací místnost
service.gui.MY_CHAT_ROOMS_TITLE=Přidat chatovací místnost
-service.gui.MUTE=Ztlumit
service.gui.MUTUALLY_ON_HOLD_STATUS=Navzájem drženo
service.gui.NAME=Jméno
service.gui.NETWORK=Síť
@@ -365,6 +347,7 @@ service.gui.NEW_MESSAGE=Nová zpráva
service.gui.NEW_NAME=Moje jméno
service.gui.NEW_STATUS_MESSAGE=Nová stavová zpráva
service.gui.NEW_STATUS_MESSAGE_SAVE=Uložit jako vlastní zprávu
+service.gui.NICKNAME=Přezdívka
service.gui.NO=Ne
service.gui.NONE=Žádný
service.gui.NO_CAMERA_AVAILABLE=Kamera není k dispozici
@@ -385,7 +368,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=Není v seznamu kontaktů
service.gui.SD_QUALITY=Standardní kvalita
service.gui.OFFLINE=Odpojen
service.gui.OK=&OK
-service.gui.OLDER_CALLS=Starší volání
service.gui.ONLINE=Připojen
service.gui.OPEN=Otevřít
service.gui.OPEN_FILE_FROM_IMAGE=Dvojklikněte pro otevření souboru.
@@ -393,9 +375,12 @@ service.gui.OPEN_FOLDER=Otevřít složku
service.gui.OPEN_IN_BROWSER=Otevřít v &prohlížeÄi
service.gui.OPTIONS=Volby
service.gui.OR=nebo
-service.gui.OR_ENTER_PHONE_NUMBER=Nebo zde zadejte telefonní Äíslo...
service.gui.ORGANIZATION=Organizace
service.gui.OTHER=Ostatní
+service.gui.chat.role.ADMINISTRATOR=administrátor
+service.gui.chat.role.MODERATOR=moderátor
+service.gui.chat.role.MEMBER=Älen
+service.gui.chat.role.SILENT_MEMBER=tichý spoleÄník
service.gui.OWNER=vlastník místnosti
service.gui.ON_MOBILE_TOOLTIP=(Na mobilu)
service.gui.PASSWORD=Heslo
@@ -411,7 +396,6 @@ service.gui.PRESENCE=Přítomnost
service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Enter' pro návrhy
service.gui.PRESS_FOR_CALL_INFO=Zobrazit detaily o hovoru
service.gui.PREVIOUS=Předchozí
-service.gui.PREVIOUS_TOOLTIP=Procházet starší konverzaci
service.gui.PRINT=&Tisk
service.gui.PROACTIVE_NOTIFICATION=píše zprávu
service.gui.PROBLEMS_ENCOUNTERED=Nalezeny problémy
@@ -420,13 +404,13 @@ service.gui.PUT_OFF_HOLD=Uvolnit (Put off hold)
service.gui.PUT_ON_HOLD=Podržet (Put on hold)
service.gui.QUIT=&UkonÄit
service.gui.READY=Připraven
+service.gui.RECENT_MESSAGES=Poslední konverzace
service.gui.REASON=Důvod
service.gui.RECEIVED={0} přijatých zpráv
service.gui.RECONNECTION_LIMIT_EXCEEDED=Odpojili a znovu pÅ™ipojili jste se k serveru příliÅ¡ rychle. ÚÄet {0} na serveru {1} je doÄasnÄ› zakázaný. PÅ™ed dalším pÅ™ihlášením budete muset chvíli poÄkat.
service.gui.RE_REQUEST_AUTHORIZATION=Znovu požádat o autorizaci
service.gui.REFERRED_STATUS=Odkazováno
service.gui.REJECT=&Zamítnout
-service.gui.REMIND_ME_LATER=Připomenout později
service.gui.REMEMBER_PASSWORD=Zapamatovat si heslo
service.gui.REMOVE=&Odebrat
service.gui.REMOVE_ACCOUNT=&Odebrat úÄet
@@ -452,29 +436,20 @@ service.gui.REVOKE_ADMIN=Zrušit práva admina
service.gui.REVOKE_MODERATOR=Odejmout moderování
service.gui.REVOKE_MEMBERSHIP=ZruÅ¡it Älenství
service.gui.REVOKE_VOICE=Odebrat hlas
-service.gui.ROOT_GROUP=Hlavní skupina (Root group)
service.gui.SAVE=&Uložit
-service.gui.SAVE_AS_DEFAULT=Uložit jako výchozí
service.gui.SEARCH=&Hledat
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Pro zobrazení vÅ¡ech místností na vybraném serveru kliknÄ›te na tlaÄítko. Pak vyberte místnost ke které se chcete pÅ™ipojit a kliknÄ›te na PÅ™ipojit.
service.gui.SEARCH_STRING_CONTACT_SOURCE=Hledaný kontakt
service.gui.SECURITY=ZabezpeÄení
-service.gui.SELECT_ACCOUNT=Vybrat úÄet
service.gui.SELECT_COLOR=Volba barvy
service.gui.SELECT_GROUP=Vybrat skupinu
-service.gui.SELECT_GROUP_WIZARD_MSG=seznam níže obsahuje všechny skupiny vašeho seznamu kontaktú. Vyberte skupinu do které chcete přidat kontakt.
service.gui.SELECT_NO_GROUP=Žádná skupina
-service.gui.SELECT_GROUP_WIZARD=Zadejte skupinu
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=Seznam níže obsahuje vÅ¡echny úÄty které podporují víceuživatelský chat. Vyberte úÄet který chcete použít pro vytvoÅ™ení chatovací místnosti.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=Seznam níže obsahuje vÅ¡echny registrované úÄty. Vyberte úÄet který chcete použít pro komunikaci s novým kontaktem.
-service.gui.SELECT_PROVIDERS_WIZARD=VýbÄ›r úÄtu
service.gui.SELECT_VIDEO_CONFERENCE=Zvolte video hovor
service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Vyberte chatovací místnost ze seznamu a kliknÄ›te na tlaÄítko OK pro pÅ™idání.
service.gui.SEND=&Odeslat
service.gui.SEND_FILE=Odeslat &soubor
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=K tomuto kontaktu neexistují žádné informace.
service.gui.SEND_MESSAGE=&Odeslat zprávu
-service.gui.SEND_AS_SMS=Odeslat jako SMS
service.gui.SEND_PRIVATE_MESSAGE=Odeslat soukromou zprávu
service.gui.SEND_SMS=O&deslat SMS
service.gui.SEND_SMS_DETAILS=Nezapomeňte, že musíte zadat Äíslo v mezinárodním formátu t.j. zaÄínající na +420 v ÄŒesku a +421 na Slovensku - napÅ™. +420777000000
@@ -482,6 +457,7 @@ service.gui.SEND_SMS_NOT_SUPPORTED=Zvolený protokol nepodporuje SMS zprávy.
service.gui.SMS=SMS
service.gui.SEND_VIA=Odeslat přes
service.gui.SENT=odesláno
+service.gui.SERVER_CHAT_ROOMS=Serverové chatovací místnosti
service.gui.SET_GLOBAL_STATUS=Nastavit globální stav
service.gui.SET_STATUS_MESSAGE=Nastavit stavovou zprávu
service.gui.SET_SUBJECT=Nastavit předmět
@@ -512,7 +488,6 @@ service.gui.STREET=Ulice
service.gui.SUBJECT=Předmět
service.gui.SUMMARY=Základní
service.gui.TELEPHONY=Telefonování
-service.gui.TODAY=Dnes
service.gui.TOOLS=&Nástroje
service.gui.TRANSFER=&Přenos
service.gui.TO=&Komu:
@@ -522,7 +497,6 @@ service.gui.TRANSFER_CALL_TO=Kam přenést:
service.gui.TRANSPARENCY_NOT_ENABLED=VaÅ¡e souÄasná konfigurace nepodporuje průhlednost.
service.gui.TYPE_YOUR_REQUEST=Zadejte váš požadavek
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Kvalita videa tohoto hovoru nemůže být změněna.
-service.gui.UNMUTE=Zapnout zvuk
service.gui.USER_IDENTIFIER=Uživatelská identifikace:
service.gui.USER_EXISTS_ERROR=Tento uživatel již existuje ve zvolené síti. Vyberte prosím vyberte jiného uživatele nebo síť.
service.gui.USERNAME_NULL=Prosím zadejte jméno a heslo.
@@ -535,7 +509,6 @@ service.gui.USE_PROVISIONING=Použít online autokonfiguraci
service.gui.VALUE=Hodnota
service.gui.VIDEO_CALL=Videohovor
service.gui.VIA=přes
-service.gui.VIA_SMS=Přes SMS
service.gui.VIEW=&Prohlížet (View)
service.gui.VIEW_HISTORY=Zobrazit &historii
service.gui.VIEW_SMILEYS=Prohlížet &smajlíky
@@ -555,9 +528,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=Nastavení hlasitosti
service.gui.WAITING_AUTHORIZATION=Čeká se na autorizaci
service.gui.WARNING=Varování
service.gui.YES=Ano
-service.gui.YESTERDAY=VÄera
-service.gui.EXISTING_ACCOUNT_ERROR=ÚÄet který jste zadali již existuje.
-service.gui.NEW_MAIL=<b>Máte novou poštu!</b><br/><b>Od:</b> {0} {1} <br/><b>Subject:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=Máte novou poštu ve vaší <a href="{1}">schránce</a> {0}:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=Máte {2} nových mailových zpráv ve vaší <a href="{1}">schránce</a> {0}:<br/>
service.gui.NEW_GMAIL_FOOTER=jedna nebo více nepÅ™eÄtených konverzací ve vaší <a href="{0}">schránce</a>.<br/>
@@ -580,7 +550,6 @@ service.gui.SECURITY_ERROR=Chyba zabezpeÄení
service.gui.SPEED=Rychlost:
service.gui.SILENT_MEMBER=tichý spoleÄník
service.gui.NON_SECURE_CONNECTION=Pro úÄet {0} není možné vytvoÅ™it bezpeÄné pÅ™ipojení. Pokud se chceÅ¡ pÅ™ipojit k nezabezpeÄenému serveru, prosím odklikni "Povolit nezabezpeÄené pÅ™ipojení" v nastavení úÄtu
-service.gui.UPDATE=Aktualizovat
service.gui.MOBILE_PHONE=Mobil
service.gui.VIDEO_PHONE=Video
service.gui.WORK_PHONE=Práce
@@ -588,6 +557,7 @@ service.gui.PHONE=Telefonní Äíslo
service.gui.PHONES=Telefony
service.gui.EDIT_NOT_SUPPORTED=Upravování tohoto úÄtu není podporováno
service.gui.SHOW_PREVIEW=(Zobrazit náhled)
+service.gui.SHOW_PREVIEW_DIALOG_TITLE=Zobrazit náhled obrázku / videa
service.gui.ZID_NAME_SET=Identifikátor jména ZRTP:
service.gui.ZID_NAME_NOT_SET=Identifikátor jména ZRTP není nastaven.
@@ -613,7 +583,6 @@ service.gui.callinfo.CALL_INFORMATION=Informace o hovoru
service.gui.callinfo.CALL_IDENTITY=Identita
service.gui.callinfo.PEER_COUNT=PoÄet úÄastníků
service.gui.callinfo.IS_CONFERENCE_FOCUS=Téma rozhovoru
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Šifrování zapnuto
service.gui.callinfo.CALL_TRANSPORT=Signalizace průběhu hovoru
service.gui.callinfo.CALL_DURATION=Doba hovoru
service.gui.callinfo.VIEW_CERTIFICATE=Zobrazit certifikát
@@ -634,10 +603,13 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=KlíÄový protokol o výmÄ›nÄ›
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=ICE kandidát rozšířeného typu
service.gui.callinfo.ICE_STATE=ICE Zpracování Stavu
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=Shromáždění kandidáti
service.gui.callinfo.ICE_STATE.RUNNING=Ověření připojení
service.gui.callinfo.ICE_STATE.COMPLETED=Hotovo
service.gui.callinfo.ICE_STATE.FAILED=Selhalo
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=Lokální IP hostitele / Port
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=Místní reflexivní IP / Port
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=Místní "relayed" IP / Port
@@ -658,9 +630,10 @@ service.gui.ALWAYS_TRUST=Přijmout certifikát trvale
service.gui.CERT_DIALOG_TITLE=Ověřit certifikát
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} nemůže ověřit identitu serveru pÅ™i pÅ™ipojování k<br><b>{1}</b>.<br><br>Certifikát serveru není podepsán důvÄ›ryhodnou autoritou, identita serveru proto nemůže být automaticky ověřena. <br><br> Chcete pokraÄovat v pÅ™ipojování?<br>Pro více informací kliknÄ›te na "Zobrazit certifikát".</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0} nemůže ověřit certifikát serveru.<br><br>Certifikát není podepsán důvÄ›ryhodnou autoritou, identita serveru proto nemůže být automaticky ověřena. <br><br> Chcete pokraÄovat v pÅ™ipojování?<br>Pro více informací kliknÄ›te na "Zobrazit certifikát".</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} nemůže ověřit identitu pÅ™ipojovaného klienta.<br><br>Certifikát není podepsán důvÄ›ryhodnou autoritou, identita klienta proto nemůže být<br> automaticky ověřena. Chcete pokraÄovat v pÅ™ipojování?<br><br>Pro více informací kliknÄ›te na "Zobrazit certifikát".</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} nemůže ověřit identitu uživatele <b>{1}</b>.<br><br> Certifikát není podepsán důvÄ›ryhodnou autoritou, identita uživatele proto nemůže být automaticky ověřena.<br><br> Chcete pokraÄovat v pÅ™ipojování?<br><br> Pro více informací, kliknÄ›te na "Zobrazit certifikát".</html>
service.gui.CONTINUE_ANYWAY=PÅ™esto pokraÄovat
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Jméno nositele:
service.gui.CERT_INFO_O=Organizace:
service.gui.CERT_INFO_C=ZemÄ›:
@@ -669,17 +642,16 @@ service.gui.CERT_INFO_L=Lokalita:
service.gui.CERT_INFO_OU=OrganizaÄní jednotka
service.gui.CERT_INFO_ISSUED_ON=Vydán dne:
service.gui.CERT_INFO_EXPIRES_ON=Expiruje dne:
+service.gui.CERT_INFO_FINGERPRINTS=Otisk
service.gui.CERT_INFO_SER_NUM=Seriové Äíslo:
service.gui.CERT_INFO_VER=Verze:
service.gui.CERT_INFO_SIGN_ALG=Algorytmus podpisu:
service.gui.CERT_INFO_ALG=Algorytmus:
service.gui.CERT_INFO_PUB_KEY=VeÅ™ejný klíÄ:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} bytů: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} bitů
service.gui.CERT_INFO_EXP=Exponent:
service.gui.CERT_INFO_KEY_SIZE=Velikost klíÄe
service.gui.CERT_INFO_SIGN=Podpis:
-service.gui.CONTINUE=PokraÄovat
service.gui.SHOW_CERT=Zobrazit certifikát
service.gui.HIDE_CERT=Skrýt certifikát
@@ -702,11 +674,9 @@ service.gui.security.SECURE_AUDIO=ZabezpeÄený zvuk
service.gui.security.AUDIO_NOT_SECURED=NezabezpeÄený zvuk
service.gui.security.SECURE_VIDEO=ZabezpeÄené video
service.gui.security.VIDEO_NOT_SECURED=NezabezpeÄené video
-service.gui.security.NO_VIDEO=Bez videa
-service.gui.security.CIPHER=Å ifra: {0}
+service.gui.security.CALL_SECURED_TOOLTIP=Hovor je zabezpeÄen. Pro více informací klikni zde.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=NezabezpeÄený hovor.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Pro sdílení bezpeÄnostního kódu se svým protÄ›jÅ¡kem, klikni zde.
-service.gui.security.COMPARE_WITH_PARTNER=Prověřte s údaji od partnera a pak klikněte na "zámek" pro potvrzení.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Porovnání s partnerem:
service.gui.security.STRING_COMPARED=Řetězce porovnány!
@@ -724,19 +694,13 @@ service.gui.avatar.imagepicker.CLICK=Klik a úsměv
service.gui.avatar.imagepicker.IMAGE_FILES=Soubor s obrázkem
service.gui.avatar.imagepicker.IMAGE_PICKER=Obrázek
service.gui.avatar.imagepicker.IMAGE_SIZE=Velikost obrázku
-service.gui.avatar.imagepicker.INITIALIZING=Inicializuji
service.gui.avatar.imagepicker.RESET=Resetovat
service.gui.avatar.imagepicker.SET=Nastavení
service.gui.avatar.imagepicker.TAKE_PHOTO=Vyfotit
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Chyba webkamery
service.gui.security.encryption.required=Je nutné šifrování!
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
impl.protocol.sip.XCAP_ERROR_TITLE=Chyba SIP v seznamu kontaktů
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=Nezle pÅ™eÄíst zdroj {0}. Pro {1}
@@ -759,9 +723,7 @@ impl.gui.main.account.DUMMY_PROTOCOL_DESCRIPTION=výběr sítě
# LDAP
impl.ldap.CONFIG_FORM_TITLE=LDAP
impl.ldap.GENERAL=Obecné
-impl.ldap.NEW=Nový
impl.ldap.EDIT=upravit
-impl.ldap.REMOVE=Odstranit
impl.ldap.ENABLED=Povoleno
impl.ldap.SERVER_NAME=Název připojení
impl.ldap.SERVER_NAME_EXAMPLE=Můj LDAP server
@@ -794,6 +756,10 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=Pevná Linka
impl.ldap.PHONE_PREFIX=Prefix telefonů
impl.ldap.PHONE_PREFIX_EXAMPLE=NapÅ™. 00
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=Adresář
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=Povolit prohledávání v adresáři Mac OS X
@@ -804,9 +770,7 @@ plugin.addrbook.PREFIX_EXAMPLE=NapÅ™.: 00
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Google kontakty
-impl.googlecontacts.NEW=Nový
impl.googlecontacts.EDIT=upravit
-impl.googlecontacts.REMOVE=Odebrat
impl.googlecontacts.ENABLED=Povoleno
impl.googlecontacts.ACCOUNT_NAME=Název úÄtu
impl.googlecontacts.SAVE=Uložit
@@ -845,13 +809,11 @@ plugin.accountinfo.ORGANIZATION=Organizace:
plugin.accountinfo.JOB_TITLE=Pracovní zařazení:
plugin.accountinfo.ABOUT_ME=O mÄ›:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
-plugin.accountinfo.USER_PICTURES=Obrázek
plugin.accountinfo.GLOBAL_ICON=Použít obrázek úÄtu
plugin.accountinfo.LOCAL_ICON=Použít tuto ikonu:
-plugin.accountinfo.CHANGE=Změnit
-plugin.accountinfo.ONLY_MESSAGE=Pouze zprávy
# connection info
+plugin.connectioninfo.TITLE=Informace o spojení
# contact info
plugin.contactinfo.TITLE=Detaily kontaktu
@@ -868,49 +830,12 @@ plugin.aimaccregwizz.USERNAME=Jméno obrazovky AIM:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Jméno obrazovky a heslo
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Zaregistrovat nový úÄet
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Pokud nemáte založen AIM úÄet, kliknÄ›te na toto tlaÄítko a úÄet založte.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Změnit výchozí nastavení serveru
# branding
plugin.branding.ABOUT_WINDOW_TITLE=O {0}
plugin.branding.LOGO_MESSAGE=Open Source VoIP a Rýchle správy
-plugin.branding.LOADING=NaÄítám
plugin.branding.ABOUT_MENU_ENTRY=&O programu
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>{1} je nyní intenzívnÄ› vyvíjen. Verze kterou máte spuÅ¡tÄ›nu je experimentální a NEMUSà PRACOVAT podle oÄekávání. Pro další informace prosím prohlédnÄ›te {2}.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 Copyright <b>jitsi.org</b>. Všechna práva vyhrazena. Více na <a href="https://jitsi.org">https://jitsi.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}>The <b>Jitsi</b> je šířen pod LGPL licencí (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=Slovníky
-plugin.dictaccregwizz.ANY_DICTIONARY=Libovolný slovník
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Libovolný slovník z {0}
-plugin.dictaccregwizz.FIRST_MATCH=První výskyt
-plugin.dictaccregwizz.NO_MATCH=Nenalezeno
-plugin.dictaccregwizz.MATCH_RESULT=Definice "{0}" nebyla nalezena, neměli jste na mysli:\n
-plugin.dictaccregwizz.INVALID_DATABASE=Slovník "{0}" již na serveru neexistuje.
-plugin.dictaccregwizz.INVALID_STRATEGY=SouÄasná strategie není na serveru dostupná.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=Protokol služby
-plugin.dictaccregwizz.HOST=Hostitel
-plugin.dictaccregwizz.SERVER_INFO=Informace serveru
-plugin.dictaccregwizz.STRATEGY_SELECTION=Výběr strategie
-plugin.dictaccregwizz.STRATEGY_LIST=Seznam strategií:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Hledat strategii
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=Strategie, díky rozdílnému přístupu, hledají podobná slova, pokud není nalezen pÅ™esný pÅ™eklad. Například Prefix strategie bude hledatslova která zaÄínají stejnÄ› jako slovo pÅ™ekládané.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Informace o Dict úÄtu
-plugin.dictaccregwizz.FIRST_ACCOUNT=Průvodce vytvoří váš první Dict úÄet na dict.org.\n\nPÅ™echodem na "Průvodce registrací úÄtu" můžete pÅ™idat nový slovník. Do pole "host" vyplňte slovník, který chcete pÅ™idat.
-plugin.dictaccregwizz.THREAD_CONNECT=Pokouším se připojit k serveru
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=Pokus o spojení selhal, toto není Dict server nebo je offline
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=Zjišťuji dostupné strategie
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Na serveru nebyla nalezena žádná strategie
-plugin.dictaccregwizz.POPULATE_LIST=Zveřejňuji seznam
-plugin.dictaccregwizz.CLOSING_CONNECTION=Zavírám spojení
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Pokud se chcete pÅ™ipojit k chatu na Facebook, musíte vytvoÅ™it/zadat "Uživatelské jméno" <br> na stránce "ÚÄet", "Nastavení úÄtu" na Facebooku.</a><br><br>Poznámka: Po zadání uživatelského jména se musíte odhlásit z webovské stránky. <br>and Může to nÄ›jakou dobu trvat, než se budete moci pÅ™ihlísit pod nuvým uživatelským jménem!</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=Protokol chatu Facebooku
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Jméno uživatele:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Jméno uživatele a heslo
+
# generalconfig
plugin.generalconfig.AUTO_START=Automaticky spouštět {0} při spuštění PC
@@ -921,9 +846,6 @@ plugin.generalconfig.SHOW_HISTORY=Zobrazit
plugin.generalconfig.HISTORY_SIZE=posledních zpráv u nových konverzací
plugin.generalconfig.SEND_MESSAGES_WITH=Odesílat zprávy pomocí stisku:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=Přenést okno do popředí
-plugin.generalconfig.ERROR_PERMISSION=Nemáte oprávnění zakázat automatické spouštění
-plugin.generalconfig.TRANSPARENCY=Průhlednost
-plugin.generalconfig.ENABLE_TRANSPARENCY=Povolit průhlednost
plugin.generalconfig.DEFAULT_LANGUAGE=Jazyk uživatelského rozhraní
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Změny se projeví po restartu aplikace.
plugin.generalconfig.SIP_CLIENT_PORT=Port SIP klienta
@@ -937,6 +859,7 @@ plugin.generalconfig.REMOVE_SPECIAL_PHONE_SYMBOLS=Odstranit speciální znaky pÅ
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS=PÅ™evést písmena na Äísla
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS_EXAMPLE=napÅ™. +420 800 VOLANI -> +420 800 865264
plugin.generalconfig.SIP_CALL_CONFIG=SIP
+plugin.generalconfig.XMPP_CONFIG=XMPP
plugin.generalconfig.OPUS_CONFIG=Opus
plugin.generalconfig.OPUS_AUDIO_BANDWIDTH=Vzorkovací frekvence:
plugin.generalconfig.OPUS_BITRATE=Průměrný datový tok enkodéru (v kbs):
@@ -968,19 +891,21 @@ plugin.icqaccregwizz.REGISTER_NEW_ACCOUNT=Zaregistrovat nový úÄet
plugin.ircaccregwizz.PROTOCOL_NAME=IRC
plugin.ircaccregwizz.PROTOCOL_DESCRIPTION=IRC protocol.
plugin.ircaccregwizz.USERNAME_AND_PASSWORD=UIN a heslo
+plugin.ircaccregwizz.USERNAME=Přezdívka
plugin.ircaccregwizz.INFO_PASSWORD=Většina IRC serverů nevyžaduje heslo.
plugin.ircaccregwizz.AUTO_NICK_CHANGE=Automaticky změnit přezdívku, pokud je již použita
plugin.ircaccregwizz.USE_DEFAULT_PORT=Použít výchozí port
plugin.ircaccregwizz.PASSWORD_NOT_REQUIRED=Moje přezdívka nevyžaduje identifikaci
plugin.ircaccregwizz.HOST=Jméno serveru:
plugin.ircaccregwizz.IRC_SERVER=Server
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE={0} autorizace
+plugin.ircaccregwizz.SASL_USERNAME=Uživatelské Jméno
# jabber accregwizz
plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=Protokol XMPP
plugin.jabberaccregwizz.USERNAME=Uživatelské jméno pro XMPP
plugin.jabberaccregwizz.PASSWORD_CONFIRM=Heslo pro kontrolu
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=ID a heslo
plugin.jabberaccregwizz.CSERVER=Server
plugin.jabberaccregwizz.SERVER=Připojit server
plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=Povolit udržování sppojení
@@ -996,13 +921,9 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Poznámka
plugin.jabberaccregwizz.RESOURCE=Zdroj
plugin.jabberaccregwizz.AUTORESOURCE=Automaticky vygenerované prostředky
plugin.jabberaccregwizz.PRIORITY=Priorita
-plugin.jabberaccregwizz.XMPP_ERROR=Chyba XMPP protokolu
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Neznámá chyba v XMPP ({0}). Ověřte jestli jste zadali správné jméno serveru.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Hesla se neshodují.
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Změnit výchozí nastavení serveru
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=PokroÄilé možnosti
plugin.jabberaccregwizz.USE_ICE=Použít ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=Použít technologii Google Jingle/ICE (Experimentální)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=Automaticky nalézt STUN/TURN servery
plugin.jabberaccregwizz.SUPPORT_TURN=Podpora TURN
plugin.jabberaccregwizz.TURN_USERNAME=Zvolte si uživatelské jméno
@@ -1029,11 +950,8 @@ plugin.jabberaccregwizz.ALLOW_NON_SECURE=Povolit nezabezpeÄené pÅ™ipojení
plugin.jabberaccregwizz.DTMF_AUTO=Auto: Automatický výběr mezi RTP a Inband
plugin.jabberaccregwizz.SERVER_OPTIONS=Volby serveru
plugin.jabberaccregwizz.CHANGE_PASSWORD=ZmÄ›nit heslo úÄtu
-plugin.jabberaccregwizz.NEW_PASSWORD=Nové heslo
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Potvrzení hesla
plugin.jabberaccregwizz.PORT_FIELD_INVALID=Vyplňte prosím správné Äíslo portu, aby jste mohl pokraÄovat.
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=ÚÄet musí být pÅ™ihlášen, pÅ™ed zmÄ›nou hesla.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=Není vyplněno heslo.
plugin.jabberaccregwizz.TLS_REQUIRED=Připojení nepoužívá protokol TLS, proto nelze změnit vaše heslo.
plugin.jabberaccregwizz.PASSWORD_CHANGED=Heslo bylo úspěšně změněno
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=Váš XMPP server nepodporuje změnu vašeho hesla.
@@ -1047,25 +965,9 @@ plugin.jabberaccregwizz.RESET=Vymazat
plugin.jabberaccregwizz.RESET_DESCRIPTION=Obnovit globální nastavení
plugin.jabberaccregwizz.DISABLE_JINGLE=Vypnout Jingle (hovory a video hovory s XMPP protokolem).
-# mailbox
-plugin.mailbox.OUTGOING=Odchozí zprávy:
-plugin.mailbox.INCOMING=Příchozí zprávy:
-plugin.mailbox.WAIT_TIME=PoÄkejte dokud nebude volání pÅ™esmÄ›rováno na hlasovou poÅ¡tu
-plugin.mailbox.MAX_MESSAGE_TIME=Maximální doba trvání příchozí zprávy
-plugin.mailbox.CONFIRM=Potvrdit
-plugin.mailbox.DEFAULTS=Výchozí nastavení
-plugin.mailbox.MAILBOX=Poštovní schránka
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Protokol pro připojení ke službě MSN.
-plugin.msnaccregwizz.USERNAME=Email:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=ID a heslo
-
# plugin manager
plugin.pluginmanager.INSTALL=Instalovat
plugin.pluginmanager.UNINSTALL=Odinstalovat
-plugin.pluginmanager.UPDATE=Aktualizovat
plugin.pluginmanager.PLUGINS=Zásuvné moduly
plugin.pluginmanager.URL=URL
plugin.pluginmanager.CHOOSE_FILE=Výběr souboru
@@ -1090,7 +992,6 @@ plugin.sipaccregwizz.SERVER_PORT=Port na serveru
plugin.sipaccregwizz.PROXY=Proxy
plugin.sipaccregwizz.PROXY_PORT=Proxy port
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Preferovaný transport
-plugin.sipaccregwizz.ADVANCED_OPTIONS=PokroÄilé možnosti
plugin.sipaccregwizz.PROXY_OPTIONS=Nastavení proxy
plugin.sipaccregwizz.PROXY_AUTO=Automatická konfigurace proxy serveru
plugin.sipaccregwizz.ENABLE_PRESENCE=Povolit přítomnost (SIMPLE)
@@ -1110,8 +1011,6 @@ plugin.sipaccregwizz.DTMF_AUTO=Automaticky: Zvolí automaticky mezi RTP a Inband
plugin.sipaccregwizz.DTMF_RTP=RTP ( RFC2833 / RFC 4733 )
plugin.sipaccregwizz.DTMF_SIP_INFO=SIP informace
plugin.sipaccregwizz.DTMF_INBAND=Inband
-plugin.sipaccregwizz.REGISTER=REGISTER
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Změnit defaultní nastavení serveru
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Povolit podporu šifrovaného spojení
plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=UveÄte podporu ZRTP v protokolu zabezpeÄení
plugin.sipaccregwizz.AUTH_NAME=Jméno pro autorizaci
@@ -1132,10 +1031,10 @@ plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=URI pro kontrolu hlasové schránky
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Hesla se neshodují.
plugin.sipaccregwizz.NO_CERTIFICATE=<none>(Použít běžné ověření.)
plugin.sipaccregwizz.SAVP_OPTION=Indikace RTP / SVAP
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=Vypnout (pouze indikace RTP/AVP)
plugin.sipaccregwizz.SAVP_OPTION_1=Povinné (nabídnout a přijmout jen RTP / SAVP)
plugin.sipaccregwizz.SAVP_OPTION_2=Volitelně (první nabídnout RTP / SAVP, pak RTP / AVP)
-plugin.sipaccregwizz.ENABLE_SDES_ATTRIBUTE=Povolit S-Descriptor (znám taky jako SDES nebo SRTP)
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=Zvolte povolené šifrování protokolů a jejich priority (horní protokol jako první):
plugin.sipaccregwizz.CIPHER_SUITES=Povolené šifrování:
plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>{0} se automaticky pokusí zabezpeÄit vÅ¡echny své hovory pomocí ZRTP a oba uvidíte a uslyšíte oznámení jen jednou, že zabezpeÄené spojení bylo navázáno. Pokud jste si dobÅ™e vÄ›domi toho, co dÄ›láte mohli byste zmÄ›nit upÅ™esňující nastavení níže.</div></html>
@@ -1149,15 +1048,6 @@ plugin.skinmanager.DEFAULT_SKIN=Výchozí skin
plugin.skinmanager.ADD_NEW_SKIN=Přidat nový skin
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=Výchozí skin aplikace
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=Protokol k pÅ™ipojení vzdáleného poÄítaÄe pÅ™es SSH.
-plugin.sshaccregwizz.USERNAME=ID úÄtu:
-plugin.sshaccregwizz.IDENTITY_FILE=Soubor s indentitou:
-plugin.sshaccregwizz.KNOWN_HOSTS=Známí hosté:
-plugin.sshaccregwizz.OPTIONAL=Volitelné
-plugin.sshaccregwizz.ACCOUNT_DETAILS=Detaily úÄtu
-
# status update
plugin.autoaway.AUTO_STATUS=Automaticky pryÄ
plugin.autoaway.ENABLE_CHANGE_STATUS=Nastavit stav při nepřítomnosti
@@ -1204,22 +1094,6 @@ plugin.whiteboard.DESELECT=OdznaÄit
plugin.whiteboard.DELETE=Smazat
plugin.whiteboard.PROPERTIES=Vlastnosti
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Protokol pro připojení ke službě Yahoo!.
-plugin.yahooaccregwizz.USERNAME=Jméno uživatele:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=ID a heslo
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=Protokol služby Zeroconf (Bonjour).
-plugin.zeroaccregwizz.FIRST_NAME=Jméno:
-plugin.zeroaccregwizz.LAST_NAME=Příjmení:
-plugin.zeroaccregwizz.EMAIL=Email:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=Zapamatovat si Bonjour kontakty?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=ID a heslo
-plugin.zeroaccregwizz.USERID=ID uživatele
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Protokol služby Google Talk
@@ -1233,19 +1107,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, portál o IP telefonii
plugin.iptelaccregwizz.USERNAME=Jméno uživatele
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=Zaregistrovat na iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIP a Chat
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Uživatelské jméno
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Opakování hesla
plugin.sip2sipaccregwizz.EMAIL=E-mailová adresa
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=Pro nápovědu k této službě prosím navštivte <br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>e-mailová adresa pro odeslání hlasové zprávy, <br>informacím o nepřijatých voláních a pro obnovení zapomenutého hesla</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>Pro nápovědu k této službě navštivte prosím <a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=Existující "sip2sip.info" úÄet
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=VytvoÅ™it nový volný úÄet na "sip2sip.info"
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP a Rychlé zprávy
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=Pro nápovědu k této službě prosím navštivte stránky:<br>http://www.ippi.com/
@@ -1254,6 +1120,7 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=Existující IPPI úÄet
plugin.ippiaccregwizz.CREATE_ACCOUNT=VytvoÅ™it zdarma nový IPPI úÄet
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Zavřít okno chatu
plugin.keybindings.CHAT_COPY=Kopírovat
plugin.keybindings.CHAT_CUT=Vyjmout
@@ -1276,15 +1143,16 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=Akce
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=Primární zkratka
plugin.keybindings.globalchooser.SHORTCUT_SECOND=Sekundární zkratka
plugin.keybindings.globalchooser.PRESS_BTN=Stiskněte pro nastavení zkratky
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=Čeká se
plugin.keybindings.globalchooser.PUSH_TO_TALK=Funkce Push to talk
plugin.keybindings.globalchooser.ENABLE_SPECIAL=Povolit speciální detekci klávesy
plugin.keybindings.PLUGIN_NAME=Klávesové zkratky
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Konverzace
plugin.keybindings.MAIN=Hlavní
plugin.keybindings.GLOBAL=Globální zkratky
# Notification Configuration Form
+plugin.notificationconfig.ENABLE_NOTIF=Povolit
plugin.notificationconfig.DESCRIPTION=Popis
plugin.notificationconfig.TURN_ON_ALL=VÅ¡echno zapnout
plugin.notificationconfig.TURN_OFF_ALL=VÅ¡echno vypnout
@@ -1306,6 +1174,7 @@ plugin.notificationconfig.tableheader.SOUND=Přehrát zvuk na výstupu pro notif
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=Přehrát zvuk
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=Přehrát zvuk na PC speakeru
plugin.notificationconfig.tableheader.DESCRIPTION=Popis akce
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Příchozí hovor
plugin.notificationconfig.event.SecurityMessage=BezpeÄnostní zpráva
plugin.notificationconfig.event.IncomingFile=Příchozí soubor
@@ -1407,6 +1276,7 @@ impl.neomedia.configform.VIDEO=Video
impl.neomedia.configform.H264=H.264
impl.neomedia.configform.H264.defaultIntraRefresh=Pravidelné vnitÅ™ní naÄítání
impl.neomedia.configform.H264.defaultProfile=Výchozí profil pro kódování do:
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=Základní osnova
impl.neomedia.configform.H264.defaultProfile.high=Vysoká kvalita
impl.neomedia.configform.H264.defaultProfile.main=Hlavní
@@ -1437,7 +1307,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=SouÄasné heslo:
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Zadejte nové heslo:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Znovu zadejte heslo:
plugin.securityconfig.masterpassword.MP_TITLE=Hlavní heslo
-plugin.securityconfig.masterpassword.MP_NOT_SET=(není nastaveno)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=Nezadali jste správné (a platné) hlavní heslo. Zkuste to prosím znovu.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=Hlavní heslo není správné!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Změna hesla se nezdařila
@@ -1453,7 +1322,6 @@ plugin.securityconfig.masterpassword.COL_PASSWORD=Heslo
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(neznámý)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(nelze dešifrovat)
plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=Uložená hesla
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=Odebrat
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=Odebrat vše
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=Opravdu si přejete odebrat všechna hesla?
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=Odebrání všech hesel
@@ -1466,6 +1334,7 @@ plugin.securityconfig.masterpassword.MP_INPUT=Prosím zadejte hlavní heslo:\n\n
plugin.otr.menu.TITLE=ZabezpeÄený chat
plugin.otr.menu.START_OTR=Zahájit soukromou komunikaci
plugin.otr.menu.END_OTR=UkonÄit soukromou komunikaci
+plugin.otr.menu.VERIFIED=Vaše soukromá konverzace je ověřena
plugin.otr.menu.LOADING_OTR=Zahajuje se soukromá konverzace...
plugin.otr.menu.TIMED_OUT=Čas pro zahájení konverzace vypršel.
plugin.otr.menu.REFRESH_OTR=ObÄerstvit soukromou kominukaci
@@ -1519,7 +1388,6 @@ plugin.globalproxy.PROXY_PORT=Proxy port
plugin.globalproxy.PROXY_USERNAME=Uživatelské jméno pro proxy
plugin.globalproxy.PROXY_PASSWORD=Heslo pro proxy
plugin.globalproxy.DESCRIPTION={0} bude používat toto nastavení proxy pro veškerá nová nebo obnovená spojení. \nPodpora proxy je experimentální a nemusí pracovat správně se všemi protokoly. Pro více detailů srovnejte s tabulkou níže.
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Autorizace </td><td> HTTP </td><td> HTTP+Autorizace </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>XMPP</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
plugin.globalproxy.FWD_DNS=Také proxy DNS
plugin.globalproxy.FWD_DNS_NOTE=Použitelné u Tor. Pomáhá se vyhnout DNS netěsnostem při přesměrovávaní veškerého provozu DNS na Tor proxy. Vyžaduje restart.
@@ -1536,6 +1404,8 @@ plugin.reconnectplugin.NETWORK_DOWN=Síťové spojení bylo ztraceno!
plugin.chatconfig.TITLE=Konverzace
plugin.chatconfig.replacement.TITLE=Obrázek/Video
plugin.chatconfig.replacement.ENABLE_SMILEY_STATUS=Povolit v chatu smajlíky
+plugin.chatconfig.replacement.REPLACEMENT_TITLE=Povolit výměnu obrázku/videa
+plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS=Povolit
plugin.chatconfig.replacement.REPLACEMENT_SOURCES=Zdroje:
plugin.chatconfig.spellcheck.TITLE=Kontrola pravopisu
@@ -1552,7 +1422,6 @@ plugin.provisioning.RESTART_WARNING=Upozorňujeme, že zmÄ›ny se projeví až pÅ
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=Kopírovat UUID do schránky
plugin.provisioning.CLIPBOARD_FAILED=Kopírování UUID do schránky selhalo
-plugin.provisioning.EXIT_ON_FAIL=Vypnout aplikaci v případě chyby autokonfigurace
plugin.provisioning.CREDENTIALS=Uložené přihlašovací údaje
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=SkuteÄnÄ› si pÅ™ejete z nastavení autokonfigurace vymazat uložené heslo?
plugin.provisioning.PROV_FAILED=Autokonfigurace selhala
@@ -1619,8 +1488,6 @@ util.dns.DNSSEC_WARNING=<html><div width="600">{0} se pokusil připojit k server
#plugin spellcheck
plugin.spellcheck.TITLE=Kontrola překlepů a gramatiky
plugin.spellcheck.MENU=Zobrazit kontrolu pravopisu a gramatiky
-plugin.spellcheck.LANG=Jazyk
-plugin.spellcheck.EDIT_PERSONAL_DICT=Upravit
plugin.spellcheck.ENABLE_SPELL_CHECK=Aktivovat kontrolu pravopisu
plugin.spellcheck.dialog.FIND=Najít další
plugin.spellcheck.dialog.REPLACE=Nahradit
diff --git a/resources/languages/resources_de.properties b/resources/languages/resources_de.properties
index 362936e..afdc21b 100644
--- a/resources/languages/resources_de.properties
+++ b/resources/languages/resources_de.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Ich
service.gui.ACCOUNT_REGISTRATION_WIZARD=Kontoassistent
service.gui.ACCOUNTS=Konten
service.gui.ADD=&Hinzufügen
-service.gui.ADD_ACCOUNT=Konto hinzufügen
service.gui.ADD_CONTACT=&Kontakt hinzufügen
service.gui.ADD_AUTHORIZED_CONTACT={0} zu den Kontakten hinzufügen
service.gui.ADD_CONTACT_TO_CONTACTLIST=Kontakt zur Kontaktliste hinzufügen
@@ -42,20 +52,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Fehler: Kontakt kann nicht hinzugefügt werd
service.gui.ADD_CONTACT_EXIST_ERROR=Der Kontakt {0} existiert bereits.
service.gui.ADD_CONTACT_NETWORK_ERROR=Der Server reagierte nicht auf die Anfrage den Kontakt {0} hinzuzufügen.
service.gui.ADD_CONTACT_NOT_SUPPORTED=Kontakt {0} konnte nicht hinzugefügt werden. Vorgang wird nicht unterstützt.
-service.gui.ADD_CONTACT_IDENTIFIER=Bitte geben Sie im folgenden Feld den Benutzernamen des hinzuzufügenden Kontakts ein.
-service.gui.ADD_CONTACT_WIZARD=Kontakt hinzufügen
service.gui.ADD_CONTACT_NOT_CONNECTED=Sie müssen angemeldet sein, um einen Kontakt hinzufügen zu können. Bitte melden Sie sich beim gewählten Anbieter an und versuchen Sie es erneut.
service.gui.ADD_GROUP_LOCAL_ERROR=Die Gruppe {0} kann nicht hinzugefügt werden. Das Problem ist bei einer lokalen Lese-/Schreiboperation aufgetreten.
service.gui.ADD_GROUP_EXIST_ERROR=Die Gruppe {0} existiert bereits in Ihrer Kontaktliste. Bitte wählen Sie einen anderen Namen.
service.gui.ADD_GROUP_NET_ERROR=Die Gruppe {0} kann nicht hinzugefügt werden. Überprüfen Sie Ihre Netzwerkverbindung und versuchen Sie es erneut.
service.gui.ADD_GROUP_ERROR=Die Gruppe {0} kann nicht hinzugefügt werden.
service.gui.ADD_GROUP_EMPTY_NAME=Der Gruppenname muss angegeben werden.
-service.gui.ADD_GROUP=Gruppe erstellen
-service.gui.ADD_SUBCONTACT=&Unterkontakt hinzufügen
service.gui.ADDRESS=Adresse
service.gui.ADMINISTRATOR=Administrator
service.gui.ADVANCED=Erweitert
-service.gui.ALL=&Alle
service.gui.ALL_CONTACTS=&Alle Kontakte
service.gui.ALTERNATE_ADDRESS=Alternative Adresse
service.gui.APPLY=&Anwenden
@@ -65,7 +70,6 @@ service.gui.AT=Wann
service.gui.AUTHORIZE=&Autorisieren
service.gui.AUTHORIZATION_ACCEPTED={0} hat die Autorisierungsanfrage akzeptiert.
service.gui.AUTHENTICATION_FAILED=Anmeldung für {0} fehlgeschlagen. Die eingegebenen Anmeldedaten sind falsch.
-service.gui.AUTHENTICATION_REQUESTED=Anmeldung erforderlich
service.gui.AUTHENTICATION_REQUESTED_SERVER=Der {0} Server benötigt Ihre Zugangsdaten.
service.gui.AUTHENTICATION_REJECTED={0} hat die Autorisierungsanfrage zurückgewiesen.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} Authentifizierung
@@ -107,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=Im nachstehenden Feld können Sie Ihren neuen
service.gui.CHANGE_NICKNAME_ERROR=Fehler beim Ändern des Nicknamens
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Nickname existiert bereits
service.gui.CHANGE_VIDEO_QUALITY=Videoqualität ändern
-service.gui.CHAT_CONFERENCE_LABEL=Konferenzen
service.gui.CHAT_CONFERENCE_ITEM_LABEL=Konferenz von {0}
service.gui.CHAT_ROOM_ALREADY_JOINED=Sie sind bereits Mitglied des Chatraums {0}.
service.gui.CHAT_ROOM_CONFIGURATION={0} Chatraum konfigurieren
@@ -121,18 +124,14 @@ service.gui.CHAT_ROOM_USER_LEFT=hat den Chatraum verlassen {0}
service.gui.CHAT_ROOM_USER_KICKED=ist von {0} hinausgeschmissen worden
service.gui.CHAT_ROOM_USER_QUIT=hat {0} beendet
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=Nachrichtenversand ist verboten (Stimme gesperrt)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Speichert den Chatraum für künftige Verwendungen
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Entfernt den markierten Chatraum von der Liste der gespeicherten Chaträume
service.gui.CHAT_ROOM_NAME=Name des Chatraums
service.gui.CLEAR_CUSTOM_MESSAGES=Benutzerdefinierte Nachrichten löschen
service.gui.ROOM_NAME=Chatraum
-service.gui.AUTOJOIN=Automatisches beitreten
service.gui.CHANGE_PASSWORD=Passwort ändern
service.gui.CHAT_ROOM_NAME_INFO=Geben Sie im folgenden Feld den Namen des Chatraums ein, den Sie erstellen wollen.
service.gui.CHAT_ROOM_NOT_EXIST=Der Chatraum {0} ist dem Server {1} unbekannt. Bitte überprüfen Sie den Namen des Chatraums.
service.gui.CHAT_ROOM_NOT_CONNECTED=Sie müssen angemeldet sein, um dem Chatraum {0} beitreten zu können.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Sie müssen verbunden sein, um einen Chatraum zu verlassen.
-service.gui.CHAT_ROOM_NOT_JOINED=Sie müssen dem Chatraum beigetreten sein, bevor Sie weitere Aktionen ausführen können.
service.gui.CHAT_ROOM_OPTIONS=Chatraum-Einstellungen
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Der Chatraum {0} erfordert eine Registrierung um beizutreten.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Der Chatraum {0} benötigt ein Passwort.
@@ -157,16 +156,15 @@ service.gui.CONNECTING=Verbinde...
service.gui.CONNECTING_STATUS=Verbinde
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Verbinde*
service.gui.CONNECTION=Verbindung
-service.gui.CONNECTION_FAILED_MSG=Die Verbindung für {0} ({1}) ist fehlgeschlagen. Bitte überprüfen Sie Ihre Netzwerkverbindung oder kontaktieren Sie Ihren Netzwerkadministrator für weitere Informationen.
service.gui.CONNECTION_EXPIRED_MSG=Sie sind nicht mit Server {0} verbunden.
service.gui.CONTACT_NAME=ID oder Nummer
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Der gewählte {0} Kontakt unterstützt keine Telefonie.
+service.gui.CONTACT_NAME_PROMPT=irene.muster@example.com
+service.gui.CONTACT_NAME_INFO=Adresse für Chat-Dienst (z.B. lisa.mueller@example.com) oder VoIP-Nummer hinzufügen
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Der ausgewählte Kontakt {0} unterstützt die Gruppenkonferenz nicht.
service.gui.CONTACT_PAUSED_TYPING={0} unterbricht das Schreiben
service.gui.CONTACT_TYPING={0} schreibt eine Nachricht
service.gui.CONTACT_TYPING_SEND_FAILED=Ups... wir konnten {0} die Schreibbenachrichtigung nicht senden
service.gui.CONTACT_INFO=&Kontaktinformation
-service.gui.CONTACTLIST=Kontaktliste
service.gui.CONTACTS=Kontakte
service.gui.COPY=&Kopieren
service.gui.COPY_LINK=&Link kopieren
@@ -176,28 +174,26 @@ service.gui.CREATE_CHAT_ROOM=&Chatraum erstellen...
service.gui.CREATE_CHAT_ROOM_ERROR=Der Chatraum mit dem Namen {0} konnte nicht erstellt werden.
service.gui.CREATE_CHAT_ROOM_WIZARD=Assistent zum Erstellen eines Chatraums
service.gui.CREATE_CONFERENCE_CALL=&Konferenz erstellen...
-service.gui.CREATE_CONFERENCE_CHAT=&Chatraum erstellen...
service.gui.CREATE_GROUP=&Gruppe erstellen...
service.gui.CREATE_GROUP_NAME=Bitte geben Sie im folgenden Feld den Namen der zu erstellenden Gruppe ein.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Ihre Kontaktliste enthält keine Gruppe. Bitte legen Sie zuerst eine Gruppe an (Datei/Gruppe erstellen).
service.gui.CREATE_VIDEO_BRIDGE=&Videobrücke erstellen...
service.gui.CREATE_VIDEO_BRIDGE_MENU=&Videobrücke erstellen
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Videokonferenz erstellen/beitreten
service.gui.CREATE_VIDEO_CONFERENCE=Videokonferenz erstellen
service.gui.CONTACT_INFO_NOT_SUPPORTED=Dieser Kontakt unterstützt keine Web-Informationen
service.gui.CUT=&Ausschneiden
-service.gui.DATE=Datum
service.gui.DELETE=Löschen
service.gui.DENY=&Ablehnen
service.gui.DESKTOP_SHARING_WARNING=<b>Soll die Bildschirmfreigabe wirklich eingeschaltet werden?</b><br>Die Freigabe zeigt den Bildschirm allen Teilnehmern dieses Anrufs.
service.gui.DESKTOP_SHARING_DIALOG_INDICATE=Ihr Bildschirm ist freigegeben
service.gui.DIALPAD=Wähltastatur
service.gui.DISPLAY_NAME=Anzeigename
+service.gui.DISPLAY_NAME_PROMPT=Lisa Mueller
+service.gui.DISPLAY_NAME_INFO=Name für diesen Kontakt. Ohne Angaben wird die Chat-Adresse oder VoIP-Nummer verwendet. (Optional)
service.gui.DISCONNECTED_STATUS=Getrennt
service.gui.DND_STATUS=Bitte nicht stören
service.gui.DO_NOT_ASK_AGAIN=Nicht mehr fragen
service.gui.DO_NOT_SHOW_AGAIN=Diese Nachricht nicht mehr anzeigen
-service.gui.DOWNLOAD_NOW=Jetzt herunterla&den
service.gui.DRAG_FOR_SHARING=Ziehe hier etwas hinein, das den anderen geschickt werden soll...
service.gui.DURATION=Dauer
service.gui.DESTROY_CHATROOM=Chatraum auflösen
@@ -218,7 +214,6 @@ service.gui.ERROR_RECEIVED_FROM=Fehler von {0} empfangen
service.gui.ESTIMATED_TIME=Geschätzte Zeit:
service.gui.EVENTS=Ereignisse
service.gui.EXIT=&Verlassen
-service.gui.EXTENDED_CRITERIA=Erweiterte Kriterien
service.gui.GENERAL=Allgemein
service.gui.GENERAL_ERROR=Allgemeiner Fehler
service.gui.GROUP_NAME=Gruppenname
@@ -260,7 +255,6 @@ service.gui.FONT_ITALIC=Kursiv
service.gui.FONT_SIZE=Größe
service.gui.FONT_STYLE=Stil
service.gui.FONT_UNDERLINE=Unterstrichen
-service.gui.FROM={0} von {1}
service.gui.GRANT_OWNERSHIP=Erlaube Eigentümer...
service.gui.GRANT_ADMIN=Erlaube Administrator...
service.gui.GRANT_MODERATOR=Erlaube Moderator
@@ -286,7 +280,6 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=Sind Sie sicher, dass Sie alle lokal gesp
service.gui.HISTORY_REMOVE_ERROR=Fehler beim Löschen der lokal gespeicherten Nachrichten.
service.gui.HOME=Privat
service.gui.HOME_PAGE=Homepage
-service.gui.HOUR=Stunde
service.gui.ICE=ICE
service.gui.IDENTIFIER=Identifikation
service.gui.IGNORE=&Ignorieren
@@ -310,13 +303,10 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Kontakte zur Videobrücke einladen
service.gui.INVITE_REASON=Grund der Einladung
service.gui.IS_CALLING={0} ruft an...
service.gui.IS_NOW={0} ist nun {1}
-service.gui.JITSI_WARNING=SIP Communicator wurde in Jitsi umbenannt<br/>. Wenn die Installation aktuell gehalten werden soll, laden Sie Jitsi bitte jetzt herunter.<br/><br/>Das Jitsi Entwickler-Team entschuldigt sich für die entstehenden Umstände.
-service.gui.JITSI_WARNING_TITLE=SIP Communicator wird zu Jitsi
service.gui.JOIN=&Teilnehmen
service.gui.JOIN_AS=T&eilnehmen als
service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=Videokonferenz beitreten
service.gui.JOIN_VIDEO=Mit Video beitreten
-service.gui.CLOSE_CHAT_ROOM_DIALOG=&Schließen
service.gui.JOB_TITLE=Beruf
service.gui.JOIN_CHAT_ROOM=Chatraum bei&treten...
service.gui.JOIN_CHAT_ROOM_TITLE=Chatraum beitreten
@@ -329,7 +319,6 @@ service.gui.KICK_FAILED=Rauswurf fehlgeschlagen
service.gui.KICK_FAILED_GENERAL_ERROR=Rauswurf von {0} fehlgeschlagen. Der Server meldete einen allgemeinen Fehler.
service.gui.KICK_FAILED_NOT_ALLOWED=Teilnehmer {0} kann nicht rausgeworfen werden. Der Eigentümer und der Administrator des Raums können nicht rausgeworfen werden.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Rauswurf von {0} gescheitert. Sie haben nicht die erforderlichen Rechte.
-service.gui.LAST=Letzter
service.gui.LAST_NAME=Nachname
service.gui.LEAVE=&Verlassen
service.gui.LIMIT_REACHED_FOR_IP=Sie haben schon zu viele Verbindungen von Ihrer IP-Adresse und der Server {0} erlaubt keine weiteren.
@@ -349,7 +338,6 @@ service.gui.MESSAGE=Nachricht
service.gui.MISSED_CALLS_TOOL_TIP=Verpasste Anrufe von:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= und {0} mehr
service.gui.MODERATOR=Moderator
-service.gui.MORE=Mehr
service.gui.MORE_LABEL=Mehr
service.gui.MOVE=Verschieben
service.gui.MOVE_SUBCONTACT=Kontakt &verschieben
@@ -358,7 +346,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=Der Zielkontakt ist derselbe wie der Ausgangs
service.gui.MOVE_SUBCONTACT_QUESTION=Sind Sie sicher, dass Sie {0} nach {1} verschieben wollen?
service.gui.MOVE_TO_GROUP=&Verschiebe in Gruppe
service.gui.MOVE_CONTACT=Verschiebe Kontakt
-service.gui.MOVE_CONTACT_ERROR=&Kontakt kann nicht verschoben werden
service.gui.MSG_DELIVERY_FAILURE=Diese Nachricht konnte nicht zugestellt werden
service.gui.MSG_DELIVERY_NOT_SUPPORTED=Das verwendete Protokoll kann Nachrichten nur zustellen, wenn Benutzer angemeldet sind. Warten Sie bis {0} wieder angemeldet ist, oder verwenden Sie ein anderes Protokoll.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Ein internes Problem ist aufgetreten. Dies ist wahrscheinlich ein Programmfehler. Bitte melden Sie ihn unter https://jitsi.org/Development/BugsAndIssues.
@@ -372,7 +359,6 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=Damit Sie Nachrichten senden können, mÃ
service.gui.MULTIPLE_LOGINS=Sie haben mehrere Verbindungen zum selben Konto. Das Konto {0} auf Server {1} ist derzeit nicht verbunden.
service.gui.MY_CHAT_ROOMS=Chatraum hinzufügen
service.gui.MY_CHAT_ROOMS_TITLE=Chatraum hinzufügen
-service.gui.MUTE=Ton aus
service.gui.MUTUALLY_ON_HOLD_STATUS=Gegenseitig gehalten
service.gui.NAME=Name
service.gui.NETWORK=Netzwerk
@@ -404,7 +390,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=Nicht in Kontaktliste
service.gui.SD_QUALITY=Standardqualität
service.gui.OFFLINE=Offline
service.gui.OK=&OK
-service.gui.OLDER_CALLS=Ältere Anrufe
service.gui.ONLINE=Online
service.gui.OPEN=Öffnen
service.gui.OPEN_FILE_FROM_IMAGE=Doppelklicken, um die Datei zu öffnen.
@@ -416,7 +401,6 @@ service.gui.OPEN_ON_ACTIVITY=Bei Aktivität
service.gui.OPEN_ON_MESSAGE=Bei neuen Nachrichten
service.gui.OPEN_ON_IMPORTANT_MESSAGE=Bei wichtigen Nachrichten
service.gui.OR=oder
-service.gui.OR_ENTER_PHONE_NUMBER=Oder geben Sie eine Telefonnummer hier ein...
service.gui.ORGANIZATION=Firma
service.gui.OTHER=Andere
service.gui.chat.role.OWNER=Besitzer
@@ -442,7 +426,6 @@ service.gui.PRESS_ENTER_FOR_SUGGESTIONS=''Enter'' für Vorschläge
service.gui.PRESS_FOR_CALL_INFO=Anrufdetails
service.gui.PRESS_TO_OPEN_CRM=Klicken um die CRM Applikation zu öffnen
service.gui.PREVIOUS=Zurück
-service.gui.PREVIOUS_TOOLTIP=Suche ältere Gespräche
service.gui.PRINT=&Drucken
service.gui.PROACTIVE_NOTIFICATION=schreibt eine Mitteilung
service.gui.PROBLEMS_ENCOUNTERED=Aufgetretene Probleme
@@ -458,7 +441,6 @@ service.gui.RECONNECTION_LIMIT_EXCEEDED=Sie haben die Verbindung zu oft vom Serv
service.gui.RE_REQUEST_AUTHORIZATION=Autorisierung erneut anfragen
service.gui.REFERRED_STATUS=Weitergeleitet
service.gui.REJECT=&Zurückweisen
-service.gui.REMIND_ME_LATER=Später erinnern
service.gui.REMEMBER_PASSWORD=Passwort speichern
service.gui.REMOVE=&Entfernen
service.gui.REMOVE_ACCOUNT=&Konto entfernen
@@ -484,29 +466,23 @@ service.gui.REVOKE_ADMIN=Admin widerrufen
service.gui.REVOKE_MODERATOR=Moderator widerrufen
service.gui.REVOKE_MEMBERSHIP=Mitgliedschaft widerrufen
service.gui.REVOKE_VOICE=Sprecherlaubnis widerrufen
-service.gui.ROOT_GROUP=Hauptgruppe
service.gui.SAVE=&Speichern
-service.gui.SAVE_AS_DEFAULT=Als Standard speichern
service.gui.SEARCH=&Suchen
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Betätigen Sie die nachfolgende Schaltfläche um alle Chaträume auf dem ausgewählten Server anzuzeigen. Wählen Sie den Chatraum dem Sie beitreten wollen aus und betätigen Sie "Beitreten".
service.gui.SEARCH_STRING_CONTACT_SOURCE=Gesuchter Kontakt
service.gui.SECURITY=Sicherheit
service.gui.SELECT_ACCOUNT=Konto auswählen
+service.gui.SELECT_ACCOUNT_INFO=Welches Konto soll für diesen Kontakt verwendet werden?
service.gui.SELECT_COLOR=Farbe auswählen
service.gui.SELECT_GROUP=Gruppe auswählen
-service.gui.SELECT_GROUP_WIZARD_MSG=Die unten angeführte Liste enthält alle Gruppen Ihrer Kontaktliste. Wählen Sie diejenige aus, zu der Sie den neuen Kontakt hinzufügen wollen.
+service.gui.SELECT_GROUP_INFO=Zu welcher Gruppe soll dieser Kontakt hinzugefügt werden? (Optional)
service.gui.SELECT_NO_GROUP=Keine Gruppe
-service.gui.SELECT_GROUP_WIZARD=Gruppe auswählen
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=Die unten angeführte Liste zeigt alle Konten, die Gruppenchats unterstützen. Wählen Sie eines aus und erstellen Sie einen Chatraum.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=Die folgende Liste enthält alle Ihre registrierten Benutzerkonten. Bitte wählen Sie das Benutzerkonto aus, das sie für den neuen Kontakt verwenden möchten.
-service.gui.SELECT_PROVIDERS_WIZARD=Konto auswählen
service.gui.SELECT_VIDEO_CONFERENCE=Videokonferenz auswählen
service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Wählen Sie einen Chatraum aus der Liste aus und betätigen Sie OK um ihn hinzuzufügen.
service.gui.SEND=&Senden
service.gui.SEND_FILE=Datei s&enden
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Für diesen Kontakt sind keine Informationen verfügbar.
service.gui.SEND_MESSAGE=Eine Nachricht &Senden
-service.gui.SEND_AS_SMS=Als SMS Versenden
service.gui.SEND_PRIVATE_MESSAGE=Private Nachricht senden
service.gui.SEND_SMS=SMS vers&enden
service.gui.SEND_SMS_DETAILS=Die Telefonnummer muss einschließlich der internationalen Vorwahl eingegeben werden, z. B. mit der +49 für eine deutsche Nummer. Beispiel: +491771234567
@@ -545,7 +521,6 @@ service.gui.STREET=Strasse
service.gui.SUBJECT=Thema
service.gui.SUMMARY=Zusammenfassung
service.gui.TELEPHONY=Telefonie
-service.gui.TODAY=Heute
service.gui.TOOLS=&Werkzeuge
service.gui.TRANSFER=Ãœbertr&agung
service.gui.TO=&An:
@@ -555,7 +530,6 @@ service.gui.TRANSFER_CALL_TO=Weiterleiten an:
service.gui.TRANSPARENCY_NOT_ENABLED=Transparenz ist in Ihrer derzeitigen Konfiguration nicht unterstützt.
service.gui.TYPE_YOUR_REQUEST=Formulieren Sie Ihre Anfrage hier
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Die Videoqualität konnte nicht geändert werden.
-service.gui.UNMUTE=Ton ein
service.gui.USER_IDENTIFIER=Benutzerkennung:
service.gui.USER_EXISTS_ERROR=Dieser Benutzer existiert bereits in dem gewählten Netzwerk. Bitte wählen Sie einen anderen Benutzer oder ein anderes Netzwerk/Protokoll.
service.gui.USERNAME_NULL=Bitte geben Sie Ihren Benutzernamen und Ihr Passwort ein.
@@ -568,7 +542,6 @@ service.gui.USE_PROVISIONING=Provisionierung verwenden
service.gui.VALUE=Wert
service.gui.VIDEO_CALL=&Videoanruf
service.gui.VIA=via
-service.gui.VIA_SMS=Via SMS
service.gui.VIEW=&Ansicht
service.gui.VIEW_HISTORY=&Verlauf anzeigen
service.gui.VIEW_SMILEYS=&Smileys anzeigen
@@ -588,9 +561,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=Lautstärke anpassen
service.gui.WAITING_AUTHORIZATION=Autorisierung ausstehend
service.gui.WARNING=Warnung
service.gui.YES=Ja
-service.gui.YESTERDAY=Gestern
-service.gui.EXISTING_ACCOUNT_ERROR=Das von Ihnen eingegebene Konto ist bereits installiert.
-service.gui.NEW_MAIL=<b>Sie haben eine neue E-Mail!</b><br/><b>Von:</b> {0} {1} <br/><b>Betreff:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=Sie haben eine neue E-Mail in ihrem {0} <a href="{1}">Posteingang</a>:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=Sie haben {2} neue E-Mails in ihrem {0} <a href="{1}">Posteingang</a>:<br/>
service.gui.NEW_GMAIL_FOOTER=Eine weitere ungelesene Konversation in ihrem <a href="{0}">Posteingang</a>.<br/>
@@ -617,7 +587,6 @@ service.gui.SECURITY_ERROR=Sicherheitsfehler
service.gui.SPEED=Geschwindigkeit:
service.gui.SILENT_MEMBER=Stilles Mitglied
service.gui.NON_SECURE_CONNECTION=Mit dem Konto {0} kann keine sichere Verbindung hergestellt werden. Um eine Verbindung zu unsicheren Servern herzustellen, muss die Option "Unsichere Verbindung erlauben" in den Kontoeinstellungen aktiviert werden.
-service.gui.UPDATE=Aktualisieren
service.gui.MOBILE_PHONE=Handy
service.gui.VIDEO_PHONE=Video
service.gui.WORK_PHONE=Geschäftlich
@@ -652,12 +621,10 @@ service.gui.callinfo.CALL_INFORMATION=Anrufinformationen
service.gui.callinfo.CALL_IDENTITY=Identität
service.gui.callinfo.PEER_COUNT=Anzahl Teilnehmer
service.gui.callinfo.IS_CONFERENCE_FOCUS=Konferenz-Organisator
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Verschlüsselung aktiv
service.gui.callinfo.CALL_TRANSPORT=Signalisierungskanal-Transport
service.gui.callinfo.CALL_DURATION=Anrufdauer
service.gui.callinfo.TLS_PROTOCOL=TLS Protokoll
service.gui.callinfo.TLS_CIPHER_SUITE=TLS Chiffrensammlung
-service.gui.callinfo.TLS_SERVER_CERTIFICATE_CHAIN=TLS Zertifikatskette
service.gui.callinfo.TLS_CERTIFICATE_CONTENT=Das TLS Zertifikat des Servers wird unten angezeigt.
service.gui.callinfo.VIEW_CERTIFICATE=Zertifikat anzeigen
service.gui.callinfo.CODEC=Codec / Frequenz
@@ -677,10 +644,14 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=Schlüsselaustauschprotokoll
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=Erweiterter ICE Kandidatentyp
service.gui.callinfo.ICE_STATE=ICE Verarbeitungsstatus
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=Kandidaten ermitteln
service.gui.callinfo.ICE_STATE.RUNNING=Verbindungstests
service.gui.callinfo.ICE_STATE.COMPLETED=Fertig
service.gui.callinfo.ICE_STATE.FAILED=Fehlgeschlagen
+service.gui.callinfo.ICE_STATE.TERMINATED=Beendet
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=Lokale IP / Port
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=Lokale reflexive IP / Port
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=Lokale weitergegebene IP / Port
@@ -701,11 +672,12 @@ service.gui.ALWAYS_TRUST=Diesem Zertifikat immer vertrauen
service.gui.CERT_DIALOG_TITLE=Zertifikat überprüfen
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} kann die Identität des Servers bei der Verbindung zu {1} nicht verifizieren.<br><br> Das Zertifikat ist nicht vertrauenswürdig, daher kann die Identität des Servers <br>nicht automatisch geprüft werden. Wollen Sie die Verbindung trotzdem aufbauen?<br><br> Um mehr Information zu erhalten, klicken Sie auf "Zertifikat anzeigen".</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0} kann die Identität des Servers nicht überprüfen.<br><br> Das Zertifikat ist nicht vertrauenswürdig, daher kann die Identität des Servers <br>nicht automatisch geprüft werden. Wollen Sie die Verbindung trotzdem aufbauen?<br><br> Um mehr Information zu erhalten, klicken Sie auf "Zertifikat anzeigen".</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} kann die Identität des Clients nicht überprüfen.<br><br> Das Zertifikat ist nicht vertrauenswürdig, daher kann die Identität des Clients <br>nicht automatisch geprüft werden. Wollen Sie die Verbindung trotzdem aufbauen?<br><br> Um mehr Information zu erhalten, klicken Sie "Zertifikat anzeigen".</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} kann die Identität des Clients {1} nicht überprüfen.<br><br> Das Zertifikat ist nicht vertrauenswürdig, daher kann die Identität des Clients <br>nicht automatisch geprüft werden. Wollen Sie die Verbindung trotzdem aufbauen?<br><br> Um mehr Information zu erhalten, klicken Sie auf "Zertifikat anzeigen".</html>
service.gui.CONTINUE_ANYWAY=Trotzdem verbinden
service.gui.CERT_INFO_CHAIN=Zertifikatskette:
service.gui.CERT_INFO_ISSUED_TO=Ausgestellt für
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Allgemeiner Name (CN):
service.gui.CERT_INFO_O=Organisation (O):
service.gui.CERT_INFO_C=Land (C):
@@ -724,12 +696,10 @@ service.gui.CERT_INFO_SIGN_ALG=Signaturalgorithmus:
service.gui.CERT_INFO_PUB_KEY_INFO=Informationen zum öffentlichen Schlüssel
service.gui.CERT_INFO_ALG=Algorithmus:
service.gui.CERT_INFO_PUB_KEY=Öffentlicher Schlüssel:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} Bytes: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} Bits
service.gui.CERT_INFO_EXP=Exponent:
service.gui.CERT_INFO_KEY_SIZE=Schlüssellänge:
service.gui.CERT_INFO_SIGN=Signatur:
-service.gui.CONTINUE=Weiter
service.gui.SHOW_CERT=Zertifikat anzeigen
service.gui.HIDE_CERT=Zertifikat ausblenden
@@ -752,12 +722,9 @@ service.gui.security.SECURE_AUDIO=Verschlüsseltes Audio
service.gui.security.AUDIO_NOT_SECURED=Audio nicht verschlüsselt
service.gui.security.SECURE_VIDEO=Verschlüsseltes Video
service.gui.security.VIDEO_NOT_SECURED=Video nicht verschlüsselt
-service.gui.security.NO_VIDEO=Kein Video
-service.gui.security.CIPHER=Algorithmus: {0}
service.gui.security.CALL_SECURED_TOOLTIP=Anruf verschlüsselt. Klicken für weitere Informationen.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Anruf nicht verschlüsselt
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Klicken um SAS mit dem Gesprächspartner zu vergleichen.
-service.gui.security.COMPARE_WITH_PARTNER=Vergleiche mit Gesprächspartner und klicke auf das Vorhängeschloß, um zu bestätigen.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Mit Gesprächspartner vergleichen:
service.gui.security.STRING_COMPARED=SAS bestätigt
@@ -775,20 +742,20 @@ service.gui.avatar.imagepicker.CLICK=Klicken und lächeln
service.gui.avatar.imagepicker.IMAGE_FILES=Bilddateien
service.gui.avatar.imagepicker.IMAGE_PICKER=Avatar bearbeiten
service.gui.avatar.imagepicker.IMAGE_SIZE=Bildgröße
-service.gui.avatar.imagepicker.INITIALIZING=Initialisierung...
service.gui.avatar.imagepicker.RESET=Zurücksetzen
service.gui.avatar.imagepicker.SET=Auswählen
service.gui.avatar.imagepicker.TAKE_PHOTO=Foto aufnehmen
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Kamerafehler
service.gui.security.encryption.required=Verschlüsselung benötigt
service.protocol.ICE_FAILED=Verbindung konnte nicht aufgebaut (ICE fehlgeschlagen, kein Relay gefunden)
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
+service.systray.MODE=Tray-Symbol Modus
+service.systray.mode.NATIVE=Standard
+service.systray.mode.DISABLED=Deaktiviert
+service.systray.mode.APPINDICATOR=AppIndicator (Unity, KDE, nicht Standard-Gnome 3; kann unter Debian abstürzen)
+service.systray.mode.APPINDICATOR_STATIC=AppIndicator statisch (keine Untermenus für Konten)
+service.systray.CLI_NOTE=Wenn die Auswahl nicht funktioniert, kann {0} mit der "--notray" option gestartet werden. Dies erzwingt den Modus "Deaktiviert" und zeigt das GUI. Die Änderung des Tray-Symbol Modus erfordert einen neustart.
impl.protocol.sip.XCAP_ERROR_TITLE=Fehler in den servergespeicherten SIP Kontakten
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=Ressource {0} kann nicht gelesen werden. Konto: {1}
@@ -818,9 +785,7 @@ impl.ldap.QUERY_CUSTOM=Benutzerdefinierte Abfrage
impl.ldap.QUERY_CUSTOM_HINT={0} dient als Platzhalter für den Suchbegriff.
impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=Automatisch Platzhalter/Wildcard zum Suchbegriff hinzufügen
impl.ldap.QUERY_PHOTO_INLINE=Fotos gemeinsam mit den anderen Attributen abfragen
-impl.ldap.NEW=Neu
impl.ldap.EDIT=Bearbeiten
-impl.ldap.REMOVE=&Entfernen
impl.ldap.ENABLED=Aktiv
impl.ldap.SERVER_NAME=Name
impl.ldap.SERVER_NAME_EXAMPLE=Mein LDAP-Server
@@ -853,6 +818,12 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=homePhone
impl.ldap.PHONE_PREFIX=Telefon-Präfix
impl.ldap.PHONE_PREFIX_EXAMPLE=Bsp.: 00
+# SIP Protocol
+impl.protocol.sip.INVALID_ADDRESS=''{0}'' ist keine gültige SIP-Adresse.
+
+#Jabber Protocol
+impl.protocol.jabber.INVALID_ADDRESS=''{0}'' ist keine gültige XMPP JID.
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=Adressbuch
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=Suche im Mac OS X-Adressbuch aktivieren
@@ -867,9 +838,7 @@ plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT=Outlook als Standard-E-Mail-Anw
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Google-Kontakte
-impl.googlecontacts.NEW=Neu
impl.googlecontacts.EDIT=Bearbeiten
-impl.googlecontacts.REMOVE=&Entfernen
impl.googlecontacts.ENABLED=Aktiv
impl.googlecontacts.ACCOUNT_NAME=Konto
impl.googlecontacts.SAVE=&Speichern
@@ -878,6 +847,10 @@ impl.googlecontacts.USERNAME=Benutzername
impl.googlecontacts.PASSWORD=Passwort
impl.googlecontacts.PREFIX=Telefon-Präfix
impl.googlecontacts.WRONG_CREDENTIALS=Falsche Anmeldedaten für Google-Konto {0}
+impl.googlecontacts.OAUTH_DIALOG_TITLE=Google Contacts Authorisierung
+impl.googlecontacts.INSTRUCTIONS=<html><p><b>Klicken Sie auf den Link um dem Google Contacts Plugin Zugriff auf das Konto zu erlauben.</b><br><br>Wenn Sie dem Link folgen, wird eine Website im Browser geöffnet. Melden Sie sich mit Ihrem Google-Konto an und gestatten den Zugriff. Nach der Genehmigung wird eine code angezeigt. Kopieren Sie diesen Code in das Textfeld und klicken Sie auf 'Speichern'</p><p>Dies muss nur einmal durchgeführt werden. Der Code wird für künftige Zugriffe gespeichert.</p></html>
+impl.googlecontacts.CODE=Code:
+impl.googlecontacts.HYPERLINK_TEXT=Hier klicken um Zugriff auf {0} zu genehmigen
# account info
plugin.accountinfo.TITLE=Kontoinformationen
@@ -908,11 +881,8 @@ plugin.accountinfo.ORGANIZATION=Firma:
plugin.accountinfo.JOB_TITLE=Beruf:
plugin.accountinfo.ABOUT_ME=Ãœber mich:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
-plugin.accountinfo.USER_PICTURES=Benutzerfotos
plugin.accountinfo.GLOBAL_ICON=Globalen Avatar verwenden
plugin.accountinfo.LOCAL_ICON=Diesen Avatar verwenden:
-plugin.accountinfo.CHANGE=Ändern
-plugin.accountinfo.ONLY_MESSAGE=Nur Nachrichten
# connection info
plugin.connectioninfo.TITLE=Verbindungsinformationen
@@ -932,52 +902,15 @@ plugin.aimaccregwizz.USERNAME=AIM-Name:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Benutzername und Passwort
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Neues Benutzerkonto anlegen
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Wenn Sie kein AIM-Konto haben, klicken Sie hier, um ein neues Konto zu erstellen.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Standardmäßige Servereinstellungen überschreiben
# branding
plugin.branding.ABOUT_WINDOW_TITLE=Ãœber {0}
plugin.branding.LOGO_MESSAGE=Open Source VoIP && Instant Messaging
-plugin.branding.LOADING=Lade
plugin.branding.ABOUT_MENU_ENTRY=&Ãœber Jitsi
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>{1} ist derzeit unter aktiver Entwicklung. Die Version, welche Sie derzeit verwenden, ist NUR EXPERIMENTELL und KÖNNTE möglicherweise NICHT wie erwartet funktionieren. Bei {2} finden Sie mehr Informationen.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 Copyright <b>jitsi.org</b>. Alle Rechte vorbehalten. <a href="http://jitsi.org">https://jitsi.org</a></font></DIV>
-plugin.branding.LICENSE=<DIV color={0}><b>Jitsi</b> steht unter der Lizenz der LGPL (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
+plugin.branding.COPYRIGHT_LICENSE=<DIV><font size=3 color={0}>Copyright 2003-{1} <a href="{2}"><b>{3}</b></a>, alle Rechte vorbehalten.</font><br><br>{4} steht unter der <a href="{5}">{6}</a>.</DIV>
plugin.busylampfield.PICKUP=Anruf holen
-# Dict protocol
-service.protocol.DICTIONARIES=Wörterbücher
-plugin.dictaccregwizz.ANY_DICTIONARY=Alle Wörterbücher
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Alle Wörterbücher von {0}
-plugin.dictaccregwizz.FIRST_MATCH=Erster Treffer
-plugin.dictaccregwizz.NO_MATCH=Keine Treffer
-plugin.dictaccregwizz.MATCH_RESULT=Keine Definitionen für "{0}" gefunden. Möglicherweise meinten Sie:\n
-plugin.dictaccregwizz.INVALID_DATABASE=Das aktuelle Wörterbuch "{0}" existiert nicht mehr auf dem Server.
-plugin.dictaccregwizz.INVALID_STRATEGY=Die aktuelle Strategie ist auf dem Server nicht verfügbar.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=Das Dict-Service-Protokoll
-plugin.dictaccregwizz.HOST=Servername
-plugin.dictaccregwizz.SERVER_INFO=Serverinformationen
-plugin.dictaccregwizz.STRATEGY_SELECTION=Strategieauswahl
-plugin.dictaccregwizz.STRATEGY_LIST=Liste der Strategien:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Suche Strategien
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=Wenn keine Übersetzung gefunden wurde, bestimmt die Strategie, wie ähnliche Wörter zu finden sind. Zum Beispiel: die "Präfix-Strategie" sucht Wörter, die den gleichen Anfang (Präfix) wie das zu übersetzende Wort haben.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Dict-Kontoinformationen
-plugin.dictaccregwizz.FIRST_ACCOUNT=Diese Seite erstellt ihr erstes Wörterbuchkonto auf dict.org.\n\nSie können weitere Wöterbuchserver mit "Konto hinzufügen" angeben. Geben sie den Namen des Wöterbuchservers im Feld "Host" an.
-plugin.dictaccregwizz.THREAD_CONNECT=Verbindungsaufbau zum Server
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=Verbindungsaufbau fehlgeschlagen. Dies ist kein Dict-Server oder der Server ist nicht erreichbar.
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=Rufe Strategien ab
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Keine Strategien auf dem Server gefunden
-plugin.dictaccregwizz.POPULATE_LIST=Liste wird geladen
-plugin.dictaccregwizz.CLOSING_CONNECTION=Schließe Verbindung
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Um den Facebook-Chat nutzen zu können, müssen Sie einen Benutzernamen <br>auf Facebook unter "Kontoeinstellungen" erstellen.</a><br><br>Achtung: Nachdem Sie einen Benutzernamen erstellt haben, müssen Sie sich von Facebook abmelden.<br>Es kann einige Minuten dauern, bis Sie den Benutzernamen hier verwenden können!</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=Facebook-Chat-Protokoll
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=E-Mail:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Benutzername und Passwort
-
# generalconfig
plugin.generalconfig.AUTO_START={0} beim Systemstart automatisch starten
plugin.generalconfig.CHATALERTS_ON_MESSAGE=Zeige Benachrichtigungen in Taskleiste/Dock
@@ -987,9 +920,6 @@ plugin.generalconfig.SHOW_HISTORY=Zeige
plugin.generalconfig.HISTORY_SIZE=vorherige Nachrichten in neuen Chats
plugin.generalconfig.SEND_MESSAGES_WITH=Sende Nachrichten mit:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=Chat-Fenster in den Vordergrund holen
-plugin.generalconfig.ERROR_PERMISSION=Sie haben nicht die Berechtigung, den Autostart auszuschalten
-plugin.generalconfig.TRANSPARENCY=Transparenz
-plugin.generalconfig.ENABLE_TRANSPARENCY=Transparenz aktivieren
plugin.generalconfig.DEFAULT_LANGUAGE=Sprache
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Die Änderungen werden erst beim nächsten Start aktiv.
plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0}% übersetzt
@@ -1005,6 +935,8 @@ plugin.generalconfig.REMOVE_SPECIAL_PHONE_SYMBOLS=Vor dem Wählen Sonderzeichen
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS=Buchstaben in Telefonnummern in Ziffern umwandeln
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS_EXAMPLE=Bsp. +1-800-ANRUFE -> +1-800-267833
plugin.generalconfig.SIP_CALL_CONFIG=SIP
+plugin.generalconfig.XMPP_CONFIG=XMPP
+plugin.generalconfig.XMPP_USE_ALL_RESOURCES=Alle Ressourcen verwenden um die Funktionalität eines Kontakts zu ermitteln
plugin.generalconfig.OPUS_CONFIG=Opus
plugin.generalconfig.OPUS_AUDIO_BANDWIDTH=Abtastrate:
plugin.generalconfig.OPUS_BITRATE=Durchschnittliche Ãœbertragungsrate (kbps):
@@ -1018,6 +950,7 @@ plugin.generalconfig.SILK_ALWAYS_ASSUME_PACKET_LOSS=Paketverlust immer annehmen:
plugin.generalconfig.SILK_SAT=Sprachaktivitätsschwelle (0 bis 1):
plugin.generalconfig.SILK_ADVERTISE_FEC=FEC-Unterstützung in SDP angeben:
plugin.generalconfig.RESTORE=Voreinstellungen wiederherstellen
+plugin.generalconfig.MINIMIZE_NOT_HIDE=Hauptfenster minimieren statt zu schliessen oder verstecken
# gibberish accregwizz
plugin.gibberishaccregwizz.PROTOCOL_NAME=Gibberish
@@ -1076,13 +1009,10 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Kommentar
plugin.jabberaccregwizz.RESOURCE=Ressource
plugin.jabberaccregwizz.AUTORESOURCE=Erzeuge Ressource automatisch
plugin.jabberaccregwizz.PRIORITY=Priorität
-plugin.jabberaccregwizz.XMPP_ERROR=XMPP-Fehler
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Unbekannter XMPP-Fehler ({0}). Überprüfen Sie, ob der Name des Servers richtig ist.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Die Passwörter stimmen nicht überein.
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Standardmäßige Servereinstellungen überschreiben
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Erweiterte Einstellungen
+plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Standardmässige Servereinstellungen überschreiben
plugin.jabberaccregwizz.USE_ICE=ICE verwenden
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=Google's Jingle/ICE Variante verwenden (experimentell)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=STUN/TURN-Server automatisch konfigurieren
plugin.jabberaccregwizz.SUPPORT_TURN=TURN aktivieren
plugin.jabberaccregwizz.TURN_USERNAME=TURN-Benutzername
@@ -1110,11 +1040,8 @@ plugin.jabberaccregwizz.DISABLE_CARBON=Nachrichtenkopien deaktivieren
plugin.jabberaccregwizz.DTMF_AUTO=Automatische Auswahl zwischen RTP und Inband
plugin.jabberaccregwizz.SERVER_OPTIONS=Server-Optionen
plugin.jabberaccregwizz.CHANGE_PASSWORD=Kontopasswort ändern
-plugin.jabberaccregwizz.NEW_PASSWORD=Neues Passwort
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Neues Passwort bestätigen
plugin.jabberaccregwizz.PORT_FIELD_INVALID=Bitte eine gültige Portnummer eingeben um fortzufahren.
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=Das Konto muss angemeldet sein um das Passwort zu ändern.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=Das Passwort ist leer.
plugin.jabberaccregwizz.TLS_REQUIRED=Die Verbindung verwendet kein SSL/TLS, eine Passwortänderung wird daher nicht unterstützt.
plugin.jabberaccregwizz.PASSWORD_CHANGED=Das Passwort wurde erfolgreich geändert
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=Der XMPP-Server unterstützt keine Passwortänderungen.
@@ -1128,21 +1055,6 @@ plugin.jabberaccregwizz.RESET=Zurücksetzen
plugin.jabberaccregwizz.RESET_DESCRIPTION=Auf globale Einstellungen zurücksetzen
plugin.jabberaccregwizz.DISABLE_JINGLE=Jingle deaktivieren (Audio- und Videoanrufe mit XMPP)
-# mailbox
-plugin.mailbox.OUTGOING=Ausgehende Meldung:
-plugin.mailbox.INCOMING=Eingehende Meldung:
-plugin.mailbox.WAIT_TIME=Warten, bis Anruf an den Anrufbeantworter weitergeleitet wurde
-plugin.mailbox.MAX_MESSAGE_TIME=Maximale Dauer eingehender Meldungen
-plugin.mailbox.CONFIRM=Bestätigen
-plugin.mailbox.DEFAULTS=Voreinstellungen
-plugin.mailbox.MAILBOX=Anrufbeantworter
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN/Live Messenger
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Das MSN/Live Messenger-Protokoll.
-plugin.msnaccregwizz.USERNAME=E-Mail:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=Kontoinformationen
-
# plugin manager
plugin.pluginmanager.INSTALL=Installieren
plugin.pluginmanager.UNINSTALL=Deinstallieren
@@ -1171,9 +1083,9 @@ plugin.sipaccregwizz.SERVER_PORT=Server-Port
plugin.sipaccregwizz.PROXY=Proxy
plugin.sipaccregwizz.PROXY_PORT=Proxy-Port
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Bevorzugter Transport
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Erweiterte Optionen
plugin.sipaccregwizz.PROXY_OPTIONS=Proxy-Server-Optionen
plugin.sipaccregwizz.PROXY_AUTO=Proxy-Server automatisch konfigurieren
+plugin.sipaccregwizz.PROXY_FORCE_BYPASS=Proxy-Sicherheitsprüfung deaktivieren (nur für Hochverfügbarkeitsszenarien)
plugin.sipaccregwizz.ENABLE_PRESENCE=Anwesenheitsfunktion aktivieren (SIMPLE)
plugin.sipaccregwizz.FORCE_P2P_PRESENCE=Anwesenheitsmodus "Peer-To-Peer" erzwingen
plugin.sipaccregwizz.OFFLINE_CONTACT_POLLING_PERIOD=Abfrageintervall für Offline-Kontakte (in Sekunden)
@@ -1191,8 +1103,6 @@ plugin.sipaccregwizz.DTMF_AUTO=Automatische Auswahl zwischen RTP und Inband (kei
plugin.sipaccregwizz.DTMF_RTP=RTP (RFC2833 / RFC4733)
plugin.sipaccregwizz.DTMF_SIP_INFO=SIP INFO
plugin.sipaccregwizz.DTMF_INBAND=Inband
-plugin.sipaccregwizz.REGISTER=REGISTER
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Servervoreinstellungen überschreiben
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Verschlüsselte Anrufe zulassen
plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=Unterstützung von ZRTP in der Protokollsignalisierung anzeigen
plugin.sipaccregwizz.AUTH_NAME=Name für die Anmeldung
@@ -1213,10 +1123,10 @@ plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=Anrufbeantworter Abruf-URI
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Die Passwörter stimmen nicht überein.
plugin.sipaccregwizz.NO_CERTIFICATE=<keines> (reguläre Anmeldung verwenden)
plugin.sipaccregwizz.SAVP_OPTION=RTP/SAVP Transport-Attribut
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=Aus (nur RTP/AVP wird angeboten)
plugin.sipaccregwizz.SAVP_OPTION_1=Zwingend (nur RTP/SAVP anbieten und annehmen)
plugin.sipaccregwizz.SAVP_OPTION_2=Optional (RTP/SAVP zuerst anbieten, dann RTP/AVP)
-plugin.sipaccregwizz.ENABLE_SDES_ATTRIBUTE=S-Descriptor Verschlüsselung aktivieren (auch bekannt als SDES oder SRTP)
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=Aktivierte Verschlüsselungsprotokolle und Priorität:
plugin.sipaccregwizz.CIPHER_SUITES=Aktivierte Verschlüsselungs-Suiten
plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>{0} versucht automatisch alle Anrufe mit ZRTP zu verschlüsseln. Beide Gesprächsteilnehmer hören und sehen eine Benachrichtigung sobald eine sichere Verbindung hergestellt wurde. Die erweiterten Einstellungen auf dieser Seite sollten ohne Expertenwissen nicht geändert werden.</div></html>
@@ -1230,15 +1140,6 @@ plugin.skinmanager.DEFAULT_SKIN=Standard Skin
plugin.skinmanager.ADD_NEW_SKIN=Neuen Skin hinzufügen...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=Der Standard-Skin der Anwendung.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=SSH ist ein Protokoll für die verschlüsselte Verbindung zu anderen Computern.
-plugin.sshaccregwizz.USERNAME=Benutzerkennung:
-plugin.sshaccregwizz.IDENTITY_FILE=Identitätsdatei:
-plugin.sshaccregwizz.KNOWN_HOSTS=Bekannte Server:
-plugin.sshaccregwizz.OPTIONAL=Optional
-plugin.sshaccregwizz.ACCOUNT_DETAILS=Kontodetails
-
# status update
plugin.autoaway.AUTO_STATUS=Automatisch abwesend
plugin.autoaway.ENABLE_CHANGE_STATUS=Status automatisch auf "abwesend" setzen
@@ -1286,22 +1187,6 @@ plugin.whiteboard.DESELECT=Auswahl aufheben
plugin.whiteboard.DELETE=Löschen
plugin.whiteboard.PROPERTIES=Einstellungen
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Das Yahoo!-Protokoll.
-plugin.yahooaccregwizz.USERNAME=Benutzername:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=Kontoinformationen
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=Das Zeroconf-Protokoll (Bonjour).
-plugin.zeroaccregwizz.FIRST_NAME=Vorname:
-plugin.zeroaccregwizz.LAST_NAME=Nachname:
-plugin.zeroaccregwizz.EMAIL=E-Mail:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=Bonjour-Kontakte merken?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=Kontoinformationen
-plugin.zeroaccregwizz.USERID=Benutzerkennung
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Das Google Talk-Protokoll
@@ -1315,19 +1200,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, das Portal für IP-Teleko
plugin.iptelaccregwizz.USERNAME=Benutzername
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=Bei iptel.org anmelden
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIP und Chat
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Benutzername
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Passwort wiederholen
plugin.sip2sipaccregwizz.EMAIL=E-Mail Adresse
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=Um Hilfe für diesen Dienst zu erhalten, besuchen Sie bitte die Seite<br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>Die E-Mail Adresse wird verwendet, um Nachrichten des Anrufbeantworters und Benachrichtigungen über verpasste Anrufe zu erhalten sowie um ein vergessenes Passwort zurückzusetzen</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>Um Hilfe für diesen Dienst zu erhalten, besuchen Sie bitte die Seite<a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=Bestehendes sip2sip.info-Konto
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Kostenloses sip2sip.info-Konto erstellen
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP && Sofortnachrichten
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=Um Hilfe für diesen Dienst zu erhalten, besuchen Sie bitte die Seite<br>http://ippi.fr
@@ -1336,6 +1213,8 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=Existierendes ippi-Konto
plugin.ippiaccregwizz.CREATE_ACCOUNT=Kostenloses ippi-Konto erstellen
# key binding chooser
+plugin.keybindings.WAITING=Kurzbefehl hinzufügen...
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Gesprächsfenster schließen
plugin.keybindings.CHAT_COPY=Kopieren
plugin.keybindings.CHAT_CUT=Ausschneiden
@@ -1358,10 +1237,10 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=Aktion
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=Primäre Tastenkombination
plugin.keybindings.globalchooser.SHORTCUT_SECOND=Sekundäre Tastenkombination
plugin.keybindings.globalchooser.PRESS_BTN=Taste drücken um Verknüpfung zu setzen
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=Warte
plugin.keybindings.globalchooser.PUSH_TO_TALK=Sprechtaste
plugin.keybindings.globalchooser.ENABLE_SPECIAL=Erkennung von Spezialtasten aktivieren
plugin.keybindings.PLUGIN_NAME=Tastenkombinationen
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Chat
plugin.keybindings.MAIN=Hauptfenster
plugin.keybindings.GLOBAL=Systemweit
@@ -1389,6 +1268,7 @@ plugin.notificationconfig.tableheader.SOUND=Ton über Benachrichtigungsgerät ab
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=Ton über Wiedergabegerät abspielen
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=Ton über PC-Lautsprecher abspielen
plugin.notificationconfig.tableheader.DESCRIPTION=Beschreibung der Benachrichtigung
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Eingehender Anruf
plugin.notificationconfig.event.SecurityMessage=Sicherheitsmitteilung
plugin.notificationconfig.event.IncomingFile=Eingehende Datei
@@ -1490,6 +1370,7 @@ impl.neomedia.configform.VIDEO=Video
impl.neomedia.configform.H264=H.264
impl.neomedia.configform.H264.defaultIntraRefresh=Zyklische Intra-Aktualisierung
impl.neomedia.configform.H264.defaultProfile=Standard-Kodierungsprofil
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=Baseline
impl.neomedia.configform.H264.defaultProfile.high=High
impl.neomedia.configform.H264.defaultProfile.main=Main
@@ -1520,7 +1401,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=Aktuelles Passwort:
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Neues Passwort:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Passwort bestätigen:
plugin.securityconfig.masterpassword.MP_TITLE=Master-Passwort
-plugin.securityconfig.masterpassword.MP_NOT_SET=(keines)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=Falsches aktuelles Passwort, bitte wiederholen.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=Das Master-Passwort ist falsch.
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Die Änderung des Passworts ist fehlgeschlagen
@@ -1536,7 +1416,7 @@ plugin.securityconfig.masterpassword.COL_PASSWORD=Passwort
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(unbekannt)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(nicht entschlüsselbar)
plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=Gespeicherte Passwörter
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=&Entfernen
+plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=Entfernen
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=Alle entfernen
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=Sind Sie sicher, dass alle Passwörter entfernt werden sollen?
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=Alle Passwörter entfernen
@@ -1632,7 +1512,7 @@ plugin.globalproxy.PROXY_PORT=Proxy-Portnummer
plugin.globalproxy.PROXY_USERNAME=Proxy-Benutzername
plugin.globalproxy.PROXY_PASSWORD=Proxy-Passwort
plugin.globalproxy.DESCRIPTION={0} verwendet von nun an diese Proxy-Konfiguration für alle Protokolle.\nDie Unterstützung für Proxy-Server befindet sich noch im Experimentierstadium und unterstützt noch nicht alle Protokolle. Die folgende Tabelle gibt weitere Hinweise:
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>XMPP</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
+plugin.globalproxy.PROTOCOL_SUPPORT=<html> <table> <tr> <td/> <td> SOSCKS4/5 </td> <td> SOSCKS4/5+Auth </td> <td> HTTP </td> <td> HTTP+Auth </td> </tr> <tr> <td>XMPP</td> <td>+</td> <td>+</td> <td>+</td> <td>+</td> </tr> <tr> <td>ICQ/AIM</td> <td>+</td> <td>+</td> <td>+</td> <td>+</td> </tr> </table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
plugin.globalproxy.FWD_DNS=DNS ebenfalls tunneln
plugin.globalproxy.FWD_DNS_NOTE=Hilfreich bei der Verwendung von Tor. Vermeidet die Offenlegung von DNS-Daten indem der gesamte DNS-Datenverkehr über den Tor-Proxy umgeleitet wird. Wird erst nach einem Neustart aktiv.
@@ -1670,7 +1550,6 @@ plugin.provisioning.RESTART_WARNING=Die Änderungen werden erst beim nächsten S
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=UUID in die Zwischenablage kopieren
plugin.provisioning.CLIPBOARD_FAILED=UUID konnte nicht in die Zwischenablage kopiert werden
-plugin.provisioning.EXIT_ON_FAIL=Programm beenden wenn die Provisionierung fehlschlägt
plugin.provisioning.CREDENTIALS=Zuletzt gespeicherte Anmeldedaten
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=Soll das gespeicherte Provisionierungspasswort wirklich entfernt werden?
plugin.provisioning.PROV_FAILED=Provisionierung fehlgeschlagen
@@ -1737,8 +1616,6 @@ util.dns.DNSSEC_WARNING=<html><div width="600">{0} hat versucht den Server <b>{1
#plugin spellcheck
plugin.spellcheck.TITLE=Rechtschreibung und Grammatik
plugin.spellcheck.MENU=Rechtschreibung und Grammatik prüfen
-plugin.spellcheck.LANG=Sprache
-plugin.spellcheck.EDIT_PERSONAL_DICT=Bearbeiten
plugin.spellcheck.ENABLE_SPELL_CHECK=Rechtschreibprüfung aktivieren
plugin.spellcheck.dialog.FIND=Nächster Fehler
plugin.spellcheck.dialog.REPLACE=Ersetzen
diff --git a/resources/languages/resources_el.properties b/resources/languages/resources_el.properties
index d9d9292..e60d690 100644
--- a/resources/languages/resources_el.properties
+++ b/resources/languages/resources_el.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Εγώ
service.gui.ACCOUNT_REGISTRATION_WIZARD=Οδηγός ΚαταχώÏησης ΛογαÏιασμοÏ
service.gui.ACCOUNTS=ΛογαÏιασμοί
service.gui.ADD=&ΠÏοσθήκη
-service.gui.ADD_ACCOUNT=ΠÏοσθήκη λογαÏιασμοÏ
service.gui.ADD_CONTACT=&ΠÏοσθήκη επαφής
service.gui.ADD_AUTHORIZED_CONTACT=ΠÏόσθεσε την/τον {0} στη λίστα των επαφών σου
service.gui.ADD_CONTACT_TO_CONTACTLIST=ΠÏόσθεσε την επαφή στην λίστα των επαφών σου
@@ -42,20 +52,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Σφάλμα Ï€Ïοσθήκης επαφής
service.gui.ADD_CONTACT_EXIST_ERROR=Η επαφή {0} υπάÏχει ήδη στη λίστα επαφών σας.
service.gui.ADD_CONTACT_NETWORK_ERROR=Ο διακομιστής δεν απάντησε στο αίτημα Ï€Ïοσθήκης της επαφής με κωδικό: {0}.
service.gui.ADD_CONTACT_NOT_SUPPORTED=Αποτυχία Ï€Ïοσθήκης της επαφής με κωδικό: {0}. Η λειτουÏγία δεν υποστηÏίζεται.
-service.gui.ADD_CONTACT_IDENTIFIER=Εισάγετε στο παÏακάτω πεδίο το αναγνωÏιστικό της επαφής που θέλετε να Ï€Ïοσθέσετε.
-service.gui.ADD_CONTACT_WIZARD=Οδηγός Ï€Ïοσθήκης επαφής
service.gui.ADD_CONTACT_NOT_CONNECTED=Θα Ï€Ïέπει να είστε συνδεδεμένοι για να Ï€Ïοσθέσετε μια επαφή. ΠαÏακαλώ συνδεθείτε στον επιλεγμένο παÏοχέα υπηÏεσιών και Ï€Ïοσπαθείστε ξανά.
service.gui.ADD_GROUP_LOCAL_ERROR=Αποτυχία Ï€Ïοσθήκης της ομάδας με όνομα: {0}. Το Ï€Ïόβλημα Ï€Ïοέκυψε κατά τη διάÏκεια μίας τοπικής λειτουÏγίας εισόδου/εξόδου.
service.gui.ADD_GROUP_EXIST_ERROR=Η ομάδα {0} υπάÏχει ήδη στη λίστα επαφών σας. ΠαÏακαλώ επιλέξτε ένα άλλο όνομα.
service.gui.ADD_GROUP_NET_ERROR=Αποτυχία Ï€Ïοσθήκης της ομάδας με όνομα: {0}. Το Ï€Ïόβλημα Ï€Ïοέκυψε λόγω αποτυχίας του δικτÏου. ΠαÏακαλώ ελέγξτε τη σÏνδεσή σας στο δίκτυο και δοκιμάστε ξανά.
service.gui.ADD_GROUP_ERROR=Αποτυχία Ï€Ïοσθήκης της ομάδας με όνομα: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=Το όνομα της ομάδας δεν Ï€Ïέπει να είναι κενό.
-service.gui.ADD_GROUP=ΔημιουÏγία ομάδας
-service.gui.ADD_SUBCONTACT=&ΠÏοσθήκη υποεπαφής
service.gui.ADDRESS=ΔιεÏθυνση
service.gui.ADMINISTRATOR=διαχειÏιστής
service.gui.ADVANCED=&Για Ï€ÏοχωÏημένους
-service.gui.ALL=&Όλα
service.gui.ALL_CONTACTS=&Όλες οι επαφές
service.gui.ALTERNATE_ADDRESS=Εναλλακτική διεÏθυνση
service.gui.APPLY=&ΕφαÏμογή
@@ -65,7 +70,6 @@ service.gui.AT=σε
service.gui.AUTHORIZE=&Εξουσιοδότησε
service.gui.AUTHORIZATION_ACCEPTED=Ο/Η {0} αποδέχτηκε το αίτημά σας για εξουσιοδότηση.
service.gui.AUTHENTICATION_FAILED=Η ταυτοποίηση απέτυχε για {0}. Ο κωδικός που εισάγατε δεν είναι έγκυÏος.
-service.gui.AUTHENTICATION_REQUESTED=Άιτηση ταυτοποίησης
service.gui.AUTHENTICATION_REQUESTED_SERVER=Ο εξυπηÏετητής {0} ζήτησε την ταυτοποίησή σας.
service.gui.AUTHENTICATION_REJECTED=Ο χÏήστης {0} απέÏÏιψε την αίτηση εξουσιοδότησης που ζητήσατε.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} ταυτοποίηση
@@ -107,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=Στο παÏακάτω πεδίο μποÏεÎ
service.gui.CHANGE_NICKNAME_ERROR=ΠαÏουσιάστηκε σφάλμα κατα την αλλαγή του ψευδωνÏμου
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Το ψευδόνυμο υπάÏχει ήδη
service.gui.CHANGE_VIDEO_QUALITY=Αλλαγή ποιότητας απομακÏυσμένου βίντεο
-service.gui.CHAT_CONFERENCE_LABEL=ΣυνέδÏια
service.gui.CHAT_CONFERENCE_ITEM_LABEL=ΣυνέδÏιο του {0}
service.gui.CHAT_ROOM_ALREADY_JOINED=Έχετε ήδη συνδεθεί στο δωμάτιο συζήτησης {0}.
service.gui.CHAT_ROOM_CONFIGURATION=Ïυθμίσεις του δωματίου συζήτησης {0}
@@ -121,18 +124,14 @@ service.gui.CHAT_ROOM_USER_LEFT=απσυνδέθηκε από το {0}
service.gui.CHAT_ROOM_USER_KICKED=απομακÏÏνθηκε από το {0}
service.gui.CHAT_ROOM_USER_QUIT=έφυγε από το {0}
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=Η αποστολή μηνυμάτων είναι απαγοÏευμένη (το δικαίωμα ομιλίας σας ανακλήθηκε)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Αποθήκευση του δωματίου συζήτησης για μελλονική χÏήση
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=ΔιαγÏαφή του επιλεγμένου δωματίου συζητήσεων από την λίστα των αποθηκευμένων δωματίων
service.gui.CHAT_ROOM_NAME=Όνομα δωματίου συζήτησης
service.gui.CLEAR_CUSTOM_MESSAGES=ΔιαγÏαφή Ï€ÏοσαÏμοσμένων μηνυμάτων
service.gui.ROOM_NAME=Δωμάτιο συζήτησης
-service.gui.AUTOJOIN=Αυτόματη σÏνδεση
service.gui.CHANGE_PASSWORD=Αλλαγή ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€Ïόσβασης
service.gui.CHAT_ROOM_NAME_INFO=Εισάγετε στο παÏακάτω πεδίο το όνομα του δωματίου συζήτησης που θέλετε να δημιουÏγήσετε.
service.gui.CHAT_ROOM_NOT_EXIST=Το δωμάτιο {0} δε βÏέθηκε στον εξυπηÏετητή {1}. ΠαÏακαλώ επαληθεÏστε ότι το όνομα που πληκτÏολογήσατε είναι σωστό.
service.gui.CHAT_ROOM_NOT_CONNECTED=ΠÏέπει να είστε συνδεδεμένος για να εισέλθετε στο δωμάτιο συζήτησης {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=ΠÏέπει να είστε συνδεδεμένος για να μποÏέσετε να φÏγετε από ένα δωμάτιο συζήτησης.
-service.gui.CHAT_ROOM_NOT_JOINED=ΠÏέπει Ï€Ïώτα να έχετε εισέλθει στο δωμάτιο συζήτησης για να μποÏέσετε να εκτελέσετε πεÏαιτέÏω ενέÏγειες με αυτό.
service.gui.CHAT_ROOM_OPTIONS=Ρυθμίσεις δωματίου συζήτησης
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Το δωμάτιο συζήτησης {0} απαιτεί εγγÏαφή για να συνδεθείτε.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Το δωμάτιο συζήτησης {0} ζήτησε κωδικό Ï€Ïόσβασης.
@@ -151,22 +150,18 @@ service.gui.CLEAR=ΚαθαÏισμός
service.gui.CLOSE=Κλείσιμ&ο
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Λάβατε ένα νέο μήνυμα Ï€Ïιν από λιγότεÏο από 2 δευτεÏόλεπτα. ΣίγουÏα θέλετε να κλείσετε αυτή τη συζήτηση;
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=ΥπάÏχουν μεταφοÏές αÏχείων σε εξέλιξη. ΣίγουÏα θέλετε να τις ακυÏώσετε;
-service.gui.CONFIRM=Επιβεβαίωση
service.gui.CONNECTED_STATUS=Συνδεθήκατε
service.gui.CONNECTING=Γίνεται σÏνδεση...
service.gui.CONNECTING_STATUS=Συνδέεται
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Γίνεται σÏνδεση...
service.gui.CONNECTION=ΣÏνδεση
-service.gui.CONNECTION_FAILED_MSG=Η σÏνδεση απέτυχε για τον ακόλουθο λογαÏιασμό: Όνομα χÏήστη: {0}, όνομα εξυπηÏετητή: {1}. ΠαÏακαλώ ελέγξτε τη σÏνδεσή σας στο δίκτυο ή επικοινωνήστε με τον διαχειÏιστή δικτÏου για πεÏισσότεÏες πληÏοφοÏίες.
service.gui.CONNECTION_EXPIRED_MSG=Είστε αποσυνδεδεμένος από τον εξυπηÏετητή {0}.
service.gui.CONTACT_NAME=Κωδικός Ταυτοποίησης ή ΑÏιθμός
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Η επιλεγμένη επαφή {0} δεν υποστηÏίζει τηλεφωνία.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Η επιλεγμένη επαφή {0} δεν υποστηÏίζει συνδιάσκεψη με chat.
service.gui.CONTACT_PAUSED_TYPING=Ο/Η {0} έπαυσε την πληκτÏολόγηση του μηνÏματος
service.gui.CONTACT_TYPING=Ο/Η {0} πληκτÏολογεί ένα μήνυμα
service.gui.CONTACT_TYPING_SEND_FAILED=Ουπς.. δεν μποÏέσαμε να ενημεÏώσουμε τον/την {0} οτι γÏάφατε
service.gui.CONTACT_INFO=&ΠληÏοφοÏίες επαφής
-service.gui.CONTACTLIST=Λίστα επαφών
service.gui.CONTACTS=Επαφές
service.gui.COPY=&ΑντιγÏαφή
service.gui.COPY_LINK=ΑντιγÏαφή &συνδέσμου
@@ -176,17 +171,14 @@ service.gui.CREATE_CHAT_ROOM=&ΔημιουÏγία δωματίου συζήτη
service.gui.CREATE_CHAT_ROOM_ERROR=Απέτυχε η δημιουÏγία του δωματίου συζήτησης {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=Οδηγός δημιουÏγίας δωματίου συζήτησης
service.gui.CREATE_CONFERENCE_CALL=&ΔημιουÏγία κλήσης για συνδιάσκεψη...
-service.gui.CREATE_CONFERENCE_CHAT=&ΔημιουÏγία συζήτησης για συνδιάσκεψη...
service.gui.CREATE_GROUP=&ΔημιουÏγία ομάδας...
service.gui.CREATE_GROUP_NAME=Στο παÏακάτω πεδίο εισάγετε το όνομα της ομάδας που θέλετε να δημιουÏγήσετε.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Η λίστα επαφών σας δεν πεÏιέχει καμία ομάδα. ΠαÏακαλώ δημιουÏγήστε Ï€Ïώτα μία ομάδα (ΑÏχείο/ΔημιουÏγία ομάδας).
service.gui.CREATE_VIDEO_BRIDGE=ΔημιουÏγία ενός &μεταγωγέα βίντεο...
service.gui.CREATE_VIDEO_BRIDGE_MENU=ΔημιουÏγία ενός &μεγαγωγέα βίντεο
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=ΔημιουÏγία / ΣÏνδεση τηλεδιάσκεψης
service.gui.CREATE_VIDEO_CONFERENCE=ΔημιουÏγία μιας νέας τηλεδιάσκεψης για αυτό το δωμάτιο συζητήσεων
service.gui.CONTACT_INFO_NOT_SUPPORTED=Η επαφή αυτή δεν υποστηÏίζει web contact info
service.gui.CUT=Απο&κοπή
-service.gui.DATE=ΗμεÏομηνία
service.gui.DELETE=ΔιαγÏαφή
service.gui.DENY=&ΆÏνηση
service.gui.DESKTOP_SHARING_WARNING=<b>Είστε σίγουÏα ότι θέλετε να ξεκινήσετε τον διαμοιÏασμό οθόνης;</b> <br> Πατώντας ΟΚ θα επιτÏέψετε στους συνομιλητές σας να βλέπουν την οθόνη σας.
@@ -197,7 +189,6 @@ service.gui.DISCONNECTED_STATUS=Αποσυνδεθήκατε
service.gui.DND_STATUS=Μην ενοχλείτε
service.gui.DO_NOT_ASK_AGAIN=Μη με ξαναÏωτήσεις
service.gui.DO_NOT_SHOW_AGAIN=Μην εμφανίσεις ξανά αυτό το μήνυμα
-service.gui.DOWNLOAD_NOW=&Κάντε download Ï„ÏŽÏα
service.gui.DRAG_FOR_SHARING=ΤÏαβήξτε εδώ ο,τιδήποτε θέλετε να μοιÏαστείτε
service.gui.DURATION=διάÏκεια
service.gui.DESTROY_CHATROOM=ΔιαγÏάψτε το δωμάτιο συζητήσεων
@@ -218,7 +209,6 @@ service.gui.ERROR_RECEIVED_FROM=Λάβαμε ένα σφάλμα από τον/Ï
service.gui.ESTIMATED_TIME=Υπολογιζόμενος χÏόνος:
service.gui.EVENTS=Συμβάντα
service.gui.EXIT=Έ&ξοδος
-service.gui.EXTENDED_CRITERIA=Εκτεταμένα κÏιτήÏια
service.gui.GENERAL=Γενικά
service.gui.GENERAL_ERROR=Γενικό σφάλμα
service.gui.GROUP_NAME=Όνομα ομάδος
@@ -260,7 +250,6 @@ service.gui.FONT_ITALIC=Πλάγια γÏάμματα
service.gui.FONT_SIZE=Μέγεθος
service.gui.FONT_STYLE=Στυλ
service.gui.FONT_UNDERLINE=ΥπογÏάμμιση
-service.gui.FROM={0} από {1}
service.gui.GRANT_OWNERSHIP=Απόδωση κυÏιότητος
service.gui.GRANT_ADMIN=Ανάθεση ΔιαχειÏÏƒÏ„Î¿Ï ....
service.gui.GRANT_MODERATOR=Ανάθεση διαμεσολαβητή
@@ -286,7 +275,6 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=Είστε βέβαιος ότι επιθ
service.gui.HISTORY_REMOVE_ERROR=ΠαÏουσιάστηκε σφάλμα κατα την διαγÏαφή των τοπικά αποθηκευμένα μηνυμάτων.
service.gui.HOME=Οικία
service.gui.HOME_PAGE=ΑÏχική σελίδα
-service.gui.HOUR=ÎÏα
service.gui.ICE=ICE
service.gui.IDENTIFIER=ΑναγνωÏιστικό
service.gui.IGNORE=&ΠαÏάβλεψη
@@ -310,13 +298,10 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=ΠÏόσκληση επαφών στÎ
service.gui.INVITE_REASON=Λόγος Ï€Ïόσκλησης
service.gui.IS_CALLING=Ο/Η {0} καλεί...
service.gui.IS_NOW=Το {0} είναι Ï„ÏŽÏα {1}
-service.gui.JITSI_WARNING=Ο SIP Communicator άλλαξε Ï€Ïόσφατα ονομασία στο Jitsi.<br/>Αν θέλετε η έκδοσή σας να είναι ενημεÏωμένη, τότε παÏακαλώ κατεβάστε το Jitsi Ï„ÏŽÏα.<br/><br/>ΛυποÏμαστε για την ÏŒ,ποια ταλαιπωÏία που αυτό ίσως σας Ï€Ïοκαλεί.<br/><br/>Η ομάδα ανάπτυξης του Jitsi
-service.gui.JITSI_WARNING_TITLE=Ο SIP Communicator έγινε Ï„ÏŽÏα Jitsi
service.gui.JOIN=&Ελάτε να συμμετάσχετε και σεις
service.gui.JOIN_AS=Îα σ&υμμετέχετε ως
service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=Συνδεθείτε σε μια Ï€ÏουπάÏχουσα τηλεδιάσκεψη
service.gui.JOIN_VIDEO=Συνδεθείτε με βίντεο
-service.gui.CLOSE_CHAT_ROOM_DIALOG=Κ&λείσιμο
service.gui.JOB_TITLE=Τίτλος εÏγασίας
service.gui.JOIN_CHAT_ROOM=&Μπείτε στο Δωμάτιο συνομιλίας chat
service.gui.JOIN_CHAT_ROOM_TITLE=Μπείτε στο Δωμάτιο συνομιλίας chat
@@ -329,7 +314,6 @@ service.gui.KICK_FAILED=Αποτυχία απόÏÏιψης
service.gui.KICK_FAILED_GENERAL_ERROR=Αποτυχία Î±Ï€Î¿ÎºÎ»ÎµÎ¹ÏƒÎ¼Î¿Ï Ï„Î¿Ï… {0}. Σημειώθηκε γενικό σφάλμα στον εξυπηÏετητή.
service.gui.KICK_FAILED_NOT_ALLOWED=Αποτυχία Î±Ï€Î¿ÎºÎ»ÎµÎ¹ÏƒÎ¼Î¿Ï Ï„Î¿Ï… {0}. Ο ιδιοκτήτης και ο διαχειÏιστής του δωματίου δεν μποÏοÏν να αποκλειστοÏν.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Αποτυχία Î±Ï€Î¿ÎºÎ»ÎµÎ¹ÏƒÎ¼Î¿Ï Ï„Î¿Ï… {0}. Δεν έχετε αÏκετά δικαιώματα γι' αυτή την ενέÏγεια.
-service.gui.LAST=Τελευταίος/α
service.gui.LAST_NAME=Επώνυμο
service.gui.LEAVE=&Έξοδος
service.gui.LIMIT_REACHED_FOR_IP=Διαθέτετε πάÏα πολλές εγγÏαφές από την τοπική διεÏθνση IP και ο διακομιστής {0} δεν σας επιτÏέπει να ανοίξετε καμία επιπλέον.
@@ -349,7 +333,6 @@ service.gui.MESSAGE=Μήνυμα
service.gui.MISSED_CALLS_TOOL_TIP=Αναπάντητες κλήσεις από:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= και {0} επιπλέον
service.gui.MODERATOR=μεσολαβητής (moderator)
-service.gui.MORE=Δείτε πεÏισσότεÏα
service.gui.MORE_LABEL=ΠεÏισσότεÏα
service.gui.MOVE=κίνηση
service.gui.MOVE_SUBCONTACT=Μ&ετακινείστε την επαφή
@@ -358,7 +341,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=Η επαφή που επιλέξατε είÎ
service.gui.MOVE_SUBCONTACT_QUESTION=Είστε βέβαιος ότι θέλετε να μετακινήσετε το {0} στο {1};
service.gui.MOVE_TO_GROUP=&Μετακινείστε στην ομάδα
service.gui.MOVE_CONTACT=Μετακινείστε την επαφή
-service.gui.MOVE_CONTACT_ERROR=&Η επαφή δεν μποÏεί να μετακινηθεί
service.gui.MSG_DELIVERY_FAILURE=Το παÏαπάνω μήνυμα δεν ήταν δυνατόν να παÏαδοθεί
service.gui.MSG_DELIVERY_NOT_SUPPORTED=Το Ï€Ïωτόκολλο που χÏησιμοποιείτε δεν υποστηÏίζει μηνÏματα εκτός σÏνδεσης. ΜποÏείτε να δοκιμάσετε να επικοινωνήσετε με τον/την {0} μέσω ενός άλλου Ï€Ïωτοκόλλου ή αναμείνατε μέχÏι να συνδεθεί.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Σημειώθηκε ένα εσωτεÏικό σφάλμα. ΠÏόκειται μάλλον για κάποιο bug. ΠαÏακαλώ αναφέÏατέ το εδώ: https://jitsi.org/Development/BugsAndIssues.
@@ -372,7 +354,6 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=Θα Ï€Ïέπει να συνδεθείÏ
service.gui.MULTIPLE_LOGINS=Συνδεθήκατε παÏαπάνω από μία φοÏά με τον ίδιο λογαÏιασμό. Ο εξής λογαÏιασμός: Όνομα χÏήστη: {0}, Όνομα διακομιστή: {1} είναι αυτή τη στιγμή χωÏίς σÏνδεση.
service.gui.MY_CHAT_ROOMS=ΠÏοσθήκη ενός δωματίου συζητήσεων
service.gui.MY_CHAT_ROOMS_TITLE=ΠÏοσθήκη ενός δωματίου συζητήσεων
-service.gui.MUTE=Σίγαση
service.gui.MUTUALLY_ON_HOLD_STATUS=Κλήση σε κÏάτηση και από τους 2 συνομιλοÏντες
service.gui.NAME=Όνομα
service.gui.NETWORK=Δίκτυο
@@ -404,7 +385,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=ΕκτόςΛίσταςΕπαφών
service.gui.SD_QUALITY=Κανονική ποιότητα
service.gui.OFFLINE=ΧωÏίς σÏνδεση
service.gui.OK=&Εντάξει
-service.gui.OLDER_CALLS=ΠαλαιότεÏες κλήσεις
service.gui.ONLINE=Με σÏνδεση
service.gui.OPEN=Άνοιξε
service.gui.OPEN_FILE_FROM_IMAGE=Κάντε διπλό κλικ για να ανοίξετε το αÏχείο.
@@ -416,7 +396,6 @@ service.gui.OPEN_ON_ACTIVITY=Άνοιγμα όταν υπάÏχει δÏαστη
service.gui.OPEN_ON_MESSAGE=Άνοιγμα μόνο όταν υπάÏχει κάποιο μÏνημα
service.gui.OPEN_ON_IMPORTANT_MESSAGE=Άνοιγμα μόνο όταν υπάÏχει κάποιο σημαντικό μήνυμα
service.gui.OR=ή
-service.gui.OR_ENTER_PHONE_NUMBER=Ή πληκτÏολογείστε έναν αÏιθμό τηλεφώνου εδώ...
service.gui.ORGANIZATION=ΟÏγανισμός
service.gui.OTHER=Άλλο
service.gui.chat.role.OWNER=Ιδιοκτήτης
@@ -442,7 +421,6 @@ service.gui.PRESS_ENTER_FOR_SUGGESTIONS="Enter" για υποδείξεις
service.gui.PRESS_FOR_CALL_INFO=Πατήστε για πληÏοφοÏίες κλήσης
service.gui.PRESS_TO_OPEN_CRM=Κάντε κλίκ για να ανοίξετε την εφαÏμογή CRM
service.gui.PREVIOUS=ΠÏοηγοÏμενος
-service.gui.PREVIOUS_TOOLTIP=Αναζήτηση στις παλαιότεÏες συνομιλίες
service.gui.PRINT=&ΕκτÏπωση
service.gui.PROACTIVE_NOTIFICATION=γÏάφει ένα μήνυμα
service.gui.PROBLEMS_ENCOUNTERED=Î’Ïέθηκαν Ï€Ïοβλήματα
@@ -458,7 +436,6 @@ service.gui.RECONNECTION_LIMIT_EXCEEDED=Συνδεθήκατε και αποσυ
service.gui.RE_REQUEST_AUTHORIZATION=Îέα αίτηση εξουσιοδότησης
service.gui.REFERRED_STATUS=ΑνεφέÏθη
service.gui.REJECT=&ΑπόÏÏιψη
-service.gui.REMIND_ME_LATER=ΥπενθÏμισέ μου αÏγότεÏα
service.gui.REMEMBER_PASSWORD=ΚÏάτα τον Κωδικό Εισόδου στη μνήμη
service.gui.REMOVE=&ΔιαγÏαφή
service.gui.REMOVE_ACCOUNT=&ΔιαγÏαφή ΛογαÏιασμοÏ
@@ -484,29 +461,20 @@ service.gui.REVOKE_ADMIN=Ανάκληση δικαιωμάτων ΔιαχειÏÎ
service.gui.REVOKE_MODERATOR=Ανάκληση μεσολαβητή (moderator)
service.gui.REVOKE_MEMBERSHIP=Ανάκληση ιδιότητος Μέλους
service.gui.REVOKE_VOICE=Ανάκληση φωνής
-service.gui.ROOT_GROUP=Ομάδα Root
service.gui.SAVE=&Αποθήκευση
-service.gui.SAVE_AS_DEFAULT=Αποθήκευση ως Ï€Ïοεπιλογή
service.gui.SEARCH=&Αναζήτηση
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Κάντε κλικ στο παÏακάτω κουμπί για να εμφανισθοÏν όλα τα Δωμάτια Chat στον επιλεχθέντα Διακομιστή. Κατόπιν επιλέξτε εκείνον στον οποίο θέλετε να μπείτε και κάντε κλικ στο κουμπί "ΣÏνδεση"
service.gui.SEARCH_STRING_CONTACT_SOURCE=Αναζητημένη επαφή
service.gui.SECURITY=Ασφάλεια
-service.gui.SELECT_ACCOUNT=Επιλογή λογαÏιασμοÏ
service.gui.SELECT_COLOR=Επιλογή χÏώματος
service.gui.SELECT_GROUP=Επιλογή ομάδος
-service.gui.SELECT_GROUP_WIZARD_MSG=Ο παÏακάτω κατάλογος πεÏιέχει όλες τις ομάδες στον Κατάλογο των επαφών σας. Επιλέξτε εκείνη στην οποία θέλετε να Ï€Ïοσθέσετε την Îέα Επαφή.
service.gui.SELECT_NO_GROUP=Καμία ομάδα
-service.gui.SELECT_GROUP_WIZARD=Επιλέξτε την ομάδα
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=Ο παÏακάτω κατάλογος πεÏιέχει όλους τους λογαÏιασμοÏÏ‚ που υποστηÏίζουν την δυνατότητα για ταυτόχÏονο chat από πολλοÏÏ‚ χÏήστες. Επιλέξτε ποιον θα χÏησιμοποιήσετε, για να φτιάξετε το δικό σας δωμάτιο chat.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=Ο παÏακάτω κατάλογος πεÏιέχει όλους τους καταχωÏημένους λογαÏιασμοÏÏ‚. Επιλέξτε εκείνον που θέλετε να χÏησιμοποιείτε, για να επικοινωνείτε με την Îέα Επαφή.
-service.gui.SELECT_PROVIDERS_WIZARD=Επιλογή λογαÏιασμοÏ
service.gui.SELECT_VIDEO_CONFERENCE=Επιλέξτε μια τηλεδιάσκεψη
service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Επιλέξτε ένα δωμάτιο συζητήσεων από τη λίστα και πατήστε στο OK για να το Ï€Ïοσθέσετε.
service.gui.SEND=&Αποστολή
service.gui.SEND_FILE=Αποστολή &αÏχείου
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Δεν υπάÏχουν πληÏοφοÏίες για αυτή την Επαφή.
service.gui.SEND_MESSAGE=&Αποστολή ενός μηνÏματος.
-service.gui.SEND_AS_SMS=Αποστολή υπό μοÏφή SMS
service.gui.SEND_PRIVATE_MESSAGE=Αποστολή Î¹Î´Î¹Ï‰Ï„Î¹ÎºÎ¿Ï Î¼Î·Î½Ïματος
service.gui.SEND_SMS=Α&ποστολή SMS
service.gui.SEND_SMS_DETAILS=Îα θυμάστε ότι Ï€Ïέπει να καταχωÏείτε τον αÏιθμό με την διεθνή μοÏφή, πχ. αÏχίζοντας με το +30 για την Ελλάδα, +302311250040
@@ -545,7 +513,6 @@ service.gui.STREET=Οδός
service.gui.SUBJECT=Θέμα
service.gui.SUMMARY=ΠεÏίληψη
service.gui.TELEPHONY=Τηλεφωνία
-service.gui.TODAY=ΣήμεÏα
service.gui.TOOLS=&ΕÏγαλεία
service.gui.TRANSFER=Μετα&φοÏά
service.gui.TO=@Σε:
@@ -555,7 +522,6 @@ service.gui.TRANSFER_CALL_TO=ΜεταφοÏά σε:
service.gui.TRANSPARENCY_NOT_ENABLED=Οι Ï„Ïέχουσες Ïυθμίσεις σας δεν υποστηÏίζουν την Διαφάνεια.
service.gui.TYPE_YOUR_REQUEST=ΠληκτÏολογείστε το αίτημά σας εδώ
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Δεν ήταν δυνατό να αλλάξει η ποιότητα του βίντεο για αυτή την κλήση.
-service.gui.UNMUTE=Διακοπή σίγασης
service.gui.USER_IDENTIFIER=Κωδικός ταυτοποίησης ΧÏήστη:
service.gui.USER_EXISTS_ERROR=Αυτός ο χÏήστης υπάÏχει ήδη στο επιλεγμένο δίκτυο. ΠαÏακαλώ επιλέξτε ένα άλλο δίκτυο.
service.gui.USERNAME_NULL=ΠαÏακαλώ συμπληÏώστε το όνομα χÏήστη και τον κωδικό σας.
@@ -568,7 +534,6 @@ service.gui.USE_PROVISIONING=ΧÏήση απ'ευθείας αÏχικοποίη
service.gui.VALUE=Τιμή
service.gui.VIDEO_CALL=&Κλήση Βίντεο
service.gui.VIA=μέσω
-service.gui.VIA_SMS=Μέσω SMS
service.gui.VIEW=&Εμφάνιση
service.gui.VIEW_HISTORY=&Εμφάνιση ΙστοÏικοÏ
service.gui.VIEW_SMILEYS=Εμφάνιση &smileys
@@ -588,9 +553,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=ΡÏθμιση ήχου
service.gui.WAITING_AUTHORIZATION=Αναμονή εξουσιοδότησης
service.gui.WARNING=ΠÏοειδοποίηση
service.gui.YES=Îαι
-service.gui.YESTERDAY=Χθες
-service.gui.EXISTING_ACCOUNT_ERROR=Ο λογαÏιασμός που οÏίσατε είναι ήδη καταχωÏημένος.
-service.gui.NEW_MAIL=<b>'Εχετε νέο ΤαχυδÏομείο!</b><br/><b>Από:</b> {0} {1} <br/><b>Θέμα:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=ΠαÏαλάβατε ένα νέο μήνυμα ταχυδÏομείου στο {0} <a href="{1}">inbox</a>:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=ΠαÏαλάβατε δÏο νέα μηνÏματα ταχυδÏομείου στο {0} <a href="{1}">inbox</a>:<br/>
service.gui.NEW_GMAIL_FOOTER=ακόμη μία συνομιλία που δεν διαβάσατε στο <a href="{0}">inbox</a>.<br/>
@@ -614,7 +576,6 @@ service.gui.SECURITY_ERROR=Σφάλμα ασφαλείας
service.gui.SPEED=ΤαχÏτητα:
service.gui.SILENT_MEMBER=σιωπηλό μέλος
service.gui.NON_SECURE_CONNECTION=Δε μποÏεί να γίνει ασφαλής σÏνδεση στο λογαÏιασμό {0}. Εάν επιθυμείτε να συνδεθείτε σε μη ασφαλή διακομιστή, ενεÏγοποιήστε την επιλογή "Îα επιτÏέπονται μη ασφαλείς συνδέσεις" στις Ïυθμίσεις του λογαÏÎ¹Î±ÏƒÎ¼Î¿Ï ÏƒÎ±Ï‚.
-service.gui.UPDATE=ΕνημέÏωση
service.gui.MOBILE_PHONE=Κινητό
service.gui.VIDEO_PHONE=Βίντεο
service.gui.WORK_PHONE=ΕÏγασία
@@ -649,12 +610,10 @@ service.gui.callinfo.CALL_INFORMATION=ΠληÏοφοÏίες κλήσης
service.gui.callinfo.CALL_IDENTITY=Ταυτότητα
service.gui.callinfo.PEER_COUNT=Πλήθος συμμετεχόντων
service.gui.callinfo.IS_CONFERENCE_FOCUS=Εστίαση συνεδÏίασης
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=ΚÏυπτογÏάφηση ενεÏγοποιημένη
service.gui.callinfo.CALL_TRANSPORT=Μέσο του ÎºÎ±Î½Î±Î»Î¹Î¿Ï ÏƒÎ·Î¼Î±Ï„Î¿Î´ÏŒÏ„Î·ÏƒÎ·Ï‚
service.gui.callinfo.CALL_DURATION=ΔιάÏκεια κλήσης
service.gui.callinfo.TLS_PROTOCOL=ΠÏωτόκολλο TLS
service.gui.callinfo.TLS_CIPHER_SUITE=ΚÏυπτογÏάφηση TLS
-service.gui.callinfo.TLS_SERVER_CERTIFICATE_CHAIN=Αλυσίδα πιστοποιητικών του διακομιστή TLS
service.gui.callinfo.TLS_CERTIFICATE_CONTENT=Το πεÏιεχόμενο του Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¹Î·Ï„Î¹ÎºÎ¿Ï TLS εμφανίζεται παÏακάτω.
service.gui.callinfo.VIEW_CERTIFICATE=ΠÏοβολή πιστοποιητικοÏ
service.gui.callinfo.CODEC=Κωδικοποιητής / Συχνότητα
@@ -664,7 +623,6 @@ service.gui.callinfo.AUDIO_INFO=ΠληÏοφοÏίες ήχου
service.gui.callinfo.VIDEO_INFO=ΠληÏοφοÏίες βίντεο
service.gui.callinfo.LOCAL_IP=Τοπική IP / ΘÏÏα
service.gui.callinfo.REMOTE_IP=ΑπομακÏυσμένη IP / ΘÏÏα
-service.gui.callinfo.BANDWITH=ΤαχÏτητα σÏνδεσης
service.gui.callinfo.LOSS_RATE=Ποσοστό απώλειας
service.gui.callinfo.RTT=RTT
service.gui.callinfo.JITTER=ΘόÏυβος
@@ -674,10 +632,13 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=ΠÏωτόκολλο ανταλλαγής κλειδιών
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=Εκτεταμένος Ï„Ïπος υποψηφίου ICE
service.gui.callinfo.ICE_STATE=Κατάσταση ICE
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=Συλλογή υποψηφίων διευθÏνσεων
service.gui.callinfo.ICE_STATE.RUNNING=Έλεγχος συνδεσιμότητας
service.gui.callinfo.ICE_STATE.COMPLETED=ΟλοκληÏώθηκε
service.gui.callinfo.ICE_STATE.FAILED=Απέτυχε
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=Τοπική IP / ΘÏÏα
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=Local reflexive IP / Port
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=Local relayed IP / Port
@@ -698,11 +659,12 @@ service.gui.ALWAYS_TRUST=Îα εμπιστεÏεσαι πάντα αυτό το
service.gui.CERT_DIALOG_TITLE=Επαλήθευση ΠιστοποιητικοÏ
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>Το {0} δε μποÏεί να επαληθεÏσει τη ταυτότητα του διακομιστή κατά τη σÏνδεση με <br><b>{1}</b>.<br><br> Το πιστοποιητικό ασφαλείας δεν είναι αξιόπιστο, οπότε η ταυτότητα του διακομιστή δε μποÏεί να πιστοποιηθεί αυτόματα.<br><br> Θέλετε να συνδεθείτε; <br> Για πεÏισσότεÏες πληÏοφοÏίες κάντε κλικ στο "Εμφάνιση ΠιστοποιητικοÏ".</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>Το {0} δε μποÏεί να επαληθεÏσει τη ταυτότητα του Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¹Î·Ï„Î¹ÎºÎ¿Ï Î±ÏƒÏ†Î±Î»ÎµÎ¯Î±Ï‚ του διακομιστή.<br><br> Το πιστοποιητικό ασφαλείας δεν είναι αξιόπιστο, οπότε η ταυτότητα του διακομιστή δε μποÏεί <br> να πιστοποιηθεί αυτόματα. Θέλετε να συνδεθείτε; <br><br> Για πεÏισσότεÏες πληÏοφοÏίες επιλέξτε "Εμφάνιση ΠιστοποιητικοÏ".</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>Το {0} δε μποÏεί να επαληθεÏσει την ταυτότητα του συνδεόμενου πελάτη.<br><br> Το πιστοποιητικό ασφαλείας δεν είναι αξιόπιστο, οπότε η ταυτότητα του διακομιστή δε μποÏεί <br> να πιστοποιηθεί αυτόματα. Θέλετε να δεχτείτε αυτή τη σÏνδεση; <br><br> Για πεÏισσότεÏες πληÏοφοÏίες επιλέξτε "Εμφάνιση ΠιστοποιητικοÏ".</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>Το {0} δε μποÏεί να επαληθεÏσει την ταυτότητα του ομότιμου {1}.<br><br> Το πιστοποιητικό ασφαλείας δεν είναι αξιόπιστο, οπότε η ταυτότητα του διακομιστή δε μποÏεί να <br> πιστοποιηθεί αυτόματα. Θέλετε να συνδεθείτε; <br><br> Για πεÏισσότεÏες πληÏοφοÏίες επιλέξτε "Εμφάνιση ΠιστοποιητικοÏ".</html>
service.gui.CONTINUE_ANYWAY=Αγνόηση και συνέχεια
service.gui.CERT_INFO_CHAIN=Αλυσίδα πιστοποιητικών:
service.gui.CERT_INFO_ISSUED_TO=Εκδόθηκε Ï€Ïος
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Κοινό Όνομα:
service.gui.CERT_INFO_O=ΟÏγανισμός:
service.gui.CERT_INFO_C=ΧώÏα:
@@ -721,12 +683,10 @@ service.gui.CERT_INFO_SIGN_ALG=ΥπογÏαφή ΑλγοÏίθμου:
service.gui.CERT_INFO_PUB_KEY_INFO=ΠληÏοφοÏίες Δημοσίου ΚλειδιοÏ
service.gui.CERT_INFO_ALG=ΑλγόÏιθμος:
service.gui.CERT_INFO_PUB_KEY=Δημόσιο Κλειδί:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} bytes: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} bits
service.gui.CERT_INFO_EXP=Εκθέτης:
service.gui.CERT_INFO_KEY_SIZE=Μέγεθος κλειδί:
service.gui.CERT_INFO_SIGN=ΥπογÏαφή:
-service.gui.CONTINUE=Συνέχεια
service.gui.SHOW_CERT=Εμφάνιση ΠιστοποιητικοÏ
service.gui.HIDE_CERT=ΑπόκÏυψη ΠιστοποιητικοÏ
@@ -749,12 +709,9 @@ service.gui.security.SECURE_AUDIO=ΚÏυπτογÏαφημένο ηχητικό
service.gui.security.AUDIO_NOT_SECURED=Μη κÏυπτογÏαφημένο ηχητικό σήμα
service.gui.security.SECURE_VIDEO=ΚÏυπτογÏαφημένο βίντεο
service.gui.security.VIDEO_NOT_SECURED=Βίντεο μη κÏυπτογÏαφημένο
-service.gui.security.NO_VIDEO=ΧωÏίς βίντεο
-service.gui.security.CIPHER=ΑλγόÏιθμος κÏυπτογÏάφησης: {0}
service.gui.security.CALL_SECURED_TOOLTIP=Κλήση κÏυπτογÏαφημένη. Για πεÏισσότεÏες πληÏοφοÏίες πατήστε εδώ.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Κλήση μη κÏυπτογÏαφημένη.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Κάντε κλικ εδώ για να συγκÏίνετε το μυστκό συνθηματικό με τον συνομιλητή σας.
-service.gui.security.COMPARE_WITH_PARTNER=ΣυγκÏίνατε με το συνομιλητή σας και κάντε κλικ στη κλειδαÏιά για επιβεβαίωση.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=ΣυγκÏίνατε με το συνομιλητή:
service.gui.security.STRING_COMPARED=Το συνθηματικό πιστοποιήθηκε!
@@ -772,20 +729,14 @@ service.gui.avatar.imagepicker.CLICK=Κάντε κλικ και Χαμογελά
service.gui.avatar.imagepicker.IMAGE_FILES=ΑÏχεία Εικόνας
service.gui.avatar.imagepicker.IMAGE_PICKER=ΦωτογÏαφία
service.gui.avatar.imagepicker.IMAGE_SIZE=Μέγεθος εικόνας
-service.gui.avatar.imagepicker.INITIALIZING=ΑÏχικοποίηση σε εξέλιξη
service.gui.avatar.imagepicker.RESET=Reset
service.gui.avatar.imagepicker.SET=ΚαθοÏισμός (Set)
service.gui.avatar.imagepicker.TAKE_PHOTO=Λήψη φωτογÏαφίας
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Σφάλμα της κάμεÏας
service.gui.security.encryption.required=Απαιτείται κÏυπτογÏάφηση!
service.protocol.ICE_FAILED=Δεν ήταν δυνατή η δημιουÏγία σÏνδεσης (το ICE απέτυχε και δεν βÏέθηκε αναμεταδότης)
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
impl.protocol.sip.XCAP_ERROR_TITLE=ΠαÏουσιάστηκε σφάλμα στη λίστα επαφών SIP
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=Ο πόÏος {0} δεν μπόÏεσε να διαβαστεί. ΛογαÏιασμός: {1}
@@ -815,9 +766,7 @@ impl.ldap.QUERY_CUSTOM=ΠÏοσαÏμοσμένο εÏώτημα
impl.ldap.QUERY_CUSTOM_HINT=ΧÏησιμοποιήστε το {0} ως σÏμβολο κÏάτησης θέσης για την αναζήτηση.
impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=Αυτόματη Ï€Ïοσθήκη Î¼Ï€Î±Î»Î±Î½Ï„Î­Ï ÏƒÏ„Î¿Î½ ÏŒÏο του εÏωτήματος
impl.ldap.QUERY_PHOTO_INLINE=Λήψη φωτογÏαφιών μαζί με τα άλλα χαÏακτηÏιστικά
-impl.ldap.NEW=Îέος/ Îέα
impl.ldap.EDIT=επεξεÏγασία
-impl.ldap.REMOVE=ΑπομάκÏυνση
impl.ldap.ENABLED=ΕνεÏγοποιήθηκε
impl.ldap.SERVER_NAME=Όνομα διακομιστή
impl.ldap.SERVER_NAME_EXAMPLE=Ο LDAP διακομιστής μου
@@ -850,6 +799,10 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=τηλέφωνοΣπιτιοÏ
impl.ldap.PHONE_PREFIX=ΠÏόθεμα τηλεφώνου
impl.ldap.PHONE_PREFIX_EXAMPLE=Πχ: 00
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=Κατάλογος ΔιευθÏνσεων
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=ΕνεÏγοποίηση αναζήτησης στο Βιβλίο ΔιευθÏνσεων MacOSX Address
@@ -864,9 +817,7 @@ plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT=Κάντε το Outlook τον
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Επαφές Google
-impl.googlecontacts.NEW=Îέος/ Îέα
impl.googlecontacts.EDIT=επεξεÏγασία
-impl.googlecontacts.REMOVE=ΑπομάκÏυνση
impl.googlecontacts.ENABLED=ΕνεÏγοποιήθηκε
impl.googlecontacts.ACCOUNT_NAME=Όνομα λογαÏιασμοÏ
impl.googlecontacts.SAVE=Αποθήκευση
@@ -905,11 +856,8 @@ plugin.accountinfo.ORGANIZATION=Όνομα οÏγανισμοÏ:
plugin.accountinfo.JOB_TITLE=Τίτλος εÏγασίας:
plugin.accountinfo.ABOUT_ME=Σχετικά με μένα:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
-plugin.accountinfo.USER_PICTURES=ΦωτογÏαφίες ΧÏήστη
plugin.accountinfo.GLOBAL_ICON=ΧÏηση του Î³ÎµÎ½Î¹ÎºÎ¿Ï ÎµÎ¹ÎºÎ¿Î½Î¹Î´Î¯Î¿Ï…
plugin.accountinfo.LOCAL_ICON=ΧÏήση Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… εικονιδίου:
-plugin.accountinfo.CHANGE=Αλλαγή
-plugin.accountinfo.ONLY_MESSAGE=Μόνον μηνÏματα
# connection info
plugin.connectioninfo.TITLE=ΠληÏοφοÏίες σÏνδεσης
@@ -929,49 +877,12 @@ plugin.aimaccregwizz.USERNAME=Όνομα οθόνης για το ΑΙΜ
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Όνομα Οθόνης και Κωδικός Εισόδου
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=ΚαταχώÏηση νέου λογαÏιασμοÏ
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Σε πεÏίπτωση που δεν έχετε έναν λογαÏιασμό AIM, κάντε κλικ σε αυτό το κουμπί για να φτιάξετε έναν καινοÏÏγιο.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=ΠαÏάκαμψη των Ï€ÏοκαθοÏισμένων επιλογών του Διακομιστή
# branding
plugin.branding.ABOUT_WINDOW_TITLE=Σχετικά με το {0}
plugin.branding.LOGO_MESSAGE=VoIP Î‘Î½Î¿Î¹ÎºÏ„Î¿Ï ÎšÏŽÎ´Î¹ÎºÎ± && ΥπηÏεσία Άμεσων Μηνυμάτων (Instant Messaging)
-plugin.branding.LOADING=ΦοÏτώνει
plugin.branding.ABOUT_MENU_ENTRY=&ΠεÏί
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>Το {1} είναι Ï„Ïεχόντως υπό ανάπτυξη. Η έκδοση που Ï„Ïέχετε είναι απλώς πειÏαματική και ΙΣΩΣ ÎΑ ΜΗ δουλέψει όπως θα αναμένατε. Για παÏαπάνω πληÏοφοÏίες, παÏακαλώ ανατÏέξτε στο {2}.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 Copyright <b>jitsi.org</b>. Με την επιφÏλαξη όλων των νομίμων δικαιωμάτων. Επισκεφθείτε το <a href="http://jitsi.org">http://jitsi.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}>Το <b>Jitsi</b> διανέμεται με τους ÏŒÏους της LGPL (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=Λεξικά
-plugin.dictaccregwizz.ANY_DICTIONARY=Οποιοδήποτε Λεξικό
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Οποιοδήποτε Λεξικό από το {0}
-plugin.dictaccregwizz.FIRST_MATCH=ΠÏώτο ταίÏασμα
-plugin.dictaccregwizz.NO_MATCH=Δεν έγινε εφικτό κανένα ταίÏιασμα
-plugin.dictaccregwizz.MATCH_RESULT=Δεν βÏέθηκαν οÏισμοί για το "{0}", ίσως να εννοείτε:\n
-plugin.dictaccregwizz.INVALID_DATABASE=Το Ï„Ïέχον Λεξικό "{0}" δεν υπάÏχει πλέον σε αυτόν τον διακομιστή.
-plugin.dictaccregwizz.INVALID_STRATEGY=Η Ï„Ïέχουσα στÏατηγική δεν είναι διαθέσιμη στον διακομιστή.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=Το ΠÏωτόκολλο υπηÏεσιών Dict
-plugin.dictaccregwizz.HOST=ΚεντÏικός Υπολογιστής
-plugin.dictaccregwizz.SERVER_INFO=ΠληÏοφοÏίες για τον Διακομιστή
-plugin.dictaccregwizz.STRATEGY_SELECTION=Επιλογή ΣτÏατηγικής
-plugin.dictaccregwizz.STRATEGY_LIST=Κατάλογος στÏατηγικών:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Αναζήτηση των στÏατηγικών
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=Η στÏατηγική σε χÏήση, για αναζήτηση παÏόμοιων λέξεων, αν δεν βÏεθεί μία μετάφÏαση, χάÏη σε διαφοÏετικές Ï€Ïοσεγγίσεις. Για παÏάδειγμα, οι στÏατηγικές Prefix θα αναζητήσουν λέξεις που να αÏχίζουν όπως και η λέξη που θέλατε να μεταφÏάσετε.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=ΠληÏοφοÏίες ΛογαÏÎ¹Î±ÏƒÎ¼Î¿Ï Dict
-plugin.dictaccregwizz.FIRST_ACCOUNT=Αυτός ο Βοηθός (wizard) θα σας φτιάξει τον Ï€Ïώτο σας ΛογαÏισμό Dict, στο dict.org.\n\nΜποÏείτε να Ï€Ïοσθέσετε ένα νέο λεξικό πηγαίνοντας στον Βοηθό ΚαταχώÏησης ΛογαÏιασμών. ΣυμπληÏώστε το Πεδίο για τον host, με το λεξικό που θα θέλατε να Ï€Ïοσθέσετε.
-plugin.dictaccregwizz.THREAD_CONNECT=ΠÏοσπάθεια σÏνδεσης με τον Διακομιστή
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=Αποτυχία της Ï€Ïοσπάθειας σÏνδεσης. Είτε αυτός δεν είναι ένας διακομιστής dict, είτε ο διακομιστής είναι χωÏίς σÏνδεση.
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=ΣτÏατηγικές ανάκτησης
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Δεν εντοπίσθηκε καμία στÏατηγική στον Διακομιστή
-plugin.dictaccregwizz.POPULATE_LIST=Γεμίζει τον Κατάλογο
-plugin.dictaccregwizz.CLOSING_CONNECTION=Κλείσιμο σÏνδεσης
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Για να χÏησιμοποιήσετε το Facebook Chat, Ï€Ïέπει να φτιάξετε έναν "Username" <br>από τη σελίδα με τις "Ρυθμίσεις του ΛογαÏιασμοÏ" σας, στο Facebook.</a><br><br>Σημείωση: Όταν φτιάχνετε ένα Όνομα χÏήστη, Ï€Ïέπει να αποσυνδεθείτε από την ιστοσελίδα<br>και μποÏεί να χÏειασθεί αÏκετή ÏŽÏα μέχÏι να μποÏέσετε να μπείτε με το νέο σας όνομα χÏήστη!</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=Το ΠÏωτόκολλο για το Facebook Chat
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Όνομα χÏήστη:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Όνομα χÏήστη και Κωδικός Ï€Ïόσβασης
+
# generalconfig
plugin.generalconfig.AUTO_START=Αυτόματη εκκίνηση του {0} όταν ο υπολογιστής επανεκκινεί.
@@ -982,9 +893,6 @@ plugin.generalconfig.SHOW_HISTORY=Εμφάνιση
plugin.generalconfig.HISTORY_SIZE=Ï€Ïόσφατα μηνÏματα σε νέα chats
plugin.generalconfig.SEND_MESSAGES_WITH=Στείλτε μηνÏματα με το:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=ΜεταφοÏά του παÏαθÏÏου chat στο Ï€Ïοσκήνιο.
-plugin.generalconfig.ERROR_PERMISSION=Δεν διαθέτετε επαÏκή δικαιώματα για την απομάκÏυνση του autostart
-plugin.generalconfig.TRANSPARENCY=Διαφάνεια
-plugin.generalconfig.ENABLE_TRANSPARENCY=ΕνεÏγοποίηση διαφάνειας
plugin.generalconfig.DEFAULT_LANGUAGE=Διεπαφή Γλώσσας
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Οι αλλαγές σας θα ενεÏγοποιηθοÏν με την επόμενη επανεκκίνηση.
plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0}% μεταφÏασμένο
@@ -1043,13 +951,13 @@ plugin.ircaccregwizz.EXAMPLE_SERVER=Π.χ.: chat.freenode.net
plugin.ircaccregwizz.USE_SECURE_CONNECTION=ΧÏησιμοποιήστε ασφαλή σÏνδεση
plugin.ircaccregwizz.ENABLE_CONTACT_PRESENCE=ΕνεÏγοποίηση παÏουσίας
plugin.ircaccregwizz.ENABLE_CHAT_ROOM_PRESENCE=ΕνεÏγοποίηση παÏουσίας στα δωμάτια συζητήσεων
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE={0} ταυτοποίηση
+plugin.ircaccregwizz.SASL_USERNAME=Όνομα χÏήστη
# jabber accregwizz
-plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=Το Ï€Ïωτόκολλο XMPP
plugin.jabberaccregwizz.USERNAME=XMPP όνομα χÏήστη
plugin.jabberaccregwizz.PASSWORD_CONFIRM=Επιβεβαίωση ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€Ïόσβασης
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=Ταυτοποίηση και Κωδικός Ï€Ïόσβασης
plugin.jabberaccregwizz.CSERVER=Διακομιστής
plugin.jabberaccregwizz.SERVER=ΣÏνδεση με τον διακομιστή
plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=ΕνεÏγοποίηση λειτουÏγίας keep alive
@@ -1065,13 +973,9 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Σχόλιο
plugin.jabberaccregwizz.RESOURCE=ΠόÏοι
plugin.jabberaccregwizz.AUTORESOURCE=Αυτόματη δημιουÏγία πόÏων
plugin.jabberaccregwizz.PRIORITY=ΠÏοτεÏαιότητα
-plugin.jabberaccregwizz.XMPP_ERROR=Σφάλμα XMPP
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Άγνωστο σφάλμα XMPP ({0}). Ελέγξτε ότι το όνομα του διακομιστή είναι σωστό.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Οι κωδικοί Ï€Ïόσβασης δε ταιÏιάζουν.
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=ΠαÏάκαμψη των Ï€ÏοκαθοÏισμένων επιλογών του διακομιστή
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=ΠÏοχωÏημένες επιλογές
plugin.jabberaccregwizz.USE_ICE=ΧÏήση του ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=ΧÏησιμοποίησε το Jingle/ICE της Google (πειÏαματικό)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=Αυτόματος εντοπισμός (Auto-discover) διακομιστών STUN/TURN
plugin.jabberaccregwizz.SUPPORT_TURN=ΥποστήÏιξη του TURN
plugin.jabberaccregwizz.TURN_USERNAME=Όνομα χÏήστη για το TURN
@@ -1099,11 +1003,8 @@ plugin.jabberaccregwizz.DISABLE_CARBON=ΑπενεÏγοποίηση των μηÎ
plugin.jabberaccregwizz.DTMF_AUTO=Αυτόματο: Îα γίνεται αυτόματη επιλογή Î¼ÎµÏ„Î±Î¾Ï RTP και Inband
plugin.jabberaccregwizz.SERVER_OPTIONS=Επιλογές εξυπηÏετητή
plugin.jabberaccregwizz.CHANGE_PASSWORD=Αλλαγή ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€Ïόσβασης λογαÏιασμοÏ
-plugin.jabberaccregwizz.NEW_PASSWORD=Îέος κωδικός Ï€Ïόσβασης
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Επιβεβαίωση του νέου ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€Ïόσβασης
plugin.jabberaccregwizz.PORT_FIELD_INVALID=ΠαÏακαλώ συμπληÏώστε ένα έγκυÏο αÏιθμό θÏÏας για να συνεχίσετε.
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=ΠÏέπει να είστε συνδεδεμένος για να αλλάξετε τον κωδικό Ï€Ïόσβασης σας.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=Το συνθηματικό είναι κενό.
plugin.jabberaccregwizz.TLS_REQUIRED=Η σÏνδεση δεν χÏησιμοποιεί TLS, δεν θα επιχειÏηθεί αλλαγή συνθηματικοÏ.
plugin.jabberaccregwizz.PASSWORD_CHANGED=Το συνθηματικό άλλαξε με επιτυχία.
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=Ο διακομιστής XMPP δεν υποστηÏίζει την αλλαγή συνθηματικοÏ.
@@ -1117,25 +1018,9 @@ plugin.jabberaccregwizz.RESET=ΕπαναφοÏά
plugin.jabberaccregwizz.RESET_DESCRIPTION=ΕπαναφοÏά στις γενικές Ïυθμίσεις
plugin.jabberaccregwizz.DISABLE_JINGLE=ΑπενεÏγοποίηση Jingle (κλήσεις με εικόνα και ήχο μέσω XMPP).
-# mailbox
-plugin.mailbox.OUTGOING=ΕξεÏχόμενο Μήνυμα:
-plugin.mailbox.INCOMING=ΕισεÏχόμενα ΜηνÏματα:
-plugin.mailbox.WAIT_TIME=ΚαθυστέÏησε ωσότου η κλήση σταλεί στο φωνητικό ΤαχυδÏομείο (Voicemail)
-plugin.mailbox.MAX_MESSAGE_TIME=Μέγιστη ΔιάÏκεια ΕισεÏχομένου Μυνήματος
-plugin.mailbox.CONFIRM=Επιβεβαίωση
-plugin.mailbox.DEFAULTS=ΠÏοκαθοÏισμένες επιλογές
-plugin.mailbox.MAILBOX=ΓÏαμματοκιβώτιο
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Ένα ΠÏωτόκολλο για σÏνδεση και chat με την υπηÏεσία MSN.
-plugin.msnaccregwizz.USERNAME=Email:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=Ταυτοποίηση και Κωδικός Ï€Ïόσβασης
-
# plugin manager
plugin.pluginmanager.INSTALL=Εγκατάσταη
plugin.pluginmanager.UNINSTALL=Απεγκατάσταση
-plugin.pluginmanager.UPDATE=ΕνημέÏωση
plugin.pluginmanager.PLUGINS=ΠÏόσθετα Plug-ins
plugin.pluginmanager.URL=Url
plugin.pluginmanager.CHOOSE_FILE=Επιλογή ΑÏχείου
@@ -1160,7 +1045,6 @@ plugin.sipaccregwizz.SERVER_PORT=ΘÏÏα Διακομιστή
plugin.sipaccregwizz.PROXY=Διακομιστής διαμεσολάβησης (Proxy)
plugin.sipaccregwizz.PROXY_PORT=ΘÏÏα διακομιστή διαμεσολάβησης (Proxy)
plugin.sipaccregwizz.PREFERRED_TRANSPORT=ΠÏοτιμώμενη μεταφοÏά
-plugin.sipaccregwizz.ADVANCED_OPTIONS=ΠÏοχωÏημένες επιλογές
plugin.sipaccregwizz.PROXY_OPTIONS=Επιλογές Διακομιστή διαμεσολάβησης (Proxy)
plugin.sipaccregwizz.PROXY_AUTO=Αυτόματη ΡÏθμιση διακομιστή διαμεσολάβησης
plugin.sipaccregwizz.ENABLE_PRESENCE=ΕνεÏγοποίηση της ΠαÏουσίας (ΑΠΛΟ)
@@ -1180,8 +1064,6 @@ plugin.sipaccregwizz.DTMF_AUTO=Αυτόματο: Îα γίνεται αυτόμÎ
plugin.sipaccregwizz.DTMF_RTP=RTP ( σÏμφωνα με τις Ï€Ïοτάσεις RFC2833 / RFC 4733 )
plugin.sipaccregwizz.DTMF_SIP_INFO=SIP INFO
plugin.sipaccregwizz.DTMF_INBAND=Εντός εÏÏους
-plugin.sipaccregwizz.REGISTER=ΕΓΓΡΑΦΗ
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=ΠαÏάκαμψη των Ï€ÏοκαθοÏισμένων επιλογών του διακομιστή
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=ΕνεÏγοποίηση υποστήÏιξης για απόκÏυψη κλήσεων
plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=ΑναφέÏετε την υποστήÏιξη της ZRTP στο Ï€Ïωτόκολλο σηματοδότησης
plugin.sipaccregwizz.AUTH_NAME=Όνομα εξουσιοδότησης
@@ -1202,10 +1084,10 @@ plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=ΔιεÏθυνση ελέγχου τηÎ
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Οι κωδικοί Ï€Ïόσβασης που δώσατε δε ταιÏιάζουν.
plugin.sipaccregwizz.NO_CERTIFICATE=<κανένα> (χÏησιμοποίησε κανονική πιστοποίηση)
plugin.sipaccregwizz.SAVP_OPTION=Ένδειξη RTP/SAVP
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=ΑπενεÏγοποιημένο (υπόδειξη μόνο RTP/AVP)
plugin.sipaccregwizz.SAVP_OPTION_1=ΥποχÏεωτικό (Ï€ÏοσφοÏά και αποδοχή μόνο RTP/SAVP)
plugin.sipaccregwizz.SAVP_OPTION_2=ΠÏοαιÏετικό (Ï€ÏοσφοÏά RTP/SAVP Ï€Ïώτα, μετά RTP/AVP)
-plugin.sipaccregwizz.ENABLE_SDES_ATTRIBUTE=ΕνεÏγοποίηση S-Descriptor (αλλιώς γνωστό ως SDES ή SRTP)
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=Επιλέξτε τα ενεÏγοποιημένα Ï€Ïωτόκολλα κÏυπτογÏάφησης και την Ï€ÏοτεÏαιότητά τους:
plugin.sipaccregwizz.CIPHER_SUITES=ΕνεÏγοποιημένες σουίτες κÏυπτογÏάφησης:
plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>το {0} θα Ï€Ïοσπαθήσει να ασφαλίσει τις κλήσεις σας αυτόματα με το ZRTP και θα σας ειδοποιήσει ηχητικά και οπτικά μόλις εδÏαιώσει μια ασφαλή σÏνδεση. Αλλάξτε τις παÏακάτω Ïυθμίσεις μόνο εάν ξέÏετε Ï€Î¿Î»Ï ÎºÎ±Î»Î¬ τι κάνετε.</div></html>
@@ -1219,15 +1101,6 @@ plugin.skinmanager.DEFAULT_SKIN=ΠÏοεπιλεγμένο skin
plugin.skinmanager.ADD_NEW_SKIN=ΠÏοσθήκη νέου skin...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=Το Ï€ÏοκαθοÏισμένο skin της εφαÏμογής.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=Ένα ΠÏωτόκολλο για την σÏνδεση απομεμακÏυσμένων μηχανημάτων μέσω SSH.
-plugin.sshaccregwizz.USERNAME=Ταυτοποίηση λογαÏισμοÏ:
-plugin.sshaccregwizz.IDENTITY_FILE=Ταυτότητα ΑÏχείου:
-plugin.sshaccregwizz.KNOWN_HOSTS=ΚαταγεγÏαμμένοι υπολογιστές:
-plugin.sshaccregwizz.OPTIONAL=ΠÏοαιÏετικό
-plugin.sshaccregwizz.ACCOUNT_DETAILS=ΛεπτομέÏειες λογαÏιασμοÏ
-
# status update
plugin.autoaway.AUTO_STATUS=Auto Away
plugin.autoaway.ENABLE_CHANGE_STATUS=Αλλαγή καταστάσεως (status) όταν είμαστε μακÏιά
@@ -1275,22 +1148,6 @@ plugin.whiteboard.DESELECT=Αποεπιλογή
plugin.whiteboard.DELETE=ΔιαγÏαφή
plugin.whiteboard.PROPERTIES=Ιδιότητες
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Ένα Ï€Ïωτόκολλο για συνομιλία μέσω της υπηÏεσίας Yahoo.
-plugin.yahooaccregwizz.USERNAME=Όνομα χÏήστη:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=Ταυτοποίηση και Κωδικός Ï€Ïόσβασης:
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=ΠÏωτόκολλο της υπηÏεσίας Zeroconf (Bonjour)
-plugin.zeroaccregwizz.FIRST_NAME=Όνομα:
-plugin.zeroaccregwizz.LAST_NAME=Επίθετο:
-plugin.zeroaccregwizz.EMAIL=Email:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=Θυμάσαι τις επαφές Bonjour ;
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=Ταυτοποίηση και Κωδικός Ï€Ïόσβασης:
-plugin.zeroaccregwizz.USERID=Ταυτότητα ΧÏήστη:
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Το ΠÏωτόκολλο Google Talk
@@ -1304,19 +1161,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, the IP Telecommunications
plugin.iptelaccregwizz.USERNAME=Όνομα χÏήστη
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=ΕγγÏαφείτε στο iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIP και chat
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Όνομα χÏήστη
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=ΠληκτÏολογείστε ξανά τον Κωδικό Ï€Ïόσβασης
plugin.sip2sipaccregwizz.EMAIL=ΔιεÏθυνση Email
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=Για παÏαπάνω βοήθεια με αυτή την υπηÏεσία επισκεφθείτε το<br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>Η διεÏθυνση email χÏησιμοποιείται για αποστολή φωνητικών μηνυμάτων, <br>ειδοποιήσεων πεÏί αναπάντητων κλήσεων και για ανάκτηση χαμένων κωδικών Ï€Ïόσβασης</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>Για παÏαπάνω βοήθεια με αυτή την υπηÏεσία επισκεφθείτε το<a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=ΥπάÏχων λογαÏιασμός sip2sip.info
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=ΔημιουÏγία ενός δωÏεάν λογαÏÎ¹Î±ÏƒÎ¼Î¿Ï sip2sip.info
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP && ΥπηÏεσία ανταλλαγής Άμεσων Μηνυμάτων (Instant Messaging)
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=Για παÏαπάνω βοήθεια με αυτή την υπηÏεσία επισκεφθείτε το<br>http://ippi.fr
@@ -1325,6 +1174,7 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=ΥπάÏχων λογαÏιασμός ipp
plugin.ippiaccregwizz.CREATE_ACCOUNT=ΔημιουÏγείστε έναν δωÏεάν λογαÏιασμό ippi
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Κλείσιμο του παÏαθÏÏου του chat
plugin.keybindings.CHAT_COPY=Αντι&γÏαφή
plugin.keybindings.CHAT_CUT=Απο&κοπή
@@ -1347,10 +1197,10 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=Όνομα
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=ΠÏωτεÏουσα συντόμευση
plugin.keybindings.globalchooser.SHORTCUT_SECOND=ΔευτεÏεÏουσα συντόμευση
plugin.keybindings.globalchooser.PRESS_BTN=Πιέστε για να θέσετε τη συντόμευση
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=Αναμονή
plugin.keybindings.globalchooser.PUSH_TO_TALK=Κουμπί ομιλίας
plugin.keybindings.globalchooser.ENABLE_SPECIAL=ΕνεÏγοποίηση ανίχνευσης ειδικών πλήκτÏων
plugin.keybindings.PLUGIN_NAME=Keybindings
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Συζητήσεις
plugin.keybindings.MAIN=ΚυÏίως
plugin.keybindings.GLOBAL=Γενικές συντομεÏσεις
@@ -1378,6 +1228,7 @@ plugin.notificationconfig.tableheader.SOUND=ΑναπαÏαγωγή ήχου μέ
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=ΑναπαÏαγωγή ήχου μέσω της συσκευής αναπαÏαγωγής
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=ΑναπαÏαγωγή ήχου μέσω του ηχείου συστήματος
plugin.notificationconfig.tableheader.DESCRIPTION=ΠεÏιγÏαφή συμβάντος
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=ΕισεÏχόμενη κλήση
plugin.notificationconfig.event.SecurityMessage=Μήνυμα ασφαλείας
plugin.notificationconfig.event.IncomingFile=ΕισεÏχόμενο αÏχείο
@@ -1479,6 +1330,7 @@ impl.neomedia.configform.VIDEO=Βίντεο
impl.neomedia.configform.H264=Η.264
impl.neomedia.configform.H264.defaultIntraRefresh=ΠεÏιοδική ενδοανανέωση
impl.neomedia.configform.H264.defaultProfile=ΠÏοεπιλεγμένο Ï€Ïοφίλ κωδικοποίησης:
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=Βάση Η.264
impl.neomedia.configform.H264.defaultProfile.high=Υψηλή
impl.neomedia.configform.H264.defaultProfile.main=ΚυÏίως
@@ -1509,7 +1361,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=ΤÏέχων ΚωδικόÏ
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Βάλτε έναν νέο Κωδικό:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=ΞαναπληκτÏολογείστε τον Κωδικό Ï€Ïόσβασης:
plugin.securityconfig.masterpassword.MP_TITLE=Γενικός Κωδικός ΠÏόσβασης
-plugin.securityconfig.masterpassword.MP_NOT_SET=(δεν καθοÏίσθηκε)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=Δεν πληκτÏολογήσατε τον σωστό Γενικό Κωδικό ΠÏόσβασης. Δοκιμάστε ξανά.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=Ο Γενικός Κωδικός ΠÏόσβασης δεν είναι οÏθός!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Η Αλλαγή ÎšÏ‰Î´Î¹ÎºÎ¿Ï Ï€Ïόσβασης απέτυχε
@@ -1525,7 +1376,6 @@ plugin.securityconfig.masterpassword.COL_PASSWORD=Κωδικός Ï€ÏόσβασÎ
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(άγνωστος)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(δεν μποÏεί να αποκÏυπτογÏαφήσει)
plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=Αποθηκευμένοι κωδικοί Ï€Ïόσβασης
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=ΑπομάκÏυνση
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=ΑπομάκÏυνση όλων
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=Είστε βέβαιος ότι θέλετε να απομακÏÏνετε όλους τους κωδικοÏÏ‚ ;
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=ΑπομάκÏυνση όλων των κωδικών Ï€Ïόσβασης
@@ -1621,7 +1471,6 @@ plugin.globalproxy.PROXY_PORT=ΘÏÏα διακομιστή διαμεσολάβ
plugin.globalproxy.PROXY_USERNAME=Όνομα χÏήστη Proxy
plugin.globalproxy.PROXY_PASSWORD=Κωδικός Ï€Ïόσβασης Proxy
plugin.globalproxy.DESCRIPTION=To {0} θα χÏησιμοποιεί τις παÏαπάνω Ïυθμίσεις proxy για όλα τα δίκτυα με τα οποία συνδέεσθε ή επανασυνδέεσεθε, από Ï„ÏŽÏα και στο εξής. \nΗ υποστήÏιξη Proxy αυτή τη στιγμή είναι σε πειÏαματικό στάδιο και δουλεÏει μόνο με μεÏικά Ï€Ïωτόκολλα. Ελέγξτε τον παÏακάτω πίνακα για πεÏισσότεÏες λεπτομέÏειες:
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>JABBER</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
plugin.globalproxy.FWD_DNS=ΧÏησιμοποιήση του διακομιστή μεσολάβησης και για το DNS
plugin.globalproxy.FWD_DNS_NOTE=ΧÏήσιμο όταν χÏησιμοποιείτε το Tor. ΑποτÏέπει τη δημοσιοποίηση των δεδομένων DNS ανακατευθÏνοντας μέσω του μεσολάβητή Tor όλα τα δεδομένα DNS. Δεν τίθεται σε Î¹ÏƒÏ‡Ï Î¼Î­Ï‡Ïι να κάνετε επανεκκίνηση.
@@ -1659,7 +1508,6 @@ plugin.provisioning.RESTART_WARNING=Σημειώστε ότι οι αλλαγέÏ
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=ΑντιγÏαφή του UUID στο Ï€ÏόχειÏο
plugin.provisioning.CLIPBOARD_FAILED=Αποτυχία αντιγÏαφής του UUID στο Ï€ÏόχειÏο
-plugin.provisioning.EXIT_ON_FAIL=ΤεÏματισμός εφαÏμογής αν η αυτόματη Ï„Ïοφοδοσία Ïυθμίσεων αποτÏχει
plugin.provisioning.CREDENTIALS=Πιο Ï€Ïόσφατα αποθηκευμένα διαπιστευτήÏια αυτόματης Ï„Ïοφοδοσίας Ïυθμίσεων
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=Είστε σίγουÏοι ότι θέλετε να σβήσετε το συνθηματικό για την αυτόματη Ï„Ïοφοδοσία Ïυθμίσεων;
plugin.provisioning.PROV_FAILED=Η παÏοχή πληÏοφοÏιών απέτυχε
@@ -1726,8 +1574,6 @@ util.dns.DNSSEC_WARNING=<html><div width="600">Το {0} επιχείÏησε νÎ
#plugin spellcheck
plugin.spellcheck.TITLE=ΟÏθογÏαφία και γÏαμματική
plugin.spellcheck.MENU=Δείξε την οÏθογÏαφία και γÏαμματική
-plugin.spellcheck.LANG=Γλώσσα
-plugin.spellcheck.EDIT_PERSONAL_DICT=ΕπεξεÏγασία
plugin.spellcheck.ENABLE_SPELL_CHECK=ΕνεÏγοποίηση οÏθογÏάφου
plugin.spellcheck.dialog.FIND=Î’Ïες το επόμενο
plugin.spellcheck.dialog.REPLACE=Αντικατάσταση
diff --git a/resources/languages/resources_es.properties b/resources/languages/resources_es.properties
index 2df833d..d8a746e 100644
--- a/resources/languages/resources_es.properties
+++ b/resources/languages/resources_es.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -25,15 +36,14 @@
# from your system's language, pass the language code to ant:
# ant -Duser.language=xx run
-service.gui.ABOUT=&Acerca de
-service.gui.ACCEPT=&Aceptar
+service.gui.ABOUT=Acerca de
+service.gui.ACCEPT=Aceptar
service.gui.ACCOUNT=Cuenta
service.gui.ACCOUNT_ME=Yo
service.gui.ACCOUNT_REGISTRATION_WIZARD=Asistente para registrar una cuenta
service.gui.ACCOUNTS=Cuentas
-service.gui.ADD=&Agregar
-service.gui.ADD_ACCOUNT=Agregar cuenta
-service.gui.ADD_CONTACT=&Agregar contacto
+service.gui.ADD=Agregar
+service.gui.ADD_CONTACT=Agregar contacto
service.gui.ADD_AUTHORIZED_CONTACT=Agregar {0} a su lista de contactos
service.gui.ADD_CONTACT_TO_CONTACTLIST=Agregar contacto a su lista de contactos
service.gui.ADD_CONTACT_TO=&Agregar contacto a
@@ -42,20 +52,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Error al agregar contacto
service.gui.ADD_CONTACT_EXIST_ERROR=El contacto {0} ya existe en su lista de contactos.
service.gui.ADD_CONTACT_NETWORK_ERROR=El servidor no responde a la solicitud de agregar el contacto con id: {0}.
service.gui.ADD_CONTACT_NOT_SUPPORTED=No se pudo agregar el contacto con id: {0}. Operación no soportada.
-service.gui.ADD_CONTACT_IDENTIFIER=Introduzca en el campo inferior el identificador del contacto que desea agregar.
-service.gui.ADD_CONTACT_WIZARD=Asistente para agregar contactos
service.gui.ADD_CONTACT_NOT_CONNECTED=Usted necesita estar conectado para agregar un contacto. Por favor, inicie sesión con el proveedor seleccionado, y vuelva a intentarlo.
service.gui.ADD_GROUP_LOCAL_ERROR=No fue posible agregar el grupo: {0}. El problema ocurrió en una operación de entrada/salida local.
service.gui.ADD_GROUP_EXIST_ERROR=El grupo {0} ya existe en su lista de contactos. Elija otro nombre.
service.gui.ADD_GROUP_NET_ERROR=No se pudo agregar el grupo: {0}. El problema fue causado por un error en la red. Por favor, revise su conexión de red e inténtelo nuevamente.
service.gui.ADD_GROUP_ERROR=No se pudo agregar el grupo: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=El nombre del grupo no puede estar vacío.
-service.gui.ADD_GROUP=Crear grupo
-service.gui.ADD_SUBCONTACT=&Agregar subcontacto
service.gui.ADDRESS=Dirección
service.gui.ADMINISTRATOR=administrador
service.gui.ADVANCED=&Avanzado
-service.gui.ALL=&Todos
service.gui.ALL_CONTACTS=&Todos los contactos
service.gui.ALTERNATE_ADDRESS=Dirección alterna
service.gui.APPLY=&Aplicar
@@ -65,7 +70,6 @@ service.gui.AT=a las
service.gui.AUTHORIZE=&Autorizar
service.gui.AUTHORIZATION_ACCEPTED={0} ha aceptado su solicitud de autorización.
service.gui.AUTHENTICATION_FAILED=La autenticación falló para {0}. La contraseña que ha introducido no es válida.
-service.gui.AUTHENTICATION_REQUESTED=Solicitud de autenticación
service.gui.AUTHENTICATION_REQUESTED_SERVER=El servidor {0} ha solicitado su autenticación.
service.gui.AUTHENTICATION_REJECTED={0} ha rechazado su solicitud de autorización.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} autenticación
@@ -107,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=En el siguiente campo, puede introducir su nue
service.gui.CHANGE_NICKNAME_ERROR=Error al cambiar el apodo
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=El apodo ya existe
service.gui.CHANGE_VIDEO_QUALITY=Cambiar la calidad del vídeo remoto
-service.gui.CHAT_CONFERENCE_LABEL=Conferencias
service.gui.CHAT_CONFERENCE_ITEM_LABEL=Conferencia de {0}
service.gui.CHAT_ROOM_ALREADY_JOINED=Ya se encuentra en la sala {0}.
service.gui.CHAT_ROOM_CONFIGURATION=Configuración de la sala {0}
@@ -121,18 +124,14 @@ service.gui.CHAT_ROOM_USER_LEFT=ha abandonado {0}
service.gui.CHAT_ROOM_USER_KICKED=ha sido expulsado de {0}
service.gui.CHAT_ROOM_USER_QUIT=ha cerrado su sesión {0}
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=El Envió de mensajes esta prohibido (revocado)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Guardar la sala de chat para uso posterior
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Eliminar la sala seleccionada de la lista de salas guardadas
service.gui.CHAT_ROOM_NAME=Nombre de la sala de charlas
service.gui.CLEAR_CUSTOM_MESSAGES=Limpiar mensajes personalizados
service.gui.ROOM_NAME=Sala de charla
-service.gui.AUTOJOIN=Auto-ingresar
service.gui.CHANGE_PASSWORD=Cambiar contraseña
service.gui.CHAT_ROOM_NAME_INFO=Introduzca en el campo inferior el nombre con el que desea crear la sala de charlas.
service.gui.CHAT_ROOM_NOT_EXIST=La sala {0} no existe en el servidor {1}. Por favor, compruebe que el nombre es el correcto.
service.gui.CHAT_ROOM_NOT_CONNECTED=Necesita estar conectado para entrar en la sala {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Tiene que estar conectado para abandonar una sala de chat.
-service.gui.CHAT_ROOM_NOT_JOINED=Necesita estar dentro de la sala de charlas para realizar acciones sobre ella.
service.gui.CHAT_ROOM_OPTIONS=Opciones de la sala
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Necesita registrarse antes poder entrar en la sala {0}.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=La sala {0} ha solicitado contraseña.
@@ -157,16 +156,15 @@ service.gui.CONNECTING=Conectando...
service.gui.CONNECTING_STATUS=Conectando
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Conectando*
service.gui.CONNECTION=Conexión
-service.gui.CONNECTION_FAILED_MSG=Falló la conexión para la cuenta: Usuario: {0}, Servidor: {1}. Por favor, verifique su conexión a la red o contacte con el administrador de red para más información.
service.gui.CONNECTION_EXPIRED_MSG=Actualmente está desconectado del servidor {0}.
service.gui.CONTACT_NAME=ID o Número
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=El contacto {0} no soporta telefonía.
+service.gui.CONTACT_NAME_PROMPT=juana.perez@ejemplo.com
+service.gui.CONTACT_NAME_INFO=Agregar una dirección de mensajería instantánea (como juana.perez@ejemplo.com) o un número de VoIP
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=El contacto {0} no soporta conferencias.
service.gui.CONTACT_PAUSED_TYPING={0} paró de escribir un mensaje
service.gui.CONTACT_TYPING={0} está escribiendo un mensaje
service.gui.CONTACT_TYPING_SEND_FAILED=oh-oh... no le pudimos decir a {0} que está escribiendo
service.gui.CONTACT_INFO=Información de &contacto
-service.gui.CONTACTLIST=Lista de Contactos
service.gui.CONTACTS=Contactos
service.gui.COPY=&Copiar
service.gui.COPY_LINK=Copiar en&lace
@@ -176,28 +174,26 @@ service.gui.CREATE_CHAT_ROOM=&Crear sala de charlas...
service.gui.CREATE_CHAT_ROOM_ERROR=Falló la creación de la sala {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=Asistente de creación de salas de charlas
service.gui.CREATE_CONFERENCE_CALL=&Crear una conferencia...
-service.gui.CREATE_CONFERENCE_CHAT=&Crear una conferencia...
service.gui.CREATE_GROUP=&Crear grupo...
service.gui.CREATE_GROUP_NAME=Introduzca en el campo inferior el nombre del grupo que desea crear.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Su lista de contactos no contiene ningún grupo. Por favor, cree primero un grupo (Archivo/Crear grupo).
service.gui.CREATE_VIDEO_BRIDGE=Crear un puente de &vídeo...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Crear un puente de &vídeo
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Crear / Unirse a videoconferencia
service.gui.CREATE_VIDEO_CONFERENCE=Crear una nueva videoconferencia para esta sala de chat
service.gui.CONTACT_INFO_NOT_SUPPORTED=Este contacto no soporta información de contacto web
service.gui.CUT=Cor&tar
-service.gui.DATE=Fecha
service.gui.DELETE=Eliminar
service.gui.DENY=&Denegar
service.gui.DESKTOP_SHARING_WARNING=<b>¿Está seguro de que desea compartir su pantalla?</b> <br> Al pulsar Aceptar permitirá que los miembros de esta llamada vean su pantalla.
service.gui.DESKTOP_SHARING_DIALOG_INDICATE=Estás compartiendo su pantalla
service.gui.DIALPAD=Teclado numérico
service.gui.DISPLAY_NAME=Mostrar nombre
+service.gui.DISPLAY_NAME_PROMPT=Juana Pérez
+service.gui.DISPLAY_NAME_INFO=Agregar un nombre a este contacto. Si se deja en blanco, la dirección de de mensajería instantánea o el número de VoIP será utilizado en su lugar. (Opcional)
service.gui.DISCONNECTED_STATUS=Desconectado
service.gui.DND_STATUS=No molestar
service.gui.DO_NOT_ASK_AGAIN=No volver a preguntar
service.gui.DO_NOT_SHOW_AGAIN=No mostrar este mensaje de nuevo
-service.gui.DOWNLOAD_NOW=&Descargar ahora
service.gui.DRAG_FOR_SHARING=Arrastre hasta aquí lo que desea compartir...
service.gui.DURATION=duración
service.gui.DESTROY_CHATROOM=Destruir sala de charlas
@@ -218,7 +214,6 @@ service.gui.ERROR_RECEIVED_FROM=Se recibió un error de {0}
service.gui.ESTIMATED_TIME=Tiempo estimado:
service.gui.EVENTS=Eventos
service.gui.EXIT=&Salir
-service.gui.EXTENDED_CRITERIA=Criterios extendidos
service.gui.GENERAL=General
service.gui.GENERAL_ERROR=Error general
service.gui.GROUP_NAME=Nombre del grupo
@@ -260,7 +255,6 @@ service.gui.FONT_ITALIC=Itálica
service.gui.FONT_SIZE=Tamaño
service.gui.FONT_STYLE=Estilo
service.gui.FONT_UNDERLINE=Subrayado
-service.gui.FROM={0} de {1}
service.gui.GRANT_OWNERSHIP=Permitir ser el propietario...
service.gui.GRANT_ADMIN=Permitir administrar...
service.gui.GRANT_MODERATOR=Permitir moderar
@@ -286,7 +280,6 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=¿Está seguro de que desea eliminar de f
service.gui.HISTORY_REMOVE_ERROR=Error al eliminar los mensajes almacenados localmente.
service.gui.HOME=Inicio
service.gui.HOME_PAGE=Página inicial
-service.gui.HOUR=Hora
service.gui.ICE=ICE
service.gui.IDENTIFIER=Identificador
service.gui.IGNORE=&Ignorar
@@ -310,13 +303,10 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Invitar contactos al puente de vídeo
service.gui.INVITE_REASON=Motivo de la invitación
service.gui.IS_CALLING={0} está llamando...
service.gui.IS_NOW={0} ahora es {1}
-service.gui.JITSI_WARNING=SIP Communicator ha sido renombrado recientemente como Jitsi.<br/>Si desea que su versión se mantenga actualizada, entonces debe descargar Jitsi ahora.<br/><br/>Disculpe cualquier inconveniencia que esto le pueda causar.<br/><br/>El equipo de desarrollo de Jitsi
-service.gui.JITSI_WARNING_TITLE=SIP Communicator ahora es Jitsi
service.gui.JOIN=&Entrar
service.gui.JOIN_AS=E&ntrar como
service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=Unirse a una videoconferencia existente
service.gui.JOIN_VIDEO=Unir vídeo
-service.gui.CLOSE_CHAT_ROOM_DIALOG=Cerra&r
service.gui.JOB_TITLE=Puesto
service.gui.JOIN_CHAT_ROOM=&Entrar a la sala...
service.gui.JOIN_CHAT_ROOM_TITLE=Entrar a la sala
@@ -329,7 +319,6 @@ service.gui.KICK_FAILED=Expulsar falló
service.gui.KICK_FAILED_GENERAL_ERROR=Falló la expulsión de {0}. Ocurrió un error general en el servidor.
service.gui.KICK_FAILED_NOT_ALLOWED=Falló la expulsión de {0}. Ni el dueño ni el administrador de la sala pueden ser expulsados.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Fallo al expulsar a {0}. No dispone de los privilegios necesarios.
-service.gui.LAST=Último
service.gui.LAST_NAME=Apellidos:
service.gui.LEAVE=&Abandonar
service.gui.LIMIT_REACHED_FOR_IP=Existen muchas cuentas registradas en el servidor {0} desde su dirección IP local, y no permite establecer más.
@@ -349,7 +338,6 @@ service.gui.MESSAGE=Mensaje
service.gui.MISSED_CALLS_TOOL_TIP=Llamadas perdidas de:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= y {0} más
service.gui.MODERATOR=moderador
-service.gui.MORE=Ver más
service.gui.MORE_LABEL=Ver más
service.gui.MOVE=Mover
service.gui.MOVE_SUBCONTACT=M&over contacto
@@ -358,7 +346,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=El contacto que ha elegido es el mismo que\n
service.gui.MOVE_SUBCONTACT_QUESTION=¿Está seguro de querer mover a {0} a {1}?
service.gui.MOVE_TO_GROUP=&Mover al grupo
service.gui.MOVE_CONTACT=Mover contacto
-service.gui.MOVE_CONTACT_ERROR=El contacto no se puede mover
service.gui.MSG_DELIVERY_FAILURE=El mensaje de arriba no pudo ser entregado
service.gui.MSG_DELIVERY_NOT_SUPPORTED=El protocolo que está utilizando no soporta mensajes mientras está desconectado. Puede intentar comunicarse con {0} usando otro protocolo o esperar a que se conecte.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Ocurrió un error interno. Es muy probable que sea un fallo de programación. Infórmelo en: https://jitsi.org/Development/BugsAndIssues.
@@ -372,7 +359,6 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=Debe estar conectado para poder enviar m
service.gui.MULTIPLE_LOGINS=Se ha conectado más de una vez con la misma cuenta de usuario. La cuenta: Usuario: {0}, Servidor: {1} está actualmente desconectada.
service.gui.MY_CHAT_ROOMS=Agregar sala de Chat
service.gui.MY_CHAT_ROOMS_TITLE=Agregar sala de chat
-service.gui.MUTE=Silencio
service.gui.MUTUALLY_ON_HOLD_STATUS=Mutuamente en Espera
service.gui.NAME=Nombre
service.gui.NETWORK=Red
@@ -404,7 +390,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=No está en la lista de Contactos
service.gui.SD_QUALITY=Calidad estándar
service.gui.OFFLINE=Desconectado
service.gui.OK=&OK
-service.gui.OLDER_CALLS=Llamadas antiguas
service.gui.ONLINE=Conectado
service.gui.OPEN=Abrir
service.gui.OPEN_FILE_FROM_IMAGE=Doble clic para abrir el archivo.
@@ -416,7 +401,6 @@ service.gui.OPEN_ON_ACTIVITY=Abrir al estar activo
service.gui.OPEN_ON_MESSAGE=Abrir al recibir mensaje
service.gui.OPEN_ON_IMPORTANT_MESSAGE=Solamente Abrir en mensajes importantes
service.gui.OR=o
-service.gui.OR_ENTER_PHONE_NUMBER=O introduzca el teléfono aquí...
service.gui.ORGANIZATION=Organización
service.gui.OTHER=Otro
service.gui.chat.role.OWNER=Propietario
@@ -442,7 +426,6 @@ service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Intro' para sugerencias
service.gui.PRESS_FOR_CALL_INFO=Presione para información de la llamada
service.gui.PRESS_TO_OPEN_CRM=Presione para abrir la aplicación CRM
service.gui.PREVIOUS=Anterior
-service.gui.PREVIOUS_TOOLTIP=Explorar conversaciones antiguas
service.gui.PRINT=Im&primir
service.gui.PROACTIVE_NOTIFICATION=está escribiendo
service.gui.PROBLEMS_ENCOUNTERED=Se encontraron problemas
@@ -458,7 +441,6 @@ service.gui.RECONNECTION_LIMIT_EXCEEDED=Ha desconectado y reconectado al servido
service.gui.RE_REQUEST_AUTHORIZATION=Volver a solicitar autorización
service.gui.REFERRED_STATUS=Referido
service.gui.REJECT=&Rechazar
-service.gui.REMIND_ME_LATER=Recordarme más tarde
service.gui.REMEMBER_PASSWORD=Recordar contraseña
service.gui.REMOVE=&Eliminar
service.gui.REMOVE_ACCOUNT=&Eliminar cuenta
@@ -484,29 +466,23 @@ service.gui.REVOKE_ADMIN=Cancelar admin
service.gui.REVOKE_MODERATOR=Cancelar moderador
service.gui.REVOKE_MEMBERSHIP=Cancelar membresía
service.gui.REVOKE_VOICE=Cancelar voz
-service.gui.ROOT_GROUP=Grupo raíz
service.gui.SAVE=&Guardar
-service.gui.SAVE_AS_DEFAULT=Guardar como predeterminado
service.gui.SEARCH=&Buscar
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Presione el botón para mostrar todas las salas de conversación existentes en el servidor seleccionado. Después seleccione aquella a la que desea conectarse y presione el botón Entrar.
service.gui.SEARCH_STRING_CONTACT_SOURCE=Contacto buscado
service.gui.SECURITY=Seguridad
service.gui.SELECT_ACCOUNT=Seleccionar cuenta de usuario
+service.gui.SELECT_ACCOUNT_INFO=¿Cual cuenta desea utilizar para comunicarse con este contacto?
service.gui.SELECT_COLOR=Seleccionar color
service.gui.SELECT_GROUP=Seleccione un grupo
-service.gui.SELECT_GROUP_WIZARD_MSG=La lista inferior contiene todos los grupos de su lista de contactos. Seleccione a la que desea agregar el nuevo contacto.
+service.gui.SELECT_GROUP_INFO=¿Que grupo desea usar para mostrar este contacto? (Opcional)
service.gui.SELECT_NO_GROUP=Sin grupo
-service.gui.SELECT_GROUP_WIZARD=Seleccione grupo
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=La lista inferior contiene todas las cuentas de usuario que tienen soporte para chat multi usuario. Seleccione aquella que desee usar para crear la sala de chat.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=La lista inferior contiene todas las cuentas de usuario registradas. Seleccione aquellas que desee usar para comunicarse con el nuevo contacto.
-service.gui.SELECT_PROVIDERS_WIZARD=Seleccione cuenta
service.gui.SELECT_VIDEO_CONFERENCE=Seleccionar videoconferencia
service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Elija una sala de chat de la lista y presione Aceptar para agregarla
service.gui.SEND=&Enviar
service.gui.SEND_FILE=Enviar archivo
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=No hay información para este contacto.
service.gui.SEND_MESSAGE=&Enviar mensaje
-service.gui.SEND_AS_SMS=Enviar como SMS
service.gui.SEND_PRIVATE_MESSAGE=Enviar mensaje privado
service.gui.SEND_SMS=Enviar S&MS
service.gui.SEND_SMS_DETAILS=Recuerde que debe introducir el teléfono en formato internacional, por ejemplo: empezando por +44 para Reino Unido, +447777000000
@@ -545,7 +521,6 @@ service.gui.STREET=Calle
service.gui.SUBJECT=Asunto
service.gui.SUMMARY=Resumen
service.gui.TELEPHONY=Telefonía
-service.gui.TODAY=Hoy
service.gui.TOOLS=&Herramientas
service.gui.TRANSFER=Trans&ferir
service.gui.TO=&Para:
@@ -555,7 +530,6 @@ service.gui.TRANSFER_CALL_TO=Transferir a:
service.gui.TRANSPARENCY_NOT_ENABLED=La transparencia no está soportada por su configuración actual.
service.gui.TYPE_YOUR_REQUEST=Escriba su petición aquí
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=No es posible cambiar la calidad de vídeo de esta llamada.
-service.gui.UNMUTE=Apagar silencio
service.gui.USER_IDENTIFIER=Identificación de usuario:
service.gui.USER_EXISTS_ERROR=Este usuario ya existe en el servidor. Escoja otro o use otro servidor.
service.gui.USERNAME_NULL=Por favor introduzca su nombre y contraseña.
@@ -568,7 +542,6 @@ service.gui.USE_PROVISIONING=Usar aprovisionamiento en línea
service.gui.VALUE=Valor
service.gui.VIDEO_CALL=&Videollamada
service.gui.VIA=vía
-service.gui.VIA_SMS=Vía SMS
service.gui.VIEW=&Ver
service.gui.VIEW_HISTORY=Ver &historial
service.gui.VIEW_SMILEYS=Ver emoticono&s
@@ -588,9 +561,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=Ajustar volumen
service.gui.WAITING_AUTHORIZATION=Esperando autorización
service.gui.WARNING=Advertencia
service.gui.YES=Sí
-service.gui.YESTERDAY=Ayer
-service.gui.EXISTING_ACCOUNT_ERROR=La cuenta introducida ya se encontraba instalada.
-service.gui.NEW_MAIL=<b>¡Ha recibido un correo!</b><br/><b> De:</b> {0} {1} <br/><b>Asunto:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=Ha recibido un nuevo mensaje de correo en su <a href="{1}">bandeja de entrada</a> {0}:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=Ha recibido {2} mensajes en su <a href="{1}">bandeja de entrada</a>{0} :<br/>
service.gui.NEW_GMAIL_FOOTER=una o más conversaciones sin leer en su <a href="{0}">bandeja de entrada</a>.<br/>
@@ -617,7 +587,6 @@ service.gui.SECURITY_ERROR=Error de seguridad
service.gui.SPEED=Velocidad:
service.gui.SILENT_MEMBER=silenciar miembro
service.gui.NON_SECURE_CONNECTION=No se puede establecer una conexión segura para la cuenta {0}. Si desea conectarse a un servidor no seguro, seleccione "Permitir conexiones no seguras" en la configuración de su cuenta
-service.gui.UPDATE=Actualizar
service.gui.MOBILE_PHONE=Móvil
service.gui.VIDEO_PHONE=Vídeo
service.gui.WORK_PHONE=Trabajo
@@ -652,12 +621,10 @@ service.gui.callinfo.CALL_INFORMATION=Información de la Llamada
service.gui.callinfo.CALL_IDENTITY=Identidad
service.gui.callinfo.PEER_COUNT=Conteo de Participantes
service.gui.callinfo.IS_CONFERENCE_FOCUS=Enfocar conferencia
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Cifrado activado
service.gui.callinfo.CALL_TRANSPORT=Señalización de transporte de llamadas
service.gui.callinfo.CALL_DURATION=Duración de la llamada
service.gui.callinfo.TLS_PROTOCOL=Protocolo TLS
service.gui.callinfo.TLS_CIPHER_SUITE=Suite de cifrado TLS
-service.gui.callinfo.TLS_SERVER_CERTIFICATE_CHAIN=Cadena del certificado del servidor TLS
service.gui.callinfo.TLS_CERTIFICATE_CONTENT=El contenido del certificado del servidor TLS se muestra a continuación.
service.gui.callinfo.VIEW_CERTIFICATE=Ver Certificado
service.gui.callinfo.CODEC=Códec / Frecuencia
@@ -677,10 +644,14 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=Protocolo de intercambio de claves
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=ICE Candidato de tipo extendido
service.gui.callinfo.ICE_STATE=Estado de Procesamiento ICE:
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=Reuniendo candidatos
service.gui.callinfo.ICE_STATE.RUNNING=Revise conectividad
service.gui.callinfo.ICE_STATE.COMPLETED=Terminado
service.gui.callinfo.ICE_STATE.FAILED=Falló
+service.gui.callinfo.ICE_STATE.TERMINATED=Finalizado
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=IP local / Puerto
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=IP Local reflexiva / Puerto
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=IP Local retransmitida / Puerto
@@ -701,11 +672,12 @@ service.gui.ALWAYS_TRUST=Siempre confiar en este certificado
service.gui.CERT_DIALOG_TITLE=Verificar Certificado
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} no puede verificar la identidad del servidor al conectarse a<br><b>{1}</b>.<br><br> El certificado no es confiable, esto significa que la identidad del servidor no puede ser verificada automáticamente. <br><br>¿Desea continuar con la conexión?<br> Para mayor información, presione "Ver Certificado".</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0} no puede verificar el certificado del servidor.<br><br> El certificado no es confiable, esto significa que la identidad del servidor no puede<br> ser verificada automáticamente. <br><br>¿Desea continuar con la conexión?<br><br> Para mayor información, de un clic en "Ver Certificado".</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} no puede verificar la identidad del cliente.<br><br> El certificado no es confiable, esto significa que la identidad del cliente no puede<br> ser verificada automáticamente. ¿Desea continuar?<br><br> Para mayor información presione "Ver Certificado".</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} no puede verificar la identidad del cliente {1}.<br><br> El certificado no es confiable, esto significa que la identidad del cliente no puede<br> ser verificada automáticamente. ¿Desea continuar con la conexión?<br><br> Para mayor información presione "Ver Certificado".</html>
service.gui.CONTINUE_ANYWAY=Continuar de todas formas
service.gui.CERT_INFO_CHAIN=Cadena del certificado:
service.gui.CERT_INFO_ISSUED_TO=Emitido a
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Nombre Común:
service.gui.CERT_INFO_O=Organización:
service.gui.CERT_INFO_C=País:
@@ -724,12 +696,10 @@ service.gui.CERT_INFO_SIGN_ALG=Algoritmo de la Firma:
service.gui.CERT_INFO_PUB_KEY_INFO=Información de la clave pública
service.gui.CERT_INFO_ALG=Algoritmo:
service.gui.CERT_INFO_PUB_KEY=Clave Pública:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} bytes: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} bits
service.gui.CERT_INFO_EXP=Exponente:
service.gui.CERT_INFO_KEY_SIZE=Tamaño de la Clave:
service.gui.CERT_INFO_SIGN=Firma:
-service.gui.CONTINUE=Continuar
service.gui.SHOW_CERT=Ver Certificado
service.gui.HIDE_CERT=Ocultar Certificado
@@ -752,12 +722,9 @@ service.gui.security.SECURE_AUDIO=Audio seguro
service.gui.security.AUDIO_NOT_SECURED=Audio no seguro
service.gui.security.SECURE_VIDEO=Vídeo seguro
service.gui.security.VIDEO_NOT_SECURED=Vídeo no seguro
-service.gui.security.NO_VIDEO=Sin video
-service.gui.security.CIPHER=Cifrado: {0}
service.gui.security.CALL_SECURED_TOOLTIP=Llamada asegurada. Para mayor información presione aquí.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Llamada no segura.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Presione aquí para comparar la seguridad con su contraparte.
-service.gui.security.COMPARE_WITH_PARTNER=Compare con su contacto y presione en el candado para confirmar.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Comparar con su contra-parte.
service.gui.security.STRING_COMPARED=¡Cadena comparada!
@@ -775,20 +742,20 @@ service.gui.avatar.imagepicker.CLICK=Presione y Sonría
service.gui.avatar.imagepicker.IMAGE_FILES=Archivos de imágenes
service.gui.avatar.imagepicker.IMAGE_PICKER=Imagen
service.gui.avatar.imagepicker.IMAGE_SIZE=Tamaño de imagen
-service.gui.avatar.imagepicker.INITIALIZING=Inicializando
service.gui.avatar.imagepicker.RESET=Reiniciar
service.gui.avatar.imagepicker.SET=Definir
service.gui.avatar.imagepicker.TAKE_PHOTO=Tomar una foto
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Error en cámara web
service.gui.security.encryption.required=¡Cifrado requerido!
service.protocol.ICE_FAILED=No se pudo establecer una conexión (falló ICE y no se encontró relé)
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
+service.systray.MODE=Modo bandeja
+service.systray.mode.NATIVE=Predeterminado
+service.systray.mode.DISABLED=Desactivado
+service.systray.mode.APPINDICATOR=AppIndicator (Unity, KDE, not plain Gnome 3; puede fallar en Debian)
+service.systray.mode.APPINDICATOR_STATIC=AppIndicator Estático (sin menú de estado de la cuenta)
+service.systray.CLI_NOTE=Si su elección no funciona, puede iniciar {0} con la opción "--notray". Esta opción va a forzar el modo de bandeja como "Desactivado" y muestra la Interfaz gráfica. Cambiar la implementación de la bandeja requiere reiniciar.
impl.protocol.sip.XCAP_ERROR_TITLE=Error en almacenamiento de lista de contactos SIP
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=No se pueden leer los recusros {0}. De {1}
@@ -818,9 +785,7 @@ impl.ldap.QUERY_CUSTOM=Consulta personalizada
impl.ldap.QUERY_CUSTOM_HINT=Usar {0} como un marcador para el término de búsqueda.
impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=Añadir automáticamente comodines en la consulta
impl.ldap.QUERY_PHOTO_INLINE=Obtener foto junto con otros atributos
-impl.ldap.NEW=Nuevo
impl.ldap.EDIT=editar
-impl.ldap.REMOVE=Eliminar
impl.ldap.ENABLED=Activado
impl.ldap.SERVER_NAME=Nombre del Servidor
impl.ldap.SERVER_NAME_EXAMPLE=Mi servidor LDAP
@@ -853,6 +818,12 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=TeléfonoCasa
impl.ldap.PHONE_PREFIX=Prefijo del teléfono
impl.ldap.PHONE_PREFIX_EXAMPLE=Ej: 00
+# SIP Protocol
+impl.protocol.sip.INVALID_ADDRESS=''{0}'' no es una dirección SIP válida.
+
+#Jabber Protocol
+impl.protocol.jabber.INVALID_ADDRESS=''{0}'' no es un JID de XMPP válido.
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=Libreta de direcciones
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=Activar búsqueda en la Libreta de Direcciones de MacOSX
@@ -867,9 +838,7 @@ plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT=Hacer a Outlook su cliente de c
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Contactos de Google
-impl.googlecontacts.NEW=Nuevo
impl.googlecontacts.EDIT=editar
-impl.googlecontacts.REMOVE=Eliminar
impl.googlecontacts.ENABLED=Activado
impl.googlecontacts.ACCOUNT_NAME=Nombre de cuenta
impl.googlecontacts.SAVE=Guardar
@@ -878,6 +847,10 @@ impl.googlecontacts.USERNAME=Nombre de cuenta
impl.googlecontacts.PASSWORD=Contraseña
impl.googlecontacts.PREFIX=Prefijo del teléfono
impl.googlecontacts.WRONG_CREDENTIALS=Credenciales erróneas de la cuenta de Google {0}
+impl.googlecontacts.OAUTH_DIALOG_TITLE=Autorización de contactos de Google
+impl.googlecontacts.INSTRUCTIONS=<html><p><b>Presione en el enlace de abajo para aprobar el plugin de contactos para acceder a la cuenta de Google .</b><br><br> Al presionar en el enlace, se abrirá una página web en su navegador. Inicie sesión con la cuenta solicitada y apruebe el acceso. Una vez aprobado, Google le mostrará un código. Copie este código en el campo de texto de abajo y presione en 'Guardar'.</p><p>Esta es una operación de una sola vez. se almacenarán tokens de autorización para su uso futuro.</p></html>
+impl.googlecontacts.CODE=Código:
+impl.googlecontacts.HYPERLINK_TEXT=Presione aquí para aprobar el acceso a {0}
# account info
plugin.accountinfo.TITLE=Información de la cuenta
@@ -908,11 +881,8 @@ plugin.accountinfo.ORGANIZATION=Nombre de la organización:
plugin.accountinfo.JOB_TITLE=Puesto:
plugin.accountinfo.ABOUT_ME=Información sobre mí:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
-plugin.accountinfo.USER_PICTURES=Fotos
plugin.accountinfo.GLOBAL_ICON=Usar icono global
plugin.accountinfo.LOCAL_ICON=Usar este ícono:
-plugin.accountinfo.CHANGE=Cambiar
-plugin.accountinfo.ONLY_MESSAGE=Sólo mensajes
# connection info
plugin.connectioninfo.TITLE=Información de la conexión
@@ -932,52 +902,15 @@ plugin.aimaccregwizz.USERNAME=Usuario AIM:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Usuario y Contraseña
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Registrar nueva cuenta
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=En el caso de no disponer de una cuenta AIM, presione este botón para crear una nueva.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Modificar las opciones predeterminadas del servidor
# branding
plugin.branding.ABOUT_WINDOW_TITLE=Acerca de {0}
plugin.branding.LOGO_MESSAGE=VoIP && Mensajería Instantánea.
-plugin.branding.LOADING=Cargando
plugin.branding.ABOUT_MENU_ENTRY=&Acerca de
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>{1} se está desarrollando actualmente. La versión que está ejecutando es únicamente experimental y PUEDE QUE NO se comporte como espera. Por favor, consulte a {2} para más información.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c) 2003-2013 Copyright <b>jitsi.org</b>. Todos los derechos reservados. Visite <a href="https://jitsi.org">https://jitsi.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}>The <b>Jitsi</b> se distribuye bajo los términos de la licencia LGPL (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
+plugin.branding.COPYRIGHT_LICENSE=<DIV><font size=3 color={0}>Copyright 2003-{1} <a href="{2}"><b>{3}</b></a>, Todos los derechos reservados.</font><br><br>{4} es distribuido bajo los términos de <a href="{5}">{6}</a>.</DIV>
plugin.busylampfield.PICKUP=Tomar llamada
-# Dict protocol
-service.protocol.DICTIONARIES=Diccionarios
-plugin.dictaccregwizz.ANY_DICTIONARY=Cualquier Diccionario
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Cualquier Diccionario de {0}
-plugin.dictaccregwizz.FIRST_MATCH=Primera Coincidencia
-plugin.dictaccregwizz.NO_MATCH=Sin coincidencias
-plugin.dictaccregwizz.MATCH_RESULT=No hay definiciones para "{0}", puede ser:\n
-plugin.dictaccregwizz.INVALID_DATABASE=El diccionario "{0}" ya no existe en el servidor.
-plugin.dictaccregwizz.INVALID_STRATEGY=La estrategia no está disponible en el servidor.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=El protocolo de servicio Dict
-plugin.dictaccregwizz.HOST=Anfitrión
-plugin.dictaccregwizz.SERVER_INFO=Información del Servidor
-plugin.dictaccregwizz.STRATEGY_SELECTION=Selección de Estrategia
-plugin.dictaccregwizz.STRATEGY_LIST=Lista de estrategias:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Buscar estrategias
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=La estrategia se usa para buscar palabras similares si una traducción no se encuentra, gracias a distintos enfoques. Por ejemplo las estrategias de prefijo buscan palabras que empiezan como la palabra que desea traducir.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Infomación de la cuenta Dict
-plugin.dictaccregwizz.FIRST_ACCOUNT=Este asistente creará su primera cuenta Dict por usted en dict.org.\n\nPuede agregar nuevos diccionarios usando el asistente de registro de cuentas. Complete el campo de anfitrión con el diccionario que desee agregar.
-plugin.dictaccregwizz.THREAD_CONNECT=Intentado conectarse al servidor
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=Fallo el intento de conexión, No es un servidor dict o está apagado
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=Recuperando estrategias
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=No hay estrategía en el servidor
-plugin.dictaccregwizz.POPULATE_LIST=Generando lista
-plugin.dictaccregwizz.CLOSING_CONNECTION=Cerrando conexión
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Para poder usar los chat de Facebook necesita crear un "Usuario" <br>desde la "Configuración de Cuenta" en Facebook.</a><br><br>Nota: ¡Cuando crea un usuario debe salir de la página <br>y esto puede tomar tiempo antes de que pueda iniciar sesión con el nuevo usuario!</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=Protocolo de Chat de Facebook
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Usuario:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Usuario y Contraseña
-
# generalconfig
plugin.generalconfig.AUTO_START=Auto - Iniciar {0} cuando arranque o reinicie el sistema
plugin.generalconfig.CHATALERTS_ON_MESSAGE=Utilizar alertas en la barra de tareas / dock para llamadas entrantes y charlas
@@ -987,9 +920,6 @@ plugin.generalconfig.SHOW_HISTORY=Mostrar
plugin.generalconfig.HISTORY_SIZE=últimos mensajes en conversaciones
plugin.generalconfig.SEND_MESSAGES_WITH=Enviar mensajes usando:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=Traer la ventana del chat al frente
-plugin.generalconfig.ERROR_PERMISSION=No dispone de los privilegios necesarios para desactivar el inicio automático
-plugin.generalconfig.TRANSPARENCY=Transparencia
-plugin.generalconfig.ENABLE_TRANSPARENCY=Activar transparencia
plugin.generalconfig.DEFAULT_LANGUAGE=Idioma de la Interfaz
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Los cambios se llevarán a cabo al reiniciar.
plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0}% traducido
@@ -1005,6 +935,8 @@ plugin.generalconfig.REMOVE_SPECIAL_PHONE_SYMBOLS=Eliminar símbolos especiales
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS=Convertir letras a números de teléfono
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS_EXAMPLE=ejemplo. +1-800-MYPHONE -> +1-800-694663
plugin.generalconfig.SIP_CALL_CONFIG=SIP
+plugin.generalconfig.XMPP_CONFIG=XMPP
+plugin.generalconfig.XMPP_USE_ALL_RESOURCES=Utilizar todos los recursos al detectar características de un contacto
plugin.generalconfig.OPUS_CONFIG=Opus
plugin.generalconfig.OPUS_AUDIO_BANDWIDTH=Tasa de muestreo:
plugin.generalconfig.OPUS_BITRATE=Tasa de bits media (kbps) del Encoder:
@@ -1018,6 +950,7 @@ plugin.generalconfig.SILK_ALWAYS_ASSUME_PACKET_LOSS=Suponer siempre la pérdida
plugin.generalconfig.SILK_SAT=Umbral de actividad de voz (0-1):
plugin.generalconfig.SILK_ADVERTISE_FEC=Anunciar soporte a FEC en SDP:
plugin.generalconfig.RESTORE=Restaurar opciones predeterminadas
+plugin.generalconfig.MINIMIZE_NOT_HIDE=Minimizar la ventana principal en lugar cerrarla o esconderla
# gibberish accregwizz
plugin.gibberishaccregwizz.PROTOCOL_NAME=Gibberish
@@ -1076,13 +1009,10 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Comentarios
plugin.jabberaccregwizz.RESOURCE=Recurso
plugin.jabberaccregwizz.AUTORESOURCE=Auto generar recurso
plugin.jabberaccregwizz.PRIORITY=Prioridad
-plugin.jabberaccregwizz.XMPP_ERROR=Error XMPP
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Error desconocido de XMPP ({0}). Verifique que el nombre del servidor es correcto.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Sus contraseñas no coinciden.
plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Modificar las opciones predeterminadas del servidor
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Opciones avanzadas
plugin.jabberaccregwizz.USE_ICE=Usar ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=Utilizar Jingle/ICE de Google (experimental)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=Auto descubrir servidores STUN/TURN
plugin.jabberaccregwizz.SUPPORT_TURN=Soporte TURN
plugin.jabberaccregwizz.TURN_USERNAME=Nombre de usuario TURN
@@ -1110,11 +1040,8 @@ plugin.jabberaccregwizz.DISABLE_CARBON=Desactivar copias de los mensajes
plugin.jabberaccregwizz.DTMF_AUTO=Auto: Selecciona automáticamente entre RTP y en banda
plugin.jabberaccregwizz.SERVER_OPTIONS=Opciones de servidor
plugin.jabberaccregwizz.CHANGE_PASSWORD=Cambiar contraseña de la cuenta
-plugin.jabberaccregwizz.NEW_PASSWORD=Nueva contraseña
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Confirmar nueva contraseña
plugin.jabberaccregwizz.PORT_FIELD_INVALID=Por favor introduzca un número de puerto válido para continuar.
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=Tiene que iniciar sesión en la cuenta para poder cambiar la contraseña.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=La contraseña esta vacía.
plugin.jabberaccregwizz.TLS_REQUIRED=La conexión no usa TLS, no se realizará el cambio de contraseña.
plugin.jabberaccregwizz.PASSWORD_CHANGED=La contraseña se cambio con éxito
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=Su servidor de XMPP no soporta el cambio de contraseña.
@@ -1128,21 +1055,6 @@ plugin.jabberaccregwizz.RESET=Reiniciar
plugin.jabberaccregwizz.RESET_DESCRIPTION=Reiniciar a la configuración global
plugin.jabberaccregwizz.DISABLE_JINGLE=Desactivar Jingle (llamadas de audio y vídeo con XMPP).
-# mailbox
-plugin.mailbox.OUTGOING=Mensaje saliente:
-plugin.mailbox.INCOMING=Mensaje entrante:
-plugin.mailbox.WAIT_TIME=Espera hasta que la llamada es enviada al buzón de voz
-plugin.mailbox.MAX_MESSAGE_TIME=Duración máxima del mensaje entrante
-plugin.mailbox.CONFIRM=Confirmar
-plugin.mailbox.DEFAULTS=Predeterminados
-plugin.mailbox.MAILBOX=Buzón
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Protocolo para conectarse y conversar mediante el protocolo MSN.
-plugin.msnaccregwizz.USERNAME=Correo:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=ID y Contraseña
-
# plugin manager
plugin.pluginmanager.INSTALL=Instalar
plugin.pluginmanager.UNINSTALL=Desinstalar
@@ -1171,9 +1083,9 @@ plugin.sipaccregwizz.SERVER_PORT=Puerto del servidor
plugin.sipaccregwizz.PROXY=Proxy
plugin.sipaccregwizz.PROXY_PORT=Puerto del proxy
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Transporte preferido
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Opciones avanzadas
plugin.sipaccregwizz.PROXY_OPTIONS=Opciones del proxy
plugin.sipaccregwizz.PROXY_AUTO=Configurar proxy de forma automática
+plugin.sipaccregwizz.PROXY_FORCE_BYPASS=Ignorar control de seguridad del proxy, seleccione en escenarios de alta disponibilidad (use sólo si es necesario)
plugin.sipaccregwizz.ENABLE_PRESENCE=Activar presencia (SIMPLE)
plugin.sipaccregwizz.FORCE_P2P_PRESENCE=Forzar envío de presencia mediante peer-to-peer
plugin.sipaccregwizz.OFFLINE_CONTACT_POLLING_PERIOD=Tiempo de sondeo de contactos desconectados (en s.)
@@ -1191,8 +1103,6 @@ plugin.sipaccregwizz.DTMF_AUTO=Auto: Selecciona automáticamente entre RTP y en
plugin.sipaccregwizz.DTMF_RTP=RTP ( RFC2833 / RFC 4733 )
plugin.sipaccregwizz.DTMF_SIP_INFO=SIP INFO
plugin.sipaccregwizz.DTMF_INBAND=En banda
-plugin.sipaccregwizz.REGISTER=REGISTRO
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Modificar las opciones predeterminadas del servidor
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Activar soporte para llamadas cifradas
plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=Indique el soporte de ZRTP en el protocolo de señalización
plugin.sipaccregwizz.AUTH_NAME=Nombre autorizado
@@ -1213,10 +1123,10 @@ plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=Revisar URI de Correo de Voz
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Sus contraseñas no coinciden.
plugin.sipaccregwizz.NO_CERTIFICATE=<ninguno> (use autenticación regular)
plugin.sipaccregwizz.SAVP_OPTION=indicador RTP/SAVP
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=Apagado (indica RTP/AVP solamente)
plugin.sipaccregwizz.SAVP_OPTION_1=Obligatorio (ofrece y acepta RTP/SAVP solamente)
plugin.sipaccregwizz.SAVP_OPTION_2=Opcional (ofrece primero RTP/SAVP, y después RTP/AVP)
-plugin.sipaccregwizz.ENABLE_SDES_ATTRIBUTE=Habilitar S-Descriptor (también conocido como SDES o SRTP)
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=Elegir protocolos con cifrado habilitado y su prioridad (superior como primer protocolo):
plugin.sipaccregwizz.CIPHER_SUITES=Habilita suites de cifrado:
plugin.sipaccregwizz.SECURITY_WARNING=<html> <div width=450> {0} automáticamente tratará de garantizar todas sus llamadas con ZRTP y podrá oír y ver una notificación una vez que una conexión segura se establece. Sólo debe cambiar la configuración avanzada si sabe muy bien lo que está haciendo. </div> </html>
@@ -1230,15 +1140,6 @@ plugin.skinmanager.DEFAULT_SKIN=Tema predeterminado
plugin.skinmanager.ADD_NEW_SKIN=Agregar un nuevo tema...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=El tema predeterminado de la aplicación.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=Protocolo para conectarse remotamente a distintas máquinas usando SSH.
-plugin.sshaccregwizz.USERNAME=ID de cuenta:
-plugin.sshaccregwizz.IDENTITY_FILE=Archivo de identidad:
-plugin.sshaccregwizz.KNOWN_HOSTS=Anfitriones conocidos:
-plugin.sshaccregwizz.OPTIONAL=Opcional
-plugin.sshaccregwizz.ACCOUNT_DETAILS=Detalles de la cuenta
-
# status update
plugin.autoaway.AUTO_STATUS=Auto Ausente
plugin.autoaway.ENABLE_CHANGE_STATUS=Cambiar el estado si no estoy presente
@@ -1286,22 +1187,6 @@ plugin.whiteboard.DESELECT=Deseleccionar
plugin.whiteboard.DELETE=Eliminar
plugin.whiteboard.PROPERTIES=Propiedades
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Protocolo para conectarse y conversar en el Servicio de Yahoo!.
-plugin.yahooaccregwizz.USERNAME=Usuario:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=Usuario y Contraseña
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=El protocolo de servicio Zeroconf (Bonjour).
-plugin.zeroaccregwizz.FIRST_NAME=Nombre:
-plugin.zeroaccregwizz.LAST_NAME=Apellidos:
-plugin.zeroaccregwizz.EMAIL=Email:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=¿Recordar contactos de Bonjour?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=ID y Contraseña
-plugin.zeroaccregwizz.USERID=User ID
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Protocolo Google Talk
@@ -1315,19 +1200,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, el Portal de Telecomunica
plugin.iptelaccregwizz.USERNAME=Usuario
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=Inscribirse a iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIP y charlas
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Usuario
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Escriba nuevamente la contraseña
plugin.sip2sipaccregwizz.EMAIL=Dirección de correo
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=Si necesita ayuda sobre este servicio visite<br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>La dirección de correo es usada para enviar mensajes del correo de voz, <br>notificaciones de llamadas perdidas y para recuperar una contraseña</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>Si necesita ayuda sobre este servicio visite <a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=Cuenta actual de sip2sip.info
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Crear una cuenta gratuita de sip2sip.info
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP y Mensajero Instantáneo
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=Si necesita ayuda sobre este servicio visite<br>http://ippi.fr
@@ -1336,6 +1213,8 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=Cuenta ippi existente
plugin.ippiaccregwizz.CREATE_ACCOUNT=Crear una cuenta ippi gratuita
# key binding chooser
+plugin.keybindings.WAITING=Pulsar acceso rápido...
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Cerrar ventana de charla
plugin.keybindings.CHAT_COPY=Copiar
plugin.keybindings.CHAT_CUT=Cortar
@@ -1358,10 +1237,10 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=Nombre
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=acceso directo principal
plugin.keybindings.globalchooser.SHORTCUT_SECOND=acceso directo secundario
plugin.keybindings.globalchooser.PRESS_BTN=Pulse para establecer atajo
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=Esperando
plugin.keybindings.globalchooser.PUSH_TO_TALK=Presione para hablar
plugin.keybindings.globalchooser.ENABLE_SPECIAL=Activar la detección de teclas especiales
plugin.keybindings.PLUGIN_NAME=Asignación de teclas
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Charla
plugin.keybindings.MAIN=Principal
plugin.keybindings.GLOBAL=Accesos rápidos globales
@@ -1389,6 +1268,7 @@ plugin.notificationconfig.tableheader.SOUND=Reproducir un sonido a través del d
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=Reproducir un sonido a través del dispositivo de reproducción
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=Reproducir un sonido a través del dispositivo de altavoz del PC
plugin.notificationconfig.tableheader.DESCRIPTION=Descripción del evento
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Llamada Entrante
plugin.notificationconfig.event.SecurityMessage=Mensaje de Seguridad
plugin.notificationconfig.event.IncomingFile=Recibiendo Archivo
@@ -1490,6 +1370,7 @@ impl.neomedia.configform.VIDEO=Vídeo
impl.neomedia.configform.H264=H.264
impl.neomedia.configform.H264.defaultIntraRefresh=Actualización Periodica de Intra
impl.neomedia.configform.H264.defaultProfile=Perfil para codificar en:
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=Base
impl.neomedia.configform.H264.defaultProfile.high=Alto
impl.neomedia.configform.H264.defaultProfile.main=Principal
@@ -1520,7 +1401,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=Contraseña actual:
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Escriba su nueva contraseña:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Reescribir la contraseña:
plugin.securityconfig.masterpassword.MP_TITLE=Contraseña Maestra
-plugin.securityconfig.masterpassword.MP_NOT_SET=(no configurado)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=No introdujo la Contraseña Maestra correcta. Por favor inténtelo nuevamente.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=¡La Contraseña Maestra no es correcta!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Falló el Cambio de Contraseña
@@ -1632,7 +1512,7 @@ plugin.globalproxy.PROXY_PORT=Puerto del proxy
plugin.globalproxy.PROXY_USERNAME=Usuario del Proxy
plugin.globalproxy.PROXY_PASSWORD=Contraseña del Proxy
plugin.globalproxy.DESCRIPTION={0} usará la configuración del proxy para todas las redes a las que está conectado o se conecte de ahora en adelante. \nEl soporte de proxy es experimental y solo funciona con algunos protocolos. Revise la siguiente tabla para más detalles:
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>JABBER</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
+plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>XMPP</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
plugin.globalproxy.FWD_DNS=Proxy también de DNS
plugin.globalproxy.FWD_DNS_NOTE=Es útil con Tor. Ayuda a evitar las fuga de DNS mediante el envío de todo el tráfico de DNS al proxy de Tor. Requiere reiniciar.
@@ -1670,7 +1550,6 @@ plugin.provisioning.RESTART_WARNING=¡Tenga en cuenta que los cambios sólo surt
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=Copiar UUID al portapapeles
plugin.provisioning.CLIPBOARD_FAILED=Falló el copiado de UUID al portapapeles
-plugin.provisioning.EXIT_ON_FAIL=Salir de la aplicación si el aprovisionamiento falla
plugin.provisioning.CREDENTIALS=Últimas credenciales de aprovisionamiento almacenadas
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=¿Está seguro que desea eliminar la contraseña de aprovisionamiento?
plugin.provisioning.PROV_FAILED=Falló el aprovisonamiento
@@ -1737,8 +1616,6 @@ util.dns.DNSSEC_WARNING=<html><div width="600">{0} ha tratado de conectarse al s
#plugin spellcheck
plugin.spellcheck.TITLE=Ortografía y Gramática
plugin.spellcheck.MENU=Mostrar Ortografía y Gramática
-plugin.spellcheck.LANG=Idioma
-plugin.spellcheck.EDIT_PERSONAL_DICT=Editar
plugin.spellcheck.ENABLE_SPELL_CHECK=Activar revisión ortográfica
plugin.spellcheck.dialog.FIND=Buscar siguiente
plugin.spellcheck.dialog.REPLACE=Reemplazar
diff --git a/resources/languages/resources_fi.properties b/resources/languages/resources_fi.properties
index 2fe17fc..726c514 100644
--- a/resources/languages/resources_fi.properties
+++ b/resources/languages/resources_fi.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,38 +43,33 @@ service.gui.ACCOUNT_ME=Minä
service.gui.ACCOUNT_REGISTRATION_WIZARD=Tilin Rekisteröinti Apuri
service.gui.ACCOUNTS=Tilit
service.gui.ADD=&Lisää
-service.gui.ADD_ACCOUNT=Lisää tili
service.gui.ADD_CONTACT=&Lisää kontakti
service.gui.ADD_AUTHORIZED_CONTACT=Lisää {0} kontakti listallesi
+service.gui.ADD_CONTACT_TO_CONTACTLIST=Lisää henkilö kontaktilistallesi
service.gui.ADD_CONTACT_TO=&Lisää kontakti
service.gui.ADD_CONTACT_ERROR=Epäonnistui lisäämään kontaktin tunnuksella: {0}
service.gui.ADD_CONTACT_ERROR_TITLE=Kontaktin lisäys Virhe
-service.gui.ADD_CONTACT_EXIST_ERROR=Kontakti {0} löytyy jo sinun kontakti listalta.
+service.gui.ADD_CONTACT_EXIST_ERROR=Kontakti {0} löytyy jo sinun kontaktilistalta.
service.gui.ADD_CONTACT_NETWORK_ERROR=Palvelin ei vastannut pyyntöön lisätä kontaktia tunnuksella: {0}
service.gui.ADD_CONTACT_NOT_SUPPORTED=Epäonnistui lisäämään kontaktin tunnuksella: {0}. Ei tuettu toiminto.
-service.gui.ADD_CONTACT_IDENTIFIER=Anna alapuolella olevaan kenttään lisättävän kontaktin tunniste.
-service.gui.ADD_CONTACT_WIZARD=Lisää kontakti apuri
service.gui.ADD_CONTACT_NOT_CONNECTED=Sinun täytyy olla yhdistettynä lisääksesi kontaktin. Kirjaudu sisään valituun palveluun ja yritä uudelleen.
service.gui.ADD_GROUP_LOCAL_ERROR=Ryhmän {0} nimen lisääminen epäonnistui. Ongelma tapahtui paikallisen IO operaation aikana.
-service.gui.ADD_GROUP_EXIST_ERROR=Ryhmä {0} löytyy jo kontakti listasta. Valitse toinen nimi.
+service.gui.ADD_GROUP_EXIST_ERROR=Ryhmä {0} löytyy jo kontaktilistasta. Valitse toinen nimi.
service.gui.ADD_GROUP_NET_ERROR=Ryhmän {0} nimen lisääminen epäonnistui. Ongelma tapahtui verkko ongelman takia. Tarkista että verkkoyhteys toimii ja yritä uudelleen.
service.gui.ADD_GROUP_ERROR=Ryhmän {0} nimen lisääminen epäonnistui.
service.gui.ADD_GROUP_EMPTY_NAME=Ryhmän nimi ei voi olla tyhjä.
-service.gui.ADD_GROUP=Luo ryhmä
-service.gui.ADD_SUBCONTACT=&Lisää ali-kontakti
service.gui.ADDRESS=Osoite
service.gui.ADMINISTRATOR=ylläpitäjä
service.gui.ADVANCED=&Edistynyt
-service.gui.ALL=&Kaikki
service.gui.ALL_CONTACTS=&Kaikki kontaktit
+service.gui.ALTERNATE_ADDRESS=Toissijainen osoite
service.gui.APPLY=&Käytä
-service.gui.ARE_CALLING=soittaa...
+service.gui.ARE_CALLING={0} soittaa...
service.gui.ARE_NOW=Olet nyt {0}
service.gui.AT=at
service.gui.AUTHORIZE=&Vahvista
service.gui.AUTHORIZATION_ACCEPTED=on hyväksynyt vahvistuspyynnön.
service.gui.AUTHENTICATION_FAILED=Tunnistus virhe {0}. Syötetty salasana ei ole oikein.
-service.gui.AUTHENTICATION_REQUESTED=Tunnistautuminen lähetetty
service.gui.AUTHENTICATION_REQUESTED_SERVER={0} palvelin pyytää sinulta tunnistautumista.
service.gui.AUTHENTICATION_REJECTED=eväsi sinun vahvistuspyynnön.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} tunnistautuminen
@@ -73,6 +79,7 @@ service.gui.AUTHORIZATION_RESPONSE=Vahvistus vastaus
service.gui.AWAY_STATUS=Poissa
service.gui.EXTENDED_AWAY_STATUS=Pidennetty poissaolo
service.gui.BAN=&Estä
+service.gui.BANNED=estetty
service.gui.BAN_FAILED=Estäminen epäonnistui
service.gui.BAN_FAILED_GENERAL_ERROR=Estäminen epäonnistui {0}. Tapahtui yleinen palvelin virhe.
service.gui.BAN_FAILED_NOT_ALLOWED=Estäminen epäonnistui {0}. Huoneen ylläpitäjää tai omistajaa ei voi estää.
@@ -85,6 +92,7 @@ service.gui.CALL=Soita
service.gui.CALL_CONTACT=Soita kontaktille
service.gui.CALL_FAILED=Soitto epäonnistui
service.gui.CALL_HISTORY_TOOL_TIP=Paina tästä nähdäksesi soitto historia
+service.gui.CALL_HISTORY_GROUP_NAME=Soittohistoria
service.gui.CALL_VIA=Soita:
service.gui.CALL_NAME_OR_NUMBER=Soita nimellä tai numerolla
service.gui.CALL_NOT_SUPPORTING_PARTICIPANT=Tämä puhelu tukee ainoastaan osallistujat {0} verkosta ja sinun {1} tunnuksesta. {2} ei ole osoitetta tähän verkkoon tai tunnukseen.
@@ -100,26 +108,41 @@ service.gui.CHANGE_ROOM_SUBJECT_LABEL=Alla olevaan kenttään voit laittaa huone
service.gui.CHANGE_NICK=Vaihda kutsumanimi
service.gui.CHANGE_NICKNAME=Vaihda kutsumanimi...
service.gui.CHANGE_NICKNAME_LABEL=Alla olevaan kenttään voit laittaa uuden kutsumanimen.
-service.gui.CHANGE_NICKNAME_ERROR=Tapahtui virhe muutettaessa nimeä
+service.gui.CHANGE_NICKNAME_ERROR=Lempinimeä muutettaessa tapahtui virhe
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Nimi on jo käytössä
service.gui.CHANGE_VIDEO_QUALITY=Vaihda etävideon laatu
-service.gui.CHAT_CONFERENCE_LABEL=Kokous
service.gui.CHAT_CONFERENCE_ITEM_LABEL=käyttäjän {0} kokouksessa
-service.gui.CHAT_ROOM_USER_JOINED=liittyi
+service.gui.CHAT_ROOM_ALREADY_JOINED=Huoneeseen {0} on jo liitytty
+service.gui.CHAT_ROOM_CONFIGURATION={0} huoneen asetukset
+service.gui.CHAT_ROOM_CONFIGURATION_FAILED=Huoneen {0} asetuslomakkeen haku epäonnistui
+service.gui.CHAT_ROOM_CONFIGURATION_FORBIDDEN=Huoneen {0} asetuslomakkeen haku epäonnistui. Vain huoneen omistajat voivat nähdä ja muokata asetuslomaketta.
+service.gui.CHAT_ROOM_CONFIGURATION_SUBMIT_FAILED=Virhe huoneen {0} asetuslomakkeen lähetyksessä.
+service.gui.CHAT_ROOM_CONFIGURATION_MEMBERS_EDIT_TITLE=Muokkaa jäsenlistaa
+service.gui.CHAT_ROOM_CONFIGURATION_MEMBERS_EDIT_DESCRIPTION=Oikealla olevassa listassa on huoneen jäsenet. Kun huoneen tila on "vain jäsenille", vain listassa olevat henkilöt voivat liittyä.
+service.gui.CHAT_ROOM_USER_JOINED=liittyi {0}
service.gui.CHAT_ROOM_USER_LEFT=on poistunut {0}
-service.gui.CHAT_ROOM_USER_QUIT=poistui {0}
+service.gui.CHAT_ROOM_USER_KICKED=potkaistiin huoneesta {0}
+service.gui.CHAT_ROOM_USER_QUIT=poistui huoneesta {0}
+service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=Viestin lähetys estetty.
service.gui.CHAT_ROOM_NAME=Keskusteluhuoneen nimi
service.gui.ROOM_NAME=Keskusteluhuone
service.gui.CHANGE_PASSWORD=Vaihda salasana
+service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Huone {0} vaatii salasanan.
service.gui.CHAT_ROOMS=Keskusteluhuone
service.gui.CHAT_ROOM=Keskusteluhuone
+service.gui.CHAT_ROOM_SUBJECT_CHANGED={0} vaihtoi aiheeksi {1}
+service.gui.CHAT_ROOM_ALTERNATE_ADDRESS=Voit jatkaa keskustelua huoneessa {0}
+service.gui.CHAT_NICKNAME_CHANGE={0} on nyt {1}
+service.gui.CHOOSE_CONTACT=Valitse yhteyshenkilö
+service.gui.CHOOSE_NUMBER=Valitse numero
+service.gui.CHOOSE_ACCOUNT=Valitse yksi tunnuksista
service.gui.CLOSE=&Sulje
-service.gui.CONFIRM=Vahvista
service.gui.CONNECTED_STATUS=Yhdistetty
service.gui.CONNECTING=Yhdistää...
service.gui.CONNECTING_STATUS=Yhdistää
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Yhdistää*
service.gui.CONNECTION=Yhdistetään...
+service.gui.CONNECTION_EXPIRED_MSG=Yhteys palvelimeen {0} on katkaistu.
service.gui.CONTACT_NAME=Tunnus tai Numero
service.gui.CONTACT_TYPING={0} kirjoittaa viestiä
service.gui.COPY=&Kopioi
@@ -129,8 +152,7 @@ service.gui.DELETE=Poista
service.gui.DENY=&Estä
service.gui.DO_NOT_ASK_AGAIN=Älä kysy uudestaan
service.gui.DO_NOT_SHOW_AGAIN=Älä näytä tätä viestiä uudestaan
-service.gui.DOWNLOAD_NOW=&Lataa nyt
-service.gui.DRAG_FOR_SHARING=Raahaa hiirellä tähän mitä haluat jakaa...
+service.gui.DRAG_FOR_SHARING=Vedä tähän tiedosto, jonka haluat jakaa...
service.gui.DURATION=kesto
service.gui.EDIT=&Muokkaa
service.gui.EMPTY_HISTORY=&Tyhjennä historia
@@ -155,16 +177,14 @@ service.gui.HIDE=Piilota
service.gui.HISTORY=&Historia
service.gui.HISTORY_CONTACT=Historia - {0}
service.gui.HOME=Koti
+service.gui.INSERT_SMILEY=Lisää hymiö
service.gui.IS_CALLING=soittaa...
-service.gui.CLOSE_CHAT_ROOM_DIALOG=&Sulje
service.gui.KICK_FAILED_GENERAL_ERROR=Estäminen epäonnistui {0}. Tapahtui yleinen palvelin virhe.
service.gui.KICK_FAILED_NOT_ALLOWED=Estäminen epäonnistui {0}. Huoneen ylläpitäjää tai omistajaa ei voi estää.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Estäminen epäonnistui {0}. Sinulla ei ole tarpeeksi oikeuksia estämiseen.
-service.gui.LAST=Viimeinen
service.gui.LIST=Viimeinen
service.gui.LOADING=Lataa...
service.gui.MESSAGE=Viesti
-service.gui.MORE=Näytä enemmän
service.gui.MORE_LABEL=Siirrä
service.gui.MOVE=Siirrä
service.gui.NEXT=&Seuraava
@@ -175,17 +195,20 @@ service.gui.NO=Ei
service.gui.NONE=Ei mitään
service.gui.NO_CAMERA_AVAILABLE=Ei kameraa saatavilla
service.gui.NO_MESSAGE=Uusi viesti
+service.gui.OFFLINE=Offline
+service.gui.OK=&OK
service.gui.ONLINE=Paikalla
service.gui.OPEN=Avaa
service.gui.OPEN_FOLDER=Avaa kansio
-service.gui.OPEN_IN_BROWSER=Avaa &selaimeen
+service.gui.OPEN_IN_BROWSER=Avaa &selaimessa
service.gui.OPTIONS=Asetukset
service.gui.OR=tai
service.gui.ORGANIZATION=Yritys:
+service.gui.chat.role.ADMINISTRATOR=ylläpitäjä
service.gui.PASSWORD=Salasana
service.gui.PASTE=&Liitä
+service.gui.PORT=Portti
service.gui.PREVIOUS=Edellinen
-service.gui.PREVIOUS_TOOLTIP=Selaa vanhoja keskusteluja
service.gui.PRINT=&Tulosta
service.gui.PROACTIVE_NOTIFICATION=kirjoittaa viestiä
service.gui.PROTOCOL=Protokolla
@@ -193,34 +216,28 @@ service.gui.QUIT=&Lopeta
service.gui.READY=Valmis
service.gui.REASON=Syy
service.gui.REJECT=&Hylkää
-service.gui.REMIND_ME_LATER=Muistuta myöhemmin
service.gui.REMEMBER_PASSWORD=Muista salasana
service.gui.REMOVE=&Poista
service.gui.REMOVE_ACCOUNT=&Poista tili
service.gui.REMOVE_ACCOUNT_MESSAGE=Haluatko varmasti poistaa tämän tilin?
service.gui.SAVE=&Tallenna
-service.gui.SAVE_AS_DEFAULT=Tallenna oletuksena
service.gui.SEARCH=&Etsi
-service.gui.SELECT_ACCOUNT=Valitse tili
-service.gui.SELECT_PROVIDERS_WIZARD=Valitse tili
service.gui.SEND=&Lähetä
service.gui.SEND_FILE=Lähetä &tiedosto
service.gui.SET_STATUS_MESSAGE=Uusi tilaviesti
service.gui.SETTINGS=&Asetukset
service.gui.SHOW=Näytä
-service.gui.SHOW_MORE=näytä lisää...
+service.gui.SHOW_MORE=Näytä lisää...
service.gui.SIGN_IN=Kirjaudu sisään
service.gui.STATUS=Tila
service.gui.SUBJECT=Aihe
service.gui.TELEPHONY=Puhelin
-service.gui.TODAY=Tänään
service.gui.TOOLS=&Työkalut
service.gui.VALUE=Arvo:
service.gui.VOICEMAIL_NO_MESSAGES=Uusi viesti
service.gui.WARNING=Varoitus
service.gui.YES=Kyllä
service.gui.NEW=Uusi
-service.gui.UPDATE=Päivitys
service.gui.MOBILE_PHONE=Matkapuhelin
service.gui.VIDEO_PHONE=Video
service.gui.WORK_PHONE=Työ
@@ -239,19 +256,22 @@ service.gui.OCTOBER=Lok
service.gui.NOVEMBER=Mar
service.gui.DECEMBER=Jou
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.COMPLETED=Valmis
+
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_O=Yritys:
service.gui.CERT_INFO_C=Maa:
service.gui.CERT_INFO_ST=Osavaltio tai lääni:
service.gui.CERT_INFO_SER_NUM=Sarjanumero:
service.gui.CERT_INFO_VER=Versio:
-service.gui.CONTINUE=Jatka
service.gui.AUTO_ANSWER_VALUE=Arvo:
service.gui.AUTO_ANSWER_VIDEO=Video
-service.gui.security.NO_VIDEO=Ei videoa
# keep the following string short
service.gui.avatar.CHOOSE_ICON=Valitse kuva
@@ -264,9 +284,6 @@ service.gui.avatar.imagepicker.CHOOSE_FILE=Valitse ...
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
# systray
@@ -274,20 +291,20 @@ service.gui.avatar.imagepicker.CHOOSE_FILE=Valitse ...
# New Account Dialog
# LDAP
-impl.ldap.NEW=Uusi
impl.ldap.EDIT=&Muokkaa
-impl.ldap.REMOVE=&Poista
impl.ldap.AUTH_NONE=Ei mitään
impl.ldap.SAVE=&Tallenna
impl.ldap.CANCEL=&Peruuta
impl.ldap.PASSWORD=Salasana
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
# Google Contacts
-impl.googlecontacts.NEW=Uusi
impl.googlecontacts.EDIT=&Muokkaa
-impl.googlecontacts.REMOVE=&Poista
impl.googlecontacts.SAVE=&Tallenna
impl.googlecontacts.CANCEL=&Peruuta
impl.googlecontacts.PASSWORD=Salasana
@@ -303,9 +320,6 @@ impl.googlecontacts.PASSWORD=Salasana
# branding
plugin.branding.ABOUT_MENU_ENTRY=&Tietoja
-# Dict protocol
-
-# facebookaccregwizz
# generalconfig
plugin.generalconfig.SHOW_HISTORY=Näytä
@@ -315,29 +329,22 @@ plugin.generalconfig.SHOW_HISTORY=Näytä
# icqaccregwizz
# irc accregwizz
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE={0} tunnistautuminen
# jabber accregwizz
plugin.jabberaccregwizz.VIDEO=Video
-# mailbox
-plugin.mailbox.CONFIRM=Vahvista
-
-# msn accregwizz
-
# plugin manager
-plugin.pluginmanager.UPDATE=Päivitys
plugin.pluginmanager.NEW=Uusi
# simple accregwizz
# sipaccregwizz
plugin.sipaccregwizz.XCAP_PASSWORD=Salasana
+#used from SecurityPanel
# skin manager
-# ssh accregwizz
-plugin.sshaccregwizz.OPTIONAL=Asetukset
-
# status update
# updatechecker
@@ -350,24 +357,21 @@ plugin.whiteboard.OPEN=Avaa
plugin.whiteboard.COLOR=Väri
plugin.whiteboard.DELETE=Poista
-# yahoo accregwizz
-
-# zero accregwizz
-
# gtalk accregwizz
# iptel accregwizz
-# sip2sip accregwizz
-
# ippi accregwizz
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_COPY=&Kopioi
plugin.keybindings.CHAT_PASTE=&Liitä
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Keskustelu
# Notification Configuration Form
+#NotificationsTable constants
# ZRTP Securing
@@ -381,6 +385,7 @@ impl.media.security.zrtp.TITLE=Soita
impl.neomedia.configform.VIDEO=Video
+#in JNIEncoder
# The callrecordingconfig plugin was never really committed into trunk and its
# ConfigurationForm was actually put in the neomedia bundle.
@@ -389,7 +394,6 @@ impl.neomedia.configform.VIDEO=Video
plugin.securityconfig.masterpassword.TITLE=Salasana
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Muista salasana
plugin.securityconfig.masterpassword.COL_PASSWORD=Salasana
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=&Poista
# otr plugin
plugin.otr.authbuddydialog.CANCEL=&Peruuta
@@ -415,7 +419,6 @@ plugin.chatconfig.TITLE=Keskustelu
net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.Deny=&Estä
#plugin spellcheck
-plugin.spellcheck.EDIT_PERSONAL_DICT=&Muokkaa
#Certificate configuration plugin
diff --git a/resources/languages/resources_fr.properties b/resources/languages/resources_fr.properties
index 6f81b83..e9aac93 100644
--- a/resources/languages/resources_fr.properties
+++ b/resources/languages/resources_fr.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Moi
service.gui.ACCOUNT_REGISTRATION_WIZARD=Assistant d'enregistrement de compte
service.gui.ACCOUNTS=Comptes
service.gui.ADD=&Ajouter
-service.gui.ADD_ACCOUNT=Ajouter un compte
service.gui.ADD_CONTACT=&Ajouter un contact
service.gui.ADD_AUTHORIZED_CONTACT=Ajouter {0} à votre liste de contacts
service.gui.ADD_CONTACT_TO_CONTACTLIST=Ajouter le contact à votre liste de contacts
@@ -42,20 +52,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Échec lors de l'ajout du contact
service.gui.ADD_CONTACT_EXIST_ERROR=Le contact {0} existe déjà dans votre liste de contact.
service.gui.ADD_CONTACT_NETWORK_ERROR=Le serveur n''a pas répondu à la requête d''ajout du contact avec l''id: {0}.
service.gui.ADD_CONTACT_NOT_SUPPORTED=Échec lors de l''ajout du contact id: {0}. L''opération n''est pas prise en charge.
-service.gui.ADD_CONTACT_IDENTIFIER=Dans le champ suivant, veuillez entrer l'identifiant du contact que vous souhaitez ajouter.
-service.gui.ADD_CONTACT_WIZARD=Assistant d'ajout de contact
service.gui.ADD_CONTACT_NOT_CONNECTED=Vous devez être connecté pour ajouter un contact. Veuillez vous connecter au fournisseur sélectionné avant de réessayer.
service.gui.ADD_GROUP_LOCAL_ERROR=Échec lors de l''ajout du groupe : {0}. Le problème est dû à un échec d''E/S lors d''une opération locale.
service.gui.ADD_GROUP_EXIST_ERROR=Le groupe {0} existe déjà dans votre liste de contact. Veuillez choisir un nom différent.
service.gui.ADD_GROUP_NET_ERROR=Échec lors de l''ajout du groupe : {0}. Le problème est dû à une erreur réseau. Veuillez vérifier votre connexion au réseau puis réessayez.
service.gui.ADD_GROUP_ERROR=Échec lors de l''ajout du groupe : {0}.
service.gui.ADD_GROUP_EMPTY_NAME=Le nom du groupe ne doit pas être vide.
-service.gui.ADD_GROUP=Créer un groupe
-service.gui.ADD_SUBCONTACT=&Ajouter un sous-contact
service.gui.ADDRESS=Adresse
service.gui.ADMINISTRATOR=administrateur
service.gui.ADVANCED=&Avancé
-service.gui.ALL=&Tous
service.gui.ALL_CONTACTS=&Tous les contacts
service.gui.ALTERNATE_ADDRESS=Autre adresse
service.gui.APPLY=&Appliquer
@@ -65,7 +70,6 @@ service.gui.AT=à
service.gui.AUTHORIZE=Autoriser
service.gui.AUTHORIZATION_ACCEPTED={0} a accepté votre demande d''autorisation.
service.gui.AUTHENTICATION_FAILED=L''authentification a échoué pour {0}. Le mot de passe que vous avez fourni est incorrect.
-service.gui.AUTHENTICATION_REQUESTED=Authentification requise
service.gui.AUTHENTICATION_REQUESTED_SERVER=Le serveur {0} demande votre authentification.
service.gui.AUTHENTICATION_REJECTED={0} a rejeté votre demande d''authentification.
service.gui.AUTHENTICATION_WINDOW_TITLE=Authentification de {0}
@@ -107,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=Vous pouvez saisir votre surnom dans le champ
service.gui.CHANGE_NICKNAME_ERROR=Erreur lors du changement de pseudonyme
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Ce pseudonyme existe déjà
service.gui.CHANGE_VIDEO_QUALITY=Changer la qualité de la vidéo
-service.gui.CHAT_CONFERENCE_LABEL=Conférence
service.gui.CHAT_CONFERENCE_ITEM_LABEL=Conférence de {0}
service.gui.CHAT_ROOM_ALREADY_JOINED=Vous avez déjà rejoint la conversation {0}.
service.gui.CHAT_ROOM_CONFIGURATION=Configuration de la conversation {0}
@@ -121,18 +124,14 @@ service.gui.CHAT_ROOM_USER_LEFT=a quitté la conversation {0}
service.gui.CHAT_ROOM_USER_KICKED=a été banni par {0}
service.gui.CHAT_ROOM_USER_QUIT=a mis un terme à {0}
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=L'envoi de message est interdit (voix annulée)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Enregistrer la discussion pour un usage futur
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Supprime la discussion sélectionnée de ma liste de favoris
service.gui.CHAT_ROOM_NAME=Nom de la conversation
service.gui.CLEAR_CUSTOM_MESSAGES=Effacer les messages personnalisés
service.gui.ROOM_NAME=Conversation
-service.gui.AUTOJOIN=Connexion automatique
service.gui.CHANGE_PASSWORD=Modifier le mot de passe
service.gui.CHAT_ROOM_NAME_INFO=Dans le champ suivant, veuillez entrer le nom de la conversation que vous souhaitez créer.
service.gui.CHAT_ROOM_NOT_EXIST=Le salon {0} est introuvable sur le serveur {1}. Veuillez vérifier la validité du nom que vous avez saisi.
service.gui.CHAT_ROOM_NOT_CONNECTED=Vous devez vous connecter pour rejoindre la conversation {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Vous devez être connecté pour pouvoir quitter une conversation.
-service.gui.CHAT_ROOM_NOT_JOINED=Vous devez d'abord rejoindre une conversation pour effectuer cette opération.
service.gui.CHAT_ROOM_OPTIONS=Options de la conversation
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Vous devez être enregistré afin de pouvoir le rejoindre le salon {0}.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Le salon {0} nécessite un mot de passe.
@@ -151,22 +150,20 @@ service.gui.CLEAR=Effacer
service.gui.CLOSE=F&ermer
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Vous avez reçu un message il y a moins de 2 secondes. Êtes-vous sûr de vouloir fermer cette conversation ?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=Des fichier sont en cours de transfert. Êtes-vous sûr de vouloir les annuler ?
-service.gui.CONFIRM=Confirmer
service.gui.CONNECTED_STATUS=Connecté
service.gui.CONNECTING=Connexion...
service.gui.CONNECTING_STATUS=Connexion
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Connexion*
service.gui.CONNECTION=Connexion
-service.gui.CONNECTION_FAILED_MSG=Échec de connexion pour le compte : Nom d''utilisateur : {0}, Nom du serveur : {1}. Veuillez vérifier votre connexion au réseau ou contacter votre administrateur réseau pour plus d''informations.
service.gui.CONNECTION_EXPIRED_MSG=Vous êtes déconnecté du serveur {0}.
service.gui.CONTACT_NAME=ID ou numéro
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Le contact {0} ne supporte pas la téléphonie.
+service.gui.CONTACT_NAME_PROMPT=joan.martin@exemple.com
+service.gui.CONTACT_NAME_INFO=Ajoutez soit une adresse de messagerie instantanée - telle que joan.martin@exemple.com - ou un numéro VoIP.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Le contact {0} ne supporte pas les conférences de messagerie.
service.gui.CONTACT_PAUSED_TYPING={0} s''est arrêté d''écrire le message
service.gui.CONTACT_TYPING={0} écrit un message
service.gui.CONTACT_TYPING_SEND_FAILED=Oups...nous ne pouvons envoyer à {0} la notification d''écriture
service.gui.CONTACT_INFO=Informations sur le &contact
-service.gui.CONTACTLIST=Liste de contacts
service.gui.CONTACTS=Contacts
service.gui.COPY=&Copier
service.gui.COPY_LINK=Copier &l'adresse
@@ -176,28 +173,26 @@ service.gui.CREATE_CHAT_ROOM=&Créer un salon...
service.gui.CREATE_CHAT_ROOM_ERROR=Échec lors de la création du salon {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=Assistant de création de salon
service.gui.CREATE_CONFERENCE_CALL=&Créer une conférence téléphonique...
-service.gui.CREATE_CONFERENCE_CHAT=&Créer une conférence de messagerie...
service.gui.CREATE_GROUP=&Créer un groupe...
service.gui.CREATE_GROUP_NAME=Veuillez saisir dans le champ suivant le nom du groupe que vous désirez créer.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Votre liste de contacts ne contient aucun groupe. Veuillez créer un groupe (Fichier/Créer un groupe) en premier lieu.
service.gui.CREATE_VIDEO_BRIDGE=Créer un &pont vidéo
service.gui.CREATE_VIDEO_BRIDGE_MENU=Créer un &pont vidéo
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Créer / Joindre la video conférence
service.gui.CREATE_VIDEO_CONFERENCE=Créer une nouvelle conférence vidéo pour ce salon de discussion
service.gui.CONTACT_INFO_NOT_SUPPORTED=Ce contact ne dispose pas d'informations en ligne
service.gui.CUT=&Couper
-service.gui.DATE=Date
service.gui.DELETE=Supprimer
service.gui.DENY=&Refuser
service.gui.DESKTOP_SHARING_WARNING=<b>Êtes vous certain de vouloir démarrer le partage d'écran?</b> <br> En cliquant sur OK, vos correspondants sur cet appel pourront voir votre écran.
service.gui.DESKTOP_SHARING_DIALOG_INDICATE=Vous partagez votre écran
service.gui.DIALPAD=Clavier téléphonique
service.gui.DISPLAY_NAME=Nom affiché
+service.gui.DISPLAY_NAME_PROMPT=Joan Martin
+service.gui.DISPLAY_NAME_INFO=Ajouter un nom à ce contact. Si laissé vide, l'adresse de messagerie instantanée ou le numéro VoIP sera utilisé à la place. (Optionnel)
service.gui.DISCONNECTED_STATUS=Déconnecté
service.gui.DND_STATUS=Ne pas déranger
service.gui.DO_NOT_ASK_AGAIN=Ne plus redemander
service.gui.DO_NOT_SHOW_AGAIN=Ne plus afficher ce message
-service.gui.DOWNLOAD_NOW=&Télécharger maintenant
service.gui.DRAG_FOR_SHARING=Glisser ici pour partager
service.gui.DURATION=durée
service.gui.DESTROY_CHATROOM=Supprimer le salon
@@ -218,7 +213,6 @@ service.gui.ERROR_RECEIVED_FROM=Erreur reçu de {0}
service.gui.ESTIMATED_TIME=Temps estimé :
service.gui.EVENTS=Événements
service.gui.EXIT=Q&uitter
-service.gui.EXTENDED_CRITERIA=Critères étendus
service.gui.GENERAL=Général
service.gui.GENERAL_ERROR=Erreur générale
service.gui.GROUP_NAME=Nom du groupe
@@ -260,7 +254,6 @@ service.gui.FONT_ITALIC=Italique
service.gui.FONT_SIZE=Taille
service.gui.FONT_STYLE=Style
service.gui.FONT_UNDERLINE=Souligné
-service.gui.FROM={0} sur {1}
service.gui.GRANT_OWNERSHIP=Attribuer la propriété...
service.gui.GRANT_ADMIN=Attribuer le statut administrateur...
service.gui.GRANT_MODERATOR=Attribuer le statut modérateur
@@ -286,7 +279,6 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=Voulez-vous vraiment supprimer définitiv
service.gui.HISTORY_REMOVE_ERROR=Erreur lors de la suppression des messages.
service.gui.HOME=Domicile
service.gui.HOME_PAGE=Page d'accueil
-service.gui.HOUR=Heure
service.gui.ICE=ICE
service.gui.IDENTIFIER=Identifiant
service.gui.IGNORE=&Ignorer
@@ -310,13 +302,10 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Inviter des contacts à la visio-conf
service.gui.INVITE_REASON=Motif de l'invitation
service.gui.IS_CALLING={0} appelle...
service.gui.IS_NOW={0} est maintenant {1}
-service.gui.JITSI_WARNING=Le communicateur SIP a récemment été renommé Jitsi.<br/>Si vous souhaitez garder votre version à jour, veuillez télécharger Jitsi.<br/><br/>Nous sommes désolés pour ce désagrément.<br/><br/>L'équipe de développement de Jitsi
-service.gui.JITSI_WARNING_TITLE=SIP Communicator devient Jitsi
service.gui.JOIN=&Rejoindre
service.gui.JOIN_AS=&Rejoindre comme
service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=Joindre une conférence vidéo existante
service.gui.JOIN_VIDEO=Joindre avec vidéo
-service.gui.CLOSE_CHAT_ROOM_DIALOG=&Fermer
service.gui.JOB_TITLE=Profession
service.gui.JOIN_CHAT_ROOM=Re&joindre la conversation...
service.gui.JOIN_CHAT_ROOM_TITLE=Rejoindre la conversation
@@ -329,7 +318,6 @@ service.gui.KICK_FAILED=Échec de la tentative d'exclusion
service.gui.KICK_FAILED_GENERAL_ERROR=Échec de l''exclusion de {0}. Une erreur du serveur est survenue.
service.gui.KICK_FAILED_NOT_ALLOWED=Échec de l''exclusion de {0}. Le propriétaire et l''administrateur de la conversation ne peuvent être exclus.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Échec de l''exclusion de {0}. Vous n''avez pas les droits suffisants pour cela.
-service.gui.LAST=Dernier
service.gui.LAST_NAME=Nom :
service.gui.LEAVE=&Quitter
service.gui.LIMIT_REACHED_FOR_IP=Vous avez trop de connexions existantes de l''adresse IP locale et le serveur {0} ne permet pas d''en ouvrir plus.
@@ -349,7 +337,6 @@ service.gui.MESSAGE=Message
service.gui.MISSED_CALLS_TOOL_TIP=Appels en absence de:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= ainsi que {0} autre(s)
service.gui.MODERATOR=modérateur
-service.gui.MORE=Voir d'avantage
service.gui.MORE_LABEL=Plus
service.gui.MOVE=Déplacer
service.gui.MOVE_SUBCONTACT=D&éplacer le sous-contact
@@ -358,7 +345,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=Le contact choisi est le même que celui que
service.gui.MOVE_SUBCONTACT_QUESTION=Êtes-vous sûr de vouloir déplacer {0} vers {1} ?
service.gui.MOVE_TO_GROUP=&Déplacer vers le groupe
service.gui.MOVE_CONTACT=D&éplacer le contact
-service.gui.MOVE_CONTACT_ERROR=Le &contact ne peut pas être déplacé
service.gui.MSG_DELIVERY_FAILURE=Le message ci-dessus n'a pas pu être délivré
service.gui.MSG_DELIVERY_NOT_SUPPORTED=Le protocole que vous utilisez n''offre pas le support de l''envoi de messages en mode déconnecté. Vous pouvez essayer de joindre {0} au moyen d''un autre protocole ou attendre que celui-ci se connecte.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Une erreur interne est survenue. Il s''agit certainement d''un bug. Veuillez le signaler ici : https://jitsi.org/Development/BugsAndIssues.
@@ -372,7 +358,6 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=Vous devez être connecté pour pouvoir
service.gui.MULTIPLE_LOGINS=Vous vous êtes connecté plus d''une fois avec le même compte. Le compte suivant : Nom d''utilisateur : {0}, Nom du serveur : {1} est actuellement déconnecté.
service.gui.MY_CHAT_ROOMS=Ajouter un salon de discussion
service.gui.MY_CHAT_ROOMS_TITLE=Ajouter un salon de discussion
-service.gui.MUTE=Muet
service.gui.MUTUALLY_ON_HOLD_STATUS=Les deux en attente
service.gui.NAME=Nom
service.gui.NETWORK=Réseau
@@ -404,7 +389,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=Pas dans la liste de contacts
service.gui.SD_QUALITY=Qualité standard
service.gui.OFFLINE=Déconnecté
service.gui.OK=&Ok
-service.gui.OLDER_CALLS=Anciens appels
service.gui.ONLINE=Connecté
service.gui.OPEN=Ouvrir
service.gui.OPEN_FILE_FROM_IMAGE=Double-cliquez pour ouvrir le fichier.
@@ -416,7 +400,6 @@ service.gui.OPEN_ON_ACTIVITY=Ouvrir lors d'activité
service.gui.OPEN_ON_MESSAGE=Ouvrir seulement lors d'un message
service.gui.OPEN_ON_IMPORTANT_MESSAGE=Ouvrir seulement lors de messages importants
service.gui.OR=ou
-service.gui.OR_ENTER_PHONE_NUMBER=Ou entrez un numéro de téléphone ici...
service.gui.ORGANIZATION=Entreprise :
service.gui.OTHER=Autre
service.gui.chat.role.OWNER=Propriétaire
@@ -442,7 +425,6 @@ service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Entrée' pour les suggestions
service.gui.PRESS_FOR_CALL_INFO=Détails d'appel
service.gui.PRESS_TO_OPEN_CRM=Appuyer pour ouvrir l'application CRM
service.gui.PREVIOUS=Précédent
-service.gui.PREVIOUS_TOOLTIP=Parcourir les anciennes conversations
service.gui.PRINT=&Imprimer
service.gui.PROACTIVE_NOTIFICATION=est en train d'écrire un message
service.gui.PROBLEMS_ENCOUNTERED=Problème survenu
@@ -458,7 +440,6 @@ service.gui.RECONNECTION_LIMIT_EXCEEDED=Vous vous êtes déconnecté et reconnec
service.gui.RE_REQUEST_AUTHORIZATION=Re-demander l'autorisation
service.gui.REFERRED_STATUS=Renvoyé
service.gui.REJECT=&Rejeter
-service.gui.REMIND_ME_LATER=Rappelez-moi plus tard
service.gui.REMEMBER_PASSWORD=Mémoriser le mot de passe
service.gui.REMOVE=&Supprimer
service.gui.REMOVE_ACCOUNT=&Supprimer le compte
@@ -484,29 +465,22 @@ service.gui.REVOKE_ADMIN=Révoquer le statut administrateur
service.gui.REVOKE_MODERATOR=Révoquer le statut modérateur
service.gui.REVOKE_MEMBERSHIP=Révoquer le statut membre
service.gui.REVOKE_VOICE=Révoquer le droit de parole
-service.gui.ROOT_GROUP=Groupe racine
service.gui.SAVE=&Sauvegarder
-service.gui.SAVE_AS_DEFAULT=Enregistrer comme valeur par défaut
service.gui.SEARCH=&Rechercher
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Cliquez sur le bouton ci-dessous pour afficher tous les salons existant du serveur sélectionné. Puis, choisissez celui que vous souhaitez rejoindre et cliquez le bouton "rejoindre".
service.gui.SEARCH_STRING_CONTACT_SOURCE=Contact recherché
service.gui.SECURITY=Sécurité
-service.gui.SELECT_ACCOUNT=Choix d'un compte
+service.gui.SELECT_ACCOUNT_INFO=Quel compte souhaitez-vous utiliser pour communiquer avec ce contact ?
service.gui.SELECT_COLOR=Choix de la couleur
service.gui.SELECT_GROUP=Choisissez un groupe
-service.gui.SELECT_GROUP_WIZARD_MSG=La liste suivante contient tous les groupes de votre liste de contacts. Choisissez celui auquel vous souhaitez ajouter un nouveau contact.
+service.gui.SELECT_GROUP_INFO=Quel groupe souhaitez-vous afficher pour ce contact ? (Optionnel)
service.gui.SELECT_NO_GROUP=Pas de groupe
-service.gui.SELECT_GROUP_WIZARD=Spécifiez un groupe
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=La liste suivante contient tous les comptes qui permettent de participer à des salons de discussion. Choisissez celui que vous souhaitez utiliser pour créer un salon.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=La liste suivante contient tous les comptes enregistrés. Choisissez celui que vous souhaitez utiliser pour communiquer avec le nouveau contact.
-service.gui.SELECT_PROVIDERS_WIZARD=Choisir un compte
service.gui.SELECT_VIDEO_CONFERENCE=Sélectionner une vidéoconférence
service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Sélectionner un salon de discussion sur la liste et appuyer sur OK pour l'ajouter.
service.gui.SEND=&Envoyer
service.gui.SEND_FILE=Envoyer un &fichier
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Aucune information n'est disponible pour ce contact.
service.gui.SEND_MESSAGE=&Envoyer un message
-service.gui.SEND_AS_SMS=Envoyer en tant que SMS
service.gui.SEND_PRIVATE_MESSAGE=Envoyer un message privé
service.gui.SEND_SMS=E&nvoyer un SMS
service.gui.SEND_SMS_DETAILS=Vous devez entrer le numéro de téléphone dans un format international, par exemple en commençant par +33 pour téléphoner en France.
@@ -545,7 +519,6 @@ service.gui.STREET=Rue
service.gui.SUBJECT=Sujet
service.gui.SUMMARY=Résumé
service.gui.TELEPHONY=Téléphonie
-service.gui.TODAY=Aujourd'hui
service.gui.TOOLS=&Outils
service.gui.TRANSFER=Trans&férer
service.gui.TO=À :
@@ -555,7 +528,6 @@ service.gui.TRANSFER_CALL_TO=Transférer à :
service.gui.TRANSPARENCY_NOT_ENABLED=La transparence ne peut pas être prise en charge avec votre configuration actuelle.
service.gui.TYPE_YOUR_REQUEST=Saisissez ici votre demande
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Nous n'avons pas pu changer la qualité vidéo pour cet appel.
-service.gui.UNMUTE=Désactiver muet
service.gui.USER_IDENTIFIER=Identificateur :
service.gui.USER_EXISTS_ERROR=Cet utilisateur existe déjà sur le réseau sélectionné. Veuillez choisir un autre utilisateur ou réseau.
service.gui.USERNAME_NULL=Veuillez renseigner votre nom d'utilisateur et votre mot de passe.
@@ -568,7 +540,6 @@ service.gui.USE_PROVISIONING=Utiliser le service en ligne
service.gui.VALUE=Valeur
service.gui.VIDEO_CALL=Appel video
service.gui.VIA=via
-service.gui.VIA_SMS=Par SMS
service.gui.VIEW=&Voir
service.gui.VIEW_HISTORY=Voir l'&historique
service.gui.VIEW_SMILEYS=Afficher les &smileys
@@ -588,9 +559,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=Ajuster le volume
service.gui.WAITING_AUTHORIZATION=Attente d'autorisation
service.gui.WARNING=Avertissement
service.gui.YES=Oui
-service.gui.YESTERDAY=Hier
-service.gui.EXISTING_ACCOUNT_ERROR=Le compte saisi est déjà installé.
-service.gui.NEW_MAIL=<b>Vous avez un nouvel email !</b><br/><b>De :</b> {0} {1} <br/><b>Sujet :</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=Vous avez reçu un nouvel email dans votre <a href="{1}">boîte de réception</a> {0} :<br/>
service.gui.NEW_GMAIL_MANY_HEADER=Vous avez reçu {2} nouveaux emails dans votre <a href="{1}">boîte de réception</a> {0} :<br/>
service.gui.NEW_GMAIL_FOOTER=une conversation non-lue supplémentaire dans votre <a href="{0}">boîte de réception</a>.<br/>
@@ -602,6 +570,9 @@ service.gui.ENTER_FULL_SCREEN_TOOL_TIP=Activer le mode plein-écran
service.gui.EXIT_FULL_SCREEN_TOOL_TIP=Désactiver le mode plein-écran
service.gui.HOLD_BUTTON_TOOL_TIP=Activer/Désactiver la mise en attente
service.gui.MUTE_BUTTON_TOOL_TIP=Activer/Désactiver le microphone ou ajuster le volume du microphone
+service.gui.PARK=Parcage
+service.gui.PARKING_SLOT=Place de parcage:
+service.gui.PARK_BUTTON_TOOL_TIP=Parcage de l'appel
service.gui.RECORD_BUTTON_TOOL_TIP=Activer/Désactiver l'Enregistrement
service.gui.LOCAL_VIDEO_BUTTON_TOOL_TIP=Activer/Désactiver la Vidéo
service.gui.SHOW_LOCAL_VIDEO_BUTTON_TOOL_TIP=Montrer/cacher la vidéo locale
@@ -614,7 +585,6 @@ service.gui.SECURITY_ERROR=Erreur de sécurité
service.gui.SPEED=Vitesse :
service.gui.SILENT_MEMBER=membre muet
service.gui.NON_SECURE_CONNECTION=Aucune connexion sécurisée ne peut être établie avec le compte {0}. Pour établir une connexion non sécurisée du serveur, l''option "autoriser une connexion non sécurisée" doit être activée.
-service.gui.UPDATE=Mise à jour
service.gui.MOBILE_PHONE=Mobile
service.gui.VIDEO_PHONE=Vidéo
service.gui.WORK_PHONE=Professionnel
@@ -649,12 +619,10 @@ service.gui.callinfo.CALL_INFORMATION=Information d'appel
service.gui.callinfo.CALL_IDENTITY=Identité
service.gui.callinfo.PEER_COUNT=Nombre de participants
service.gui.callinfo.IS_CONFERENCE_FOCUS=Organisateur de conférences
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Encodage actif
service.gui.callinfo.CALL_TRANSPORT=Transport du canal de signalisation
service.gui.callinfo.CALL_DURATION=Durée d'appel
service.gui.callinfo.TLS_PROTOCOL=Protocole TLS
service.gui.callinfo.TLS_CIPHER_SUITE=Liste de chiffrement TLS
-service.gui.callinfo.TLS_SERVER_CERTIFICATE_CHAIN=Liste de certificats du serveur TLS
service.gui.callinfo.TLS_CERTIFICATE_CONTENT=Le contenu du certificat du serveur TLS est affiché ci-dessous.
service.gui.callinfo.VIEW_CERTIFICATE=Voir le certificat
service.gui.callinfo.CODEC=Codec / Fréquence
@@ -664,7 +632,7 @@ service.gui.callinfo.AUDIO_INFO=Information audio
service.gui.callinfo.VIDEO_INFO=Information vidéo
service.gui.callinfo.LOCAL_IP=IP local / Port
service.gui.callinfo.REMOTE_IP=IP partenaire / Port
-service.gui.callinfo.BANDWITH=Largeur de bande
+service.gui.callinfo.BANDWITH=Bande passante
service.gui.callinfo.LOSS_RATE=taux de perte
service.gui.callinfo.RTT=RTT
service.gui.callinfo.JITTER=Jitter
@@ -674,10 +642,13 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=Protocole d'échange de clés
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=Amélioration du candidat type ICE
service.gui.callinfo.ICE_STATE=Statut du traitement ICE
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=Candidats regroupés
service.gui.callinfo.ICE_STATE.RUNNING=contrôles de connexion
service.gui.callinfo.ICE_STATE.COMPLETED=Terminé
service.gui.callinfo.ICE_STATE.FAILED=Échec
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=IP local / Port
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=IP local réfléchi / Port
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=IP local transmis / Port
@@ -698,11 +669,12 @@ service.gui.ALWAYS_TRUST=Toujours faire confiance à ce certificat
service.gui.CERT_DIALOG_TITLE=Vérifier le certificat
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} ne peut pas vérifier l''identité du serveur lors de la connexion à <b>{1}</b>.<br><br> Le certificat est inconnu, ce qui signifie que l''identité du serveur n''a pu être vérifiée automatiquement.<br><br>Voulez-vous poursuivre la connexion ?<br><br> Pour plus d''informations, cliquez sur "Afficher le certificat".</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0} ne peut pas vérifier l''identité du serveur.<br><br> Le certificat est inconnu, ce qui signifie que l''identité du serveur n''a pu être vérifiée automatiquement. Voulez-vous poursuivre la connexion ?<br><br> Pour plus d''informations, cliquez sur "Afficher le certificat".</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} ne peut pas vérifier l''identité du client.<br><br> Le certificat est inconnu, ce qui signifie que l''identité du client n''a pu être vérifiée automatiquement. <br><br> Voulez-vous poursuivre la connexion ?<br><br> Pour plus d''informations, cliquez sur "Afficher le certificat".</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} ne peut vérifier l''identité du vis-àvis {1}.<br><br> Le certificat est inconnu, ce qui signifie que l''identité du vis-à-vis n''a pu être vérifiée automatiquement. <br><br>Voulez-vous poursuivre la connexion ?<br><br> Pour plus d''informations, cliquez sur "Afficher le certificat".</html>
service.gui.CONTINUE_ANYWAY=Continuer quand même
service.gui.CERT_INFO_CHAIN=Chaîne de certificat :
service.gui.CERT_INFO_ISSUED_TO=Émis pour
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Nom Commun :
service.gui.CERT_INFO_O=Organisation :
service.gui.CERT_INFO_C=Pays :
@@ -721,16 +693,14 @@ service.gui.CERT_INFO_SIGN_ALG=Algorithme de signature :
service.gui.CERT_INFO_PUB_KEY_INFO=Information sur la clé publique
service.gui.CERT_INFO_ALG=Algorithme :
service.gui.CERT_INFO_PUB_KEY=Clé publique :
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} octets : {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} bits
service.gui.CERT_INFO_EXP=Exposant
service.gui.CERT_INFO_KEY_SIZE=Taille de la clé :
service.gui.CERT_INFO_SIGN=Signature :
-service.gui.CONTINUE=Continuer
service.gui.SHOW_CERT=Afficher le certificat
service.gui.HIDE_CERT=Masquer le certificat
-service.gui.AUTO_ANSWER=Réponse automatique et transmisssion de l'appel
+service.gui.AUTO_ANSWER=Réponse automatique et transmission de l'appel
service.gui.AUTO_ANSWER_LABEL=Réponse automatique
service.gui.AUTO_ANSWER_ALL_CALLS=Tous les appels
service.gui.AUTO_ANSWER_ALERT_INFO_FIELDS=Uniquement pour les appels qui demandent une réponse automatique ("Alerte-info" avec "réponse automatique")
@@ -749,12 +719,9 @@ service.gui.security.SECURE_AUDIO=Audio crypté
service.gui.security.AUDIO_NOT_SECURED=Audio non crypté
service.gui.security.SECURE_VIDEO=Vidéo crypté
service.gui.security.VIDEO_NOT_SECURED=Vidéo non crypté
-service.gui.security.NO_VIDEO=Aucune vidéo
-service.gui.security.CIPHER=Algorithme: {0}
service.gui.security.CALL_SECURED_TOOLTIP=Appel crypté. Cliquez pour plus d'information.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Appel non crypté.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Cliquez ici pour comparer le secret sécurisé avec votre interlocuteur.
-service.gui.security.COMPARE_WITH_PARTNER=Comparez avec votre correspondant et cliquez sur le cadenas pour confirmer.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Comparez avec votre correspondant:
service.gui.security.STRING_COMPARED=SAS confirmé
@@ -772,20 +739,14 @@ service.gui.avatar.imagepicker.CLICK=Cliquez et souriez
service.gui.avatar.imagepicker.IMAGE_FILES=Fichiers d'images
service.gui.avatar.imagepicker.IMAGE_PICKER=Image
service.gui.avatar.imagepicker.IMAGE_SIZE=Taille de l'image
-service.gui.avatar.imagepicker.INITIALIZING=Initialisation
service.gui.avatar.imagepicker.RESET=Réinitialiser
service.gui.avatar.imagepicker.SET=Définir
service.gui.avatar.imagepicker.TAKE_PHOTO=Prendre une photo
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Erreur de la webcam
service.gui.security.encryption.required=Cryptage requis
service.protocol.ICE_FAILED=Impossible d'établir la connexion (ICE a échoué et aucun relais n'a été trouvé)
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
impl.protocol.sip.XCAP_ERROR_TITLE=Erreur dans les contacts SIP itinérants
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=La ressource{0} ne peut être lu. Compte: {1}
@@ -815,9 +776,7 @@ impl.ldap.QUERY_CUSTOM=Requête personnalisée
impl.ldap.QUERY_CUSTOM_HINT=Utilisez {0} comme espace réservé pour la recherche.
impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=Ajouter automatiquement des caractères génériques pour la requête
impl.ldap.QUERY_PHOTO_INLINE=Récupérer la photo avec d'autres attributs
-impl.ldap.NEW=Nouveau
impl.ldap.EDIT=Édition
-impl.ldap.REMOVE=Supprimer
impl.ldap.ENABLED=Activer
impl.ldap.SERVER_NAME=Nom du serveur
impl.ldap.SERVER_NAME_EXAMPLE=Mon serveur LDAP
@@ -850,6 +809,12 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=TéléphoneDomicile
impl.ldap.PHONE_PREFIX=Indicatif téléphonique
impl.ldap.PHONE_PREFIX_EXAMPLE=Ex.: 00
+# SIP Protocol
+impl.protocol.sip.INVALID_ADDRESS=''{0}'' n'est pas une adresse SIP correcte.
+
+#Jabber Protocol
+impl.protocol.jabber.INVALID_ADDRESS=''{0}'' n'est pas un JID XMPP valide.
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=Carnet d'adresses
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=Activer les recherches dans le carnet MacOSX
@@ -864,9 +829,7 @@ plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT=Définir Outlook comme logiciel
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Contacts Google
-impl.googlecontacts.NEW=Nouveau
impl.googlecontacts.EDIT=Édition
-impl.googlecontacts.REMOVE=Supprimer
impl.googlecontacts.ENABLED=Activer
impl.googlecontacts.ACCOUNT_NAME=Nom du compte
impl.googlecontacts.SAVE=Enregistrer
@@ -875,6 +838,9 @@ impl.googlecontacts.USERNAME=Nom du compte
impl.googlecontacts.PASSWORD=Mot de passe
impl.googlecontacts.PREFIX=Indicatif téléphonique
impl.googlecontacts.WRONG_CREDENTIALS=Mauvais identifiants pour le compte Google {0}
+impl.googlecontacts.OAUTH_DIALOG_TITLE=Autorisation de contacts Google
+impl.googlecontacts.CODE=Code :
+impl.googlecontacts.HYPERLINK_TEXT=Cliquer ici pour donner accès à {0}
# account info
plugin.accountinfo.TITLE=Informations du compte
@@ -905,11 +871,8 @@ plugin.accountinfo.ORGANIZATION=Entreprise:
plugin.accountinfo.JOB_TITLE=Profession:
plugin.accountinfo.ABOUT_ME=À mon propos:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
-plugin.accountinfo.USER_PICTURES=Images du contact
plugin.accountinfo.GLOBAL_ICON=Utilisez l'icône global
plugin.accountinfo.LOCAL_ICON=Utiliser cette icône:
-plugin.accountinfo.CHANGE=Changer
-plugin.accountinfo.ONLY_MESSAGE=Messages uniquement
# connection info
plugin.connectioninfo.TITLE=Informations de connexion
@@ -929,49 +892,13 @@ plugin.aimaccregwizz.USERNAME=Nom d'utilisateur AIM :
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Nom d'utilisateur et mot de passe
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Enregistrer un nouveau compte
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Si vous n'avez pas de compte AIM, cliquez sur ce bouton pour en créer un nouveau.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Passer outre les paramètres par défaut du serveur
# branding
plugin.branding.ABOUT_WINDOW_TITLE=À propos de {0}
plugin.branding.LOGO_MESSAGE=VoIP && Messagerie instantanée Open Source
-plugin.branding.LOADING=Chargement
plugin.branding.ABOUT_MENU_ENTRY=&À propos
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>{1} est actuellement en développement intensif. Cette version est expérimentale et peut NE PAS fonctionner comme elle devrait. Plus d''informations sur {2}.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 Copyright <b>jitsi.org</b>. Tous droits réservés. Rendez-vous sur <a href="https://jitsi.org">https://jitsi.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}><b>Jitsi</b> est distribué selon les conditions de la LGPL (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=Dictionnaires
-plugin.dictaccregwizz.ANY_DICTIONARY=Tous les dictionnaires
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Tous les dictionnaires de {0}
-plugin.dictaccregwizz.FIRST_MATCH=Premier résultat
-plugin.dictaccregwizz.NO_MATCH=Aucun résultat
-plugin.dictaccregwizz.MATCH_RESULT=Aucune définition trouvée pour "{0}", peut-être vouliez vous dire :\n
-plugin.dictaccregwizz.INVALID_DATABASE=Le dictionnaire actuel "{0}" n''existe plus sur le serveur.
-plugin.dictaccregwizz.INVALID_STRATEGY=La stratégie actuelle n'existe plus sur le serveur.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=Protocole du service Dict
-plugin.dictaccregwizz.HOST=Hôte
-plugin.dictaccregwizz.SERVER_INFO=Informations sur le serveur
-plugin.dictaccregwizz.STRATEGY_SELECTION=Sélection de la stratégie
-plugin.dictaccregwizz.STRATEGY_LIST=Liste des stratégies :
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Rechercher les stratégies
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=Les stratégies sont utilisées pour rechercher les mots similaires si aucune définition n'a été trouvée. Il existe différentes approches ; par exemple : la stratégie Prefix recherchera tous les mots qui commencent comme le mot dont vous cherchez la définition.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Information sur le compte Dict
-plugin.dictaccregwizz.FIRST_ACCOUNT=Cet assistant va créer votre premier compte Dict sur le serveur dict.org.\n\nVous pouvez ajouter d'autres serveurs de dictionnaires en utilisant à nouveau cet assistant. Renseignez le champ Hôte avec le dictionnaire que vous souhaitez ajouter.
-plugin.dictaccregwizz.THREAD_CONNECT=Tentative de connexion au serveur
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=La tentative de connexion a échoué. Le serveur est hors ligne ou ce n'est pas un serveur de dictionnaires.
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=Récupération des stratégies
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Aucune stratégie n'a été trouvée sur le serveur
-plugin.dictaccregwizz.POPULATE_LIST=Mise à jour de la liste
-plugin.dictaccregwizz.CLOSING_CONNECTION=Fermeture de la connexion
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Pour utiliser la discussion instantanée de Facebook, vous devez vous créer un "nom d'utilisateur"<br>depuis la page "Paramètres du compte" sur Facebook.</a><br><br>Note: lorsque vous créez votre nom d'utilisateur, vous devrez vous déconnecter de la page web.<br>Cela peut prendre un peu de temps avant que vous puissiez vous connecter avec votre nouveau nom d'utilisateur !</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=Protocole de discussion instantanée Facebook
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Nom d'utilisateur :
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Nom d'utilisateur et mot de passe
+
+plugin.busylampfield.PICKUP=Répondre à l'appel
# generalconfig
plugin.generalconfig.AUTO_START=Ouvrir {0} automatiquement au démarrage de l''ordinateur
@@ -982,9 +909,6 @@ plugin.generalconfig.SHOW_HISTORY=Afficher les
plugin.generalconfig.HISTORY_SIZE=derniers messages
plugin.generalconfig.SEND_MESSAGES_WITH=Envoyer les messages avec :
plugin.generalconfig.BRING_WINDOW_TO_FRONT=Fenêtre de conversation au premier plan
-plugin.generalconfig.ERROR_PERMISSION=Vous n'avez pas les droits requis pour désactiver le démarrage automatique
-plugin.generalconfig.TRANSPARENCY=Transparence
-plugin.generalconfig.ENABLE_TRANSPARENCY=Activer la transparence
plugin.generalconfig.DEFAULT_LANGUAGE=Langue
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Les modifications prendront effet au prochain démarrage de l'application.
plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0}% traduit
@@ -1000,6 +924,7 @@ plugin.generalconfig.REMOVE_SPECIAL_PHONE_SYMBOLS=Enlever les symboles spéciaux
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS=Convertir les lettres en chiffres
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS_EXAMPLE=Ex. +1-800-MONTEL-> +1-800-666895
plugin.generalconfig.SIP_CALL_CONFIG=SIP
+plugin.generalconfig.XMPP_CONFIG=XMPP
plugin.generalconfig.OPUS_CONFIG=Opus
plugin.generalconfig.OPUS_AUDIO_BANDWIDTH=Taux d'échantillonnage
plugin.generalconfig.OPUS_BITRATE=Taux de transfert moyen (kbps):
@@ -1043,13 +968,18 @@ plugin.ircaccregwizz.EXAMPLE_SERVER=Ex. : chat.freenode.net
plugin.ircaccregwizz.USE_SECURE_CONNECTION=Utiliser une connexion sécurisée
plugin.ircaccregwizz.ENABLE_CONTACT_PRESENCE=Présence contacts activé
plugin.ircaccregwizz.ENABLE_CHAT_ROOM_PRESENCE=Présence salon de discussion activé
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE=Authentification SASL
+plugin.ircaccregwizz.ENABLE_SASL_AUTHENTICATION=Activer l'authentification SASL
+plugin.ircaccregwizz.SASL_USERNAME=Nom d'utilisateur
+plugin.ircaccregwizz.SASL_AUTHZ_ROLE=Rôle
+plugin.ircaccregwizz.SASL_IRC_PASSWORD_USED=Le mot de passe ci-dessus est utilisé pour l'authentification SASL
+plugin.ircaccregwizz.RESOLVE_DNS_THROUGH_PROXY=Toujours résoudre les noms DNS au travers du proxy
# jabber accregwizz
plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=Protocole XMPP
plugin.jabberaccregwizz.USERNAME=Nom d'utilisateur XMPP
plugin.jabberaccregwizz.PASSWORD_CONFIRM=Confirmer le mot de passe
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=ID et mot de passe
plugin.jabberaccregwizz.CSERVER=Serveur
plugin.jabberaccregwizz.SERVER=Serveur
plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=Activer keep alive
@@ -1065,13 +995,9 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Commentaire
plugin.jabberaccregwizz.RESOURCE=Ressource
plugin.jabberaccregwizz.AUTORESOURCE=Ressource auto-générée
plugin.jabberaccregwizz.PRIORITY=Priorité
-plugin.jabberaccregwizz.XMPP_ERROR=Erreur XMPP
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Erreur XMPP inconnue ({0}). Vérifiez que le nom du serveur est correct.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Les mots de passe ne correspondent pas.
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Passer outre les paramètres par défaut du serveur
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Options avancées
plugin.jabberaccregwizz.USE_ICE=Utiliser ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=Utiliser ICE/Jingle Google (Expérimental !)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=Découverte automatique des serveurs STUN/TURN
plugin.jabberaccregwizz.SUPPORT_TURN=Support TURN
plugin.jabberaccregwizz.TURN_USERNAME=Nom d'utilisateur TURN
@@ -1099,11 +1025,8 @@ plugin.jabberaccregwizz.DISABLE_CARBON=Désactiver les messages en copie cachée
plugin.jabberaccregwizz.DTMF_AUTO=Choix automatique entre RTP et l'intrabande
plugin.jabberaccregwizz.SERVER_OPTIONS=Options du serveur
plugin.jabberaccregwizz.CHANGE_PASSWORD=Modifier le mot de passe du compte
-plugin.jabberaccregwizz.NEW_PASSWORD=nouveau mot de passe
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Confirmer le mot de passe
plugin.jabberaccregwizz.PORT_FIELD_INVALID=Prière de saisir un numéro de port valide pour continuer.
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=Le compte doit être connecté pour modifier le mot de passe.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=Le mot de passe est vide
plugin.jabberaccregwizz.TLS_REQUIRED=La connexion n'utilise aucun SSL/TLS, une modification du mot de passe n'est pas pris en charge.
plugin.jabberaccregwizz.PASSWORD_CHANGED=Le mot de passe a été modifié avec succès
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=Le serveur ne prend aucune modification de mot de passe en charge.
@@ -1117,25 +1040,9 @@ plugin.jabberaccregwizz.RESET=Réinitialiser
plugin.jabberaccregwizz.RESET_DESCRIPTION=Réinitialiser les paramètres globaux
plugin.jabberaccregwizz.DISABLE_JINGLE=Désactiver Jingle ( Son et appel visio avec XMPP)
-# mailbox
-plugin.mailbox.OUTGOING=Message sortant :
-plugin.mailbox.INCOMING=Messages entrants :
-plugin.mailbox.WAIT_TIME=Délai avant de rediriger l'appel sur la messagerie vocale
-plugin.mailbox.MAX_MESSAGE_TIME=Durée maximum pour les messages entrants
-plugin.mailbox.CONFIRM=Confirmer
-plugin.mailbox.DEFAULTS=Par défaut
-plugin.mailbox.MAILBOX=Boîte aux lettres
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Un protocole pour se connecter et discuter sur le service MSN.
-plugin.msnaccregwizz.USERNAME=Email :
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=Nom d'utilisateur et mot de passe
-
# plugin manager
plugin.pluginmanager.INSTALL=Installer
plugin.pluginmanager.UNINSTALL=Désinstaller
-plugin.pluginmanager.UPDATE=Mise à jour
plugin.pluginmanager.PLUGINS=Plug-ins
plugin.pluginmanager.URL=URL
plugin.pluginmanager.CHOOSE_FILE=Sélectionner un fichier
@@ -1160,9 +1067,9 @@ plugin.sipaccregwizz.SERVER_PORT=Port du serveur
plugin.sipaccregwizz.PROXY=Proxy
plugin.sipaccregwizz.PROXY_PORT=Port du proxy
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Transport privilégié
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Options avancées
plugin.sipaccregwizz.PROXY_OPTIONS=Options du proxy
plugin.sipaccregwizz.PROXY_AUTO=Configuration automatique du proxy
+plugin.sipaccregwizz.PROXY_FORCE_BYPASS=Outrepasser la vérification de sécurité du proxy en cas de scénario de haute disponibilité (à utiliser si nécessaire)
plugin.sipaccregwizz.ENABLE_PRESENCE=Activer la présence (SIMPLE)
plugin.sipaccregwizz.FORCE_P2P_PRESENCE=Forcer le mode de présence peer-to-peer
plugin.sipaccregwizz.OFFLINE_CONTACT_POLLING_PERIOD=Période d'interrogation des contacts déconnectés (en s.)
@@ -1180,8 +1087,6 @@ plugin.sipaccregwizz.DTMF_AUTO=Choix automatique entre RTP et l'intrabande (pas
plugin.sipaccregwizz.DTMF_RTP=RTP (RFC2833 / RFC4733)
plugin.sipaccregwizz.DTMF_SIP_INFO=INFO SIP
plugin.sipaccregwizz.DTMF_INBAND=Intrabande
-plugin.sipaccregwizz.REGISTER=REGISTER
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Passer outre les paramètres par défaut du serveur
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Activer le support pour les appels chiffrés
plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=Montrez le soutien de ZRTP dans le protocole de signalisation
plugin.sipaccregwizz.AUTH_NAME=Nom d'autorisation
@@ -1202,10 +1107,10 @@ plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=Récupération du répondeur URI
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Les mots de passe ne correspondent pas.
plugin.sipaccregwizz.NO_CERTIFICATE=<aucun> (utiliser l'enregistrement régulier)
plugin.sipaccregwizz.SAVP_OPTION=Indication RTP/SAVP
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=Ã partir de (proposer seulement RTP/AVP)
plugin.sipaccregwizz.SAVP_OPTION_1=Obligatoire (proposer et offrir seulement RTP/SAVP)
plugin.sipaccregwizz.SAVP_OPTION_2=En option (d'abord proposer RTP/SAVP puis RTP/AVP)
-plugin.sipaccregwizz.ENABLE_SDES_ATTRIBUTE=Activer le cryptage S-Descriptor ( aussi connu comme SDES ou SRTP)
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=Protocole de décryptage activé et priorité:
plugin.sipaccregwizz.CIPHER_SUITES=Suite de cryptage activée
plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>{0} tente automatiquement de crypter toutes les communications avec ZRTP. Les deux interlocuteurs entendent et voient une alerte lorsqu''une connexion sécurisée est établie. Les paramètres avancés sur cette page ne ​​doivent pas être modifiées sans expertise.</div></html>
@@ -1219,15 +1124,6 @@ plugin.skinmanager.DEFAULT_SKIN=Thème par défaut
plugin.skinmanager.ADD_NEW_SKIN=Ajouter un nouveau thème...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=Le thème par défaut pour l'application.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=Un protocole pour se connecter à des machines distantes avec SSH.
-plugin.sshaccregwizz.USERNAME=Identifiant du compte :
-plugin.sshaccregwizz.IDENTITY_FILE=Fichier d'identité :
-plugin.sshaccregwizz.KNOWN_HOSTS=Hôtes connus :
-plugin.sshaccregwizz.OPTIONAL=Optionnel
-plugin.sshaccregwizz.ACCOUNT_DETAILS=Détails du compte
-
# status update
plugin.autoaway.AUTO_STATUS=Statut d'absence automatique
plugin.autoaway.ENABLE_CHANGE_STATUS=Changer le statut en cas d'absence
@@ -1275,22 +1171,6 @@ plugin.whiteboard.DESELECT=Dé-sélectionner
plugin.whiteboard.DELETE=Supprimer
plugin.whiteboard.PROPERTIES=Propriétés
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Un protocole pour se connecter et discuter sur le service Yahoo!
-plugin.yahooaccregwizz.USERNAME=Nom d'utilisateur :
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=ID et mot de passe
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=Protocole Zeroconf (Bonjour).
-plugin.zeroaccregwizz.FIRST_NAME=Prénom :
-plugin.zeroaccregwizz.LAST_NAME=Nom :
-plugin.zeroaccregwizz.EMAIL=Email :
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=Se rappeler des contacts Bonjour ?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=ID et mot de passe
-plugin.zeroaccregwizz.USERID=Identifiant utilisateur
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Protocole Google Talk
@@ -1304,19 +1184,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, le portail de télécommu
plugin.iptelaccregwizz.USERNAME=Nom d'utilisateur
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=S'enregistrer à iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIP et messagerie instantanée
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Nom d'utilisateur
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Entrez à nouveau votre mot de passe
plugin.sip2sipaccregwizz.EMAIL=Adresse email
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=Pour une aide concernant ce service rendez-vous sur<br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>L'adresse email est utilisée pour les envois de messages audio, <br>de notifications d'appels manqués et pour la récupération de mots de passe perdus</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>Pour une aide concernant ce service rendez-vous sur <a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=Compte sip2sip.info existant
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Créer une compte sip2sip.info gratuit
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP && Messagerie Instantanée
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=Pour une aide concernant ce service rendez-vous sur<br>http://ippi.fr
@@ -1325,6 +1197,7 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=Compte SIP existant
plugin.ippiaccregwizz.CREATE_ACCOUNT=Créer un compte ippi gratuit
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Fermer la fenêtre de conversation
plugin.keybindings.CHAT_COPY=Copier
plugin.keybindings.CHAT_CUT=Couper
@@ -1347,10 +1220,10 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=Action
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=Raccourci primaire
plugin.keybindings.globalchooser.SHORTCUT_SECOND=Raccourci secondaire
plugin.keybindings.globalchooser.PRESS_BTN=Appuyez sur le bouton pour régler le lien
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=en attente
plugin.keybindings.globalchooser.PUSH_TO_TALK=Bouton interphone
plugin.keybindings.globalchooser.ENABLE_SPECIAL=Activer la reconnaissance des touches spéciales
plugin.keybindings.PLUGIN_NAME=Raccourcis
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Chat
plugin.keybindings.MAIN=Fenêtre principal
plugin.keybindings.GLOBAL=Raccourcis globaux
@@ -1378,6 +1251,7 @@ plugin.notificationconfig.tableheader.SOUND=Jouer un son à travers le dispositi
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=Jouer un son à travers le dispositif de reproduction
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=Jouer un son à travers les haut-parleurs de l'ordinateur
plugin.notificationconfig.tableheader.DESCRIPTION=Description de la norification
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Appel entrant
plugin.notificationconfig.event.SecurityMessage=Message de sécurité
plugin.notificationconfig.event.IncomingFile=Fichier entrant
@@ -1479,6 +1353,7 @@ impl.neomedia.configform.VIDEO=Vidéo
impl.neomedia.configform.H264=H.264
impl.neomedia.configform.H264.defaultIntraRefresh=Utiliser les images intra périodique pour le rafraîchissement
impl.neomedia.configform.H264.defaultProfile=Profile d'encodage par défaut à utiliser :
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=Ligne de base
impl.neomedia.configform.H264.defaultProfile.high=Haute
impl.neomedia.configform.H264.defaultProfile.main=Principal
@@ -1509,7 +1384,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=Mot de passe actuel :
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Entrez le nouveau mot de passe :
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Retaper le nouveau mot de passe :
plugin.securityconfig.masterpassword.MP_TITLE=Mot de passe principal
-plugin.securityconfig.masterpassword.MP_NOT_SET=(non défini)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=Vous n'avez pas entré le bon mot de passe principal. Veuillez réessayer.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=Le mot de passe principal est incorrect !
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Échec du changement de mot de passe
@@ -1525,7 +1399,6 @@ plugin.securityconfig.masterpassword.COL_PASSWORD=Mot de passe
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(inconnu)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(impossible de déchiffrer)
plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=Mot de passe enregistré
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=Supprimer
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=Tout supprimer
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=Êtes-vous certain de supprimer tous les mots de passe ?
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=Supprimer tous les mots de passe
@@ -1621,7 +1494,6 @@ plugin.globalproxy.PROXY_PORT=Port du proxy
plugin.globalproxy.PROXY_USERNAME=Utilisateur du proxy
plugin.globalproxy.PROXY_PASSWORD=Mot de passe proxy
plugin.globalproxy.DESCRIPTION={0} utilisera les paramètres de proxy ci-dessus pour tous les réseaux auxquels vous vous connectez ou vous reconnecterez à partir de maintenant. La prise en charge du proxy est encore expérimentale et ne fonctionne qu''avec certains protocoles. Reportez-vous au tableau ci-dessous pour plus de détails :
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>JABBER</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
plugin.globalproxy.FWD_DNS=Utiliser le proxy aussi pour DNS
plugin.globalproxy.FWD_DNS_NOTE=Utile lorsque vous utilisez Tor. Évite la divulgation de données DNS en filtrant tout, le trafic DNS est redirigée par le proxy Tor. Ne prendra effet qu'après le redémarrage.
@@ -1659,7 +1531,6 @@ plugin.provisioning.RESTART_WARNING=Veuillez noter que les changements prendront
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=Copier l'UUID dans le presse-papiers
plugin.provisioning.CLIPBOARD_FAILED=Échec de la copie de l'UUID dans le presse-papiers
-plugin.provisioning.EXIT_ON_FAIL=Fermer le programme lors de l'échec de l'approvisionnement
plugin.provisioning.CREDENTIALS=Dernières informations d'identification stockées
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=Êtes-vous sûr de vouloir supprimer le mot de passe approvisioné?
plugin.provisioning.PROV_FAILED=Échec de l'approvisionnement
@@ -1726,8 +1597,6 @@ util.dns.DNSSEC_WARNING=<html><div width="600"> a essayé de contacter le serveu
#plugin spellcheck
plugin.spellcheck.TITLE=Grammaire et Orthographe
plugin.spellcheck.MENU=Afficher Grammaire et Orthographe
-plugin.spellcheck.LANG=Langue
-plugin.spellcheck.EDIT_PERSONAL_DICT=Éditer
plugin.spellcheck.ENABLE_SPELL_CHECK=Activer la vérification d'orthographe
plugin.spellcheck.dialog.FIND=Chercher Suivant
plugin.spellcheck.dialog.REPLACE=Remplacer
diff --git a/resources/languages/resources_ga.properties b/resources/languages/resources_ga.properties
index 92bd41c..da083f3 100644
--- a/resources/languages/resources_ga.properties
+++ b/resources/languages/resources_ga.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -31,14 +42,11 @@ service.gui.ACCOUNT=Cuntas
service.gui.ACCOUNT_ME=Mise
service.gui.ACCOUNTS=Cuntais
service.gui.ADD=&Cuir leis
-service.gui.ADD_ACCOUNT=Cuir cuntas leis
service.gui.ADD_CONTACT=&Cuir teagmhálaí leis
service.gui.ADD_CONTACT_TO=&Cuir an teagmhálaí le
-service.gui.ADD_GROUP=Cruthaigh baicle
service.gui.ADDRESS=Seoladh
service.gui.ADMINISTRATOR=riarthóir
service.gui.ADVANCED=&Ardroghanna
-service.gui.ALL=&Uile
service.gui.ALL_CONTACTS=&Gach teagmhálaí
service.gui.ALTERNATE_ADDRESS=Seoladh malartach
service.gui.APPLY=&Cuir i bhfeidhm
@@ -46,7 +54,6 @@ service.gui.ARE_CALLING=Tá {0} ag glaoch...
service.gui.ARE_NOW=Tá tú {0} anois
service.gui.AT=ag
service.gui.AUTHORIZE=&Ceadaigh
-service.gui.AUTHENTICATION_REQUESTED=Fíordheimhniú iarrtha
service.gui.AUTHORIZATION_REQUESTED=Fíordheimhniú iarrtha
service.gui.BUSY_MESSAGE=Is dona liom ach tá mé gnóthach faoi láthair.
service.gui.BUSY_STATUS=Gnóthach
@@ -58,7 +65,6 @@ service.gui.CANCEL=&Cealaigh
service.gui.CHAT=Comhrá
service.gui.CHANGE_FONT=Athraigh an chlófhoireann
service.gui.CHANGE_ROOM_SUBJECT=Athraigh ábhar an tseomra...
-service.gui.CHAT_CONFERENCE_LABEL=Comhdhálacha
service.gui.CHAT_CONFERENCE_ITEM_LABEL=Comhdháil {0}
service.gui.CHAT_ROOM_USER_LEFT=d'fhág {0}
service.gui.CHANGE_PASSWORD=Athraigh an focal faire
@@ -71,7 +77,6 @@ service.gui.COUNTRY=Tír
service.gui.SHOW_MORE_TOOLTIP=Brúigh anseo chun tuilleadh torthaí a thaispeáint
service.gui.CLEAR=Glan
service.gui.CLOSE=Dún
-service.gui.CONFIRM=Deimhnigh
service.gui.CONNECTED_STATUS=Nasctha
service.gui.CONNECTING=Ag nascadh...
service.gui.CONNECTING_STATUS=Ag nascadh
@@ -103,7 +108,6 @@ service.gui.FONT_ITALIC=Iodálach
service.gui.FONT_SIZE=Méid
service.gui.FONT_STYLE=Nós
service.gui.FONT_UNDERLINE=Cuir líne faoi
-service.gui.FROM={0} ó {1}
service.gui.GUEST=cuairteoir
service.gui.HANG_UP=Críochnaigh
service.gui.HD_QUALITY=Físeán ardghléine
@@ -112,7 +116,6 @@ service.gui.HIDE=Folaigh
service.gui.HIDE_OFFLINE_CONTACTS=Cuir teagmhálacha nach bhfuil ceangailte i bhfolach
service.gui.HOME=Baile
service.gui.HOME_PAGE=Leathanach baile
-service.gui.HOUR=Uair
service.gui.ICE=ICE
service.gui.IDENTIFIER=Aitheantóir
service.gui.IGNORE=&Déan neamhaird de
@@ -126,6 +129,11 @@ service.gui.NO_MESSAGE=Níl teachtaireacht ann
+#enum values from IceProcessingState
+
+
+
+#service.gui.CERT_INFO_ are combined from Rdn names
# keep the following string short
@@ -134,9 +142,6 @@ service.gui.NO_MESSAGE=Níl teachtaireacht ann
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
# systray
@@ -149,9 +154,7 @@ impl.gui.main.account.DUMMY_PROTOCOL_DESCRIPTION=roghnaigh líonra
# LDAP
impl.ldap.FIELDS=Réimsí
impl.ldap.QUERY=Iarrtas
-impl.ldap.NEW=Nua
impl.ldap.EDIT=eagar
-impl.ldap.REMOVE=Bain
impl.ldap.ENABLED=Cumasaithe
impl.ldap.AUTH_NONE=Dada
impl.ldap.AUTH_SIMPLE=Diúid
@@ -165,14 +168,16 @@ impl.ldap.SCOPE=Cuimse
impl.ldap.MAIL_FIELD_EXAMPLE=post
impl.ldap.PHONE_PREFIX_EXAMPLE=M.sh.: 00
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.PREFIX_EXAMPLE=M.sh.: 00
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Teagmhálacha Google
-impl.googlecontacts.NEW=Nua
impl.googlecontacts.EDIT=eagar
-impl.googlecontacts.REMOVE=Bain
impl.googlecontacts.ENABLED=Cumasaithe
impl.googlecontacts.ACCOUNT_NAME=Ainm an chuntais
impl.googlecontacts.SAVE=Taisc
@@ -196,8 +201,6 @@ plugin.accountinfo.PHONE=Uimhir ghutháin:
plugin.accountinfo.ABOUT_ME=Maidir Liomsa:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
plugin.accountinfo.LOCAL_ICON=Bain feidhm as an deilbhín seo:
-plugin.accountinfo.CHANGE=Athraigh
-plugin.accountinfo.ONLY_MESSAGE=Teachtaireachtaí amháin
# connection info
@@ -212,26 +215,14 @@ plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Cláraigh cuntas nua
# branding
plugin.branding.ABOUT_WINDOW_TITLE=Maidir le {0}
plugin.branding.LOGO_MESSAGE=Cur teachtaireachtaí meandracha && VoIP Foinse Oscailte
-plugin.branding.LOADING=Ag luchtú
plugin.branding.ABOUT_MENU_ENTRY=&Maidir le
-# Dict protocol
-service.protocol.DICTIONARIES=Foclóirí
-plugin.dictaccregwizz.ANY_DICTIONARY=Foclóir ar bith
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.HOST=Óstach
-plugin.dictaccregwizz.CLOSING_CONNECTION=Ag dúnadh an naisc
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
# generalconfig
plugin.generalconfig.SHOW_HISTORY=Taispeáin
plugin.generalconfig.HISTORY_SIZE=teachtaireachtaí le gairid i gcomhráite nua
plugin.generalconfig.SEND_MESSAGES_WITH=Seol teachtaireachtaí le:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=Tabhair fuinneog an chomhrá chun tosaigh
-plugin.generalconfig.TRANSPARENCY=Trédhearcacht
-plugin.generalconfig.ENABLE_TRANSPARENCY=Cumasaigh trédhearcacht
plugin.generalconfig.DEFAULT_LANGUAGE=Teanga an chomhéadain
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Cuirfear na hathruithe a rinne tú i bhfeidhm an chéad uair eile a tosófar é.
plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0}% aistrithe
@@ -249,30 +240,16 @@ plugin.generalconfig.SILK_CONFIG=Síoda
# irc accregwizz
# jabber accregwizz
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Ardroghanna
plugin.jabberaccregwizz.USE_ICE=Bain feidhm as ICE
plugin.jabberaccregwizz.SERVER_OPTIONS=Roghanna an fhreastalaithe
plugin.jabberaccregwizz.CHANGE_PASSWORD=Athraigh focal faire an chuntais
-plugin.jabberaccregwizz.NEW_PASSWORD=Focal faire nua
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Deimhnigh an focal faire nua
-plugin.jabberaccregwizz.PASSWORD_EMPTY=Tá an focal faire folamh.
plugin.jabberaccregwizz.PASSWORD_CHANGED=Athraíodh an focal faire go rathúil.
plugin.jabberaccregwizz.AUDIO=Fuaim
plugin.jabberaccregwizz.VIDEO=Físeán
-# mailbox
-plugin.mailbox.INCOMING=Teachtaireachtaí isteach:
-plugin.mailbox.CONFIRM=Deimhnigh
-plugin.mailbox.DEFAULTS=Réamhshocruithe
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.USERNAME=Seoladh ríomhphoist:
-
# plugin manager
plugin.pluginmanager.INSTALL=Suiteáil
plugin.pluginmanager.UNINSTALL=Díshuiteáil
-plugin.pluginmanager.UPDATE=Nuashonrú
plugin.pluginmanager.URL=Url
plugin.pluginmanager.CHOOSE_FILE=Roghnaigh comhad
plugin.pluginmanager.SYSTEM=Córas
@@ -282,11 +259,10 @@ plugin.pluginmanager.NEW=Nua
plugin.simpleaccregwizz.SIGNUP=Nach bhfuil tú cláraithe fós?
# sipaccregwizz
+#used from SecurityPanel
# skin manager
-# ssh accregwizz
-
# status update
# updatechecker
@@ -310,26 +286,17 @@ plugin.whiteboard.MODIFICATION=Mionathrú
plugin.whiteboard.THICKNESS=Tiús:
plugin.whiteboard.GRID=Mogallra
-# yahoo accregwizz
-
-# zero accregwizz
-plugin.zeroaccregwizz.FIRST_NAME=Ainm:
-plugin.zeroaccregwizz.LAST_NAME=Sloinne:
-plugin.zeroaccregwizz.EMAIL=Seoladh ríomhphoist:
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
# iptel accregwizz
-# sip2sip accregwizz
+# ippi accregwizz
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Clóscríobh arís an focal faire
plugin.sip2sipaccregwizz.EMAIL=Seoladh ríomhphoist
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Cruthaigh cuntas sip2sip.info saor in aisce
-
-# ippi accregwizz
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_COPY=Macasamhlaigh
plugin.keybindings.CHAT_CUT=Gearr
plugin.keybindings.CHAT_NEXT_TAB=Cluaisín ar aghaidh
@@ -339,6 +306,7 @@ plugin.keybindings.MAIN_RENAME=Athainmnigh an teagmhálaí
plugin.keybindings.globalchooser.ANSWER_CALL=Freagair an glao
plugin.keybindings.globalchooser.HANGUP_CALL=Críochnaigh an glao
plugin.keybindings.globalchooser.PUSH_TO_TALK=Brúigh chun labhairt
+#Enum KeybindingSet.Category
plugin.keybindings.GLOBAL=Aicearraí coiteanna
# Notification Configuration Form
@@ -352,6 +320,7 @@ plugin.notificationconfig.BROWSE_SOUND=Roghnaigh comhad fuaime
plugin.notificationconfig.BROWSE_PROGRAM=Roghnaigh ríomhchlár
plugin.notificationconfig.tableheader.ENABLE=Cumasaigh nó díchumasaigh an ghné seo
plugin.notificationconfig.tableheader.DESCRIPTION=Cur síos ar imeacht
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Glao isteach
plugin.notificationconfig.event.SecurityMessage=Teachtaireacht Slándála
plugin.notificationconfig.event.IncomingFile=Comhad isteach
@@ -367,6 +336,7 @@ plugin.notificationconfig.event.NetworkNotifications=Fógraí an líonra
+#in JNIEncoder
# The callrecordingconfig plugin was never really committed into trunk and its
# ConfigurationForm was actually put in the neomedia bundle.
@@ -375,7 +345,6 @@ plugin.notificationconfig.event.NetworkNotifications=Fógraí an líonra
plugin.securityconfig.masterpassword.CURRENT_PASSWORD=An focal faire reatha:
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Cuir isteach focal faire nua:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Cuir isteach arís an focal faire nua:
-plugin.securityconfig.masterpassword.MP_NOT_SET=(gan socrú)
# otr plugin
@@ -409,8 +378,6 @@ net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult
#plugin spellcheck
plugin.spellcheck.TITLE=Litriú agus Gramadach
plugin.spellcheck.MENU=Taispeáin Litriú agus Gramadach
-plugin.spellcheck.LANG=Teanga
-plugin.spellcheck.EDIT_PERSONAL_DICT=Eagar
plugin.spellcheck.ENABLE_SPELL_CHECK=Cumasaigh an litreoir
plugin.spellcheck.dialog.FIND=Aimsigh ar aghaidh
plugin.spellcheck.dialog.REPLACE=Ionadaigh
diff --git a/resources/languages/resources_gd.properties b/resources/languages/resources_gd.properties
index a578b7b..3e8aa90 100644
--- a/resources/languages/resources_gd.properties
+++ b/resources/languages/resources_gd.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Mise
service.gui.ACCOUNT_REGISTRATION_WIZARD=Draoidh clàradh nan cunntasan
service.gui.ACCOUNTS=Cunntasan
service.gui.ADD=&Cuir ris
-service.gui.ADD_ACCOUNT=Cuir cunntas ris
service.gui.ADD_CONTACT=C&uir neach-aithne ris
service.gui.ADD_AUTHORIZED_CONTACT=Cuir {0} ri liosta an luchd-aithne agad
service.gui.ADD_CONTACT_TO=Cuir an &neach-aithne ri
@@ -41,20 +51,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Mearachd a' cur ris neach-aithne
service.gui.ADD_CONTACT_EXIST_ERROR=Tha an neach-aithne {0} air liosta an luchd-aithne agad mu thràth.
service.gui.ADD_CONTACT_NETWORK_ERROR=Cha do fhreagair am frithealaiche nuair a dh''iarr sinn an neach-aithne aig a bheil an ID {0} a chur ris.
service.gui.ADD_CONTACT_NOT_SUPPORTED=Cha b'' urrainn dhuinn an neach-aithne aig a bheil an ID {0} a chur ris. Chan eil taic ris a leithid seo a ghnìomh.
-service.gui.ADD_CONTACT_IDENTIFIER=Cuir aithnichear an neach-aithne a tha thu airson cur ris san raon gu h-ìosal.
-service.gui.ADD_CONTACT_WIZARD=Draoidh cur ris an luchd-aithne
service.gui.ADD_CONTACT_NOT_CONNECTED=Feumaidh ceangal a bhith agad mus urrainn dhut neach-aithne a chur ris. Clàraich a-steach aig an t-solaraiche a thagh thu ''s feuch ris a-rithist.
service.gui.ADD_GROUP_LOCAL_ERROR=Cha b'' urrainn dhuinn am buidheann air a bheil {0} a chur ris. Dh''èirich an duilgheadas seo ri linn gnìomh IO ionadail.
service.gui.ADD_GROUP_EXIST_ERROR=Tha am buidheann {0} air liosta an luchd-aithne agad mu thràth. Nach tagh thu ainm eile?
service.gui.ADD_GROUP_NET_ERROR=Cha b'' urrainn dhuinn am buidheann air a bheil {0} a chur ris. Dh''èirich an duilgheadas seo ri linn fàilligeadh an lìonraidh. Dèan cinnteach gu bheil ceangal agad ris an lìonra ''s feuch ris a-rithist.
service.gui.ADD_GROUP_ERROR=Cha b'' urrainn dhuinn am buidheann air a bheil {0} a chur ris.
service.gui.ADD_GROUP_EMPTY_NAME=Chan fhaod ainm a'' bhuidhinn a bhith falamh.
-service.gui.ADD_GROUP=Cruthaich buidheann
-service.gui.ADD_SUBCONTACT=C&uir fo-neach-aithne ris
service.gui.ADDRESS=Seòladh
service.gui.ADMINISTRATOR=rianaire
service.gui.ADVANCED=&Adhartach
-service.gui.ALL=A &h-uile
service.gui.ALL_CONTACTS=&A h-uile neach-aithne
service.gui.APPLY=&Cuir an sàs
service.gui.ARE_CALLING=Tha {0} a'' cur fòn...
@@ -63,7 +68,6 @@ service.gui.AT=aig
service.gui.AUTHORIZE=&Thoir ùghdarras
service.gui.AUTHORIZATION_ACCEPTED=Ghabh {0} ris d'' iarrtas ùghdarrachaidh.
service.gui.AUTHENTICATION_FAILED=Dh''fhàillig dearbhadh {0}. Chuir thu a-steach facal-faire nach eil dligheach.
-service.gui.AUTHENTICATION_REQUESTED=Dearbhadh ''ga iarraidh
service.gui.AUTHENTICATION_REQUESTED_SERVER=Dh''iarr frithealaiche {0} dearbhadh ort.
service.gui.AUTHENTICATION_REJECTED=Dhiùlt {0} d'' iarrtas ùghdarrachaidh.
service.gui.AUTHENTICATION_WINDOW_TITLE=Dearbhadh {0}
@@ -103,7 +107,6 @@ service.gui.CHANGE_NICKNAME_LABEL=''S urrainn dhut am far-ainm ùr agad a chur a
service.gui.CHANGE_NICKNAME_ERROR=Mearachd le atharrachadh an fhar-ainm
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Tha am far-ainm seo ann mu thràth
service.gui.CHANGE_VIDEO_QUALITY=Atharraich càileachd a'' video chèin
-service.gui.CHAT_CONFERENCE_LABEL=Co-labhairtean
service.gui.CHAT_CONFERENCE_ITEM_LABEL=A'' cho-labhairt aig {0}
service.gui.CHAT_ROOM_ALREADY_JOINED=Chaidh an seòmar cabadaich {0} a cheangal ris mu thràth.
service.gui.CHAT_ROOM_CONFIGURATION=Rèiteachadh an t-seòmair chabadaich {0}
@@ -114,18 +117,14 @@ service.gui.CHAT_ROOM_USER_JOINED=- chaidh iad a-steach dha {0}
service.gui.CHAT_ROOM_USER_LEFT=- dh''fhàg iad {0}
service.gui.CHAT_ROOM_USER_KICKED=- air breab fhaighinn às an t-seòmar {0}
service.gui.CHAT_ROOM_USER_QUIT=- dh''fhàg iad {0}
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Sàbhailidh seo an seòmar cabadaich air eagal ''s gum bi feum agad uaireigin eile
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Bheir seo air falbh an seòmar a thagh thu o liosta nan seòmraichean a chaidh a shàbhaladh
service.gui.CHAT_ROOM_NAME=Ainm an t-seòmair chabadaich
service.gui.CLEAR_CUSTOM_MESSAGES=Falamhaich na teachdaireachdan gnàthaichte
service.gui.ROOM_NAME=Seòmar cabadaich
-service.gui.AUTOJOIN=Gabh pàirt gu fèin-obrachail
service.gui.CHANGE_PASSWORD=Atharraich am facal-faire
service.gui.CHAT_ROOM_NAME_INFO=Cuir ainm an t-seòmair chabadaich a tha thu airson cruthachadh san raon gu h-ìosal.
service.gui.CHAT_ROOM_NOT_EXIST=Cha b'' urrainn dhuinn an seòmar {0} a lorg air an fhrithealaiche {1}. Dèan cinnteach gu bheil an t-ainm a chuir thu a-steach ceart.
service.gui.CHAT_ROOM_NOT_CONNECTED=Feumaidh tu clàradh a-steach mus urrainn dhut a dhol a-steach dhan t-seòmar chabadaich {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Feumaidh tu clàradh a-steach mus urrainn dhut seòmar cabadaich fhàgail.
-service.gui.CHAT_ROOM_NOT_JOINED=Feumaidh tu a bhith ceangailte ris an t-seòmar chabadaich mus urrainn dhut rudan a dhèanamh ann.
service.gui.CHAT_ROOM_OPTIONS=Roghainnean an t-seòmair chabadaich
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Feumaidh tu clàradh mus urrainn dhut ceangal ris an t-seòmar chabadaich {0}.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Dh''iarr an seòmar cabadaich {0} facal-faire.
@@ -142,22 +141,18 @@ service.gui.CLEAR=Falamhaich
service.gui.CLOSE=Dùi&n
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Fhuair thu teachdaireachd ùr diog no dhà air ais. A bheil thu cinnteach gu bheil thu airson a'' chabadaich seo a dhùnadh?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=Tha faidhlichean ''gan tar-aiseag agad fhathast. A bheil thu cinnteach gu bheil thu airson sgur dheth?
-service.gui.CONFIRM=Dearbhaich
service.gui.CONNECTED_STATUS=Ceangailte ris
service.gui.CONNECTING=A'' dèanamh ceangal...
service.gui.CONNECTING_STATUS=A'' dèanamh ceangal
service.gui.CONNECTING_EARLY_MEDIA_STATUS=A'' dèanamh ceangal*
service.gui.CONNECTION=Ceangal
-service.gui.CONNECTION_FAILED_MSG=Dh''fhàillig an ceangal aig a'' chunntas a leanas: Ainm-cleachdaiche: {0}, ainm an fhrithealaiche: {1}. Dèan cinnteach gu bheil ceangal agad ris an lìonra no cuir fios gu rianaire an lìonraidh agad airson barrachd fiosrachaidh.
service.gui.CONNECTION_EXPIRED_MSG=Chan eil ceangal agad ris an fhrithealaiche {0} aig an àm seo.
service.gui.CONTACT_NAME=ID no àireamh
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Chan eil an neach-aithne a thagh thu, {0}, comasach air fònadh.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Chan eil an neach-aithne a thagh thu, {0}, comasach air co-labhairtean cabadaich.
service.gui.CONTACT_PAUSED_TYPING=Sguir {0} de sgrìobhadh na teachdaireachd
service.gui.CONTACT_TYPING=Tha {0} a'' sgrìobhadh teachdaireachd
service.gui.CONTACT_TYPING_SEND_FAILED=ìoc... cha b'' urrainn dhuinn innse dha {0} gun robh thu a'' sgrìobhadh rud
service.gui.CONTACT_INFO=&Fiosrachadh conaltraidh
-service.gui.CONTACTLIST=Liosta an luchd-aithne
service.gui.CONTACTS=Luchd-aithne
service.gui.COPY=Dèan lethbhrea&c
service.gui.COPY_LINK=Dèan &lethbhreac dhen cheangal
@@ -167,17 +162,14 @@ service.gui.CREATE_CHAT_ROOM=&Cruthaich seòmar cabadaich...
service.gui.CREATE_CHAT_ROOM_ERROR=Dh''fhàillig cruthachadh an t-seòmair chabadaich {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=Draoidh cruthachadh nan seòmraichean cabadaich
service.gui.CREATE_CONFERENCE_CALL=&Cruthaich gairm co-labhairt...
-service.gui.CREATE_CONFERENCE_CHAT=&Cruthaich cabadaich co-labhairt...
service.gui.CREATE_GROUP=&Cruthaich buidheann...
service.gui.CREATE_GROUP_NAME=Cuir ainm a'' bhuidhinn a tha thu airson cruthachadh san raon gu h-ìosal.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Chan eil buidheann sam bith air liosta an luchd-aithne agad. Nach cruthaich thu buidheann an toiseach (Faidhle » Cruthaich buidheann).
service.gui.CREATE_VIDEO_BRIDGE=Cruthaich drochaid &video...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Cruthaich drochaid &video
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Cruthaich / Gabh pàirt ann an co-labhairt video
service.gui.CREATE_VIDEO_CONFERENCE=Cruthaich co-labhairt video ùr dhan t-seòmar chabadaich seo
service.gui.CONTACT_INFO_NOT_SUPPORTED=Chan eil an neach-aithne seo comasach air fiosrachadh conaltraidh-lìn a làimhseachadh
service.gui.CUT=&Gearr às
-service.gui.DATE=Ceann-là
service.gui.DELETE=Sguab às
service.gui.DENY=&Diùlt
service.gui.DESKTOP_SHARING_WARNING=<b>A bheil thu cinnteach gu bheil thu airson tòiseachadh air co-roinneadh na sgrìn agad?</b> <br>Ma bhriogas tu air "Ceart ma-thà", chì càch sa chòmhradh seo an sgrìn agad.
@@ -187,7 +179,6 @@ service.gui.DISCONNECTED_STATUS=Air a dhì-cheangal
service.gui.DND_STATUS=Na bris a-steach orm
service.gui.DO_NOT_ASK_AGAIN=Na faighnich dhìom a-rithist
service.gui.DO_NOT_SHOW_AGAIN=Na seall an teachdaireachd seo a-rithist
-service.gui.DOWNLOAD_NOW=L&uchdaich a-nuas an-dràsta
service.gui.DRAG_FOR_SHARING=Slaod dad an-seo a bu toigh leat co-roinneadh...
service.gui.DURATION=faid
service.gui.EDIT=D&easaich
@@ -206,7 +197,6 @@ service.gui.ERROR_RECEIVED_FROM=Fhuaras mearachd o {0}
service.gui.ESTIMATED_TIME=Tuairmeas ama:
service.gui.EVENTS=Tachartasan
service.gui.EXIT=&Fàg an-seo
-service.gui.EXTENDED_CRITERIA=Cuspair-deuchainnean adhartach
service.gui.GENERAL=Coitcheann
service.gui.GENERAL_ERROR=Mearachd choitcheann
service.gui.GROUP_NAME=Ainm a'' bhuidhinn
@@ -248,7 +238,6 @@ service.gui.FONT_ITALIC=Eadailteach
service.gui.FONT_SIZE=Meud
service.gui.FONT_STYLE=Stoidhle
service.gui.FONT_UNDERLINE=Loidhne fodha
-service.gui.FROM={0} o {1}
service.gui.GRANT_OWNERSHIP=Thoir seachad seilbheachd...
service.gui.GRANT_ADMIN=Thoir seachad inbhe rianaire...
service.gui.GRANT_MODERATOR=Thoir seachad inbhe modaratair
@@ -274,7 +263,6 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=A bheil thu cinnteach gu bheil thu airson
service.gui.HISTORY_REMOVE_ERROR=Mearachd a'' toirt air falbh nan teachdaireachdan a tha ''gan stòradh gu h-ionadail.
service.gui.HOME=Dhachaigh
service.gui.HOME_PAGE=Duilleag-dhachaigh
-service.gui.HOUR=Uair a thìde
service.gui.ICE=ICE
service.gui.IDENTIFIER=Aithnichear
service.gui.IGNORE=&Leig seachad
@@ -295,13 +283,10 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Thoir cuireadh dhan luchd-aithne gu d
service.gui.INVITE_REASON=Adhbhar a'' chuiridh
service.gui.IS_CALLING=Tha {0} a'' cur fòn...
service.gui.IS_NOW=Tha {0} {1} an-dràsta
-service.gui.JITSI_WARNING=''S e Jitsi an t-ainm ùr air SIP Communicator.<br/>Ma tha thu airson ''s gum fan am prògram cho ùr ''s a ghabhas, nach luchdaich thu a-nuas Jitsi an-dràsta?<br/><br/>Tha sinn duilich ma chuir sin fo mhì-ghoireas sam bith thu.<br/><br/>Sgioba leasachadh Jitsi
-service.gui.JITSI_WARNING_TITLE=''S e Jitsi an t-ainm ùr air an SIP Communicator
service.gui.JOIN=&Rach ann
service.gui.JOIN_AS=Rach &ann mar
service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=Gabh pàirt ann an co-labhairt video a tha ann mu thràth
service.gui.JOIN_VIDEO=Gabh pàirt sa video
-service.gui.CLOSE_CHAT_ROOM_DIALOG=Dùi&n
service.gui.JOB_TITLE=Ainm an dreuchd
service.gui.JOIN_CHAT_ROOM=Rach &dhan t-seòmar chabadaich...
service.gui.JOIN_CHAT_ROOM_TITLE=Rach dhan t-seòmar chabadaich
@@ -314,7 +299,6 @@ service.gui.KICK_FAILED=Dh''fhàillig a b(h)reabadh
service.gui.KICK_FAILED_GENERAL_ERROR=Dh''fhàillig breabadh {0}. Thachair mearachd air an fhrithealaiche.
service.gui.KICK_FAILED_NOT_ALLOWED=Dh''fhàillig breabadh {0}. Cha b'' urrainn dhuinn sealbhadair is rianaire an t-seòmair a bhreabadh.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Dh''fhàillig breabadh {0}. Chan eil cead gu leòr agad sin a dhèanamh.
-service.gui.LAST=Sloinneadh
service.gui.LAST_NAME=Sloinneadh
service.gui.LEAVE=&Fàg
service.gui.LIMIT_REACHED_FOR_IP=Rinn cus dhaoine clàradh on t-seòladh IP ionadail agad agus chan eil am frithealaiche {0} a'' dol a cheadachadh barrachd dhiubh.
@@ -334,7 +318,6 @@ service.gui.MESSAGE=Teachdaireachd
service.gui.MISSED_CALLS_TOOL_TIP=Chaill thu gairmean o:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= agus {0} a bharrachd
service.gui.MODERATOR=modaratair
-service.gui.MORE=Fac an corr
service.gui.MORE_LABEL=Barrachd
service.gui.MOVE=Gluais
service.gui.MOVE_SUBCONTACT=G&luais an neach-aithne
@@ -343,7 +326,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=Tha an neach-aithne a thagh thu co-ionnann ri
service.gui.MOVE_SUBCONTACT_QUESTION=A bheil thu cinnteach gu bheil thu airson {1} a ghluasad dha {0}?
service.gui.MOVE_TO_GROUP=&Gluais dhan bhuidheann
service.gui.MOVE_CONTACT=Gluais an neach-aithne
-service.gui.MOVE_CONTACT_ERROR=&Cha ghabh an neach-aithne a ghluasad
service.gui.MSG_DELIVERY_FAILURE=Cha b'' urrainn dhuinn an teachdaireachd gu h-àrd a libhrigeadh
service.gui.MSG_DELIVERY_NOT_SUPPORTED=Chan eil am pròtacal a thagh thu a'' cur taic ri teachdaireachdan far loidhne. ''S urrainn dhut feuchainn ri {0} a ruigsinn slighe pròtacail eile no fuireach gus am bi e/i air loidhne.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Thachair mearachd inntearnail. Tha coltas gur e buga a dh''adhbharaich seo, nach dèan thu aithris air an-seo: https://jitsi.org/Development/BugsAndIssues.
@@ -356,7 +338,6 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=Bu chòir dhut ceangal a dhèanamh ma th
service.gui.MULTIPLE_LOGINS=Rinn thu clàradh a-steach barrachd air aon turas leis an aon chunntas. Tha an cunntas (ainm-cleachdaiche: {0}, ainm an fhrithealaiche: {1}) gun cheangal an-dràsta fhèin.
service.gui.MY_CHAT_ROOMS=Cuir seòmar cabadaich ris
service.gui.MY_CHAT_ROOMS_TITLE=Cuir seòmar cabadaich ris
-service.gui.MUTE=Mùch
service.gui.MUTUALLY_ON_HOLD_STATUS=An dà chuid ''ga chumail
service.gui.NAME=Ainm
service.gui.NETWORK=Lìonra
@@ -387,7 +368,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=Chan-eil-e-air-liosta-an-luchd-aithne
service.gui.SD_QUALITY=Càileachd stannardach
service.gui.OFFLINE=Far loidhne
service.gui.OK=&Ceart ma-thà
-service.gui.OLDER_CALLS=Gairmean nas sine
service.gui.ONLINE=Air loidhne
service.gui.OPEN=Fosgail
service.gui.OPEN_FILE_FROM_IMAGE=Dèan briogadh dùbailte gus am faidhle fhosgladh.
@@ -399,7 +379,6 @@ service.gui.OPEN_ON_ACTIVITY=ma bhios gnìomhachd ann
service.gui.OPEN_ON_MESSAGE=ma bhios teachdaireachd ann a-mhàin
service.gui.OPEN_ON_IMPORTANT_MESSAGE=ma bhios teachdaireachd chudromach ann a-mhàin
service.gui.OR=no
-service.gui.OR_ENTER_PHONE_NUMBER=No cuir a-steach àireamh fòn an-seo...
service.gui.ORGANIZATION=Buidheann
service.gui.OTHER=Eile
service.gui.OWNER=seilbheadair an t-seòmair
@@ -418,7 +397,6 @@ service.gui.PRESS_ENTER_FOR_SUGGESTIONS="Enter" airson molaidhean
service.gui.PRESS_FOR_CALL_INFO=Dèan brùthadh airson fiosrachadh mun ghairm
service.gui.PRESS_TO_OPEN_CRM=Brùth gus an aplacaid CRM fhosgladh
service.gui.PREVIOUS=Air ais
-service.gui.PREVIOUS_TOOLTIP=Brabhsaich còmhraidhean nas sine
service.gui.PRINT=Clò-&bhuail
service.gui.PROACTIVE_NOTIFICATION=- a'' sgrìobhadh teachdaireachd
service.gui.PROBLEMS_ENCOUNTERED=Thachair sinn ri duilgheadas
@@ -433,7 +411,6 @@ service.gui.RECONNECTION_LIMIT_EXCEEDED=Rinn thu ''s bhris thu an ceangal ris an
service.gui.RE_REQUEST_AUTHORIZATION=Iarr ùghdarachadh a-rithist
service.gui.REFERRED_STATUS=Air ath-threòrachadh
service.gui.REJECT=&Diùlt
-service.gui.REMIND_ME_LATER=Cuir ''nam chuimhne às a dhèidh seo
service.gui.REMEMBER_PASSWORD=Cuimhnich am facal-faire
service.gui.REMOVE=&Thoir air falbh
service.gui.REMOVE_ACCOUNT=Thoi&r air falbh an cunntas
@@ -459,29 +436,20 @@ service.gui.REVOKE_ADMIN=Thoir air falbh inbhe rianaire
service.gui.REVOKE_MODERATOR=Thoir air falbh inbhe modaratair
service.gui.REVOKE_MEMBERSHIP=Thoir air falbh a'' bhallrachd
service.gui.REVOKE_VOICE=Thoir air falbh an guth
-service.gui.ROOT_GROUP=Buidheann root
service.gui.SAVE=&Sàbhail
-service.gui.SAVE_AS_DEFAULT=Sàbhail mar roghainn bhunaiteach
service.gui.SEARCH=&Lorg
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Briog air a'' phutan gu h-ìosal airson liosta shlàn nan seòmraichean cabadaich a tha air an fhrithealaiche a thagh thu. Tagh am fear a tha thu ag iarraidh a dhol ann is briog air a'' phutan "Rach ann" an uairsin.
service.gui.SEARCH_STRING_CONTACT_SOURCE=Neach-aithne a chaidh a lorg
service.gui.SECURITY=Tèarainteachd
-service.gui.SELECT_ACCOUNT=Tagh cunntas
service.gui.SELECT_COLOR=Tagh dath
service.gui.SELECT_GROUP=Tagh buidheann
-service.gui.SELECT_GROUP_WIZARD_MSG=Tha gach buidheann a tha air liosta an luchd-aithne agad air an liosta gu h-ìosal. Tagh am fear a chuireas sinn an neach-aithne ùr ris.
service.gui.SELECT_NO_GROUP=Gun bhuidheann
-service.gui.SELECT_GROUP_WIZARD=Sònraich buidheann
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=Tha gach cunntas a chuireas taic ri cabadaich iomadh cleachdaiche air an liosta gu h-ìosal. Tagh am fear a bu mhath leat cleachdadh gus an seòmar cabadaich agad a chruthachadh.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=Tha gach cunntas clàraichte air an liosta gu h-ìosal. Tagh am fear a bu chaomh leat cleachdadh gus conaltradh a dhèanamh ris an neach-aithne ùr.
-service.gui.SELECT_PROVIDERS_WIZARD=Tagh cunntas
service.gui.SELECT_VIDEO_CONFERENCE=Tagh co-labhairt video
service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Tagh seòmar cabadaich on liosta is briog air "Ceart ma-thà" gus a chur ris.
service.gui.SEND=C&uir
service.gui.SEND_FILE=Cuir am &faidhle
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Chan eil fiosrachadh ann mun neach-aithne seo.
service.gui.SEND_MESSAGE=C&uir teachdaireachd
-service.gui.SEND_AS_SMS=Cuir mar SMS
service.gui.SEND_PRIVATE_MESSAGE=Cuir teachdaireachd phrìobhaideach
service.gui.SEND_SMS=Cu&ir SMS
service.gui.SEND_SMS_DETAILS=Cuimhnich gum bi agad an àireamh a chur a-steach sa chruth eadar-nàiseanta, m.e. a'' tòiseachadh le +44 airson na Rìoghachd Aonaichte , mar eisimpleir +447777000000
@@ -520,7 +488,6 @@ service.gui.STREET=Sràid
service.gui.SUBJECT=Cuspair
service.gui.SUMMARY=Gearr-chunntas
service.gui.TELEPHONY=Fònadh
-service.gui.TODAY=An-diugh
service.gui.TOOLS=&Innealan
service.gui.TRANSFER=&Sìn air adhart
service.gui.TO=&Gu:
@@ -530,7 +497,6 @@ service.gui.TRANSFER_CALL_TO=Sìn air adhart gu:
service.gui.TRANSPARENCY_NOT_ENABLED=Chan eil an rèiteachadh làithreach agad a'' cur taic ri trìd-shoilleireachd.
service.gui.TYPE_YOUR_REQUEST=Sgrìobh d'' iarrtas an-seo
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Cha b'' urrainn dhuinn càileachd a'' video atharrachadh airson a'' ghairm seo.
-service.gui.UNMUTE=Till an fhuaim
service.gui.USER_IDENTIFIER=Aithnichear a'' chleachdaiche:
service.gui.USER_EXISTS_ERROR=Tha an cleachdaiche seo air an lìonra a thagh thu mu thràth. Feuch is tagh cleachdaiche no lìonra eile.
service.gui.USERNAME_NULL=Cuir a-steach an t-ainm-cleachdaiche ''s am facal-faire agad.
@@ -543,7 +509,6 @@ service.gui.USE_PROVISIONING=Cleachd solar air loidhne
service.gui.VALUE=Luach
service.gui.VIDEO_CALL=Gairm &video
service.gui.VIA=slighe
-service.gui.VIA_SMS=Slighe SMS
service.gui.VIEW=&Sealladh
service.gui.VIEW_HISTORY=Seall an eachdraid&h
service.gui.VIEW_SMILEYS=Seall na &samhlaidhean-gnùise
@@ -563,9 +528,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=Atharraich àirde na fuaime
service.gui.WAITING_AUTHORIZATION=A'' feitheamh ri ùghdarachadh
service.gui.WARNING=Rabhadh
service.gui.YES=Tha
-service.gui.YESTERDAY=An-dè
-service.gui.EXISTING_ACCOUNT_ERROR=Chaidh an cunntas a chuir thu a-steach a stàladh mu thràth.
-service.gui.NEW_MAIL=<b>Tha aon teachdaireachd ùr agad!</b><br/><b>O:</b> {0} {1} <br/><b>Cuspair:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=Fhuair thu teachdaireachd puist ùr sa <a href="{1}">bhogsa a-steach</a> {0} agad:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=Fhuair thu {2} teachdaireachd(an) puist ùr(a) sa <a href="{1}">bhogsa a-steach</a> {0} agad:<br/>
service.gui.NEW_GMAIL_FOOTER=aon chòmhradh eile gun leughadh sa <a href="{0}">bhogsa a-steach</a> agad.<br/>
@@ -589,7 +551,6 @@ service.gui.SECURITY_ERROR=Mearachd tèarainteachd
service.gui.SPEED=Astar:
service.gui.SILENT_MEMBER=ball sàmhach
service.gui.NON_SECURE_CONNECTION=Chan urrainn dhuinn ceangal tèarainte a dhèanamh airson a'' chunntais {0}. Ma tha thu airson ceangal ri frithealaiche nach eil tèarainte, cuir cromag ri "Ceadaich ceanglaichean nach eil tèarainte" ann an rèiteachadh a'' chunntais agad.
-service.gui.UPDATE=Ùraich
service.gui.MOBILE_PHONE=Fòn-làimhe
service.gui.VIDEO_PHONE=Video
service.gui.WORK_PHONE=Obair
@@ -624,7 +585,6 @@ service.gui.callinfo.CALL_INFORMATION=Fiosrachadh mun ghairm
service.gui.callinfo.CALL_IDENTITY=Dearbh-aithne
service.gui.callinfo.PEER_COUNT=Àireamh nan com-pàirtichean
service.gui.callinfo.IS_CONFERENCE_FOCUS=Fòcas na co-labhairt
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Tha an crioptachadh an comas
service.gui.callinfo.CALL_TRANSPORT=A'' siognaileadh giùlanair na gairm
service.gui.callinfo.CALL_DURATION=Faid na gairm
service.gui.callinfo.VIEW_CERTIFICATE=Seall an teisteanas
@@ -635,7 +595,6 @@ service.gui.callinfo.AUDIO_INFO=Fiosrachadh mun fhuaim
service.gui.callinfo.VIDEO_INFO=Fiosrachadh mun video
service.gui.callinfo.LOCAL_IP=IP/Port ionadail
service.gui.callinfo.REMOTE_IP=IP/Port cèin
-service.gui.callinfo.BANDWITH=Tar-chur dàta
service.gui.callinfo.LOSS_RATE=Reat a'' challa
service.gui.callinfo.RTT=RTT
service.gui.callinfo.JITTER=Jitter
@@ -645,10 +604,13 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=Pròtacal malairt na h-iuchrach
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=Seòrsa de thagraiche ICE leudaichte
service.gui.callinfo.ICE_STATE=Staid pròiseasadh ICE
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=Cruinnich na tagraichean
service.gui.callinfo.ICE_STATE.RUNNING=Sgrùdaidhean a'' chomais-cheangail
service.gui.callinfo.ICE_STATE.COMPLETED=Air a choileanadh
service.gui.callinfo.ICE_STATE.FAILED=Dh''fhàillig e
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=IP/Port an òstair ionadail
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=IP/Port faileasach ionadail
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=IP/Port ath-sheachadaichte ionadail
@@ -669,9 +631,10 @@ service.gui.ALWAYS_TRUST=Cuir earbsa san teisteanas seo an-còmhnaidh
service.gui.CERT_DIALOG_TITLE=Dearbh an teisteanas
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>Chan urrainn dha {0} dearbh-àithne an fhrithealaiche a dhearbhadh nuair a cheanglas e ri <br><b>{1}</b>.<br><br> Chan eil earbsa san teisteanas agus is ciall dha sin nach urrainn dhuinn dearbh-àithne an fhrithealaiche a dhearbhadh gu fèin-obrachail.<br><br> A bheil thu airson ceangal co-dhiù?<br> Airson barrachd fiosrachaidh, briog air "Seall an teisteanas".</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>Chan urrainn dha {0} dearbh-àithne an fhrithealaiche a dhearbhadh.<br><br> Chan eil earbsa san teisteanas agus is ciall dha sin nach urrainn dhuinn<br> dearbh-àithne an fhrithealaiche a dhearbhadh gu fèin-obrachail. A bheil thu airson ceangal co-dhiù?<br><br> Airson barrachd fiosrachaidh, briog air "Seall an teisteanas".</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>Chan urrainn dha {0} dearbh-àithne a'' chliaint a tha a'' ceangal a dhearbhadh.<br><br> Chan eil earbsa san teisteanas agus is ciall dha sin nach urrainn dhuinn<br> dearbh-àithne a'' chliaint a dhearbhadh gu fèin-obrachail. A bheil thu airson gabhail ris a'' cheangal co-dhiù?<br><br> Airson barrachd fiosrachaidh, briog air "Seall an teisteanas".</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>Chan urrainn dha {0} dearbh-àithne an t-seise {1} a dhearbhadh.<br><br> Chan eil earbsa san teisteanas agus is ciall dha sin nach urrainn dhuinn<br> dearbh-àithne an t-seise a dhearbhadh gu fèin-obrachail. A bheil thu airson ceangal co-dhiù?<br><br> Airson barrachd fiosrachaidh, briog air "Seall an teisteanas".</html>
service.gui.CONTINUE_ANYWAY=Lean air adhart co-dhiù
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Ainm cumanta:
service.gui.CERT_INFO_O=Buidheann:
service.gui.CERT_INFO_C=Ainm na dùthcha:
@@ -685,12 +648,10 @@ service.gui.CERT_INFO_VER=Tionndadh:
service.gui.CERT_INFO_SIGN_ALG=Algairim an t-soidhnidh:
service.gui.CERT_INFO_ALG=Algairim:
service.gui.CERT_INFO_PUB_KEY=Iuchair phoblach:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} bytes: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} bits
service.gui.CERT_INFO_EXP=Easponant:
service.gui.CERT_INFO_KEY_SIZE=Meud na h-iuchrach:
service.gui.CERT_INFO_SIGN=Soidhneadh:
-service.gui.CONTINUE=Lean air adhart
service.gui.SHOW_CERT=Seall an teisteanas
service.gui.HIDE_CERT=Falaich an teisteanas
@@ -713,11 +674,8 @@ service.gui.security.SECURE_AUDIO=Fuaim thèarainte
service.gui.security.AUDIO_NOT_SECURED=Chan eil an fhuaim tèarainte
service.gui.security.SECURE_VIDEO=Video tèarainte
service.gui.security.VIDEO_NOT_SECURED=Chan eil a'' video tèarainte
-service.gui.security.NO_VIDEO=Chan eil video ann
-service.gui.security.CIPHER=Sifir: {0}
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Chan eil a'' ghairm tèarainte.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Briog an-seo gus coimeas a dhèanamh eadar an rùn tèarainteachd agadsa agus aig a'' chèile agad.
-service.gui.security.COMPARE_WITH_PARTNER=Dèan coimeas leis a'' chèile agus briog air a'' ghlas gus a dhearbhadh.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Dèan coimeas leis a'' chèile:
service.gui.security.STRING_COMPARED=Chaidh coimeas a dhèanamh eadar an dà shreang!
@@ -735,19 +693,13 @@ service.gui.avatar.imagepicker.CLICK=Dèan briogadh is fiamh-ghàire
service.gui.avatar.imagepicker.IMAGE_FILES=Faidhlichean deilbh
service.gui.avatar.imagepicker.IMAGE_PICKER=Dealbh
service.gui.avatar.imagepicker.IMAGE_SIZE=Meud an deilbh
-service.gui.avatar.imagepicker.INITIALIZING=''Ga thòiseachadh
service.gui.avatar.imagepicker.RESET=Ath-shuidhich
service.gui.avatar.imagepicker.SET=Suidhich
service.gui.avatar.imagepicker.TAKE_PHOTO=Tog dealbh
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Mearachd leis a'' chamara-lìn
service.gui.security.encryption.required=Tha feum air crioptachadh!
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
impl.protocol.sip.XCAP_ERROR_TITLE=Mearachd ann an stòras liosta an luchd-aithne SIP
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=Cha ghabh an goireas {0} a leughadh. Airson {1}
@@ -777,9 +729,7 @@ impl.ldap.QUERY_CUSTOM=Ceist ghnàthaichte
impl.ldap.QUERY_CUSTOM_HINT=Cleachd {0} mar glèidheadair-àite airson an fhacail-luirg seo.
impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=Cuir saoragan ri teirm na ceiste gu fèin-obrachail
impl.ldap.QUERY_PHOTO_INLINE=Faigh an dealbh an cois nam buadhan eile
-impl.ldap.NEW=Ùr
impl.ldap.EDIT=deasaich
-impl.ldap.REMOVE=Thoir air falbh
impl.ldap.ENABLED=An comas
impl.ldap.SERVER_NAME=Ainm an fhrithealaiche
impl.ldap.SERVER_NAME_EXAMPLE=Am frithealaiche LDAP agam
@@ -812,6 +762,10 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=fòn dachaidh
impl.ldap.PHONE_PREFIX=Ro-leasachan fòn
impl.ldap.PHONE_PREFIX_EXAMPLE=M.e.: 00
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=Leabhar nan seòladh
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=Cuir an comas lorg ann an leabhar sheòlaidhean MacOSX
@@ -822,9 +776,7 @@ plugin.addrbook.PREFIX_EXAMPLE=M.e.: 00
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Luchd-aithne Google
-impl.googlecontacts.NEW=Ùr
impl.googlecontacts.EDIT=deasaich
-impl.googlecontacts.REMOVE=Thoir air falbh
impl.googlecontacts.ENABLED=An comas
impl.googlecontacts.ACCOUNT_NAME=Ainm a'' chunntais
impl.googlecontacts.SAVE=Sàbhail
@@ -863,11 +815,8 @@ plugin.accountinfo.ORGANIZATION=Ainm a' bhuidhinn:
plugin.accountinfo.JOB_TITLE=Ainm an dreuchd:
plugin.accountinfo.ABOUT_ME=Mu mo dhèidhinn:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
-plugin.accountinfo.USER_PICTURES=Dealbhan a'' chleachdaiche
plugin.accountinfo.GLOBAL_ICON=Cleachd ìomhaigheag uile-choitcheann
plugin.accountinfo.LOCAL_ICON=Cleachd an ìomhaigheag seo:
-plugin.accountinfo.CHANGE=Atharraich
-plugin.accountinfo.ONLY_MESSAGE=Teachdaireachdan a-mhàin
# connection info
@@ -886,49 +835,12 @@ plugin.aimaccregwizz.USERNAME=Ainm-sgrìn AIM:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Ainm-sgrìn ''s facal-faire
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Clàraich cunntas ùr
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Mur eil cunntas AIM agad, briog air a'' phutan seo gus fear ùr a chruthachadh.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Tar-àithn bun-roghainnean an fhrithealaiche
# branding
plugin.branding.ABOUT_WINDOW_TITLE=Mu dhèidhinn {0}
plugin.branding.LOGO_MESSAGE=VoIP ⊠grad-theachdaireachdan le còd fosgailte
-plugin.branding.LOADING=''Ga luchdadh
plugin.branding.ABOUT_MENU_ENTRY=&Mu dheidhinn
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>Tha {1} ''ga leasachadh an-dràsta fhèin. ''S e tionndadh deuchainneil a tha agad agus DH''FHAOIDTE nach obraich e mar a tha dùil. Thoir sùil air {2} airson barrachd fiosrachaidh.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 Còir-lethbhreac <b>jitsi.org</b>. Gach còir glèidhte. Tadhail air <a href="https://jitsi.org">https://jitsi.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}>Tha <b>Jitsi</b> ''ga sgaoileadh fo theirmichean an LGPL (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=Faclairean
-plugin.dictaccregwizz.ANY_DICTIONARY=Faclair sam bith
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Faclair sam bith o {0}
-plugin.dictaccregwizz.FIRST_MATCH=A'' chiad mhaids
-plugin.dictaccregwizz.NO_MATCH=Gun mhaids
-plugin.dictaccregwizz.MATCH_RESULT=Cha deach deifinisean a lorg airson "{0}", an robh na leanas fa-near dhut:\n
-plugin.dictaccregwizz.INVALID_DATABASE=Chan eil am faclair làithreach "{0}" air an fhrithealaiche tuilleadh.
-plugin.dictaccregwizz.INVALID_STRATEGY=Chan eil an ro-innleachd làithreach ri fhaighinn air an fhrithealaiche.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=Pròtacal seirbheis Dict
-plugin.dictaccregwizz.HOST=Ã’stair
-plugin.dictaccregwizz.SERVER_INFO=Fiosrachadh mun fhrithealaiche
-plugin.dictaccregwizz.STRATEGY_SELECTION=Taghadh na ro-innleachd
-plugin.dictaccregwizz.STRATEGY_LIST=Liosta nan ro-innleachdan:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Ro-innleachdan luirg
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=Thèid an ro-innleachd a chleachdadh gus faclan a tha coltach ri chèile a lorg mur an deach eadar-theangachadh a lorg, stèidhichte air diofar dòighean-obrach. Ma eisimpleir, lorgaidh ro-innleachdan nan ro-leasachan faclan a tha a'' tòiseachadh mar a tha am facal air an dèanadh tu eadar-theangachadh.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Fiosrachadh a'' chunntais Dict
-plugin.dictaccregwizz.FIRST_ACCOUNT=Cruthaichidh an draoidh seo a' chiad chunntas Dict dhut air dict.org.\n\n'S urrainn dhut faclair ùr a chruthachadh ma thèid thu gu draoidh clàradh nan cunntasan. Cuir am faclair a bu toigh leat a chur ris ann an lìon an òstair.
-plugin.dictaccregwizz.THREAD_CONNECT=A'' feuchainn ri ceangal a dhèanamh ris an fhrithealaiche
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=Dh''fhàillig an ceangal, chan e frithealaiche Dict a tha seo no tha am frithealaiche far loidhne
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=A'' faighinn nan ro-innleachdan
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Cha deach ro-innleachd a lorg air an fhrithealaiche
-plugin.dictaccregwizz.POPULATE_LIST=A'' lìonadh na liosta
-plugin.dictaccregwizz.CLOSING_CONNECTION=A'' dùnadh a'' cheangail
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Mus urrainn dhut Facebook Chat a chleachdadh, feumaidh tu ainm-cleachdaiche<br>a chruthachadh air duilleag nan "Account Settings" air Facebook.</a><br><br>An aire: Nuair a chruthaicheas tu ainm-cleachdaiche,<br>feumaidh tu clàradh às an duilleag-lìn is faodaidh gum bi greis mus urrainn dhut clàradh a-steach leis an ainm ùr!</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=Pròtacal Facebook Chat
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Ainm-cleachdaiche:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Ainm-cleachdaiche ''s facal-faire
+
# generalconfig
plugin.generalconfig.AUTO_START=Tòisich {0} gu fèin-obrachail nuair a thòisicheas an coimpiutair agad
@@ -939,9 +851,6 @@ plugin.generalconfig.SHOW_HISTORY=Seall
plugin.generalconfig.HISTORY_SIZE=teachdaireachdan a sgrìobhadh o chionn goirid ann an cabadaich ùr
plugin.generalconfig.SEND_MESSAGES_WITH=Cuir teachdaireachdan le:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=Gluais uinneag na cabadaich gun bheulaibh
-plugin.generalconfig.ERROR_PERMISSION=Chan eil pribhleidean gu leòr agad gus casg a chur air an fhèin-tòiseachadh
-plugin.generalconfig.TRANSPARENCY=Trìd-shoilleireachd
-plugin.generalconfig.ENABLE_TRANSPARENCY=Cuir an comas trìd-shoilleireachd
plugin.generalconfig.DEFAULT_LANGUAGE=Cànan na h-eadar-aghaidh
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Bidh na h-atharraichean agad an sàs ann an ath-thuras a thòisicheas tu.
plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0}% air eadar-theangachadh
@@ -995,11 +904,9 @@ plugin.ircaccregwizz.HOST=Ainm an òstair:
plugin.ircaccregwizz.IRC_SERVER=Frithealaiche
# jabber accregwizz
-plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=Pròtacal XMPP
plugin.jabberaccregwizz.USERNAME=Ainm-cleachdaiche XMPP
plugin.jabberaccregwizz.PASSWORD_CONFIRM=Dearbhaich am facal-faire
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=ID is am facal-faire
plugin.jabberaccregwizz.CSERVER=Frithealaiche
plugin.jabberaccregwizz.SERVER=Ceangail am frithealaiche
plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=Cuir an comas an ceangal buan
@@ -1015,13 +922,9 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Beachd
plugin.jabberaccregwizz.RESOURCE=Goireas
plugin.jabberaccregwizz.AUTORESOURCE=Gin an goireas gu fèin-obrachail
plugin.jabberaccregwizz.PRIORITY=Prìomhachas
-plugin.jabberaccregwizz.XMPP_ERROR=Mearachd XMPP
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Mearachd XMPP nach aithne dhuinn ({0}). Dèan cinnteach gu bheil ainm an fhrithealaiche ceart.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Chan eil an dà fhacal-faire co-ionnann.
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Tar-àithn bun-roghainnean an fhrithealaiche
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Roghainnean adhartach
plugin.jabberaccregwizz.USE_ICE=Cleachd ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=Cleachd Jingle Google/ICE (deuchainneil)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=Mothaich do dh''fhrithealaichean STUN/TURN gu fèin-obrachail
plugin.jabberaccregwizz.SUPPORT_TURN=Cuir taic ri TURN
plugin.jabberaccregwizz.TURN_USERNAME=Ainm-cleachdaiche TURN
@@ -1049,11 +952,8 @@ plugin.jabberaccregwizz.DISABLE_CARBON=Cuir carboin nan teachdaireachdan à coma
plugin.jabberaccregwizz.DTMF_AUTO=Gu fèin-obrachail: Dèan taghadh eadar RTP is Inband gu fèin-obrachail
plugin.jabberaccregwizz.SERVER_OPTIONS=Roghainnean an fhrithealaiche
plugin.jabberaccregwizz.CHANGE_PASSWORD=Atharraich facal-faire a'' chunntais
-plugin.jabberaccregwizz.NEW_PASSWORD=Facal-faire ùr
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Dearbh am facal-faire ùr
plugin.jabberaccregwizz.PORT_FIELD_INVALID=Nach cuir thu a-steach àireamh puirt dhligheach mus lean thu air adhart?
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=Feumaidh tu clàradh a-steach mus gabh am facal-faire atharrachadh.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=Tha am facal-faire bàn.
plugin.jabberaccregwizz.TLS_REQUIRED=Chan eil an ceangal seo a'' cleachdadh TLS, chan fheuch sinn ris am facal-faire atharrachadh.
plugin.jabberaccregwizz.PASSWORD_CHANGED=Chaidh am facal-faire atharrachadh
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=Chan eil am frithealaiche XMPP agad a'' ceadachadh atharrachadh fhaclan-faire.
@@ -1067,25 +967,9 @@ plugin.jabberaccregwizz.RESET=Ath-shuidhich
plugin.jabberaccregwizz.RESET_DESCRIPTION=Ath-shuidhich na roghainnean uile-choitcheann
plugin.jabberaccregwizz.DISABLE_JINGLE=Cuir às comas Jingle (gairmean gutha is video le XMPP).
-# mailbox
-plugin.mailbox.OUTGOING=Teachdaireachdan a thèid a-mach:
-plugin.mailbox.INCOMING=Teachdaireachdan a thig a-steach:
-plugin.mailbox.WAIT_TIME=Cuir dàil air gus an deach a'' ghairm a chur gun phost-ghutha
-plugin.mailbox.MAX_MESSAGE_TIME=Faid as motha de theachdaireachdan a thig a-steach
-plugin.mailbox.CONFIRM=Dearbhaich
-plugin.mailbox.DEFAULTS=Bun-roghainnean
-plugin.mailbox.MAILBOX=Bogsa-puist
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Pròtacal leis an urrainn dhut ceangal ri seirbheis MSN agus cabadaich air.
-plugin.msnaccregwizz.USERNAME=Post-d:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=ID is am facal-faire
-
# plugin manager
plugin.pluginmanager.INSTALL=Stàlaich
plugin.pluginmanager.UNINSTALL=Dì-stàlaich
-plugin.pluginmanager.UPDATE=Ùraich
plugin.pluginmanager.PLUGINS=Plugain
plugin.pluginmanager.URL=URL
plugin.pluginmanager.CHOOSE_FILE=Tagh faidhle
@@ -1110,7 +994,6 @@ plugin.sipaccregwizz.SERVER_PORT=Port an fhrithealaiche
plugin.sipaccregwizz.PROXY=Progsaidh
plugin.sipaccregwizz.PROXY_PORT=Port a'' phrogsaidh
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Giùlanair as fhearr leat
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Roghainnean adhartach
plugin.sipaccregwizz.PROXY_OPTIONS=Roghainnean a'' phrogsaidh
plugin.sipaccregwizz.PROXY_AUTO=Rèitich am progsaidh gu fèin-obrachail
plugin.sipaccregwizz.ENABLE_PRESENCE=Cuir làthaireachd an comas (SIMPLE)
@@ -1130,8 +1013,6 @@ plugin.sipaccregwizz.DTMF_AUTO=Gu fèin-obrachail: Dèan taghadh eadar RTP is In
plugin.sipaccregwizz.DTMF_RTP=RTP ( RFC2833 / RFC 4733 )
plugin.sipaccregwizz.DTMF_SIP_INFO=SIP INFO
plugin.sipaccregwizz.DTMF_INBAND=Inband
-plugin.sipaccregwizz.REGISTER=REGISTER
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Tar-àithn bun-roghainnean an fhrithealaiche
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Cuir an comas taic ri gairmean crioptaichte
plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=Nochd gu bheil taic ri ZRTP sa phròtacal siognailidh
plugin.sipaccregwizz.AUTH_NAME=Ainm an ùghdarachaidh
@@ -1152,10 +1033,10 @@ plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=URI sgrùdadh puist-ghutha
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Chan eil an dà fhacal-faire co-ionnann.
plugin.sipaccregwizz.NO_CERTIFICATE=<none> (cleachd dearbhadh àbhaisteach)
plugin.sipaccregwizz.SAVP_OPTION=Taisbeanadh RTP/SAVP
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=Dheth (taisbean RTP/AVP a-mhàin)
plugin.sipaccregwizz.SAVP_OPTION_1=Èigneachail (na tairg is na gabh ach ri RTP/SAVP)
plugin.sipaccregwizz.SAVP_OPTION_2=Roghainneil (tairg RTP/SAVP an toiseach is RTP/AVP an uairsin)
-plugin.sipaccregwizz.ENABLE_SDES_ATTRIBUTE=Cuir an comas S-Descriptor (air a bheil SDES no SRTP cuideachd)
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=Tagh pròtacalan crioptachaidh a tha an comas agus na prìomhachasan aca (am pròtacal aig a'' bharr an toiseach):
plugin.sipaccregwizz.CIPHER_SUITES=Cipher suites a tha an comas:
plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>Feuchaidh {0} gu fèin-obrachail ris na gairmean uile agad a dhèanamh tèarainte le ZRTP agus cluinnidh an dithis agaibh brath turas a chaidh ceangal tèarainte a stèidheachadh. Cha bu chòir dhut na roghainnean adhartach gu h-ìosal atharrachadh ach ma tha thu gu math eòlach air a leithid a rud.</div></html>
@@ -1169,15 +1050,6 @@ plugin.skinmanager.DEFAULT_SKIN=An craiceann bunaiteach
plugin.skinmanager.ADD_NEW_SKIN=Cuir craiceann ùr ris...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=Craiceann bunaiteach na h-aplacaid.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=Pròtacal leis an urrainn dhut ceangal a dhèanamh ri innealan cèin slighe SSH.
-plugin.sshaccregwizz.USERNAME=ID a'' chunntais:
-plugin.sshaccregwizz.IDENTITY_FILE=Faidhle na dearbh-aithne:
-plugin.sshaccregwizz.KNOWN_HOSTS=Ã’stairean as aithne dhuinn:
-plugin.sshaccregwizz.OPTIONAL=Roghainneil
-plugin.sshaccregwizz.ACCOUNT_DETAILS=Fiosrachadh a'' chunntais
-
# status update
plugin.autoaway.AUTO_STATUS=Suidhich "Air falbh" gu fèin-obrachail
plugin.autoaway.ENABLE_CHANGE_STATUS=Atharraich mo làthaireachd nuair a bhios mi air falbh
@@ -1224,22 +1096,6 @@ plugin.whiteboard.DESELECT=Dì-thagh
plugin.whiteboard.DELETE=Sguab às
plugin.whiteboard.PROPERTIES=Roghainnean
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Pròtacal leis an urrainn dhut ceangal ri seirbheis Yahoo! agus cabadaich air.
-plugin.yahooaccregwizz.USERNAME=Ainm-cleachdaiche:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=ID is am facal-faire
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=Pròtacal na seirbheise Zeroconf (Bonjour).
-plugin.zeroaccregwizz.FIRST_NAME=Ainm:
-plugin.zeroaccregwizz.LAST_NAME=Sloinneadh
-plugin.zeroaccregwizz.EMAIL=Post-d:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=A bheil thu airson luchd-aithne Bonjour a chumail an cuimhne?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=ID is facal-faire
-plugin.zeroaccregwizz.USERID=ID a'' chleachdaiche
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Pròtacal Google Talk
@@ -1253,19 +1109,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, am portal cian-chonaltrad
plugin.iptelaccregwizz.USERNAME=Ainm-cleachdaiche
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=Fo-sgrìobh gu iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIP agus cabadaich
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Ainm-cleachdaiche
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Cuir am facal-faire a-steach a-rithist
plugin.sip2sipaccregwizz.EMAIL=Seòladh puist-d
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=Airson cobhar leis an t-seirbheis seo, tadhail air<br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>Thèid an seòladh puist-d a chleachdadh gus post-gutha agus brathan mu, <br>ghairmean a chaill thu a chur agus faclan-faire a dhìochuimhnich thu aiseag</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>Airson cobhair leis an t-seirbheis seo, tadhail air <a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=Cunntas sip2sip.info a tha ann mu thràth
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Cruthaich cunntas sip2sip.info saor an-asgaidh
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP ⊠grad-theachdaireachdan
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=Airson cobhar leis an t-seirbheis seo, tadhail air<br>http://ippi.fr
@@ -1274,6 +1122,7 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=Cunntas ippi a tha ann mu thràth
plugin.ippiaccregwizz.CREATE_ACCOUNT=Cruthaich cunntas ippi ùr
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Dùin uinneag na cabadaich
plugin.keybindings.CHAT_COPY=Dèan lethbhreac
plugin.keybindings.CHAT_CUT=Gearr às
@@ -1296,10 +1145,10 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=Ainm
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=Prìomh ath-ghoirid
plugin.keybindings.globalchooser.SHORTCUT_SECOND=Dàrna ath-ghoirid
plugin.keybindings.globalchooser.PRESS_BTN=Dèan brùthadh gus an ath-ghoirid a shuidheachadh
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=A'' feitheamh
plugin.keybindings.globalchooser.PUSH_TO_TALK=Brùth airson bruidhinn
plugin.keybindings.globalchooser.ENABLE_SPECIAL=Cuir an comas mothachadh do dh''iuchraichean sònraichte
plugin.keybindings.PLUGIN_NAME=Ceanglaichean iuchrach
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Cabadaich
plugin.keybindings.MAIN=Prìomh-cheangal iuchrach
plugin.keybindings.GLOBAL=Ath-ghoiridean uile-choitcheann
@@ -1326,6 +1175,7 @@ plugin.notificationconfig.tableheader.SOUND=Cluich fuaim tro uidheam bhrathan
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=Cluich fuaim tro uidheam cluiche
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=Cluich fuaim tro glaodhaire a'' PC
plugin.notificationconfig.tableheader.DESCRIPTION=Tuairisgeul tachartais
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Gairm a'' tighinn a-steach
plugin.notificationconfig.event.SecurityMessage=Teachdaireachd tèarainteachd
plugin.notificationconfig.event.IncomingFile=Faidhle a'' tighinn a-steach
@@ -1427,6 +1277,7 @@ impl.neomedia.configform.VIDEO=Video
impl.neomedia.configform.H264=H.264
impl.neomedia.configform.H264.defaultIntraRefresh=Ath-nuadhachadh Intra cunbhalach
impl.neomedia.configform.H264.defaultProfile=A'' phròifil bhunaiteach dhan a nithear còdachadh:
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=Bun-loidhne
impl.neomedia.configform.H264.defaultProfile.high=Àrd
impl.neomedia.configform.H264.defaultProfile.main=Prìomh-phròifil
@@ -1457,7 +1308,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=Am facal-faire làithreach
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Cuir a-steach am facal-faire ùr:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Cuir a-steach am facal-faire a-rithist:
plugin.securityconfig.masterpassword.MP_TITLE=Prìomh-fhacal-faire
-plugin.securityconfig.masterpassword.MP_NOT_SET=(cha deach a shuidheachadh)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=Cha do chuir thu a-steach am prìomh fhacal-faire làithreach ceart. Feuch ris a-rithist.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=Tha am prìomh fhacal-faire cearr!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Dh''fhàillig atharrachadh an fhacail-fhaire
@@ -1473,7 +1323,6 @@ plugin.securityconfig.masterpassword.COL_PASSWORD=Facal-faire
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(neo aithnichte)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(cha ghabh a dhì-chrioptachadh)
plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=Faclan-faire a tha ''gan stòradh
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=Thoir air falbh
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=Thoir air falbh a h-uile
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=A bheil thu airson gach facal-faire a thoirt air falbh?
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=Thoir air falbh a h-uile facal-faire
@@ -1569,7 +1418,6 @@ plugin.globalproxy.PROXY_PORT=Port a'' phrogsaidh
plugin.globalproxy.PROXY_USERNAME=Ainm-cleachdaiche a'' phrogsaidh
plugin.globalproxy.PROXY_PASSWORD=Facal-faire a'' phrogsaidh
plugin.globalproxy.DESCRIPTION=Cleachdaidh {0} na roghainnean progsaidh gu h-àrd airson a h-uile lìonra a cheanglas tu ris no a dh'ath-cheanglas tu ris. \nTha an taic ri progsaidhean caran deuchainneil an-dràsta agus chan obraich e ach le cuid a phròtacalan. Thoir sùil air a' chlàr gu h-ìosal airson barrachd fiosrachaidh:
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>XMPP</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
plugin.globalproxy.FWD_DNS=DNS progsaidh cuideachd
plugin.globalproxy.FWD_DNS_NOTE=Feumail le Tor. ''S urrainn dhut aoideanan DNS a sheachnadh leis is e a'' sìneadh air adhart an trafaig DNS air fad gun phrogsaidh Tor. Bidh agad ri ath-thòiseachadh.
@@ -1602,7 +1450,6 @@ plugin.provisioning.RESTART_WARNING=Thoir an aire nach dèid na h-atharraichean
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=Cuir lethbhreac dhen UUID air an stòr-bhòrd
plugin.provisioning.CLIPBOARD_FAILED=Cha b'' urrainn dhuinn lethbhreac dhen UUID a chur air an stòr-bhòrd
-plugin.provisioning.EXIT_ON_FAIL=Fàg an aplacaid ma dh''fhàilligeas am provisioning
plugin.provisioning.CREDENTIALS=Na teisteasan provisioning mu dheireadh a chaidh a stòradh
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=A bheil thu airson facal-faire a'' provisioning a thoirt air falbh?
plugin.provisioning.PROV_FAILED=Dh''fhàillig am provisioning
@@ -1669,8 +1516,6 @@ util.dns.DNSSEC_WARNING=<html><div width="600">Dh''fheuch {0} ri ceangal a dhèa
#plugin spellcheck
plugin.spellcheck.TITLE=Litreachadh is gràmar
plugin.spellcheck.MENU=Seall dearbhadh an litreachaidh is a'' ghràmair
-plugin.spellcheck.LANG=Cànan
-plugin.spellcheck.EDIT_PERSONAL_DICT=Deasaich
plugin.spellcheck.ENABLE_SPELL_CHECK=Cuir an comas an dearbhair-litreachaidh
plugin.spellcheck.dialog.FIND=Lorg an ath-fhear
plugin.spellcheck.dialog.REPLACE=Cuir ''na àite
diff --git a/resources/languages/resources_he.properties b/resources/languages/resources_he.properties
index 8dc5f1e..5199796 100644
--- a/resources/languages/resources_he.properties
+++ b/resources/languages/resources_he.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=×× ×™
service.gui.ACCOUNT_REGISTRATION_WIZARD=×שף הרשמת חשבון
service.gui.ACCOUNTS=חשבונות
service.gui.ADD=&הוסף
-service.gui.ADD_ACCOUNT=הוסף חשבון
service.gui.ADD_CONTACT=&הוסף ×יש קשר
service.gui.ADD_AUTHORIZED_CONTACT=הוסף ×ת {0} ×ל רשימת ×ישי ×”×§×©×¨×™× ×©×œ×š
service.gui.ADD_CONTACT_TO=&הוסף ×נשי קשר ×ל
@@ -41,17 +51,12 @@ service.gui.ADD_CONTACT_ERROR_TITLE=שגי×ת הוספת ×יש קשר
service.gui.ADD_CONTACT_EXIST_ERROR=×יש הקשר {0} כבר מצוי ברשימת ×ישי ×”×§×©×¨×™× ×©×œ×š.
service.gui.ADD_CONTACT_NETWORK_ERROR=שרת ×œ× ×”×’×™×‘ לבקשתנו להוספת ×יש קשר ×¢× ×ž×–×”×”: {0}.
service.gui.ADD_CONTACT_NOT_SUPPORTED=כשל בהוספת ×יש קשר ×¢× ×ž×–×”×”: {0}. פעולה ×œ× × ×ª×ž×›×ª.
-service.gui.ADD_CONTACT_IDENTIFIER=בשדה להלן, הזן המזהה של ×יש הקשר ×שר ברצונך להוסיף.
-service.gui.ADD_CONTACT_WIZARD=×שף הוספת ×יש קשר
service.gui.ADD_GROUP_EXIST_ERROR=הקבוצה {0} כבר מצויה ברשימת ×”×§×©×¨×™× ×©×œ×š. ×× × ×‘×—×¨ ×©× ×חר.
service.gui.ADD_GROUP_ERROR=כשל בהוספת קבוצה בש×: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=×©× ×”×§×‘×•×¦×” ×œ× ×™×›×•×œ להיות ריק.
-service.gui.ADD_GROUP=צור קבוצה
-service.gui.ADD_SUBCONTACT=&הוסף ×יש קשר משני
service.gui.ADDRESS=כתובת
service.gui.ADMINISTRATOR=מנהלן
service.gui.ADVANCED=&מתקד×
-service.gui.ALL=&הכל
service.gui.ALL_CONTACTS=&כל ×נשי הקשר
service.gui.APPLY=&החל
service.gui.ARE_CALLING=×ž×ª×§×©×¨×™× ×›×¢×ª...
@@ -59,7 +64,6 @@ service.gui.ARE_NOW=הינך {0} כעת
service.gui.AUTHORIZE=&הרש××”
service.gui.AUTHORIZATION_ACCEPTED=×יש הקשר קיבל ×ת בקשת הרש×תך.
service.gui.AUTHENTICATION_FAILED=×ימות עבור {0} נכשל. הסיסמה שהזנת ×”×™× ×” שגויה.
-service.gui.AUTHENTICATION_REQUESTED=התבקש ×ישור
service.gui.AUTHENTICATION_REQUESTED_SERVER=השרת {0} ביקש ×ת ×ישורך.
service.gui.AUTHENTICATION_REJECTED=×יש הקשר דחה ×ת בקשת הרש×תך.
service.gui.AUTHENTICATION_WINDOW_TITLE=‫{0} ×ימות
@@ -101,7 +105,6 @@ service.gui.CHAT_ROOM_USER_QUIT={0} יצ×/×”
service.gui.CHAT_ROOM_NAME=×©× ×—×“×¨ שיחה
service.gui.CLEAR_CUSTOM_MESSAGES=טהר הודעות מות×מות
service.gui.ROOM_NAME=חדר שיחה
-service.gui.AUTOJOIN=הצטרף ×וטומטית
service.gui.CHANGE_PASSWORD=שנה סיסמה
service.gui.CHAT_ROOM_NAME_INFO=בשדה להלן, הזן ×ת ×”×©× ×©×œ חדר השיחה ×שר ברצונך ליצור.
service.gui.CHAT_ROOM_NOT_EXIST=החדר {0} ×œ× × ×ž×¦× ×‘×ª×•×š השרת {1}. ×× × ×•×“× ×× ×”×©× ×©×”×§×œ×“×ª הינו מדויק.
@@ -120,7 +123,6 @@ service.gui.CLEAR=טהר
service.gui.CLOSE=&סגור
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=קיבלת הודעה חדשה מלפני פחות משתי שניות. ×”×× ×תה בטוח ×›×™ ברצונך לסגור ×ת שיחה זו?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=יש לך העברות קובץ פעילות. ×”×× ×תה בטוח ×›×™ ברצונך לבטלן?
-service.gui.CONFIRM=×מת
service.gui.CONNECTED_STATUS=מחובר
service.gui.CONNECTING=מתחבר כעת...
service.gui.CONNECTING_STATUS=מתחבר כעת
@@ -128,12 +130,10 @@ service.gui.CONNECTING_EARLY_MEDIA_STATUS=מתחבר כעת*
service.gui.CONNECTION=חיבור
service.gui.CONNECTION_EXPIRED_MSG=×תה מנותק כעת מהשרת {0}.
service.gui.CONTACT_NAME=מזהה ×ו מספר
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=×יש קשר נבחר {0} ×œ× ×ª×•×ž×š בטלפוניה.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=×יש קשר נבחר {0} ×œ× ×ª×•×ž×š בשיחת ועידה.
service.gui.CONTACT_PAUSED_TYPING=â€{0} פסק מלהקליד ×ת ההודעה
service.gui.CONTACT_TYPING=â€{0} מקליד כעת הודעה
service.gui.CONTACT_INFO=&מידע ×יש קשר
-service.gui.CONTACTLIST=רשימת קשר
service.gui.CONTACTS=ה&עתק
service.gui.COPY=ה&עתק
service.gui.COPY_LINK=העתק &קישור
@@ -143,14 +143,11 @@ service.gui.CREATE_CHAT_ROOM=&צור חדר שיחה...
service.gui.CREATE_CHAT_ROOM_ERROR=נכשל ליצור חדר שיחה {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=×שף יצירת חדר שיחה
service.gui.CREATE_CONFERENCE_CALL=&צור קרי×ת ועידה...
-service.gui.CREATE_CONFERENCE_CHAT=&צור שיחת ועידה...
service.gui.CREATE_GROUP=&צור קבוצה...
service.gui.CREATE_GROUP_NAME=בשדה להלן, הזן ×ת ×”×©× ×©×œ הקבוצה ×שר ברצונך ליצור.
-service.gui.CREATE_FIRST_GROUP_WIZARD=רשימת ×”×§×©×¨×™× ×©×œ ×œ× ×ž×›×™×œ×” ××£ קבוצה. ×× × ×¦×•×¨ קבוצה צחילה (קובץ/צור קבוצה).
service.gui.CREATE_VIDEO_BRIDGE=יצירת &גשר ויד×ו...
service.gui.CREATE_VIDEO_BRIDGE_MENU=צור &גשר ויד×ו
service.gui.CUT=&גזור
-service.gui.DATE=ת×ריך
service.gui.DELETE=מחק
service.gui.DENY=&×סור
service.gui.DESKTOP_SHARING_WARNING=<b>×”×× ×תה בטוח ×›×™ ברצונך להתחיל שיתוף מסך?</b> <br> לחיצה על ×ישור תתיר ל×× ×©×™× ×‘×©×™×—×” ×–×” לר×ות ×ת המסך שלך.
@@ -159,7 +156,6 @@ service.gui.DISPLAY_NAME=×©× ×¦×’
service.gui.DND_STATUS=× × ×œ× ×œ×”×¤×¨×™×¢
service.gui.DO_NOT_ASK_AGAIN=×ל תש×ל שוב
service.gui.DO_NOT_SHOW_AGAIN=×ל תציג ×ת הודעה זו שוב
-service.gui.DOWNLOAD_NOW=&הורד כעת
service.gui.DRAG_FOR_SHARING=גרור לכ×ן כל דבר ×שר ברצונך לשתף...
service.gui.DURATION=משך
service.gui.EDIT=&ערוך
@@ -173,7 +169,6 @@ service.gui.ERROR_WAS=השגי××” היתה: {0}
service.gui.ESTIMATED_TIME=×ומדן זמן:
service.gui.EVENTS=×ירועי×
service.gui.EXIT=×™&צי××”
-service.gui.EXTENDED_CRITERIA=קריטריון מורחב
service.gui.GENERAL=כללי
service.gui.GENERAL_ERROR=שגי××” גנרית
service.gui.GROUP_NAME=×©× ×§×‘×•×¦×”
@@ -227,7 +222,6 @@ service.gui.HIDE_OFFLINE_CONTACTS=התר ×נשי קשר ×œ× ×ž×§×•×•× ×™×
service.gui.HISTORY=&היסטוריה
service.gui.HISTORY_CONTACT=היסטוריה - {0}
service.gui.HOME=בית
-service.gui.HOUR=שעה
service.gui.IDENTIFIER=מזהה
service.gui.IGNORE=&התעל×
service.gui.INSERT_SMILEY=שבץ סמיילי
@@ -241,10 +235,8 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=הזמן ×נשי קשר לגשר ו×
service.gui.INVITE_REASON=סיבת הזמנה
service.gui.IS_CALLING=מתקשר/ת כעת...
service.gui.IS_NOW=â€{0} כעת {1}
-service.gui.JITSI_WARNING_TITLE=â€SIP Communicator × ×”×™×” Jitsi
service.gui.JOIN=ה&צטרף
service.gui.JOIN_AS=הצטרף &בתור
-service.gui.CLOSE_CHAT_ROOM_DIALOG=ס&גור
service.gui.JOIN_CHAT_ROOM_NAME=×× × ×”×–×Ÿ ×ת ×”×©× ×©×œ חדר השיחה ×ליו ברצונך להצטרף.
service.gui.KICK=&בעט
service.gui.KICK_FAILED=בעיטה נכשלה
@@ -258,19 +250,16 @@ service.gui.MESSAGE=הודעה
service.gui.MISSED_CALLS_TOOL_TIP=שיחה ×שר ×œ× × ×¢× ×ª×” מן:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= ועוד {0} נוספות
service.gui.MODERATOR=×חר××™
-service.gui.MORE=ר××” עוד
service.gui.MORE_LABEL=×”×–×–
service.gui.MOVE=×”×–×–
service.gui.MOVE_SUBCONTACT=×”&×–×– ×יש קשר
service.gui.MOVE_SUBCONTACT_QUESTION=×”×× ×תה בטוח ×›×™ ברצונך להעביר ×ת {0} ×ל {1}?
service.gui.MOVE_TO_GROUP=&העבר ×ל קבוצה
service.gui.MOVE_CONTACT=×”×–×– ×יש קשר
-service.gui.MOVE_CONTACT_ERROR=&×יש קשר ×œ× × ×™×ª×Ÿ להזזה
service.gui.MSG_DELIVERY_FAILURE=ההודעה לעיל ×œ× ×”×™×ª×” יכולה להימסר
service.gui.MSG_DELIVERY_ERROR=נכשל למסור הודעה.
service.gui.MSG_DELIVERY_UNKNOWN_ERROR=×ירעה שגי××” ×œ× ×ž×•×›×¨×ª בעת מסירת הודעתך.
service.gui.MSG_RECEIVED={0} כתב/ה
-service.gui.MUTE=השתק
service.gui.NAME=ש×
service.gui.NETWORK=רשת עבודה
service.gui.NETWORK_FAILURE=כשל רשת עבודה
@@ -297,7 +286,6 @@ service.gui.OPEN_FILE_FROM_IMAGE=קליק כפול כדי לפתוח קובץ.
service.gui.OPEN_FOLDER=פתח תיקייה
service.gui.OPEN_IN_BROWSER=פתח בתוך &דפדפן
service.gui.OPTIONS=×פשרויות
-service.gui.OR_ENTER_PHONE_NUMBER=×ו הזן מספר טלפון ×›×ן...
service.gui.ORGANIZATION=×רגון:
service.gui.OTHER=×חר
service.gui.PASSWORD=סיסמה
@@ -310,7 +298,6 @@ service.gui.PREFERENCES=העדפות
service.gui.PREFIX=קידומת
service.gui.PRESS_FOR_CALL_INFO=לחץ למידע שיחה
service.gui.PREVIOUS=קוד×
-service.gui.PREVIOUS_TOOLTIP=עיון בשיחות ישנות
service.gui.PRINT=&הדפס
service.gui.PROTOCOL=פרוטוקול
service.gui.QUIT=×™&צי××”
@@ -318,7 +305,6 @@ service.gui.READY=מוכן
service.gui.REASON=סיבה
service.gui.RE_REQUEST_AUTHORIZATION=בקש שוב הרש××”
service.gui.REJECT=&סרב
-service.gui.REMIND_ME_LATER=הזכר לי מ×וחר יותר
service.gui.REMEMBER_PASSWORD=זכור סיסמה
service.gui.REMOVE=&הסר
service.gui.REMOVE_ACCOUNT=&הסר חשבון
@@ -339,22 +325,15 @@ service.gui.REVOKE_ADMIN=שלול מנהלן
service.gui.REVOKE_MODERATOR=שלול ×חר××™
service.gui.REVOKE_MEMBERSHIP=שלול חברות
service.gui.REVOKE_VOICE=שלול ביטוי
-service.gui.ROOT_GROUP=קבוצת שורש
service.gui.SAVE=&שמור
-service.gui.SAVE_AS_DEFAULT=שמור כברירת מחדל
service.gui.SEARCH=&חפש
service.gui.SECURITY=×בטחה
-service.gui.SELECT_ACCOUNT=בחירת חשבון
service.gui.SELECT_COLOR=בחירת צבע
service.gui.SELECT_GROUP=בחירת קבוצה
service.gui.SELECT_NO_GROUP=×ין קבוצה
-service.gui.SELECT_GROUP_WIZARD=ציין קבוצה
-service.gui.SELECT_PROVIDERS_WIZARD=בחירת חשבון
service.gui.SEND=&שלח
service.gui.SEND_FILE=שלח &קובץ
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=×ין מידע עבור ×יש קשר ×–×”.
service.gui.SEND_MESSAGE=&שלח הודעה
-service.gui.SEND_AS_SMS=שלח בצורה של SMS
service.gui.SEND_SMS=&שלח SMS
service.gui.SEND_SMS_DETAILS=זכור ×›×™ עליך להזין ×ת המספר בפורמט בינל×ומי למשל ‎+44 עבור הממלכה המ×וחדת לדוגמ×, ‎+447777000000
service.gui.SEND_SMS_NOT_SUPPORTED=הפרוטוקול בו בחרת ×œ× ×ª×•×ž×š בהודעות SMS.
@@ -383,7 +362,6 @@ service.gui.STREET=רחוב
service.gui.SUBJECT=נוש×
service.gui.SUMMARY=תמצית
service.gui.TELEPHONY=טלפוניה
-service.gui.TODAY=היו×
service.gui.TOOLS=&כלי×
service.gui.TRANSFER=&העבר
service.gui.TO=&×ל:
@@ -391,7 +369,6 @@ service.gui.TRANSFER_CALL_MSG=בחר ×ת ×©× ×©×œ ×יש הקשר ×שר בר×
service.gui.TRANSFER_CALL_TITLE=העבר קרי××”
service.gui.TRANSFER_CALL_TO=העבר ×ל:
service.gui.TYPE_YOUR_REQUEST=הקלד ×ת בקשתך ×›×ן
-service.gui.UNMUTE=×יין השתקה
service.gui.USER_IDENTIFIER=מזהה משתמש:
service.gui.USER_EXISTS_ERROR=משתמש ×–×” כבר ×§×™×™× ×‘×©×ª הנבחרת. × × ×œ×‘×—×•×¨ משתמש ×ו רשת ×חרי×.
service.gui.USERNAME_NULL=× × ×œ×ž×œ× ×©× ×ž×©×ª×ž×© וסיסמה.
@@ -401,7 +378,6 @@ service.gui.UNKNOWN_STATUS=מצב ×œ× ×ž×•×›×¨
service.gui.UNREGISTERED_MESSAGE=×œ× × ×™×ª×Ÿ להתקשר ×¢× ×”×—×©×‘×•×Ÿ הב×: ×©× ×ž×©×ª×ž×©: {0}, ×©× ×©×¨×ª: {1}. הינך כעת ×œ× ×ž×§×•×•×Ÿ.
service.gui.VALUE=ערך:
service.gui.VIDEO_CALL=&שיחת ויד×ו
-service.gui.VIA_SMS=ב×מצעות SMS
service.gui.VIEW=&תצוגה
service.gui.VIEW_HISTORY=הצג &היסטוריה
service.gui.VIEW_SMILEYS=הצג &סמיילי×
@@ -419,8 +395,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=הת×× ×¢×•×¦×ž×”
service.gui.WAITING_AUTHORIZATION=ממתין להרש××”
service.gui.WARNING=×זהרה
service.gui.YES=כן
-service.gui.YESTERDAY=×תמול
-service.gui.EXISTING_ACCOUNT_ERROR=החשבון שהזנת כבר קיי×.
service.gui.NEW=חדש
service.gui.ENTER_FULL_SCREEN_TOOL_TIP=הפעל מסך מל×
service.gui.EXIT_FULL_SCREEN_TOOL_TIP=נטרל מסך מל×
@@ -436,7 +410,6 @@ service.gui.SECURITY_WARNING=×זהרת ×בטחה
service.gui.SECURITY_ERROR=שגי×ת ×בטחה
service.gui.SPEED=מהירות:
service.gui.SILENT_MEMBER=השתק חבר
-service.gui.UPDATE=עדכון
service.gui.MOBILE_PHONE=נייד
service.gui.VIDEO_PHONE=ויד×ו
service.gui.WORK_PHONE=עבודה
@@ -465,7 +438,6 @@ service.gui.DECEMBER=דצמבר
service.gui.callinfo.TECHNICAL_CALL_INFO=מידע שיחה טכני
service.gui.callinfo.CALL_INFORMATION=מידע שיחה
service.gui.callinfo.CALL_IDENTITY=זהות
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=הצפנה מ×ופשרת
service.gui.callinfo.CALL_DURATION=משך שיחה
service.gui.callinfo.VIEW_CERTIFICATE=הצג תעודה
service.gui.callinfo.CODEC=קודק / תדירות
@@ -475,15 +447,19 @@ service.gui.callinfo.AUDIO_INFO=מידע ×ודיו
service.gui.callinfo.VIDEO_INFO=מידע ויד×ו
service.gui.callinfo.LOCAL_IP=â€IP מקומי / פורט
service.gui.callinfo.REMOTE_IP=â€IP מרוחק / פורט
-service.gui.callinfo.BANDWITH=Bandwith
service.gui.callinfo.RTT=RTT
service.gui.callinfo.MEDIA_STREAM_RTP=RTP
service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
+
+#enum values from IceProcessingState
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=â€IP מ×רח מקומי / פורט
service.gui.callinfo.ICE_REMOTE_HOST_ADDRESS=â€IP מ×רח מרוחק / פורט
service.gui.CERT_DIALOG_TITLE=×מת תעודה
service.gui.CONTINUE_ANYWAY=המשך בכל ×ופן
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=×©× ×›×œ×œ×™:
service.gui.CERT_INFO_O=×רגון:
service.gui.CERT_INFO_C=×©× ×רץ:
@@ -498,7 +474,6 @@ service.gui.CERT_INFO_SIGN_ALG=××œ×’×•×¨×™×ª× ×—×ª×™×ž×”:
service.gui.CERT_INFO_ALG=×לגורית×:
service.gui.CERT_INFO_PUB_KEY=מפתח פומבי:
service.gui.CERT_INFO_SIGN=חתימה:
-service.gui.CONTINUE=המשך
service.gui.SHOW_CERT=הצג תעודה
service.gui.HIDE_CERT=הסתר תעודה
@@ -511,8 +486,6 @@ service.gui.security.SECURE_AUDIO=×ודיו מ×ובטח
service.gui.security.AUDIO_NOT_SECURED=×ודיו ×œ× ×ž×ובטח
service.gui.security.SECURE_VIDEO=ויד×ו מ×ובטח
service.gui.security.VIDEO_NOT_SECURED=ויד×ו ×œ× ×ž×ובטח
-service.gui.security.NO_VIDEO=×ין ויד×ו
-service.gui.security.CIPHER=צופן: {0}
service.gui.security.CALL_NOT_SECURED_TOOLTIP=שיחה ×œ× ×ž×ובטחת.
# keep the following string short
@@ -526,15 +499,10 @@ service.gui.avatar.imagepicker.IMAGE_PICKER=תמונה
service.gui.avatar.imagepicker.IMAGE_SIZE=מידת תמונה
service.gui.avatar.imagepicker.RESET=×יפוס
service.gui.avatar.imagepicker.TAKE_PHOTO=לקיחת תמונה
-service.gui.avatar.imagepicker.WEBCAM_ERROR=שגי×ת מצלמת רשת
service.gui.security.encryption.required=נדרשת הצפנה!
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
# systray
@@ -550,9 +518,7 @@ impl.gui.main.account.DUMMY_PROTOCOL_DESCRIPTION=בחר רשת עבודה
# LDAP
impl.ldap.CONFIG_FORM_TITLE=תצורת LDAP
impl.ldap.GENERAL=כללי
-impl.ldap.NEW=חדש
impl.ldap.EDIT=ערוך
-impl.ldap.REMOVE=הסר
impl.ldap.ENABLED=מ×ופשרת
impl.ldap.SERVER_NAME=×©× ×©×¨×ª
impl.ldap.SERVER_NAME_EXAMPLE=שרת LDAP
@@ -568,6 +534,10 @@ impl.ldap.MAILSUFFIX_FIELD_EXAMPLE=â€â€Ž@domain.org (×œ× ×œ×©×›×•×— להוסי
impl.ldap.PHONE_PREFIX=קידומת טלפון
impl.ldap.PHONE_PREFIX_EXAMPLE=דוגמ×: 00
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=ספר כתובות
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=×פשר חיפוש ספר ×˜×œ×¤×•× ×™× MacOSX
@@ -576,9 +546,7 @@ plugin.addrbook.PREFIX_EXAMPLE=דוגמ×: 00
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=×נשי קשר של Google
-impl.googlecontacts.NEW=חדש
impl.googlecontacts.EDIT=ערוך
-impl.googlecontacts.REMOVE=הסר
impl.googlecontacts.ENABLED=מ×ופשרת
impl.googlecontacts.ACCOUNT_NAME=×©× ×—×©×‘×•×Ÿ
impl.googlecontacts.SAVE=שמור
@@ -601,9 +569,6 @@ plugin.accountinfo.GENDER=מין:
plugin.accountinfo.COUNTRY=×רץ
plugin.accountinfo.EMAIL=דו×״ל:
plugin.accountinfo.PHONE=טלפון:
-plugin.accountinfo.USER_PICTURES=תמונת משתמש
-plugin.accountinfo.CHANGE=שנה
-plugin.accountinfo.ONLY_MESSAGE=הודעות בלבד
# connection info
@@ -619,34 +584,16 @@ plugin.aimaccregwizz.PROTOCOL_DESCRIPTION=פרוטוקול השירות AIM
plugin.aimaccregwizz.USERNAME=×©× ×ª×¦×•×’×” AIM:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=×©× ×ª×¦×•×’×” וסיסמה
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=×¨×™×©×•× ×—×©×‘×•×Ÿ חדש
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=עקוף הגדרות שרת משתמטות
# branding
plugin.branding.ABOUT_WINDOW_TITLE=×ודות {0}
plugin.branding.ABOUT_MENU_ENTRY=&×ודות
-# Dict protocol
-service.protocol.DICTIONARIES=מילוני×
-plugin.dictaccregwizz.ANY_DICTIONARY=הוסף מילון
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=הוסף מילון מן {0}
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=פרוטוקול השירות Dict
-plugin.dictaccregwizz.HOST=מ×רח
-plugin.dictaccregwizz.SERVER_INFO=מידע שרת
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=מידע חשבון Dict
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=הפרוטוקול Facebook Chat
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=×©× ×ž×©×ª×ž×©:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=×©× ×ž×©×ª×ž×© וסיסמה
# generalconfig
plugin.generalconfig.SHOW_HISTORY=הצג
plugin.generalconfig.HISTORY_SIZE=הודעות חדשות בשיחה חדשה
plugin.generalconfig.SEND_MESSAGES_WITH=שלח הודעות ×¢×:
-plugin.generalconfig.TRANSPARENCY=שקיפות
-plugin.generalconfig.ENABLE_TRANSPARENCY=×פשר שקיפות
plugin.generalconfig.DEFAULT_LANGUAGE=שפת ממשק
plugin.generalconfig.SIP_CLIENT_PORT=פורט לקוח SIP
plugin.generalconfig.SIP_CLIENT_SECURE_PORT=פורט לקוח SIP מ×ובטח
@@ -680,11 +627,9 @@ plugin.ircaccregwizz.HOST=×©× ×ž×רח:
plugin.ircaccregwizz.IRC_SERVER=שרת
# jabber accregwizz
-plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=הפרוטוקול XMPP
plugin.jabberaccregwizz.USERNAME=×©× ×ž×©×ª×ž×© XMPP
plugin.jabberaccregwizz.PASSWORD_CONFIRM=×מת סיסמה
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=מזהה וסיסמה
plugin.jabberaccregwizz.CSERVER=שרת
plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=×פשר keep alive
plugin.jabberaccregwizz.NEW_ACCOUNT_TITLE=×¨×™×©×•× ×—×©×‘×•×Ÿ חדש XMPP
@@ -695,13 +640,9 @@ plugin.jabberaccregwizz.SERVER_COLUMN=שרת
plugin.jabberaccregwizz.RESOURCE=מש×ב
plugin.jabberaccregwizz.AUTORESOURCE=חולל מש×ב ×וטומטית
plugin.jabberaccregwizz.PRIORITY=עדיפות
-plugin.jabberaccregwizz.XMPP_ERROR=שגי×ת XMPP
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=שגי×ת XMPP ×œ× ×ž×•×›×¨×ª. ×•×“× ×©×©× ×”×©×¨×ª מדויק.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=סיסמתך ×œ× ×ª×מה.
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=עקוף הגדרות שרת משתמטות
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=×פשרויות מתקדמות
plugin.jabberaccregwizz.USE_ICE=השתמש ב־ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=נצל Google's Jingle/ICE (ניסיוני)
plugin.jabberaccregwizz.TURN_USERNAME=×©× ×ž×©×ª×ž×© TURN
plugin.jabberaccregwizz.IP_ADDRESS=כתובת IP
plugin.jabberaccregwizz.ADD_STUN_SERVER=הוסף שרת STUN
@@ -717,9 +658,6 @@ plugin.jabberaccregwizz.USE_UPNP=השתמש ב־UPnP
plugin.jabberaccregwizz.EXISTING_ACCOUNT=חשבון XMPP קיי×
plugin.jabberaccregwizz.SERVER_OPTIONS=×פשרויות שרת
plugin.jabberaccregwizz.CHANGE_PASSWORD=שנה סיסמת חשבון
-plugin.jabberaccregwizz.NEW_PASSWORD=סיסמה חדשה
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=×מת סיסמה חדשה
-plugin.jabberaccregwizz.PASSWORD_EMPTY=הסיסמה ריקה.
plugin.jabberaccregwizz.PASSWORD_CHANGED=הסיסמה שונתה בהצלחה
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=שרת jabber ×–×” ×œ× ×ª×•×ž×š בשינוי סיסמה.
plugin.jabberaccregwizz.PASSWORD_NOT_STORED=הסיסמה שונתה בתוך השרת, ×ך תצורה מקומית ×œ× ×¢×•×“×›× ×”
@@ -731,23 +669,9 @@ plugin.jabberaccregwizz.VIDEO=ויד×ו
plugin.jabberaccregwizz.RESET=×יפוס
plugin.jabberaccregwizz.RESET_DESCRIPTION=×פס ×ל ההגדרות הגלובליות
-# mailbox
-plugin.mailbox.OUTGOING=הודעות יוצ×ות:
-plugin.mailbox.INCOMING=הודעות נכנסות:
-plugin.mailbox.CONFIRM=×מת
-plugin.mailbox.DEFAULTS=ברירות מחדל
-plugin.mailbox.MAILBOX=תיבת דו×ר
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=פרוטוקול להתחברות ולשיחה בשירות MSN.
-plugin.msnaccregwizz.USERNAME=דו×״ל:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=מזהה וסיסמה
-
# plugin manager
plugin.pluginmanager.INSTALL=התקנה
plugin.pluginmanager.UNINSTALL=הסרה
-plugin.pluginmanager.UPDATE=עדכון
plugin.pluginmanager.PLUGINS=תוספות
plugin.pluginmanager.URL=Url
plugin.pluginmanager.CHOOSE_FILE=בחר קובץ
@@ -767,7 +691,6 @@ plugin.sipaccregwizz.REGISTRAR=רש×
plugin.sipaccregwizz.SERVER_PORT=פורט שרת
plugin.sipaccregwizz.PROXY_PORT=פורט Proxy
plugin.sipaccregwizz.PREFERRED_TRANSPORT=מוביל מועדף
-plugin.sipaccregwizz.ADVANCED_OPTIONS=×פשרויות מתקדמות
plugin.sipaccregwizz.PROXY_OPTIONS=×פשרויות Proxy
plugin.sipaccregwizz.PROXY_AUTO=הגדר Proxy ×וטומטית
plugin.sipaccregwizz.KEEP_ALIVE_METHOD=שיטת Keep alive
@@ -776,7 +699,6 @@ plugin.sipaccregwizz.KEEP_ALIVE_INTERVAL_INFO=בין 1 לבין 3600 שניות
plugin.sipaccregwizz.DTMF_METHOD=שיטת טזמ״ת (DTMF)
plugin.sipaccregwizz.DTMF_RTP=RTP ( RFC2833 / RFC 4733 )
plugin.sipaccregwizz.DTMF_SIP_INFO=מידע SIP
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=עקוף הגדרות שרת משתמטות
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=×פשר תמיכה להצפנת קרי×ות
plugin.sipaccregwizz.AUTH_NAME=×©× ×”×¨×©××”
plugin.sipaccregwizz.DISPLAY_NAME=×©× ×¦×’
@@ -792,6 +714,7 @@ plugin.sipaccregwizz.XCAP_SERVER_URI=â€URI/כתובת שרת
plugin.sipaccregwizz.VOICEMAIL=דו×ר קולי
plugin.sipaccregwizz.NOT_SAME_PASSWORD=הסיסמה שלך ×œ× ×ª×•×מת.
plugin.sipaccregwizz.SAVP_OPTION=התוויית RTP/SAVP
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=כבוי (התווה על RTP/AVP בלבד)
plugin.sipaccregwizz.SAVP_OPTION_1=מחייב (הצע וקבל רק RTP/SAVP)
plugin.sipaccregwizz.SAVP_OPTION_2=רשות (הצע RTP/SAVP ר×שית, ×חרי כן RTP/AVP)
@@ -805,15 +728,6 @@ plugin.skinmanager.DEFAULT_SKIN=סקין משתמט
plugin.skinmanager.ADD_NEW_SKIN=הוסף סקין חדש...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=הסקין משתמט של היישו×.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=פרוטוקול להתחברות ×ל מכונות מרוחקות על פני SSH.
-plugin.sshaccregwizz.USERNAME=מזהה חשבון:
-plugin.sshaccregwizz.IDENTITY_FILE=קובץ זהות:
-plugin.sshaccregwizz.KNOWN_HOSTS=מ××¨×—×™× ×ž×•×›×¨×™×:
-plugin.sshaccregwizz.OPTIONAL=רשות
-plugin.sshaccregwizz.ACCOUNT_DETAILS=פרטי חשבון
-
# status update
plugin.autoaway.ENABLE_CHANGE_STATUS=שנה מצב בזמן נעדרות
@@ -841,22 +755,6 @@ plugin.whiteboard.THICKNESS=עובי:
plugin.whiteboard.DELETE=מחק
plugin.whiteboard.PROPERTIES=מ×פייני×
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=פרוטוקול להתחברות ולשיחה בשירות Yahoo‪!‬.
-plugin.yahooaccregwizz.USERNAME=×©× ×ž×©×ª×ž×©:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=מזהה וסיסמה
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=פרוטוקול השירות Zeroconf (‫Bonjour)
-plugin.zeroaccregwizz.FIRST_NAME=×©× ×¤×¨×˜×™:
-plugin.zeroaccregwizz.LAST_NAME=×©× ×ž×©×¤×—×”:
-plugin.zeroaccregwizz.EMAIL=דו×״ל:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=לזכור ×נשי קשר Bonjour?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=מזהה וסיסמה
-plugin.zeroaccregwizz.USERID=מזהה משתמש
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=הפרוטוקול Google Talk
@@ -869,21 +767,16 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=â€iptel.org, פורטל טלקומ×
plugin.iptelaccregwizz.USERNAME=×©× ×ž×©×ª×ž×©
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=הרשמה ×ל iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=â€VoIP ושיחה
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=×©× ×ž×©×ª×ž×©
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=הקלד מחדש סיסמה
plugin.sip2sipaccregwizz.EMAIL=כתובת דו×״ל
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=חשבון sip2sip.info קיי×
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=צור חשבון sip2sip.info חינמי
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.EXISTING_ACCOUNT=חשבון ippi קיי×
plugin.ippiaccregwizz.CREATE_ACCOUNT=צור חשבון ippi חינמי
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=סגור חלון שיחה
plugin.keybindings.CHAT_COPY=העתק
plugin.keybindings.CHAT_CUT=גזור
@@ -904,6 +797,7 @@ plugin.keybindings.globalchooser.SHOW_CONTACTLIST=הצג רשימת קשרי×
plugin.keybindings.globalchooser.SHORTCUT_NAME=ש×
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=קיצור דרך עיקרי
plugin.keybindings.globalchooser.SHORTCUT_SECOND=קיצור דרך שני
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=שיחה
plugin.keybindings.MAIN=ר×שי
plugin.keybindings.GLOBAL=קיצורי דרך גלובליי×
@@ -918,6 +812,7 @@ plugin.notificationconfig.PROGRAM_FILE=קובץ תוכנית:
plugin.notificationconfig.BROWSE_SOUND=בחר קובץ צליל
plugin.notificationconfig.BROWSE_PROGRAM=בחר תוכנית
plugin.notificationconfig.tableheader.DESCRIPTION=תי×ור של ×ירוע
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=קרי××” נכנסת
plugin.notificationconfig.event.SecurityMessage=הודעת ×בטחה
plugin.notificationconfig.event.IncomingFile=קובץ נכנס
@@ -986,6 +881,7 @@ impl.neomedia.configform.AUDIO=שמע
impl.neomedia.configform.VIDEO=ויד×ו
impl.neomedia.configform.H264=H.264
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.main=ר×שי
impl.neomedia.configform.H264.preferredKeyFrameRequester.rtcp=RTCP
@@ -1006,7 +902,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=סיסמה נוכחית:
plugin.securityconfig.masterpassword.ENTER_PASSWORD=הזן סיסמה חדשה:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=הזן סיסמה שוב:
plugin.securityconfig.masterpassword.MP_TITLE=סיסמה ר×שית
-plugin.securityconfig.masterpassword.MP_NOT_SET=(×œ× × ×§×‘×¢)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=×œ× ×‘×–× ×ª ×ת הסיסמה הר×שית המדויקצ. × × ×œ× ×¡×•×ª שוב.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=סיסמה ר×שית ××™× ×” מדויקת!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=שינוי סיסמה נכשל
@@ -1021,7 +916,6 @@ plugin.securityconfig.masterpassword.COL_PASSWORD=סיסמה
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(×œ× ×™×“×•×¢)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(×œ× × ×™×ª×Ÿ לפענח)
plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=סיסמ×ות מ×וחסנות
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=הסר
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=הסר הכל
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=×”×× ×תה בטוח ×›×™ ברצונך להסיר ×ת כל הסיסמ×ות?
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=הסר ×ת כל הסיסמ×ות
@@ -1106,7 +1000,6 @@ plugin.provisioning.RESTART_WARNING=×©×™× ×œ×‘ ×©×”×©×™× ×•×™×™× ×©×œ×š ×™×›× 
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=העתק UUID ×ל לוח גזירה
plugin.provisioning.CLIPBOARD_FAILED=כשל בהעתקת UUID ×ל לוח גזירה
-plugin.provisioning.EXIT_ON_FAIL=×¦× ×ž×”×™×™×©×•× ×‘×ž×™×“×” וה×ספקה נכשלת
plugin.provisioning.CREDENTIALS=נתוני התחברות של ×ספקה ש×וחסנו ל×חרונה
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=×”×× ×תה בטוח ×›×™ ברצונך להסיר סיסמת ×ספקה?
plugin.provisioning.PROV_FAILED=×ספקה נכשלה
@@ -1141,8 +1034,6 @@ net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult
#plugin spellcheck
plugin.spellcheck.TITLE=×יות ודקדוק
plugin.spellcheck.MENU=הצג ×יות ודקדוק
-plugin.spellcheck.LANG=שפה
-plugin.spellcheck.EDIT_PERSONAL_DICT=ערוך
plugin.spellcheck.ENABLE_SPELL_CHECK=×פשר בדיקת ×יות
plugin.spellcheck.dialog.FIND=×ž×¦× ×ת הב×
plugin.spellcheck.dialog.REPLACE=החלף
diff --git a/resources/languages/resources_hi.properties b/resources/languages/resources_hi.properties
index 37df92d..1089715 100644
--- a/resources/languages/resources_hi.properties
+++ b/resources/languages/resources_hi.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -25,13 +36,27 @@
# from your system's language, pass the language code to ant:
# ant -Duser.language=xx run
+service.gui.ABOUT=बारे में
+service.gui.ACCEPT=सà¥à¤µà¥€à¤•à¤¾à¤°à¥‡à¤‚ (&A)
service.gui.ACCOUNT=खाता
+service.gui.ACCOUNT_ME=मैं
service.gui.ACCOUNT_REGISTRATION_WIZARD=खाता पंजीकरण
service.gui.ACCOUNTS=खाता
-service.gui.ADD_ACCOUNT=खाता जोड़ो
+service.gui.ADD=जोड़ें
+service.gui.ADD_CONTACT=संपरà¥à¤• जोड़ें
+service.gui.ADD_AUTHORIZED_CONTACT=अपनी समà¥à¤ªà¤°à¥à¤• सूची में जोड़ें
+service.gui.ADD_CONTACT_TO_CONTACTLIST=इस समà¥à¤ªà¤°à¥à¤• को मेरी समà¥à¤ªà¤°à¥à¤• सूची में जोड़ें
+service.gui.ADD_CONTACT_ERROR=आईडी के साथ संपरà¥à¤• जोड़ने में विफल: {0}
service.gui.ADD_CONTACT_ERROR_TITLE=संपरà¥à¤• जोड़ने में तà¥à¤°à¥à¤Ÿà¤¿
-service.gui.ADD_GROUP=समूह बनाये
+service.gui.ADD_CONTACT_EXIST_ERROR=संपरà¥à¤• {0} पहले से ही आपकी संपरà¥à¤• सूची में मौजूद है।
+service.gui.ADD_GROUP_ERROR=नाम के साथ समूह जोड़ने में विफल: {0}।
+service.gui.ADD_GROUP_EMPTY_NAME=समूह का नाम खाली नहीं होना चाहिà¤à¥¤
+service.gui.ADDRESS=पता
service.gui.ADMINISTRATOR=पà¥à¤°à¤¶à¤¾à¤¸à¤•
+service.gui.ADVANCED=विसà¥à¤¤à¥ƒà¤¤
+service.gui.ALL_CONTACTS=सभी संपरà¥à¤•à¥‹à¤‚
+service.gui.ALTERNATE_ADDRESS=वैकलà¥à¤ªà¤¿à¤• पता
+service.gui.APPLY=लागू करें
service.gui.ARE_NOW=आप अभी
service.gui.AWAY_STATUS=दूर
service.gui.BROWSE=ढूंढना
@@ -42,27 +67,30 @@ service.gui.CHANGE_NICK=उपनाम परिवरà¥à¤¤à¤¨
service.gui.CHANGE_NICKNAME=उपनाम परिवरà¥à¤¤à¤¨
service.gui.ROOM_NAME=गपशप के कमरे
service.gui.CHAT_ROOMS=गपशप के कमरे
+service.gui.CHAT_ROOM=गपशप के कमरे
service.gui.CONTACTS=संपरà¥à¤•
service.gui.CREATE_GROUP=समूह बनाये
-service.gui.DATE=तिथि
service.gui.DELETE=मिटाà¤à¤
service.gui.DO_NOT_ASK_AGAIN=फिर ना पूछें
service.gui.DURATION=अवधि
+service.gui.chat.role.ADMINISTRATOR=पà¥à¤°à¤¶à¤¾à¤¸à¤•
+
+#enum values from IceProcessingState
+#service.gui.CERT_INFO_ are combined from Rdn names
+
+
# keep the following string short
# service.gui.avatar.imagepicker
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
# systray
@@ -71,6 +99,10 @@ service.gui.DURATION=अवधि
# LDAP
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
# Google Contacts
@@ -85,9 +117,6 @@ service.gui.DURATION=अवधि
# branding
-# Dict protocol
-
-# facebookaccregwizz
# generalconfig
@@ -99,20 +128,15 @@ service.gui.DURATION=अवधि
# jabber accregwizz
-# mailbox
-
-# msn accregwizz
-
# plugin manager
# simple accregwizz
# sipaccregwizz
+#used from SecurityPanel
# skin manager
-# ssh accregwizz
-
# status update
# updatechecker
@@ -122,22 +146,19 @@ service.gui.DURATION=अवधि
# whiteboard
plugin.whiteboard.DELETE=मिटाà¤à¤
-# yahoo accregwizz
-
-# zero accregwizz
-
# gtalk accregwizz
# iptel accregwizz
-# sip2sip accregwizz
-
# ippi accregwizz
# key binding chooser
+#in new ChatWindow() -> manipulated
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=गपशप
# Notification Configuration Form
+#NotificationsTable constants
# ZRTP Securing
@@ -150,6 +171,7 @@ impl.media.security.zrtp.TITLE=कॉल
+#in JNIEncoder
# The callrecordingconfig plugin was never really committed into trunk and its
# ConfigurationForm was actually put in the neomedia bundle.
diff --git a/resources/languages/resources_hr.properties b/resources/languages/resources_hr.properties
index 2ac99d9..5640f9f 100644
--- a/resources/languages/resources_hr.properties
+++ b/resources/languages/resources_hr.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Ja
service.gui.ACCOUNT_REGISTRATION_WIZARD=ÄŒarobnjak za registraciju kontakta
service.gui.ACCOUNTS=RaÄuni
service.gui.ADD=&Dodaj
-service.gui.ADD_ACCOUNT=Dodaj raÄun
service.gui.ADD_CONTACT=&Dodaj kontakt
service.gui.ADD_AUTHORIZED_CONTACT=Dodaj {0} u svoju listu kontakata
service.gui.ADD_CONTACT_TO=&Dodaj kontakt u
@@ -41,20 +51,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Dodaj kontakt greška
service.gui.ADD_CONTACT_EXIST_ERROR=Kontakt {0} se već nalazi u listi kontakata
service.gui.ADD_CONTACT_NETWORK_ERROR=Poslužitelj nije odgovorio na zahtjev za dodavanjem kontakta sa idenfikatorom: {0}.
service.gui.ADD_CONTACT_NOT_SUPPORTED=Greška pri dodavanju kontakta sa identifikatorom: {0}. Operacija nije podržana.
-service.gui.ADD_CONTACT_IDENTIFIER=U niže navedeno polje unesite identifikator kontakta kojeg želite dodati.
-service.gui.ADD_CONTACT_WIZARD=ÄŒarobnjak za dodavanje kontakata
service.gui.ADD_CONTACT_NOT_CONNECTED=Morate biti spojeni da biste mogli dodati kontakt. Molimo prijavite se na odabranog davatelja i pokušajte ponovo.
service.gui.ADD_GROUP_LOCAL_ERROR=Greška prilikom dodavanja grupe sa imenom: {0}. Problem se javio tijekom lokalne IO operacije.
service.gui.ADD_GROUP_EXIST_ERROR=Grupa {0} već postoji u vašem popisu kontakata. Molimo odaberite drugo ime.
service.gui.ADD_GROUP_NET_ERROR=Greška prilikom dodavanja grupa sa imenom: {0}. Problem se javio zbog pada mreže. Provjerite svoje mrežne veze i pokušajte ponovo.
service.gui.ADD_GROUP_ERROR=Greška prilikom dodavanja grupe sa imenom: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=Ime grupe ne smije biti prazno.
-service.gui.ADD_GROUP=Kreiraj grupu
-service.gui.ADD_SUBCONTACT=&Dodaj podkontakt
service.gui.ADDRESS=Adresa
service.gui.ADMINISTRATOR=administrator
service.gui.ADVANCED=&Napredno
-service.gui.ALL=&Sve
service.gui.ALL_CONTACTS=&Svi kontakti
service.gui.ALTERNATE_ADDRESS=Druga adresa
service.gui.APPLY=&Primijeni
@@ -64,7 +69,6 @@ service.gui.AT=na
service.gui.AUTHORIZE=&Odobri
service.gui.AUTHORIZATION_ACCEPTED={0} je prihvatio vaš zahtjev za autorizaciju.
service.gui.AUTHENTICATION_FAILED=Autentikacija nije uspjela za {0}. Unešena lozinka nije ispravna.
-service.gui.AUTHENTICATION_REQUESTED=Zatražena autentikacija
service.gui.AUTHENTICATION_REJECTED={0} je odbio zahtjev za autorizaciju.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} provjera autentiÄnosti
service.gui.AUTHORIZATION_REQUESTED=Zahtjev za autorizaciju
@@ -96,23 +100,18 @@ service.gui.CHANGE_NICKNAME_LABEL=Možete unijeti nadimak u polje ispod.
service.gui.CHANGE_NICKNAME_ERROR=Greška pri promjeni nadimka
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Nadimak već postoji
service.gui.CHANGE_VIDEO_QUALITY=Promijeni kvalitet prikaza udaljenog videa.
-service.gui.CHAT_CONFERENCE_LABEL=Konferencije
service.gui.CHAT_CONFERENCE_ITEM_LABEL={0} konferencija
service.gui.CHAT_ROOM_ALREADY_JOINED=Soba {0} je već ukljuÄena.
service.gui.CHAT_ROOM_CONFIGURATION=Konfiguracija sobe {0}
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=Slanje poruka je zabranjeno (glasovno opozvano)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Spremi sobu za buduću uporabu
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=BriÅ¡e oznaÄenu sobu iz popisa spremljenih soba
service.gui.CHAT_ROOM_NAME=Ime sobe
service.gui.CLEAR_CUSTOM_MESSAGES=ObriÅ¡i korisniÄki definirane poruke
service.gui.ROOM_NAME=Soba za razgovor
-service.gui.AUTOJOIN=Automatsko pridruživanje
service.gui.CHANGE_PASSWORD=Promijeni lozinku
service.gui.CHAT_ROOM_NAME_INFO=Unesite ime sobe za razgovor koju želite kreirati u polje ispod.
service.gui.CHAT_ROOM_NOT_EXIST=Na poslužitelju {1} ne postoji soba {0}. Provjerite jeste li upisali ispravno ime.
service.gui.CHAT_ROOM_NOT_CONNECTED=Morate biti spojeni da biste se pridružili sobi {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Morate biti spojeni da biste mogli izaći iz sobe.
-service.gui.CHAT_ROOM_NOT_JOINED=Morate biti prijavljeni u sobi da biste radili dodatne operacije u njoj.
service.gui.CHAT_ROOM_OPTIONS=Opcije sobe za razgovor
service.gui.CHAT_ROOM=Soba za razgovor
service.gui.CHAT_ROOM_SUBJECT_CHANGED={0} je promijenio temu u {1}
@@ -124,20 +123,16 @@ service.gui.CITY=Grad
service.gui.COUNTRY=Zemlja
service.gui.SHOW_MORE_TOOLTIP=Kliki za prikaz više rezultata
service.gui.CONNECTION=Veza
-service.gui.CONNECTION_FAILED_MSG=Za sljedeći raÄun veza nije uspjela: KorisniÄko ime: {0}, Poslužitelj: {1}. Provjerite mrežne veze ili kontaktirajte mrežnog administratora za viÅ¡e informacija.
service.gui.CONNECTION_EXPIRED_MSG=Trenutno ste iskljuÄeni sa poslužitelja {0}.
service.gui.CONTACT_NAME=ID ili Broj
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Odabrani kontakt {0} ne podržava telefoniranje.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Odabrani kontakt {0} ne podržava konferenciju.
service.gui.CONTACT_PAUSED_TYPING={0} je prestao pisati
service.gui.CONTACT_TYPING={0} piše poruku
service.gui.CONTACT_TYPING_SEND_FAILED=uh... nismo mogli obavijestiti {0} da ste pisali
service.gui.CREATE_CHAT_ROOM_WIZARD=ÄŒarobnjak za kreiranje soba za razgovor
service.gui.CREATE_CONFERENCE_CALL=&Kreiraj konferencijski poziv
-service.gui.CREATE_CONFERENCE_CHAT=&Kreiraj konferenciju
service.gui.CREATE_GROUP=&Kreiraj grupu...
service.gui.CREATE_GROUP_NAME=Unesite ime grupe koju želite kreirati u polje ispod
-service.gui.CREATE_FIRST_GROUP_WIZARD=Vaš popis kontakata ne sadrži niti jednu grupu. Prvo kreirajte grupu (Datoteka/Kreiraj grupu).
service.gui.CREATE_VIDEO_BRIDGE=Kreiraj &video most...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Kreiraj &video most
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Kreiraj / prikljuÄi se video konferenciji
@@ -145,7 +140,6 @@ service.gui.DISCONNECTED_STATUS=IskljuÄen
service.gui.DND_STATUS=Ne smetaj
service.gui.DO_NOT_ASK_AGAIN=Ne pitaj ponovno
service.gui.DO_NOT_SHOW_AGAIN=Ne prikazuj više ovu poruku
-service.gui.DOWNLOAD_NOW=&Preuzmi sada
service.gui.DRAG_FOR_SHARING=Povucite ovdje sve što želite dijeliti...
service.gui.DURATION=trajanje
service.gui.DESTROY_CHATROOM=Izbriši sobu za razgovor
@@ -157,7 +151,6 @@ service.gui.ERROR_RECEIVED_FROM=Greška primljena od {0}
service.gui.ESTIMATED_TIME=OÄekivano vrijeme:
service.gui.EVENTS=Događaji
service.gui.EXIT=I&zlaz
-service.gui.EXTENDED_CRITERIA=Proširi uvjet
service.gui.GENERAL=Općenito
service.gui.FILE_RECEIVE_FAILED=Greška prilikom prebacivanja datoteke od {0}.
service.gui.FILE_SENDING_TO=Å aljem datoteku prema {0}.
@@ -189,7 +182,6 @@ service.gui.HISTORY=&Povijest
service.gui.HISTORY_REMOVE_ERROR=Greška prilikom brisanja lokalno spremljenih poruka.
service.gui.HOME=PoÄetak
service.gui.HOME_PAGE=PoÄetna stranica
-service.gui.HOUR=Sat
service.gui.IDENTIFIER=Identifikator
service.gui.IGNORE=&Zanemari
service.gui.INSERT_SMILEY=Ubaci smješka
@@ -205,6 +197,11 @@ service.gui.IS_NOW={0} je sada {1}
+#enum values from IceProcessingState
+
+
+
+#service.gui.CERT_INFO_ are combined from Rdn names
# keep the following string short
@@ -213,9 +210,6 @@ service.gui.IS_NOW={0} je sada {1}
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
# systray
@@ -224,6 +218,10 @@ service.gui.IS_NOW={0} je sada {1}
# LDAP
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
# Google Contacts
@@ -238,9 +236,6 @@ service.gui.IS_NOW={0} je sada {1}
# branding
-# Dict protocol
-
-# facebookaccregwizz
# generalconfig
@@ -252,20 +247,15 @@ service.gui.IS_NOW={0} je sada {1}
# jabber accregwizz
-# mailbox
-
-# msn accregwizz
-
# plugin manager
# simple accregwizz
# sipaccregwizz
+#used from SecurityPanel
# skin manager
-# ssh accregwizz
-
# status update
# updatechecker
@@ -274,21 +264,18 @@ service.gui.IS_NOW={0} je sada {1}
# whiteboard
-# yahoo accregwizz
-
-# zero accregwizz
-
# gtalk accregwizz
# iptel accregwizz
-# sip2sip accregwizz
-
# ippi accregwizz
# key binding chooser
+#in new ChatWindow() -> manipulated
+#Enum KeybindingSet.Category
# Notification Configuration Form
+#NotificationsTable constants
# ZRTP Securing
@@ -300,6 +287,7 @@ service.gui.IS_NOW={0} je sada {1}
+#in JNIEncoder
# The callrecordingconfig plugin was never really committed into trunk and its
# ConfigurationForm was actually put in the neomedia bundle.
diff --git a/resources/languages/resources_hu.properties b/resources/languages/resources_hu.properties
index 47ac7ba..f7bfa1f 100644
--- a/resources/languages/resources_hu.properties
+++ b/resources/languages/resources_hu.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -25,60 +36,54 @@
# from your system's language, pass the language code to ant:
# ant -Duser.language=xx run
-service.gui.ABOUT=Névjegy
-service.gui.ACCEPT=Elfogad
+service.gui.ABOUT=&Névjegy
+service.gui.ACCEPT=&Elfogadás
service.gui.ACCOUNT=Felhasználói fiók
service.gui.ACCOUNT_ME=Én
service.gui.ACCOUNT_REGISTRATION_WIZARD=Fiók regisztrációs varázsló
service.gui.ACCOUNTS=Felhasználói fiókok
-service.gui.ADD=Hozzáad
-service.gui.ADD_ACCOUNT=Fiók hozzáadása
-service.gui.ADD_CONTACT=Partner felvétele
+service.gui.ADD=&Hozzáadás
+service.gui.ADD_CONTACT=&Partner felvétele
service.gui.ADD_AUTHORIZED_CONTACT={0} felvétele a partnerlistára
service.gui.ADD_CONTACT_TO_CONTACTLIST=A partner felvétele a partnerlistára
service.gui.ADD_CONTACT_TO=Partner felvétele ehhez
service.gui.ADD_CONTACT_ERROR={0} partner felvétele nem sikerült
service.gui.ADD_CONTACT_ERROR_TITLE=Hiba a partner felvételekor
-service.gui.ADD_CONTACT_EXIST_ERROR={0} már szerepel partnerként a partnerlistában
+service.gui.ADD_CONTACT_EXIST_ERROR={0} már szerepel partnerlistában
service.gui.ADD_CONTACT_NETWORK_ERROR=A szerver nem válaszolt {0} partnerfelvételi kérelmünkre
service.gui.ADD_CONTACT_NOT_SUPPORTED={0} partner felvétele nem sikerült. Ez a művelet nem támogatott.
-service.gui.ADD_CONTACT_IDENTIFIER=Ebbe a mezőbe írd be annak a partnernek az azonosítóját, akit fel szeretnél venni.
-service.gui.ADD_CONTACT_WIZARD=Partner felvételi varázsló
service.gui.ADD_CONTACT_NOT_CONNECTED=Partner felvételéhez kapcsolódva kell lenned. Jelentkezz be a kiválasztott szolgáltatóhoz, és próbáld újra.
service.gui.ADD_GROUP_LOCAL_ERROR=A {0} csoport létrehozása nem sikerült. A probléma egy helyi IO művelet közben történt.
service.gui.ADD_GROUP_EXIST_ERROR=A {0} csoport már szerepel a partnerlistában. Válassz egy másik nevet.
service.gui.ADD_GROUP_NET_ERROR=A {0} csoport létrehozása nem sikerült. A problémát hálózati hiba okozta. Ellenőrizd a hálózati kapcsolatod, és próbáld újra.
service.gui.ADD_GROUP_ERROR=A {0} csoport létrehozása nem sikerült.
service.gui.ADD_GROUP_EMPTY_NAME=A csoport neve nem lehet üres.
-service.gui.ADD_GROUP=Csoport létrehozása
-service.gui.ADD_SUBCONTACT=Alpartner felvétele
service.gui.ADDRESS=Cím
service.gui.ADMINISTRATOR=rendszergazda
-service.gui.ADVANCED=Speciális
-service.gui.ALL=Mind
-service.gui.ALL_CONTACTS=Minden partner
+service.gui.ADVANCED=&Speciális
+service.gui.ALL_CONTACTS=&Minden partner
service.gui.ALTERNATE_ADDRESS=Alternatív cím
-service.gui.APPLY=Alkalmaz
+service.gui.APPLY=&Alkalmaz
service.gui.ARE_CALLING={0} hív...
service.gui.ARE_NOW=Te most {0} vagy
-service.gui.AUTHORIZE=Engedélyez
+service.gui.AT=itt:
+service.gui.AUTHORIZE=&Engedélyezés
service.gui.AUTHORIZATION_ACCEPTED={0} elfogadta az engedélyezési kérésed.
service.gui.AUTHENTICATION_FAILED={0} hitelesítése nem sikerült. A beírt jelszó nem jó.
-service.gui.AUTHENTICATION_REQUESTED=Hitelesítés folyamatban
service.gui.AUTHENTICATION_REQUESTED_SERVER=A {0} szerver kéri, hogy hitelesítsd magad.
service.gui.AUTHENTICATION_REJECTED={0} elutasította az engedélyezési kérésed.
-service.gui.AUTHENTICATION_WINDOW_TITLE={0} engedélyezés
+service.gui.AUTHENTICATION_WINDOW_TITLE={0} hitelesítés
service.gui.AUTHORIZATION_REQUESTED=Engedélyezés folyamatban
-service.gui.AUTHORIZATION_REQUESTED_INFO={0} partner kéri az engedélyezésedet.
+service.gui.AUTHORIZATION_REQUESTED_INFO={0} partner kéri az engedélyezésed.
service.gui.AUTHORIZATION_RESPONSE=Válasz az engedélyezésre
service.gui.AWAY_STATUS=Nincs a gépnél
-service.gui.EXTENDED_AWAY_STATUS=Hosszabb ideje nincs a gépnél
-service.gui.BAN=Letilt
-service.gui.BANNED=letiltva
-service.gui.BAN_FAILED=Letiltás nem sikerült
-service.gui.BAN_FAILED_GENERAL_ERROR={0} letiltása nem sikerült. Egy meg nem határozott szerver hiba történt.
-service.gui.BAN_FAILED_NOT_ALLOWED={0} letiltása nem sikerült. A csevegőszoba tulajdonosa és rendszergazdája nem tiltható le.
-service.gui.BAN_FAILED_NOT_ENOUGH_PERMISSIONS={0} letiltása nem sikerült. A letiltáshoz nincs elég jogosultságod.
+service.gui.EXTENDED_AWAY_STATUS=Hosszabb távollét
+service.gui.BAN=&Kitiltás
+service.gui.BANNED=kitiltva
+service.gui.BAN_FAILED=Kitiltás sikertelen
+service.gui.BAN_FAILED_GENERAL_ERROR={0} kitiltása nem sikerült. Egy meg nem határozott szerver hiba történt.
+service.gui.BAN_FAILED_NOT_ALLOWED={0} kitiltása nem sikerült. A csevegőszoba tulajdonosa és rendszergazdája nem tiltható ki.
+service.gui.BAN_FAILED_NOT_ENOUGH_PERMISSIONS={0} kitiltása nem sikerült. Nincs jogosultságod.
service.gui.BRB_MESSAGE=Most nem vagyok a gépnél, de nemsokára leszek.
service.gui.BROWSE=Böngészés
service.gui.BUSY_MESSAGE=Bocsánat, most el vagyok foglalva.
@@ -87,7 +92,7 @@ service.gui.CALL=Hívás
service.gui.CALL_CONTACT=Partner hívása
service.gui.CALL_FAILED=Sikertelen hívás
service.gui.CALL_HISTORY_TOOL_TIP=A korábbi hívások listájáért kattints ide.
-service.gui.CALL_HISTORY_GROUP_NAME=Korábbi hívások
+service.gui.CALL_HISTORY_GROUP_NAME=Hívástörténet
service.gui.CALL_VIA=Hívás ezen keresztül:
service.gui.CALL_NAME_OR_NUMBER=Név vagy szám hívása
service.gui.CALL_NOT_SUPPORTING_PARTICIPANT=Ezzel a hívással csak a {0} hálózatban lévők, és a te {1} fiókod hívható. {2} nem tartalmaz ehhez a hálózathoz, illetve fiókhoz tartozó címet.
@@ -106,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=Ebbe a mezőbe írd be az új beceneved.
service.gui.CHANGE_NICKNAME_ERROR=Hiba a becenév megváltoztatása közben
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Ez a becenév már létezik
service.gui.CHANGE_VIDEO_QUALITY=A távoli videó minőség megváltoztatása
-service.gui.CHAT_CONFERENCE_LABEL=Konferenciák
service.gui.CHAT_CONFERENCE_ITEM_LABEL={0} konferenciája
service.gui.CHAT_ROOM_ALREADY_JOINED=A(z) {0} csevegés már csatlakozott.
service.gui.CHAT_ROOM_CONFIGURATION={0} csevegés beállítása
@@ -120,18 +124,14 @@ service.gui.CHAT_ROOM_USER_LEFT=távozott {0}-ból/ből
service.gui.CHAT_ROOM_USER_KICKED=ki lett rúgva {0}-ból/ből
service.gui.CHAT_ROOM_USER_QUIT=kilépett {0}-ból/ből
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=Tilos üzenet küldeni (hang nem engedélyezett)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Elmenti a csevegést későbbi használatra
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Törli a kiválasztott csevegést az elmentett csevegések listájából.
service.gui.CHAT_ROOM_NAME=Csevegés neve
service.gui.CLEAR_CUSTOM_MESSAGES=Testreszabott üzenetek törlése
service.gui.ROOM_NAME=Csevegés
-service.gui.AUTOJOIN=Automatikus csatlakozás
service.gui.CHANGE_PASSWORD=Jelszó megváltoztatása
service.gui.CHAT_ROOM_NAME_INFO=Ebbe a mezőbe írd be a létrehozandó csevegés nevét.
service.gui.CHAT_ROOM_NOT_EXIST=A(z) {0} csevegés nem található a(z) {1} szerveren. Ellenőrizd, hogy beírt név helyes-e.
service.gui.CHAT_ROOM_NOT_CONNECTED=A(z) {0} csevegéshez való csatlakozáshoz be kell jelentkezned.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Csak bejelentkezve tudsz kilépni a csevegésből.
-service.gui.CHAT_ROOM_NOT_JOINED=A csevegéshez előbb csatlakoznod kell, hogy abban további műveleteket tudj kezdeményezni.
service.gui.CHAT_ROOM_OPTIONS=Csevegés beállítások
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=A(z) {0} csevegéshez való csatlakozáshoz regisztráció szükséges.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=A(z) {0} csevegés jelszót igényel.
@@ -139,6 +139,7 @@ service.gui.CHAT_ROOMS=Csevegések
service.gui.CHAT_ROOM=Csevegés
service.gui.CHAT_ROOM_SUBJECT_CHANGED={0} megváltoztatta a tárgyat {1}-ra/re
service.gui.CHAT_ROOM_ALTERNATE_ADDRESS=Folytathatod a beszélgetést a {0} csevegésben.
+service.gui.CHAT_NICKNAME_CHANGE={0} új neve {1}
service.gui.CHOOSE_CONTACT=Válassz partnert
service.gui.CHOOSE_NUMBER=Válassz számot
service.gui.CHOOSE_ACCOUNT=Válassz egyet a alábbi fiókok közül.
@@ -149,54 +150,199 @@ service.gui.CLEAR=Törlés
service.gui.CLOSE=Bezár
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Az utolsó üzenetet kevesebb mint 2 másodperccel ezelőtt kaptad. Biztos, hogy be akarod zárni ezt a csevegést?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=Fájlküldés folyamatban. Biztos, hogy le akarod állítani?
-service.gui.CONFIRM=Mehet
service.gui.CONNECTED_STATUS=Kapcsolódva
service.gui.CONNECTING=Kapcsolódás...
service.gui.CONNECTING_STATUS=Kapcsolódás
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Kapcsolódás*
service.gui.CONNECTION=Kapcsolat
-service.gui.CONNECTION_FAILED_MSG=Kapcsolat sikertelen a következő fiókkal: Felhasználó: {0}, szerver név: {1}. Ellenőrizd a hálózati kapcsolatod, vagy további információért lépj kapcsolatba a hálózat-karbantartóval.
service.gui.CONNECTION_EXPIRED_MSG=Jelenleg le vagy kapcsolódva a {0} szerverről.
service.gui.CONTACT_NAME=Azonosító vagy szám
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=A kiválasztott {0} partner nem képes telefonálni.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=A kiválasztott {0} partner nem képes csevegés konferenciázni.
service.gui.CONTACT_PAUSED_TYPING={0} szünetet tart az üzenet írása közben
service.gui.CONTACT_TYPING={0} üzenetet ír
service.gui.CONTACT_TYPING_SEND_FAILED=hűha... nem tudtuk megmondani {0}-nak/nek, hogy írtál
service.gui.CONTACT_INFO=Elérhetőség
-service.gui.CONTACTLIST=Partnerlista
+service.gui.CONTACTS=Partnerek
+service.gui.COPY=Másolás
+service.gui.COPY_LINK=Hivatkozás másolása
+service.gui.CREATE=Létrehoz
+servoce.gui.CREATE_CALL_FAILED=A hívás indítása sikertelen.
+service.gui.CREATE_CHAT_ROOM=Csevegés létrehozása...
service.gui.CREATE_CHAT_ROOM_ERROR={0} csevegés létrehozása sikertelen.
service.gui.CREATE_CHAT_ROOM_WIZARD=Csevegés létrehozó varázsló
service.gui.CREATE_CONFERENCE_CALL=Konferenciahívás létrehozása...
-service.gui.CREATE_CONFERENCE_CHAT=Konferencia csevegés létrehozása...
service.gui.CREATE_GROUP=Csoport létrehozása...
service.gui.CREATE_GROUP_NAME=Ebbe a mezőbe írd be a létrehozandó csoport nevét.
-service.gui.CREATE_FIRST_GROUP_WIZARD=A partnerlistád nem tartalmaz egy csoportot sem. Először hozz létre egy csoportot (Fájl -> Csoport létrehozása).
service.gui.CREATE_VIDEO_BRIDGE=Videó híd létrehozása...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Videó híd létrehozása
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Videó konferencia kezdés / csatlakozás
service.gui.CREATE_VIDEO_CONFERENCE=Új videó konferencia létrehozása ebben a csevegésben
service.gui.CONTACT_INFO_NOT_SUPPORTED=Ennek a partnernek nincs webes elérhetősége
service.gui.CUT=Kivágás
-service.gui.DATE=Dátum
service.gui.DELETE=Töröl
service.gui.DENY=Elutasít
service.gui.DESKTOP_SHARING_WARNING=<b>Biztosan meg akarod osztani a képernyődet?</b> <br> A Rendben-re kattintva a hívás minden résztvevője látni fogja a képernyődet.
-
-
-
-
+service.gui.DESKTOP_SHARING_DIALOG_INDICATE=Képernyő megosztva
+service.gui.DIALPAD=Számlap
+service.gui.DISPLAY_NAME=Képernyő név
+service.gui.DISCONNECTED_STATUS=Kapcsolat bontva
+service.gui.DND_STATUS=Ne zavarj
+service.gui.DO_NOT_ASK_AGAIN=Többször ne kérdezd
+service.gui.DO_NOT_SHOW_AGAIN=Ez az üzenet többször ne jelenjen meg.
+service.gui.DRAG_FOR_SHARING=Húzd ide bármit, amit meg akarsz osztani...
+service.gui.DURATION=időtartam
+service.gui.DESTROY_CHATROOM=Csevegés megsemmisítése
+service.gui.DESTROY_MESSAGE=Csevegés megsemmisítése
+service.gui.EDIT=Szerkeszt
+service.gui.EDITED_AT={0}-nál/nél szerkesztett
+service.gui.EMAIL=Email
+service.gui.EMAILS=Emailek
+service.gui.EMPTY_HISTORY=Előzmények törlése
+service.gui.ENABLE_DESKTOP_REMOTE_CONTROL=Munkaasztal távvezérlés engedélyezése
+service.gui.ENABLE_TYPING_NOTIFICATIONS=Jelezze másoknál, ha üzenetet írunk nekik (csevegés tevékenység küldése)
+service.gui.END_CONFERENCE=Konferencia befejezése
+service.gui.ENTER_PHONE_NUMBER=Ãrd be a telefonszámot
+service.gui.ENTER_NAME_OR_NUMBER=Ãrd be a nevet vagy a számot
+service.gui.ERROR=Hiba
+service.gui.ERROR_WAS=Hiba: {0}
+service.gui.ERROR_RECEIVED_FROM=Hibát kaptunk {0}-tól/től
+service.gui.ESTIMATED_TIME=Becsült időtartam:
+service.gui.EVENTS=Események
+service.gui.EXIT=Kilépés
+service.gui.GENERAL=Ãltalános
+service.gui.GENERAL_ERROR=Ãltalános hiba
+service.gui.GROUP_NAME=Csoport neve
+service.gui.FAILED_STATUS=Sikertelen hívás
+service.gui.FAILED_TO_JOIN_CHAT_ROOM={0} nem tudott csatlakozni a csevegéshez.
+service.gui.FAX=Fax
+service.gui.FFC_STATUS=Elérhető (csevegésre)
+service.gui.FILE=Fájl
+service.gui.FILE_WAITING_TO_ACCEPT=Várakozás {0}-ra/re, hogy elfogadja a fájlodat.
+service.gui.FILE_UNABLE_TO_SEND=Hiba a {0}-nak/nek szánt fájl küldése közben.
+service.gui.FILE_RECEIVE_FAILED=Hiba a {0}-tól/től érkező fájl fogadása közben.
+service.gui.FILE_SENDING_TO=Fájl küldése {0}- nak/nek.
+service.gui.FILE_RECEIVING_FROM=Fájl fogadása {0}-tól/től.
+service.gui.FILE_SEND_COMPLETED=A fájl küldés sikerült {0}-nak/nek.
+service.gui.FILE_RECEIVE_COMPLETED=Fájl fagadva {0}-tól/től.
+service.gui.FILE_TRANSFER_CANCELED=Fájl átvitel törölve.
+service.gui.FILE_SEND_FAILED=Fájl küldés sikertelen: {0}.
+service.gui.FILE_TOO_BIG=A fájlméret meghaladja a protokol által maximálisan engedélyezett méretet: {0}.
+service.gui.FILE_SEND_REFUSED={0} visszautasította ezt a fájlt.
+service.gui.FILE_TRANSFER_REFUSED=A fájl fogadása vissza lett visszautasítva.
+service.gui.FILE_TRANSFER_NOT_SUPPORTED=A kiválasztott partner nem támogatja a fájl átvitelt.
+service.gui.FILE_TRANSFER_PREPARING=Fájl küldés előkészítése {0}-nak/nek. Kis türelmet...
+service.gui.FILE_TRANSFER_REQUEST_RECIEVED={0} szeretne egy fájlt megosztani veled.
+service.gui.FILE_DOES_NOT_EXIST=Az adott fájl nem található. Vagy törölve lett, vagy át lett helyezve.
+service.gui.FILE_OPEN_FAILED=Nem sikerült megnyitni a fájlt. Valószínű törölve lett, vagy át lett helyezve.
+service.gui.FILE_OPEN_NOT_SUPPORTED=A fájl megnyitás funkciót ez a rendszer sajnos nem támogatja.
+service.gui.FILE_OPEN_NO_PERMISSION=Nincs elég jogosultságod ennek a fájlnak a megnyitására. Ellenőrizd az olvasási jogosultságaidat, és próbáld meg újra.
+service.gui.FILE_OPEN_NO_APPLICATION=Ehhez a fájl típushoz nem található alkalmazás.
+service.gui.FINISH=Befejez
+service.gui.FOLDER_DOES_NOT_EXIST=Az ezt a fájlt tartalmazó mappa nem található. Vagy törölve lett, vagy át lett helyezve.
+service.gui.FOLDER_OPEN_FAILED=A mappa megnyitása nem sikerült.
+service.gui.FOLDER_OPEN_NO_PERMISSION=Nincs elég jogosultságod ennek a mappának a megnyitásához. Ellenőrizd az olvasási jogosultságaidat, és próbáld meg újra.
+service.gui.FOLDER_OPEN_NO_APPLICATION=Nem találtunk olyan alkalmazást, ami meg tudná nyitni ezt a mappát.
+service.gui.FONT=Betűtípus
+service.gui.FONT_BOLD=Félkövér
+service.gui.FONT_COLOR=Szín
+service.gui.FONT_FAMILY=Család
+service.gui.FONT_ITALIC=dőlt
+service.gui.FONT_SIZE=Méret
+service.gui.FONT_STYLE=Stílus
+service.gui.FONT_UNDERLINE=Aláhúzott
+service.gui.GRANT_OWNERSHIP=Tulajdonjog megadása...
+service.gui.GRANT_ADMIN=Adminisztrátor jogosultság megadása...
+service.gui.GRANT_MODERATOR=Közvetítő (moderator) jogosultság megadása
+service.gui.GRANT_MEMBERSHIP=Tagság megadása
+service.gui.GRANT_VOICE=Hang megadása
+service.gui.GUEST=látogató
+service.gui.HANG_UP=Vonalbontás
+service.gui.HD_QUALITY=HD videó
+service.gui.HELP=Súgó
+service.gui.HIDE=Elrejt
+service.gui.HIDE_OFFLINE_CONTACTS=Kijelentkezett partnerek elrejtése
+service.gui.HIDE_MAIN_WINDOW=<DIV>Az X ablak gomb megnyomása nem lépteti ki az alkalmazást, hanem<BR>csak elrejti. Ha ki akarsz lépni, akkor azt a Fájl/Kilépés pontra kattintva teheted.</DIV>
+service.gui.HISTORY=Előzmények
+service.gui.HISTORY_CONTACT=Előzmények - {0}
+service.gui.HISTORY_TOGGLE_PER_CONTACT=Az ehhez a partnerhez tartozó előzmények rögzítésének kikapcsolása
+service.gui.HISTORY_TOGGLE_PER_CHATROOM=Előzmények kikapcsolása ebben a csevegésben
+service.gui.HISTORY_TOGGLE_ALL=Előzmények kikapcsolása az összes csevegésben, és az összes partnerrel
+service.gui.HISTORY_ERASE_PER_CONTACT=Az összes előzmény törlése ezzel a partnerrel
+service.gui.HISTORY_ERASE_PER_CHATROOM=Az összes előzmény törlése ebben a csevegésben
+service.gui.HISTORY_ERASE_ALL=Az összes előzmény törlése {0}-ban/ben
+service.gui.HISTORY_REMOVE_PER_CONTACT_WARNING=Biztosan véglegesen törölni akarod az összes ezen a gépen tárolt üzenetet {0}-val/vel?
+service.gui.HISTORY_REMOVE_ALL_WARNING=Biztosan véglegesen törölni akarod az összes ezen a gépen tárolt üzenetet?
+service.gui.HISTORY_REMOVE_ERROR=Az ezen a gépen tárolt üzenetek törlése nem sikerült.
+service.gui.HOME=Kezdőlap
+service.gui.HOME_PAGE=Kezdő oldal
+service.gui.ICE=ICE (?)
+service.gui.IDENTIFIER=Azonosító
+service.gui.IGNORE=Mégse
+service.gui.INSERT_SMILEY=Mosolygó arc beillesztése
+service.gui.INCOMING_CALL=Bejövő hívás {0}-tól/től
+service.gui.INCOMING_SCREEN_SHARE=Képernyőmegosztás kezdeményezés {0}-tól/től
+service.gui.INCOMING_CALL_STATUS=Bejövő hívás
+service.gui.INCOMING_SCREEN_SHARE_STATUS=Bejövő képernyőmegosztás
+service.gui.INSTANT_MESSAGINGS=Ãœzenetek
+service.gui.IM=Ãœzenet
+service.gui.INITIATING_CALL_STATUS=Hívás kezdeményezése
+service.gui.INVITATION=Meghívó szövege
+service.gui.INVITATION_RECEIVED=Meghívás érkezett
+service.gui.INVITATION_RECEIVED_MSG={0} meghívott, hogy csatlakozz a(z) {1} csevegéshez. Elfogadhatod, elutasíthatod, vagy figyelmen kívül hagyhatod ezt a meghívást.
+service.gui.INVITATION_REJECTED={0} elutasította meghívásodat a csevegéshez való csatlakozáshoz. Ok: {1}.
+service.gui.INVITE=Meghív
+service.gui.INVITE_CONTACT_MSG=Válaszd ki azoknak a partnereknek a nevét, akiket ehhez a csevegéshez szeretnél hozzáadni, és kattints a Meghív gombra.
+service.gui.INVITE_CONTACT_TO_CHAT=Partnerek meghívása csevegéshez
+service.gui.INVITE_CONTACT_TO_CALL=Partnerek meghívása beszélgetéshez
+service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Partnerek meghívása videó átjátszásra (video bridge)
+service.gui.INVITE_REASON=A meghívás oka
+service.gui.IS_CALLING={0} hív...
+service.gui.IS_NOW={0} mostantól {1}
+service.gui.JOIN=Csatlakozás
+service.gui.JOIN_AS=Csatlakozás másként
+service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=Csatlakozás meglévő videókonferenciához
+service.gui.JOIN_VIDEO=Videó csatlakoztatása
+service.gui.JOB_TITLE=Beosztás
+service.gui.JOIN_CHAT_ROOM=Csatlakozás csevegéshez...
+service.gui.JOIN_CHAT_ROOM_TITLE=Csatlakozás csevegéshez
+service.gui.JOIN_CHAT_ROOM_NAME=Ãrd be a csevegés nevét, amihez csatlakozni szeretnél.
+service.gui.JOIN_CHAT_ROOM_WIZARD=Csevegés csatlakozó varázsló
+service.gui.JOIN_AUTOMATICALLY=Csatlakozás automatikusan
+service.gui.DONT_JOIN_AUTOMATICALLY=Ne csatlakozzon automatikusan
+service.gui.KICK=Kick (?)
+service.gui.KICK_FAILED=Kirúgás sikertelen
+service.gui.KICK_FAILED_GENERAL_ERROR={0} kirúgása nem sikerült. Ãltalános szerver hiba történt.
+service.gui.KICK_FAILED_NOT_ALLOWED={0} kirúgása nem sikerült. A csevegés tulajdonosát és adminisztrátorát nem lehet kirúgni.
+service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS={0} kirúgása nem sikerült. A kirúgáshoz nincs elég jogosultságod.
+service.gui.LAST_NAME=Vezetéknév
+service.gui.LEAVE=Elhagy
+service.gui.LIMIT_REACHED_FOR_IP=Túl sok regisztráció van már a helyi IP címről, és a(z) {0} szerver nem enged már többet nyitni.
+service.gui.LIST=Lista
+service.gui.LOADING_ROOMS=Csevegések betöltése...
+service.gui.LOADING=Betöltés...
+service.gui.LOCALLY_ON_HOLD_STATUS=Helyileg várakoztatva
+service.gui.LOGIN_NETWORK_ERROR=A bejelentkezés hálózati hiba miatt nem sikerült: felhasználó: {0}, szerver név: {1}. Ellenőrizd a hálózati csatlakozásodat.
+service.gui.LOGIN_GENERAL_ERROR=Hiba bejelentkezés közben: felhasználó: {0}, szerver név: {1}:{2}.
+service.gui.chat.role.ADMINISTRATOR=rendszergazda
+service.gui.SHOW_OFFLINE_CONTACTS=Kijelentkezett partnerek elrejtése
+
+
+
+
+#enum values from IceProcessingState
+
+
+
+#service.gui.CERT_INFO_ are combined from Rdn names
# keep the following string short
# service.gui.avatar.imagepicker
+service.gui.avatar.imagepicker.CANCEL=Mégse
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
# systray
@@ -204,12 +350,28 @@ service.gui.DESKTOP_SHARING_WARNING=<b>Biztosan meg akarod osztani a képernyőd
# New Account Dialog
# LDAP
+impl.ldap.GENERAL=Ãltalános
+impl.ldap.EDIT=Szerkeszt
+impl.ldap.CANCEL=Mégse
+impl.ldap.MAIL_FIELD_EXAMPLE=Email
+
+# SIP Protocol
+
+#Jabber Protocol
# Address book plugin
# Google Contacts
+impl.googlecontacts.EDIT=Szerkeszt
+impl.googlecontacts.CANCEL=Mégse
# account info
+plugin.accountinfo.DISPLAY_NAME=Képernyő név
+plugin.accountinfo.LAST_NAME=Vezetéknév
+plugin.accountinfo.CITY=Város
+plugin.accountinfo.COUNTRY=Ország
+plugin.accountinfo.EMAIL=Email
+plugin.accountinfo.JOB_TITLE=Beosztás
# connection info
@@ -218,10 +380,8 @@ service.gui.DESKTOP_SHARING_WARNING=<b>Biztosan meg akarod osztani a képernyőd
# aimaccregwizz
# branding
+plugin.branding.ABOUT_MENU_ENTRY=Névjegy
-# Dict protocol
-
-# facebookaccregwizz
# generalconfig
@@ -230,50 +390,54 @@ service.gui.DESKTOP_SHARING_WARNING=<b>Biztosan meg akarod osztani a képernyőd
# icqaccregwizz
# irc accregwizz
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE={0} engedélyezés
# jabber accregwizz
-# mailbox
-
-# msn accregwizz
-
# plugin manager
# simple accregwizz
# sipaccregwizz
+plugin.sipaccregwizz.DISPLAY_NAME=Képernyő név
+#used from SecurityPanel
# skin manager
-# ssh accregwizz
-
# status update
# updatechecker
+plugin.updatechecker.BUTTON_CLOSE=Bezár
# usersearch
# whiteboard
-
-# yahoo accregwizz
-
-# zero accregwizz
+plugin.whiteboard.COLOR=Szín
+plugin.whiteboard.DELETE=Töröl
# gtalk accregwizz
# iptel accregwizz
-# sip2sip accregwizz
-
# ippi accregwizz
# key binding chooser
+#in new ChatWindow() -> manipulated
+plugin.keybindings.CHAT_COPY=Másolás
+plugin.keybindings.CHAT_CUT=Kivágás
+#Enum KeybindingSet.Category
+plugin.keybindings.CHAT=Csevegés
# Notification Configuration Form
+#NotificationsTable constants
+plugin.notificationconfig.event.IncomingCall=Bejövő hívás
+plugin.notificationconfig.event.IncomingFile=Bejövő hívás
+plugin.notificationconfig.event.HangUp=Vonalbontás
# ZRTP Securing
# ZRTP Configuration
+impl.media.security.zrtp.TITLE=Hívás
@@ -281,6 +445,7 @@ service.gui.DESKTOP_SHARING_WARNING=<b>Biztosan meg akarod osztani a képernyőd
+#in JNIEncoder
# The callrecordingconfig plugin was never really committed into trunk and its
# ConfigurationForm was actually put in the neomedia bundle.
@@ -288,6 +453,10 @@ service.gui.DESKTOP_SHARING_WARNING=<b>Biztosan meg akarod osztani a képernyőd
# Security configuration form title
# otr plugin
+plugin.otr.authbuddydialog.CANCEL=Mégse
+plugin.otr.authbuddydialog.HELP=Súgó
+plugin.otr.configform.GENERATE=Ãltalános
+plugin.otr.configform.COLUMN_NAME_CONTACT=Partnerek
# global proxy plugin
#plugin.globalproxy.PROTOCOL_SUPPORT
@@ -297,17 +466,21 @@ service.gui.DESKTOP_SHARING_WARNING=<b>Biztosan meg akarod osztani a képernyőd
#plugin chat config
+plugin.chatconfig.TITLE=Csevegés
#provisioning plugin
# packet logging service
# dns config plugin
+net.java.sip.communicator.util.dns.SecureResolveMode.IgnoreDnssec=Mégse
+net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.Deny=Elutasít
#plugin spellcheck
#Certificate configuration plugin
+plugin.certconfig.KEYSTORE=Fájl
# Phone number contact source plugin
diff --git a/resources/languages/resources_id.properties b/resources/languages/resources_id.properties
index e142468..9ad1416 100644
--- a/resources/languages/resources_id.properties
+++ b/resources/languages/resources_id.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Saya
service.gui.ACCOUNT_REGISTRATION_WIZARD=Pemandu Pendaftaran Akun
service.gui.ACCOUNTS=Akun-akun
service.gui.ADD=&Tambah
-service.gui.ADD_ACCOUNT=Tambah akun
service.gui.ADD_CONTACT=&Tambah kontak
service.gui.ADD_AUTHORIZED_CONTACT=Tambah {0} ke daftar kontak anda
service.gui.ADD_CONTACT_TO_CONTACTLIST=Tambahkan {0} ke daftar kontak anda
@@ -42,20 +52,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Kegagalan menambah kontak
service.gui.ADD_CONTACT_EXIST_ERROR=Kontak {0} sudah ada di daftar kontak anda.
service.gui.ADD_CONTACT_NETWORK_ERROR=Server tidak merespon permintaan menambahkan kontak dengan id: {0}
service.gui.ADD_CONTACT_NOT_SUPPORTED=Gagal menambahkan kontak dengan id: {0}. Operasi tidak didukung.
-service.gui.ADD_CONTACT_IDENTIFIER=Pada isian dibawah masukan pengenal dari kontak yang ingin anda tambahkan.
-service.gui.ADD_CONTACT_WIZARD=Pemandu penambahan kontak
service.gui.ADD_CONTACT_NOT_CONNECTED=Anda harus terhubung agar dapat menambahkan kontak. Silahkan terhubung ke provider terpilih dan coba lagi.
service.gui.ADD_GROUP_LOCAL_ERROR=Gagal menambah grup dengan nama: {0}. Permasalahan terjadi pada saat operasi Input/Output lokal
service.gui.ADD_GROUP_EXIST_ERROR=Grup {0} sudah ada di daftar kontak anda. Silahkan gunakan nama yang lain.
service.gui.ADD_GROUP_NET_ERROR=Gagal menambah grup dengan nama: {0}. Permasalah terjadi karena kesalahan jaringan. Silahkan periksa koneksi jaringan dan coba lagi.
service.gui.ADD_GROUP_ERROR=Gagal menambah grup dengan nama: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=Nama grup tidak boleh kosong.
-service.gui.ADD_GROUP=Buat grup
-service.gui.ADD_SUBCONTACT=&Tambah sub-kontak
service.gui.ADDRESS=Alamat
service.gui.ADMINISTRATOR=administratur
service.gui.ADVANCED=&Mahir
-service.gui.ALL=&Semua
service.gui.ALL_CONTACTS=&Semua kontak
service.gui.ALTERNATE_ADDRESS=Alamat alternatif
service.gui.APPLY=&Terapkan
@@ -65,7 +70,6 @@ service.gui.AT=di
service.gui.AUTHORIZE=Otorisasikan
service.gui.AUTHORIZATION_ACCEPTED={0} kontak telah menerima permintaan otorisasi anda.
service.gui.AUTHENTICATION_FAILED=Autentikasi gagal untuk {0}. Kata sandi yang anda masukkan tidak benar.
-service.gui.AUTHENTICATION_REQUESTED=Autentikasi diminta
service.gui.AUTHENTICATION_REQUESTED_SERVER=Server {0} telah meminta autentikasi anda.
service.gui.AUTHENTICATION_REJECTED={0} telah menolak permintaan autorisasi anda.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} autentikasi
@@ -107,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=Pada isian dibawah, anda dapat menuliskan pang
service.gui.CHANGE_NICKNAME_ERROR=Gagal merubah nama panggilan
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Nama panggilan sudah ada
service.gui.CHANGE_VIDEO_QUALITY=Ubah kualitas remote video
-service.gui.CHAT_CONFERENCE_LABEL=Konferensi
service.gui.CHAT_CONFERENCE_ITEM_LABEL=konferensi milik {0}
service.gui.CHAT_ROOM_ALREADY_JOINED=Sudah tergabung dengan ruang bincang {0}.
service.gui.CHAT_ROOM_CONFIGURATION=konfigurasi ruang bincang {0}
@@ -119,13 +122,11 @@ service.gui.CHAT_ROOM_USER_KICKED=telah diusir dari {0}
service.gui.CHAT_ROOM_USER_QUIT=telah menghentikan {0}
service.gui.CHAT_ROOM_NAME=Nama ruang bincang
service.gui.ROOM_NAME=Ruang Bincang
-service.gui.AUTOJOIN=Gabung Otomatis
service.gui.CHANGE_PASSWORD=Ubah Kata Sandi
service.gui.CHAT_ROOM_NAME_INFO=Pada isian dibawah tuliskan nama ruang bincang yaang ingin anda buat.
service.gui.CHAT_ROOM_NOT_EXIST=Ruang {0} tidak ditemukan pada server {1}. Silahkan periksa apakah nama yang anda ketikkan sudah benar.
service.gui.CHAT_ROOM_NOT_CONNECTED=Anda perlu login untuk ikut dalam ruang bincang {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Anda perlu login untuk meninggalkan sebuah ruang bincang.
-service.gui.CHAT_ROOM_NOT_JOINED=Anda harus tergabung dalam ruang bincang untuk melakukan hal lebih lanjut.
service.gui.CHAT_ROOM_OPTIONS=Pilihan ruang bincang
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Ruang bincang {0} membutuhkan pendaftaran untuk dapat bergabung.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Ruang bincang {0} meminta kata sandi.
@@ -139,16 +140,13 @@ service.gui.CONNECTING=Menyambung...
service.gui.CONNECTING_STATUS=Sambungan
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Menyambung...
service.gui.CONNECTION=Sambungan
-service.gui.CONNECTION_FAILED_MSG=Koneksi gagal untuk akun berikut: Nama Pengguna: {0}, Nama Server: {1}. Silaahkan periksa koneksi jaringan atau hubungi administratur jaringan anda untuk informasi lebih lanjut.
service.gui.CONNECTION_EXPIRED_MSG=Anda saat ini terputus dari server {0}.
service.gui.CONTACT_NAME=ID atau Nomer
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Kontak terpilih {0} tidak mendukung telephony.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Kontak terpilih {0} tidak mendukung konferensi perbincangan.
service.gui.CONTACT_PAUSED_TYPING={0} berhenti mengetikkan pesan
service.gui.CONTACT_TYPING={0} sedang mengetik pesan
service.gui.CONTACT_TYPING_SEND_FAILED=wakwawww.. kami tidak dapat memberitahu {0} anda sedang menulis
service.gui.CONTACT_INFO=&Informasi kontak
-service.gui.CONTACTLIST=Daftar Kontak
service.gui.CONTACTS=Kontak
service.gui.COPY=Salin
service.gui.COPY_LINK=Salin tautan
@@ -158,15 +156,12 @@ service.gui.CREATE_CHAT_ROOM=&Buat ruang bincang..
service.gui.CREATE_CHAT_ROOM_ERROR=Gagal membuat ruang bincang {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=Pemandu pembuatan ruang bincang
service.gui.CREATE_CONFERENCE_CALL=&Buat sebuah panggilan konferensi...
-service.gui.CREATE_CONFERENCE_CHAT=&Buat sebuah perbincangan konferensi...
service.gui.CREATE_GROUP=&Buat grup
service.gui.CREATE_GROUP_NAME=Pada isian dibawah ketikkan nama grup yang ingin anda buat.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Tidak ada grup dalam daftar kontak anda. Silahkan membuat sebuah grup dahulu.
service.gui.CREATE_VIDEO_BRIDGE=Membuat jembatan &video...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Membuat jembatan &video
service.gui.CONTACT_INFO_NOT_SUPPORTED=Kontak ini tidak mendukung informasi web
service.gui.CUT=Potong
-service.gui.DATE=Tanggal
service.gui.DELETE=Hapus
service.gui.DENY=Tolak
service.gui.DESKTOP_SHARING_WARNING=<b>Anda yakin ingin menmulai berbagi layar?</b> <br> Memilih OK akan mengijinkan orang dalam panggilan ini untuk melihat tampilan layar anda.
@@ -176,7 +171,6 @@ service.gui.DISCONNECTED_STATUS=Terputus
service.gui.DND_STATUS=Jangan diganggu
service.gui.DO_NOT_ASK_AGAIN=Jangan tanya lagi
service.gui.DO_NOT_SHOW_AGAIN=Jangan tampilkan pesan ini lagi
-service.gui.DOWNLOAD_NOW=Unduh sekarang
service.gui.DRAG_FOR_SHARING=Seret kesini apa saja yang ingin anda bagi...
service.gui.DURATION=durasi
service.gui.EDIT=&Edit
@@ -193,7 +187,6 @@ service.gui.ERROR_WAS=Kesalahan yaitu: {0}
service.gui.ESTIMATED_TIME=Perkiraan waktu:
service.gui.EVENTS=Kejadian
service.gui.EXIT=Keluar
-service.gui.EXTENDED_CRITERIA=Kriteria tambahan
service.gui.GENERAL=Umum
service.gui.GENERAL_ERROR=Kesalahan umum
service.gui.GROUP_NAME=Nama grup
@@ -251,12 +244,12 @@ service.gui.HISTORY=Riwayat
service.gui.HISTORY_CONTACT=Riwayat - {0}
service.gui.HOME=Beranda
service.gui.HOME_PAGE=Halaman Depan
-service.gui.HOUR=Jam
service.gui.ICE=ICE
service.gui.IDENTIFIER=Pengenal
service.gui.IGNORE=Abaikan
service.gui.INSERT_SMILEY=Masukkan senyuman
service.gui.INCOMING_CALL=Panggilan masuk diterima dari: {0}
+service.gui.INCOMING_SCREEN_SHARE=Panggilan masuk diterima dari: {0}
service.gui.INCOMING_CALL_STATUS=Panggilan masuk
service.gui.INITIATING_CALL_STATUS=Memulai panggilan
service.gui.INVITATION=Teks undangan
@@ -269,11 +262,8 @@ service.gui.INVITE_CONTACT_TO_CALL=Undang kontak ke panggilan
service.gui.INVITE_REASON=ALasan undangan
service.gui.IS_CALLING=sedang memanggil...
service.gui.IS_NOW={0} sekarang {1}
-service.gui.JITSI_WARNING=SIP Communicator telah berganti nama menjadi Jitsi.<br/>Jika anda ingin versi milik anda tetap terkini, silahkan unduh Jitsi.<br/><br/>Kami mohon maaf atass ketidaknyamanan ini<br/><br/> Tim PengembangJitsi
-service.gui.JITSI_WARNING_TITLE=SIP Communicator menjadi Jitsi
service.gui.JOIN=Gabung
service.gui.JOIN_AS=Gabung sebagai
-service.gui.CLOSE_CHAT_ROOM_DIALOG=Tutup
service.gui.JOB_TITLE=Pekerjaan
service.gui.JOIN_CHAT_ROOM=Gabung ruang bincang...
service.gui.JOIN_CHAT_ROOM_TITLE=Gabung ruang bincang
@@ -284,7 +274,6 @@ service.gui.KICK_FAILED=Pengusiran gagal
service.gui.KICK_FAILED_GENERAL_ERROR=Gagal mengusir {0}. Terjadi kesalahan umum server.
service.gui.KICK_FAILED_NOT_ALLOWED=Gagal mengusir {0}. Pemilik dan administratur ruang tidak dapat diusir.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Gagal mengusir {0}. Anda tidak punya cukup hak untuk melakukannya.
-service.gui.LAST=Teerakhir
service.gui.LAST_NAME=Nama Belakang:
service.gui.LEAVE=Pergi
service.gui.LIMIT_REACHED_FOR_IP=Anda telah memiliki terlalu banyak pendaftaran dari alamat IP lokal dan server {0} tidak mengijinkan membuka lebih lanjut lagi.
@@ -304,7 +293,6 @@ service.gui.MESSAGE=Pesan:
service.gui.MISSED_CALLS_TOOL_TIP=Pesan tak terjawab dari:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= dan {0} lagi
service.gui.MODERATOR=moderator
-service.gui.MORE=Lihat lebih lanjut
service.gui.MORE_LABEL=Pindah
service.gui.MOVE=Pindah
service.gui.MOVE_SUBCONTACT=Pindahkan Kontak
@@ -313,7 +301,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=Kontak yang anda pilih sama dengan sumber. Ha
service.gui.MOVE_SUBCONTACT_QUESTION=Apa anda yakin ingin memindahkan {0} ke {1}?
service.gui.MOVE_TO_GROUP=&Pindah ke grup
service.gui.MOVE_CONTACT=Pindah Kontak
-service.gui.MOVE_CONTACT_ERROR=Kontak tidak dapat dipindahkan
service.gui.MSG_DELIVERY_FAILURE=Pesan diatas tidak dapat terkirim
service.gui.MSG_DELIVERY_NOT_SUPPORTED=Protokol yang anda gunaakan tidak mendukung pesan offline. Anda dapat mencoba menghubungi kontak ini melalui protokol lain atau menunggu sampai dia online.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Sebuah kesalahan internal telah terjadi. Kemungkinan besar ini adalah cacat aplikasi. Harap laporkan ke: http://www.sip-communicator.org/index.php/Development/BugsAndIssues. Server mengembalikan error: {0}
@@ -324,7 +311,6 @@ service.gui.MSG_NOT_POSSIBLE=Pengiriman pesan tidak dimungkinkan untuk kontak in
service.gui.MSG_RECEIVED={0} menulis
service.gui.MSG_SEND_CONNECTION_PROBLEM=Anda harus terhubung untuk dapat mengirim pesan.
service.gui.MULTIPLE_LOGINS=Anda telah masuk lebih dari sekali dengan akun yang sama. Akun berikut: Nama Pengguna: {0}, Nama Server: {1} saat ini terputus.
-service.gui.MUTE=Bisu
service.gui.NAME=Nama
service.gui.NETWORK=Jaringan
service.gui.NETWORK_FAILURE=Kesalahan Jaringan
@@ -334,6 +320,7 @@ service.gui.NEW_MESSAGE=Pesan baru
service.gui.NEW_NAME=Nama baru
service.gui.NEW_STATUS_MESSAGE=Status pesan baru
service.gui.NEW_STATUS_MESSAGE_SAVE=Simpan sebagai pesan unik
+service.gui.NICKNAME=Nama panggilan
service.gui.NO=Tidak
service.gui.NONE=Tidak ada
service.gui.NO_CAMERA_AVAILABLE=Tidak ada kamera
@@ -353,7 +340,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=TidakDiDaftarKontak
service.gui.SD_QUALITY=Kualitas standard
service.gui.OFFLINE=Offline
service.gui.OK=OK
-service.gui.OLDER_CALLS=Panggilan lama
service.gui.ONLINE=Online
service.gui.OPEN=Buka
service.gui.OPEN_FILE_FROM_IMAGE=Klik ganda untuk membuka berkas.
@@ -361,9 +347,12 @@ service.gui.OPEN_FOLDER=Buka folder
service.gui.OPEN_IN_BROWSER=Buka di browser
service.gui.OPTIONS=Pilihan
service.gui.OR=atau
-service.gui.OR_ENTER_PHONE_NUMBER=atau masukkan nomor telepon disini...
service.gui.ORGANIZATION=Organization:
service.gui.OTHER=Lainnya
+service.gui.chat.role.ADMINISTRATOR=administratur
+service.gui.chat.role.MODERATOR=moderator
+service.gui.chat.role.MEMBER=anggota
+service.gui.chat.role.SILENT_MEMBER=anggota diam
service.gui.OWNER=pemilik ruang
service.gui.PASSWORD=Kata Sandi
service.gui.PASSWORD_CHANGE_FAILURE=Perubahan kata sandi gagal
@@ -377,7 +366,6 @@ service.gui.PRESENCE=Kehadiran
service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Enter' untuk saran
service.gui.PRESS_FOR_CALL_INFO=Tekan untuk informasi panggilan
service.gui.PREVIOUS=Sebelumnya
-service.gui.PREVIOUS_TOOLTIP=Jalajahi percakapan lama
service.gui.PRINT=Cetak
service.gui.PROACTIVE_NOTIFICATION=sedang mengetik pesan
service.gui.PROTOCOL=Protokol
@@ -389,7 +377,6 @@ service.gui.REASON=Alasan
service.gui.RECONNECTION_LIMIT_EXCEEDED=Anda telah terputus dan menyambung kembali ke server terlalu cepat. Akun berikut: Nama Pengguna {0}, Nama Server: {1} sementara dicekal dan harus menunggu sementara sebelum mencoba untuk masuk lagi.
service.gui.RE_REQUEST_AUTHORIZATION=Meminta otorisasi
service.gui.REJECT=Tolak
-service.gui.REMIND_ME_LATER=Ingatkan saya nanti
service.gui.REMEMBER_PASSWORD=Ingat kata sandi
service.gui.REMOVE=Hapus
service.gui.REMOVE_ACCOUNT=Hapus akun
@@ -413,27 +400,18 @@ service.gui.REVOKE_ADMIN=Batalkan administrasi
service.gui.REVOKE_MODERATOR=Batalkan pengaturan
service.gui.REVOKE_MEMBERSHIP=Batalkan keanggotaan
service.gui.REVOKE_VOICE=Batalkan suara
-service.gui.ROOT_GROUP=Grup utama
service.gui.SAVE=Simpan
-service.gui.SAVE_AS_DEFAULT=Simpan sebagai default
service.gui.SEARCH=Cari
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Klik tombol dibawah untuk menampilkan semua ruang bincang yang terssedia di server terpilih. Lalu pilih satu yang anda ingin bergabung dan tekan tombol Gabung.
service.gui.SEARCH_STRING_CONTACT_SOURCE=Kontak pencarian
service.gui.SECURITY=Keamanan
-service.gui.SELECT_ACCOUNT=Pilih akun
service.gui.SELECT_COLOR=Pilih warna
service.gui.SELECT_GROUP=Pilih grup
-service.gui.SELECT_GROUP_WIZARD_MSG=daftar dibawah berisi seluruh grup dalam daftar kontak anda. Pilih satu yang anda ingin tambahkan kontak baru.
service.gui.SELECT_NO_GROUP=Tidak ada grup
-service.gui.SELECT_GROUP_WIZARD=Tentukan grup
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=Daftar dibawah berisi seluruh akun yang mendukung fitur percakapan banyak pengguna. Pilih satu yang anda inginkan untuk membuat ruang bincang anda.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=Daftar dibawah berisi seluruh akun yang terdaftar. Pilih satu yang anda inginkan untuk berkomunikasi dengan kontak baru.
-service.gui.SELECT_PROVIDERS_WIZARD=Pilih aakun
service.gui.SEND=Kirim
service.gui.SEND_FILE=Kirim berkas
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Tidak ada informasi untuk kontak ini.
service.gui.SEND_MESSAGE=Kirim sebuah pesan
-service.gui.SEND_AS_SMS=Kirim sebagai SMS
service.gui.SEND_SMS=Kirim SMS
service.gui.SEND_SMS_DETAILS=Ingat bahwa abda perlu memasukkan angka dalam bentuk internasional, seperti dimulai dengan +62 untuk Indonesia dengan contoh +629998812345
service.gui.SEND_SMS_NOT_SUPPORTED=Protokol yang anda pilih tidak mendukung pesan SMS.
@@ -468,7 +446,6 @@ service.gui.STREET=Jalan
service.gui.SUBJECT=Subyek
service.gui.SUMMARY=Ringkasan
service.gui.TELEPHONY=Telephony
-service.gui.TODAY=Hari ini
service.gui.TOOLS=Perkakas
service.gui.TRANSFER=Pengiriman
service.gui.TO=Kepada:
@@ -478,7 +455,6 @@ service.gui.TRANSFER_CALL_TO=Kirim Ke:
service.gui.TRANSPARENCY_NOT_ENABLED=Transsparansi tidak didukung oleh konfigurasi anda saat ini.
service.gui.TYPE_YOUR_REQUEST=Ketikkan permintaan anda disini
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Kami tidak dapat mengubah kualitas video untuk kontak ini.
-service.gui.UNMUTE=Bersuara
service.gui.USER_IDENTIFIER=Identitas pengguna:
service.gui.USER_EXISTS_ERROR=Pengguna ini sudah ada di jaringan terpilih. Silahkan pilih pengguna atau jaringan lainnya.
service.gui.USERNAME_NULL=Silahkan isi nama pengguna dan kata sandi anda.
@@ -488,7 +464,6 @@ service.gui.UNKNOWN_STATUS=Keadaan tidak diketahui
service.gui.UNREGISTERED_MESSAGE=Tidak dapat menghubungi akun berikut: Nama Pengguna: {0}, Nama Server: {1}. Anda saat ini offline.
service.gui.VALUE=Nilai
service.gui.VIDEO_CALL=Panggilan video
-service.gui.VIA_SMS=Melalui SMS
service.gui.VIEW=Tampilan
service.gui.VIEW_HISTORY=Lihat riwayat
service.gui.VIEW_SMILEYS=Lihat Senyuman
@@ -508,9 +483,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=Mengatur volume
service.gui.WAITING_AUTHORIZATION=Menunggu otorisasi
service.gui.WARNING=Peringatan
service.gui.YES=Ya
-service.gui.YESTERDAY=Kemarin
-service.gui.EXISTING_ACCOUNT_ERROR=Akun yang anda ketikkan sudah terinstal.
-service.gui.NEW_MAIL=<b>Anda memiliki satu Surat baru!</b><br/><b>Dari:</b> {0} {1} <br/><b>Subyek:</b> {2} <br/>{3}
service.gui.NEW_GMAIL_HEADER=Anda telah menerima sebuah surat baru dalam <a href="{1}">inbox</a> {0} anda:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=Anda telah menerima {2} surat baru dalam <a href="{1}">inbox</a> {0} anda:<br/>
service.gui.NEW_GMAIL_FOOTER=satu atau lebih percakapan belum terbaca dalam <a href="{0}">inbox</a> anda.<br/>
@@ -563,7 +535,6 @@ service.gui.callinfo.CALL_INFORMATION=Informasi panggilan
service.gui.callinfo.CALL_IDENTITY=Pengenal
service.gui.callinfo.PEER_COUNT=jumlah peserta
service.gui.callinfo.IS_CONFERENCE_FOCUS=fokus konferensi
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Penyandian aktif
service.gui.callinfo.CALL_TRANSPORT=transport panggilan dihubungi
service.gui.callinfo.CALL_DURATION=Durasi panggilan
service.gui.callinfo.VIEW_CERTIFICATE=Tampilkan Sertifikat
@@ -581,10 +552,13 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=protokol pertukaran kunci
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=tipe perluasan kandidat ICE
service.gui.callinfo.ICE_STATE=Tahapan Pemrosesan ICE
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=kumpulkan kandidat
service.gui.callinfo.ICE_STATE.RUNNING=Memeriksa koneksi
service.gui.callinfo.ICE_STATE.COMPLETED=Selesai
service.gui.callinfo.ICE_STATE.FAILED=Gagal
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=IP / Port komputer lokal
service.gui.callinfo.ICE_REMOTE_HOST_ADDRESS=IP / Port komputer remote
service.gui.callinfo.DECODED_WITH_FEC=paket di-decode dengan FEC
@@ -595,9 +569,10 @@ service.gui.ALWAYS_TRUST=Selalu percaya sertifikat ini
service.gui.CERT_DIALOG_TITLE=Periksa Sertifikat
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} tidak dapat memeriksa indentitas server ketika menghubungi <br>{1}:{2}.<br><br> Sertifikat tidak terpercaya, yang berarti identitas server tidak dapat diperiksa secara otomatis. Apakah anda ingin meneruskan menyambung?<br><br> Untuk informasi lebih lanjut, klik "Tampilkan Sertifikat".</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0} tidak dapat memeriksa indentitas server ketika menghubungi <br>{1}:{2}.<br><br> Sertifikat tidak terpercaya, yang berarti identitas server tidak dapat diperiksa secara otomatis. Apakah anda ingin meneruskan menyambung?<br><br> Untuk informasi lebih lanjut, klik "Tampilkan Sertifikat".</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} tidak dapat memeriksa indentitas server ketika menghubungi <br>{1}:{2}.<br><br> Sertifikat tidak terpercaya, yang berarti identitas server tidak dapat diperiksa secara otomatis. Apakah anda ingin meneruskan menyambung?<br><br> Untuk informasi lebih lanjut, klik "Tampilkan Sertifikat".</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} tidak dapat memeriksa indentitas server ketika menghubungi <br>{1}:{2}.<br><br> Sertifikat tidak terpercaya, yang berarti identitas server tidak dapat diperiksa secara otomatis. Apakah anda ingin meneruskan menyambung?<br><br> Untuk informasi lebih lanjut, klik "Tampilkan Sertifikat".</html>
service.gui.CONTINUE_ANYWAY=Tetap lanjutkan
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Common Name:
service.gui.CERT_INFO_O=Organization:
service.gui.CERT_INFO_C=Country Name:
@@ -611,12 +586,10 @@ service.gui.CERT_INFO_VER=Versi:
service.gui.CERT_INFO_SIGN_ALG=Algoritma Tanda Tangan:
service.gui.CERT_INFO_ALG=Algoritma
service.gui.CERT_INFO_PUB_KEY=Kunci Publik:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} bytes: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} bits
service.gui.CERT_INFO_EXP=Eksponen
service.gui.CERT_INFO_KEY_SIZE=Panjang Kunci
service.gui.CERT_INFO_SIGN=Tanda Tangan:
-service.gui.CONTINUE=Lanjutkan
service.gui.SHOW_CERT=Tampilkan Sertifikat
service.gui.HIDE_CERT=Sembunyikan Sertifikat
@@ -635,11 +608,9 @@ service.gui.security.SECURE_AUDIO=Audio diamankan
service.gui.security.AUDIO_NOT_SECURED=Audio tidak diamankan
service.gui.security.SECURE_VIDEO=Video diamankan
service.gui.security.VIDEO_NOT_SECURED=Video tidak diamankan
-service.gui.security.NO_VIDEO=Tidak ada video
-service.gui.security.CIPHER=Penyandi: {0}
+service.gui.security.CALL_SECURED_TOOLTIP=Panggilan diamankan. Untuk informasi lebih lanjut tekan disini.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Panggilan tidak diamankan.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Tekan disini untuk membandingkan raasia keamanan dengan rekan anda.
-service.gui.security.COMPARE_WITH_PARTNER=Bandingkan dengan rekan dan ketik gembok untuk konfirmasi.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Bandingkan dengan rekan: {0}
service.gui.security.STRING_COMPARED=String terbandingkan!
@@ -656,19 +627,13 @@ service.gui.avatar.imagepicker.CLICK=Tekan dan Senyum
service.gui.avatar.imagepicker.IMAGE_FILES=Berkas gambar
service.gui.avatar.imagepicker.IMAGE_PICKER=Gambar
service.gui.avatar.imagepicker.IMAGE_SIZE=Ukuran gambar
-service.gui.avatar.imagepicker.INITIALIZING=Memulai
service.gui.avatar.imagepicker.RESET=Ulang
service.gui.avatar.imagepicker.SET=Jadikan
service.gui.avatar.imagepicker.TAKE_PHOTO=Mengambil foto
-service.gui.avatar.imagepicker.WEBCAM_ERROR=kesalahan webcam
service.gui.security.encryption.required=Enkripsi diperlukan
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
impl.protocol.sip.XCAP_ERROR_TITLE=Kesalahan di penyimpanan daftar kontak SIP
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=Resource tidak dapat membaca {0}. Untuk {1}
@@ -691,9 +656,7 @@ impl.gui.main.account.DUMMY_PROTOCOL_DESCRIPTION=pilih jaringan
# LDAP
impl.ldap.CONFIG_FORM_TITLE=Konfigurasi LDAP
impl.ldap.GENERAL=Umum
-impl.ldap.NEW=Baru
impl.ldap.EDIT=&Edit
-impl.ldap.REMOVE=Hapus
impl.ldap.ENABLED=Hidupkan
impl.ldap.SERVER_NAME=Nama Server
impl.ldap.SERVER_NAME_EXAMPLE=Server LDAP saya
@@ -726,6 +689,10 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=telponRumah
impl.ldap.PHONE_PREFIX=awalan Telpon
impl.ldap.PHONE_PREFIX_EXAMPLE=Contoh: 00
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=Buku alamat
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=Hidupkan pencarian buku alamat MacOSX
@@ -735,9 +702,7 @@ plugin.addrbook.PREFIX_EXAMPLE=Contoh: 00
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Kontak Google
-impl.googlecontacts.NEW=Baru
impl.googlecontacts.EDIT=&Edit
-impl.googlecontacts.REMOVE=Hapus
impl.googlecontacts.ENABLED=Hidupkan
impl.googlecontacts.ACCOUNT_NAME=Nama Akun
impl.googlecontacts.SAVE=Simpan
@@ -764,9 +729,6 @@ plugin.accountinfo.EMAIL=Surel:
plugin.accountinfo.PHONE=Telepon:
plugin.accountinfo.MOBILE_PHONE=telponSeluler
plugin.accountinfo.JOB_TITLE=Pekerjaan
-plugin.accountinfo.USER_PICTURES=Gambar Pengguna
-plugin.accountinfo.CHANGE=Ubah
-plugin.accountinfo.ONLY_MESSAGE=Hanya pesan
# connection info
@@ -785,47 +747,12 @@ plugin.aimaccregwizz.USERNAME=Nama layar AIM:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Nama layar dan kata sandi
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Daftarkan akun baru
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Jika anda tidak memiliki akun AIM, klik tombol ini untuk membuat yang baru.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Mengganti pilihan awal server
# branding
plugin.branding.ABOUT_WINDOW_TITLE=Tentang {0}
plugin.branding.LOGO_MESSAGE=VoIP && Instant Messaging Open Source
-plugin.branding.LOADING=Memuat
plugin.branding.ABOUT_MENU_ENTRY=Tentang
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>{1} saat ini sedang aktif dikembangkan. Versi anda jalankan saat ini bersifat eksperimental dan MUNGKIN TIDAK bekerja sebagaimana mestinya. Silahkan merujuk ke {2} untuk informasi lebih lanjut.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2009 Hak Cipta <b>sip-communicator.org</b>. Semua hak terpelihara. Kunjungi <a href="http://sip-communicator.org">http://sip-communicator.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}>The <b>SIP Communicator</b> didistribusikan dalam lisensi LGPL (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=Kamus
-plugin.dictaccregwizz.ANY_DICTIONARY=Kamus Apa saja
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Kamus apa saja dari {0}
-plugin.dictaccregwizz.FIRST_MATCH=Temuan Pertama
-plugin.dictaccregwizz.NO_MATCH=Tidak ada yang cocok
-plugin.dictaccregwizz.MATCH_RESULT=Tidak ada definisi ditemukan untuk "{0}", mungkin maksud anda:\n
-plugin.dictaccregwizz.INVALID_DATABASE=Kamus "{0}" sudah tidak ada lagi di server.
-plugin.dictaccregwizz.INVALID_STRATEGY=Strategi ini tidak tersedia di server.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=Protokol layanan Dict
-plugin.dictaccregwizz.HOST=Host
-plugin.dictaccregwizz.SERVER_INFO=Informasi Server
-plugin.dictaccregwizz.STRATEGY_SELECTION=Pilihan Strategi
-plugin.dictaccregwizz.STRATEGY_LIST=Daftar Strategi:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Strategi pencarian
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=Strategi digunakan untuk mencari kaa yang mirip jika sebuah terjemahan tidak ditemukan, berkat beragam pendekatan. Sebagai contoh, strategi Prefix akan mencari kata yang diawali mirip dengan kata yang ingin anda terjemahkan.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Informasi Akun Dict
-plugin.dictaccregwizz.THREAD_CONNECT=Mencoba menghubungi server
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=hubungan gagal. ini bukan server dict atau server sedang offline
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=Mengambil strategi
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Tidak ada strategi di server
-plugin.dictaccregwizz.POPULATE_LIST=Mengumpulkan daftar
-plugin.dictaccregwizz.CLOSING_CONNECTION=Menutup koneksi
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=Protokol Obrolan Facebook
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Nama Pengguna
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Nama layar dan kata sandi
+
# generalconfig
plugin.generalconfig.AUTO_START=Menjalankan {0} otomatis saat komputer dinyalakan
@@ -836,9 +763,6 @@ plugin.generalconfig.SHOW_HISTORY=Tampilkan
plugin.generalconfig.HISTORY_SIZE=pesan terkini di obrolan baru
plugin.generalconfig.SEND_MESSAGES_WITH=Kirim pesan dengan:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=Bawa jendela obrolan ke depan
-plugin.generalconfig.ERROR_PERMISSION=Jika anda tidak punya cukup hak untuk menghilangkan autostart
-plugin.generalconfig.TRANSPARENCY=Tembus pandang
-plugin.generalconfig.ENABLE_TRANSPARENCY=Hidupkan tembus pandang
plugin.generalconfig.DEFAULT_LANGUAGE=Bahasa antar muka
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Perubahan anda akan berdampak setelah dinyalakan ulang berikutnya.
plugin.generalconfig.SIP_CLIENT_PORT=PORT klien SIP
@@ -880,18 +804,19 @@ plugin.icqaccregwizz.REGISTER_NEW_ACCOUNT=Daftarkan akun baru
plugin.ircaccregwizz.PROTOCOL_NAME=IRC
plugin.ircaccregwizz.PROTOCOL_DESCRIPTION=Protokol IRC
plugin.ircaccregwizz.USERNAME_AND_PASSWORD=UIN dan kata sandi
+plugin.ircaccregwizz.USERNAME=Nama panggilan
plugin.ircaccregwizz.INFO_PASSWORD=Kebanyakan server IRC tidak membutuhkan password.
plugin.ircaccregwizz.AUTO_NICK_CHANGE=Otomatis mengganti panggilan jika sudah terpakai
plugin.ircaccregwizz.USE_DEFAULT_PORT=Gunakan port awal
plugin.ircaccregwizz.HOST=Hostname
plugin.ircaccregwizz.IRC_SERVER=Server
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE={0} autentikasi
+plugin.ircaccregwizz.SASL_USERNAME=Nama Pengguna
# jabber accregwizz
-plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=Protokol XMPP
plugin.jabberaccregwizz.USERNAME=nama pengguna XMPP
plugin.jabberaccregwizz.PASSWORD_CONFIRM=konfirmasi kata sandi
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=ID dan kata sandi
plugin.jabberaccregwizz.CSERVER=Server
plugin.jabberaccregwizz.SERVER=Hubungi Server
plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=Hidupkan keep alive
@@ -907,13 +832,9 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Komentar
plugin.jabberaccregwizz.RESOURCE=Resource
plugin.jabberaccregwizz.AUTORESOURCE=Membuat resource otomatis
plugin.jabberaccregwizz.PRIORITY=Prioritas
-plugin.jabberaccregwizz.XMPP_ERROR=Kesalahan XMPP
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Kesalahan XMPP tidak diketahui. Periksa nama server telah benar.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Kata sandi tidak sama.
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Mengganti pilihan awal server
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Pilihan lanjutan
plugin.jabberaccregwizz.USE_ICE=Gunakan ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=Gunakan Google Jingle/ICE (eksperimental)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=Menemukan server STUN/TURN otomatis
plugin.jabberaccregwizz.SUPPORT_TURN=Dukung TURN
plugin.jabberaccregwizz.TURN_USERNAME=Nama pengguna TURN
@@ -937,16 +858,9 @@ plugin.jabberaccregwizz.EXISTING_ACCOUNT=Akun XMPP telah ada
plugin.jabberaccregwizz.DOMAIN_BYPASS_CAPS=Domain yang akan menggunakan panggilan GTalk
plugin.jabberaccregwizz.TELEPHONY_DOMAIN=DOmain Telephony
plugin.jabberaccregwizz.ALLOW_NON_SECURE=Izinkan koneksi tidak aman
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=konfirmasi kata sandi
plugin.jabberaccregwizz.VIDEO=Video
plugin.jabberaccregwizz.RESET=Ulang
-# mailbox
-
-# msn accregwizz
-plugin.msnaccregwizz.USERNAME=Surel:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=ID dan kata sandi
-
# plugin manager
plugin.pluginmanager.NEW=Baru
@@ -957,20 +871,15 @@ plugin.simpleaccregwizz.LOGIN_USERNAME=Nama Pengguna
plugin.sipaccregwizz.PROTOCOL_NAME=SIP
plugin.sipaccregwizz.PROTOCOL_DESCRIPTION=Protokol XMPP
plugin.sipaccregwizz.USERNAME_AND_PASSWORD=Nama layar dan kata sandi
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Pilihan lanjutan
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Mengganti pilihan awal server
plugin.sipaccregwizz.DISPLAY_NAME=Nama tampilan
plugin.sipaccregwizz.EXISTING_ACCOUNT=Akun XMPP telah ada
plugin.sipaccregwizz.CREATE_ACCOUNT=Membuat akun baru XMPP
plugin.sipaccregwizz.XCAP_PASSWORD=Kata Sandi
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Kata sandi tidak sama.
+#used from SecurityPanel
# skin manager
-# ssh accregwizz
-plugin.sshaccregwizz.USERNAME=Info Akun
-plugin.sshaccregwizz.OPTIONAL=Pilihan
-
# status update
# updatechecker
@@ -983,41 +892,31 @@ plugin.whiteboard.OPEN=Buka
plugin.whiteboard.COLOR=Warna
plugin.whiteboard.DELETE=Hapus
-# yahoo accregwizz
-plugin.yahooaccregwizz.USERNAME=Nama Pengguna
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=ID dan kata sandi
-
-# zero accregwizz
-plugin.zeroaccregwizz.FIRST_NAME=Nama Depan:
-plugin.zeroaccregwizz.LAST_NAME=Nama Belakang:
-plugin.zeroaccregwizz.EMAIL=Surel:
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=ID dan kata sandi
-plugin.zeroaccregwizz.USERID=ID Pengguna:
-
# gtalk accregwizz
plugin.googletalkaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Jika anda tidak memiliki akun AIM, klik tombol ini untuk membuat yang baru.
# iptel accregwizz
plugin.iptelaccregwizz.USERNAME=Nama Pengguna
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.USERNAME=Nama Pengguna
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Membuat akun baru XMPP
-
# ippi accregwizz
+plugin.sip2sipaccregwizz.USERNAME=Nama Pengguna
plugin.ippiaccregwizz.EXISTING_ACCOUNT=Akun XMPP telah ada
plugin.ippiaccregwizz.CREATE_ACCOUNT=Membuat akun baru XMPP
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_COPY=Salin
plugin.keybindings.CHAT_CUT=Potong
plugin.keybindings.CHAT_PASTE=Rekat
plugin.keybindings.MAIN_RENAME=Ganti nama kontak
plugin.keybindings.globalchooser.SHORTCUT_NAME=Nama
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Bincang
# Notification Configuration Form
+plugin.notificationconfig.ENABLE_NOTIF=Hidupkan
plugin.notificationconfig.RESTORE=Kembalikan awal
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Panggilan masuk
plugin.notificationconfig.event.IncomingFile=Panggilan masuk
plugin.notificationconfig.event.HangUp=Gantung
@@ -1037,6 +936,7 @@ impl.media.configform.VIDEO_RESET=Kembalikan awal
impl.neomedia.configform.VIDEO=Video
+#in JNIEncoder
impl.neomedia.configform.H264.preferredKeyFrameRequester.rtcp=RTP
# The callrecordingconfig plugin was never really committed into trunk and its
@@ -1051,7 +951,6 @@ plugin.securityconfig.masterpassword.MP_CHANGE_SUCCESS_MSG=Kata sandi berhasil d
plugin.securityconfig.masterpassword.MP_REMOVE_SUCCESS_MSG=Kata sandi berhasil diubah
plugin.securityconfig.masterpassword.COL_NAME=Nama
plugin.securityconfig.masterpassword.COL_PASSWORD=Kata Sandi
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=Hapus
# otr plugin
plugin.otr.menu.CB_RESET=Ulang
@@ -1072,6 +971,7 @@ plugin.reconnectplugin.CONNECTION_FAILED_MSG=Koneksi gagal untuk akun berikut: N
#plugin chat config
plugin.chatconfig.TITLE=Bincang
+plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS=Hidupkan
#provisioning plugin
@@ -1085,7 +985,6 @@ net.java.sip.communicator.util.dns.SecureResolveMode.IgnoreDnssec=Abaikan
net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.Deny=Tolak
#plugin spellcheck
-plugin.spellcheck.EDIT_PERSONAL_DICT=&Edit
#Certificate configuration plugin
diff --git a/resources/languages/resources_it.properties b/resources/languages/resources_it.properties
index b70e7c0..b8ac264 100644
--- a/resources/languages/resources_it.properties
+++ b/resources/languages/resources_it.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Me
service.gui.ACCOUNT_REGISTRATION_WIZARD=Creazione guidata account
service.gui.ACCOUNTS=Account
service.gui.ADD=&Aggiungi
-service.gui.ADD_ACCOUNT=Aggiungi account
service.gui.ADD_CONTACT=&Aggiungi contatto
service.gui.ADD_AUTHORIZED_CONTACT=Aggiungi {0} ai tuoi contatti
service.gui.ADD_CONTACT_TO_CONTACTLIST=Aggiungi alla lista contatti
@@ -42,20 +52,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Errore durante la creazione del contatto
service.gui.ADD_CONTACT_EXIST_ERROR=Il contatto {0} esiste già nella tua rubrica.
service.gui.ADD_CONTACT_NETWORK_ERROR=Il server non ha risposto alla richiesta di aggiunta del contatto con id: {0}.
service.gui.ADD_CONTACT_NOT_SUPPORTED=Errore durante la creazione del contatto con id: {0}. Operazione non supportata.
-service.gui.ADD_CONTACT_IDENTIFIER=Inserisci l'identificativo del contatto che vuoi aggiungere nel campo sottostante.
-service.gui.ADD_CONTACT_WIZARD=Creazione guidata contatto
service.gui.ADD_CONTACT_NOT_CONNECTED=È necessario essere connessi per aggiungere un contatto. Effettua il login al provider selezionato e tenta di nuovo.
service.gui.ADD_GROUP_LOCAL_ERROR=Errore durante la creazione del gruppo {0}. Il problema si è verificato durante un'operazione I/O locale.
service.gui.ADD_GROUP_EXIST_ERROR=Il gruppo {0} esiste già nella tua rubrica. Scegli un altro nome.
service.gui.ADD_GROUP_NET_ERROR=Errore durante la creazione del gruppo {0}. Il problema si è verificato a causa di un errore di rete. Verifica la connessione e riprova.
service.gui.ADD_GROUP_ERROR=Errore durante la creazione del gruppo {0}.
service.gui.ADD_GROUP_EMPTY_NAME=Il nome del gruppo non può essere vuoto.
-service.gui.ADD_GROUP=Crea gruppo
-service.gui.ADD_SUBCONTACT=&Aggiungi sottocontatto
service.gui.ADDRESS=Indirizzo
service.gui.ADMINISTRATOR=amministratore
service.gui.ADVANCED=&Avanzate
-service.gui.ALL=&Tutti
service.gui.ALL_CONTACTS=&Tutti i contatti
service.gui.ALTERNATE_ADDRESS=Indirizzo alternativo
service.gui.APPLY=&Applica
@@ -65,7 +70,6 @@ service.gui.AT=alle
service.gui.AUTHORIZE=&Autorizza
service.gui.AUTHORIZATION_ACCEPTED={0} ha accettato la tua richiesta di autorizzazione.
service.gui.AUTHENTICATION_FAILED=Autenticazione fallita per {0}. La password inserita non è valida.
-service.gui.AUTHENTICATION_REQUESTED=Richiesta autenticazione
service.gui.AUTHENTICATION_REQUESTED_SERVER=Il server {0} ha richiesto la tua autenticazione.
service.gui.AUTHENTICATION_REJECTED={0} ha rifiutato la tua richiesta di autorizzazione.
service.gui.AUTHENTICATION_WINDOW_TITLE=autenticazione di {0}
@@ -107,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=Inserisci il tuo nuovo nickname nel campo sott
service.gui.CHANGE_NICKNAME_ERROR=Si è verificato un errore nel cambio del nickname
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Il nickname è già esistente
service.gui.CHANGE_VIDEO_QUALITY=Cambia la qualità del video ricevuto
-service.gui.CHAT_CONFERENCE_LABEL=Conferenze
service.gui.CHAT_CONFERENCE_ITEM_LABEL=Conferenza di {0}
service.gui.CHAT_ROOM_ALREADY_JOINED=Sei già entrato nella chatroom {0}.
service.gui.CHAT_ROOM_CONFIGURATION=Configurazione della chatroom {0}
@@ -121,18 +124,14 @@ service.gui.CHAT_ROOM_USER_LEFT=è uscito dalla chatroom {0}
service.gui.CHAT_ROOM_USER_KICKED=è stato espulso dalla chatroom {0}
service.gui.CHAT_ROOM_USER_QUIT=è uscito dalla chatroom {0}
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=Invio di messaggi non possibile (voce bloccata)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Salva la chatroom per usi futuri
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Rimuovi la chatroom selezionata dalla lista delle chatroom salvate
service.gui.CHAT_ROOM_NAME=Nome della chatroom
service.gui.CLEAR_CUSTOM_MESSAGES=Cancella i messaggi personalizzati
service.gui.ROOM_NAME=Chatroom
-service.gui.AUTOJOIN=Entra automaticamente
service.gui.CHANGE_PASSWORD=Cambia password
service.gui.CHAT_ROOM_NAME_INFO=Inserisci il nome della nuova chatroom nel campo sottostante.
service.gui.CHAT_ROOM_NOT_EXIST=Impossibile trovare la chatroom {0} sul server {1}. Verificare che il nome sia corretto.
service.gui.CHAT_ROOM_NOT_CONNECTED=Devi essere connesso per poter entrare nella chatroom {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Devi essere connesso per poter uscire da una chatroom.
-service.gui.CHAT_ROOM_NOT_JOINED=Devi essere nella chatroom per poter effettuare ulteriori operazioni con essa.
service.gui.CHAT_ROOM_OPTIONS=Opzioni della chatroom
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Per accedere alla chatroom {0} devi essere registrato.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Per accedere alla chatroom {0} devi conoscerne la password.
@@ -151,22 +150,18 @@ service.gui.CLEAR=Cancella
service.gui.CLOSE=C&hiudi
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Hai ricevuto un nuovo messaggio meno di 2 secondi fa. Sei sicuro di volere chiudere?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=Hai trasferimenti di file in corso. Sei sicuro di volerli annullare?
-service.gui.CONFIRM=Conferma
service.gui.CONNECTED_STATUS=Connesso
service.gui.CONNECTING=Connessione in corso...
service.gui.CONNECTING_STATUS=Connessione in corso
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Connessione in corso...
service.gui.CONNECTION=Connessione
-service.gui.CONNECTION_FAILED_MSG=Errore durante la connessione con il seguente account: Nome utente: {0}, Server: {1}. Controlla la tua connessione di rete o contatta il tuo amministratore di rete per maggiori informazioni.
service.gui.CONNECTION_EXPIRED_MSG=Sei attualmente disconnesso dal server {0}.
service.gui.CONTACT_NAME=ID o Numero
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Il contatto selezionato {0} non supporta le chiamate vocali.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Il contatto {0} non supporta le chat multiutente.
service.gui.CONTACT_PAUSED_TYPING={0} ha interrotto la digitazione
service.gui.CONTACT_TYPING={0} sta digitando
service.gui.CONTACT_TYPING_SEND_FAILED=ops... non abbiamo potuto dire a {0} che stavi scrivendo
service.gui.CONTACT_INFO=&Informazioni sul contatto
-service.gui.CONTACTLIST=Rubrica
service.gui.CONTACTS=Contatti
service.gui.COPY=&Copia
service.gui.COPY_LINK=Copia il &link
@@ -176,17 +171,14 @@ service.gui.CREATE_CHAT_ROOM=&Crea chatroom
service.gui.CREATE_CHAT_ROOM_ERROR=Errore durante la creazione della chatroom {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=Creazione guidata chatroom
service.gui.CREATE_CONFERENCE_CALL=&Crea chiamata vocale multiutente
-service.gui.CREATE_CONFERENCE_CHAT=&Crea chat multiutente
service.gui.CREATE_GROUP=&Crea gruppo
service.gui.CREATE_GROUP_NAME=Inserisci il nome del nuovo gruppo nel campo sottostante.
-service.gui.CREATE_FIRST_GROUP_WIZARD=La tua rubrica non contiene alcun gruppo. Creare prima un gruppo (File/Crea gruppo).
service.gui.CREATE_VIDEO_BRIDGE=Crea &videoconferenza...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Crea &videoconferenza
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Crea o unisciti a una videoconferenza
service.gui.CREATE_VIDEO_CONFERENCE=Crea una nuova videoconferenza per questa chatroom
service.gui.CONTACT_INFO_NOT_SUPPORTED=Questo contatto non supporta la trasmissione delle sue informazioni
service.gui.CUT=Taglia
-service.gui.DATE=Data
service.gui.DELETE=Rimuovi
service.gui.DENY=&Nega
service.gui.DESKTOP_SHARING_WARNING=<b>Sei sicuro di voler iniziare la condivisione dello schermo?</b> <br> Premendo OK i contatti presenti in questa chiamata vedranno il tuo schermo.
@@ -197,7 +189,6 @@ service.gui.DISCONNECTED_STATUS=Disconnesso
service.gui.DND_STATUS=Non disturbare
service.gui.DO_NOT_ASK_AGAIN=Non chiedere in futuro
service.gui.DO_NOT_SHOW_AGAIN=Non mostrare questo messaggio in futuro
-service.gui.DOWNLOAD_NOW=&Scarica ora
service.gui.DRAG_FOR_SHARING=Trascina qui ciò che vuoi condividere...
service.gui.DURATION=Durata
service.gui.DESTROY_CHATROOM=Elimina la chatroom
@@ -218,7 +209,6 @@ service.gui.ERROR_RECEIVED_FROM=Errore ricevuto da {0}
service.gui.ESTIMATED_TIME=Tempo stimato:
service.gui.EVENTS=Eventi
service.gui.EXIT=&Esci
-service.gui.EXTENDED_CRITERIA=Criteri avanzati
service.gui.GENERAL=Generale
service.gui.GENERAL_ERROR=Errore generico
service.gui.GROUP_NAME=Nome gruppo
@@ -260,7 +250,6 @@ service.gui.FONT_ITALIC=Corsivo
service.gui.FONT_SIZE=Dimensione
service.gui.FONT_STYLE=Stile
service.gui.FONT_UNDERLINE=Sottolineato
-service.gui.FROM={0} da {1}
service.gui.GRANT_OWNERSHIP=Concedi stato di proprietario
service.gui.GRANT_ADMIN=Concedi stato di amministratore
service.gui.GRANT_MODERATOR=Concedi stato di moderatore
@@ -286,7 +275,6 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=Sei sicuro di voler rimuovere permanentem
service.gui.HISTORY_REMOVE_ERROR=Errore nella rimozione dei messaggi salvati.
service.gui.HOME=Casa
service.gui.HOME_PAGE=Home page
-service.gui.HOUR=Ora
service.gui.ICE=ICE
service.gui.IDENTIFIER=Identificativo
service.gui.IGNORE=&Ignora
@@ -294,6 +282,7 @@ service.gui.INSERT_SMILEY=Inserisci smiley
service.gui.INCOMING_CALL=Ricevuta chiamata in entrata da: {0}
service.gui.INCOMING_SCREEN_SHARE=Ricevuto un invito per la condivisione dello schermo da: {0}
service.gui.INCOMING_CALL_STATUS=Chiamata in arrivo
+service.gui.INCOMING_SCREEN_SHARE_STATUS=Condivisione schermo in arrivo
service.gui.INSTANT_MESSAGINGS=IM
service.gui.IM=IM
service.gui.INITIATING_CALL_STATUS=Inizializzazione della chiamata
@@ -309,13 +298,10 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Invita contatti per una videoconferen
service.gui.INVITE_REASON=Motivo dell'invito
service.gui.IS_CALLING={0} sta chiamando...
service.gui.IS_NOW={0} è ora {1}
-service.gui.JITSI_WARNING=SIP Communicator è stato recentemente rinominato in Jitsi.<br/>Se vuoi che la tua versione rimanga aggiornata, scarica Jitsi ora.<br/><br/>Ci scusiamo per ogni inconveniente che questo possa causarti.<br/><br/>Il team di sviluppatori di Jitsi
-service.gui.JITSI_WARNING_TITLE=SIP Communicator è diventato Jitsi
service.gui.JOIN=&Entra
service.gui.JOIN_AS=E&ntra come
-service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=Unisciti ad una sessione di videoconferenza esistente
+service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=Unisciti ad una videoconferenza in corso
service.gui.JOIN_VIDEO=Unisciti con il video
-service.gui.CLOSE_CHAT_ROOM_DIALOG=C&hiudi
service.gui.JOB_TITLE=Titolo professionale
service.gui.JOIN_CHAT_ROOM=&Entra in una chatroom
service.gui.JOIN_CHAT_ROOM_TITLE=Entra in una chatroom
@@ -328,7 +314,6 @@ service.gui.KICK_FAILED=Espulsione fallita
service.gui.KICK_FAILED_GENERAL_ERROR=Impossibile espellere {0}. Si è verificato un errore generico sul server.
service.gui.KICK_FAILED_NOT_ALLOWED=Impossibile espellere {0}. Il proprietario e l''amministratore della chatroom non possono essere espulsi.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Impossibile espellere {0}. Non hai privilegi sufficienti per farlo.
-service.gui.LAST=Ultimo
service.gui.LAST_NAME=Cognome
service.gui.LEAVE=&Esci
service.gui.LIMIT_REACHED_FOR_IP=Limite registrazioni per il tuo indirizzo IP raggiunto sul server {0}.
@@ -348,7 +333,6 @@ service.gui.MESSAGE=Messaggio
service.gui.MISSED_CALLS_TOOL_TIP=Chiamate perse da:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= e altri {0}
service.gui.MODERATOR=moderatore
-service.gui.MORE=Vedi altro
service.gui.MORE_LABEL=Ancora
service.gui.MOVE=Sposta
service.gui.MOVE_SUBCONTACT=Sp&osta contatto
@@ -357,7 +341,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=Il contatto selezionato coincide con quello \
service.gui.MOVE_SUBCONTACT_QUESTION=Sei sicuro di voler spostare {0} in {1}?
service.gui.MOVE_TO_GROUP=&Sposta nel gruppo
service.gui.MOVE_CONTACT=Sposta contatto
-service.gui.MOVE_CONTACT_ERROR=Il contatto non può essere spostato
service.gui.MSG_DELIVERY_FAILURE=Impossibile consegnare il messaggio
service.gui.MSG_DELIVERY_NOT_SUPPORTED=Il protocollo che stai utilizzando non supporta i messaggi offline. Puoi provare a raggiungere {0} attraverso un altro account o aspettare che torni online.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Errore interno. Questo è quasi sicuramente un bug. Riportalo qui: https://jitsi.org/Development/BugsAndIssues.
@@ -371,7 +354,6 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=Devi essere connesso per poter inviare m
service.gui.MULTIPLE_LOGINS=Impossibile effettuare login multipli per il seguente account: Nome utente: {0}, Server: {1}. Esso è attualmente disconnesso.
service.gui.MY_CHAT_ROOMS=Aggiungi chat room
service.gui.MY_CHAT_ROOMS_TITLE=Aggiungi chat room
-service.gui.MUTE=Silenzioso
service.gui.MUTUALLY_ON_HOLD_STATUS=Chiamata messa in attesa reciprocamente
service.gui.NAME=Nome
service.gui.NETWORK=Rete
@@ -403,7 +385,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=Non nella lista contatti
service.gui.SD_QUALITY=Qualità normale
service.gui.OFFLINE=Disconnesso
service.gui.OK=&OK
-service.gui.OLDER_CALLS=Chiamate precedenti
service.gui.ONLINE=Connesso
service.gui.OPEN=Apri
service.gui.OPEN_FILE_FROM_IMAGE=Doppio click per aprire il file.
@@ -415,7 +396,6 @@ service.gui.OPEN_ON_ACTIVITY=Apri in caso di attività
service.gui.OPEN_ON_MESSAGE=Apri in caso di nuovi messaggi
service.gui.OPEN_ON_IMPORTANT_MESSAGE=Apri solo in caso di messaggi importanti
service.gui.OR=o
-service.gui.OR_ENTER_PHONE_NUMBER=Oppure inserisci qui il numero di telefono
service.gui.ORGANIZATION=Organizzazione
service.gui.OTHER=Altro
service.gui.chat.role.OWNER=Proprietario
@@ -424,6 +404,7 @@ service.gui.chat.role.MODERATOR=Moderatore
service.gui.chat.role.MEMBER=Membro
service.gui.chat.role.GUEST=Ospite
service.gui.chat.role.SILENT_MEMBER=Membro silenzioso
+service.gui.chat.role.OUTCAST=Bandito dalla partecipazione
service.gui.OWNER=proprietario della chatroom
service.gui.ON_MOBILE_TOOLTIP=(su dispositivo mobile)
service.gui.PASSWORD=Password
@@ -440,7 +421,6 @@ service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Invio' per suggerimenti
service.gui.PRESS_FOR_CALL_INFO=Premere per informazioni sulla chiamata
service.gui.PRESS_TO_OPEN_CRM=Premi per aprire l'applicazione CRM
service.gui.PREVIOUS=Precedente
-service.gui.PREVIOUS_TOOLTIP=Sfoglia conversazioni più vecchie
service.gui.PRINT=&Stampa
service.gui.PROACTIVE_NOTIFICATION=sta scrivendo un messaggio
service.gui.PROBLEMS_ENCOUNTERED=Sono stati incontrati dei problemi
@@ -456,7 +436,6 @@ service.gui.RECONNECTION_LIMIT_EXCEEDED=Ti sei disconnesso e riconnesso al serve
service.gui.RE_REQUEST_AUTHORIZATION=Richiedi nuovamente l'autorizzazione
service.gui.REFERRED_STATUS=Inoltrata
service.gui.REJECT=&Rifiuta
-service.gui.REMIND_ME_LATER=Ricorda in seguito
service.gui.REMEMBER_PASSWORD=Ricorda password
service.gui.REMOVE=&Rimuovi
service.gui.REMOVE_ACCOUNT=&Rimuovi account
@@ -482,29 +461,20 @@ service.gui.REVOKE_ADMIN=Revoca status di amministratore
service.gui.REVOKE_MODERATOR=Revoca status di moderatore
service.gui.REVOKE_MEMBERSHIP=Revoca stato di membro
service.gui.REVOKE_VOICE=Revoca voce
-service.gui.ROOT_GROUP=Gruppo radice
service.gui.SAVE=&Salva
-service.gui.SAVE_AS_DEFAULT=Salva come predefiniti
service.gui.SEARCH=&Cerca
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Clicca il bottone sottostante per mostrare tutte le chatroom disponibili nel server selezionato. Seleziona la chatroom in cui intendi entrare e premi il bottone entra.
service.gui.SEARCH_STRING_CONTACT_SOURCE=Contatti cercati
service.gui.SECURITY=Sicurezza
-service.gui.SELECT_ACCOUNT=Seleziona account
service.gui.SELECT_COLOR=Seleziona colore
service.gui.SELECT_GROUP=Seleziona gruppo
-service.gui.SELECT_GROUP_WIZARD_MSG=La lista sottostante contiene tutti i gruppi presenti nella tua rubrica. Seleziona quello in cui vuoi inserire il nuovo contatto.
service.gui.SELECT_NO_GROUP=Nessun gruppo
-service.gui.SELECT_GROUP_WIZARD=Specifica gruppo
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=La lista sottostante contiene tutti gli account che supportano chat multiutente. Seleziona quella che vuoi utilizzare per creare la nuova chatroom.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=La lista sottostante contiene tutti gli account registrati. Seleziona quello che vuoi utilizzare per comunicare con il nuovo contatto.
-service.gui.SELECT_PROVIDERS_WIZARD=Seleziona account
service.gui.SELECT_VIDEO_CONFERENCE=Seleziona la videoconferenza
service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Seleziona una chat room dall'elenco e premi OK per aggiungerla
service.gui.SEND=&Invia
service.gui.SEND_FILE=Invia &file
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Nessuna informazione disponibile per questo contatto.
service.gui.SEND_MESSAGE=&Invia un messaggio
-service.gui.SEND_AS_SMS=Invia come SMS
service.gui.SEND_PRIVATE_MESSAGE=Invia messaggio privato
service.gui.SEND_SMS=Invia &SMS
service.gui.SEND_SMS_DETAILS=Ricorda che devi inserire il numero in formato internazionale, anteponendo, ad esempio, il prefisso +44 nel caso dell'UK (es. +447777000000)
@@ -543,7 +513,6 @@ service.gui.STREET=Via
service.gui.SUBJECT=Oggetto
service.gui.SUMMARY=Sommario
service.gui.TELEPHONY=Telefonia
-service.gui.TODAY=Oggi
service.gui.TOOLS=&Strumenti
service.gui.TRANSFER=Tras&ferisci
service.gui.TO=&A:
@@ -553,7 +522,6 @@ service.gui.TRANSFER_CALL_TO=Trasferisci a:
service.gui.TRANSPARENCY_NOT_ENABLED=La trasparenza non è supportata dalla configurazione attuale.
service.gui.TYPE_YOUR_REQUEST=Inserisci la richiesta qui
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Non è stato possibile cambiare la qualità del video per questa chiamata.
-service.gui.UNMUTE=Disabilita silenzioso
service.gui.USER_IDENTIFIER=Identificativo utente:
service.gui.USER_EXISTS_ERROR=Questo utente esiste già nella rete selezionata. Scegliere un altro utente o un'altra rete.
service.gui.USERNAME_NULL=Devi riempire i campi relativi a Nome utente e password.
@@ -566,7 +534,6 @@ service.gui.USE_PROVISIONING=Usa il provisioning di rete
service.gui.VALUE=Valore
service.gui.VIDEO_CALL=Chiamata &video
service.gui.VIA=via
-service.gui.VIA_SMS=Via SMS
service.gui.VIEW=&Visualizza
service.gui.VIEW_HISTORY=Visualizza &cronologia
service.gui.VIEW_SMILEYS=Visualizza &smiley
@@ -586,9 +553,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=Imposta volume
service.gui.WAITING_AUTHORIZATION=In attesa di autorizzazione
service.gui.WARNING=Avviso
service.gui.YES=Sì
-service.gui.YESTERDAY=Ieri
-service.gui.EXISTING_ACCOUNT_ERROR=L'account inserito è già installato.
-service.gui.NEW_MAIL=<b>Hai una nuova Mail!</b><br/><b>Da:</b> {0} {1} <br/><b>Oggetto:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=Hai ricevuto un nuovo messaggio di posta nella tua <a href="{1}">casella</a> {0}:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=Hai ricevuto {2} nuovi messaggi di posta nella tua <a href="{1}">casella</a> {0}:<br/>
service.gui.NEW_GMAIL_FOOTER=un''altra conversazione non letta nella tua <a href="{0}">casella</a>.<br/>
@@ -600,7 +564,10 @@ service.gui.ENTER_FULL_SCREEN_TOOL_TIP=Entra nella modalità a tutto schermo
service.gui.EXIT_FULL_SCREEN_TOOL_TIP=Esci dalla modalità a tutto schermo
service.gui.HOLD_BUTTON_TOOL_TIP=Commuta stato di attesa
service.gui.MUTE_BUTTON_TOOL_TIP=Attiva/disattiva audio o mantieni premuto per cambiare il volume del microfono
-service.gui.RECORD_BUTTON_TOOL_TIP=Attiva/disattiva registrazione chiamata
+service.gui.PARK=Parcheggia
+service.gui.PARKING_SLOT=Numero del parcheggio:
+service.gui.PARK_BUTTON_TOOL_TIP=Inoltra chiamata
+service.gui.RECORD_BUTTON_TOOL_TIP=Parcheggia la chiamata
service.gui.LOCAL_VIDEO_BUTTON_TOOL_TIP=Video on/off
service.gui.SHOW_LOCAL_VIDEO_BUTTON_TOOL_TIP=Mostra/nascondi video locale
service.gui.SHOW_HIDE_PEERS_TOOL_TIP=Mostra/nascondi la lista dei partecipanti
@@ -612,7 +579,6 @@ service.gui.SECURITY_ERROR=Errore di sicurezza
service.gui.SPEED=Velocità:
service.gui.SILENT_MEMBER=membro silenzioso
service.gui.NON_SECURE_CONNECTION=Non è stato possibile instaurare una connessione sicura per l''account {0}. Se vuoi connetterti ad un server non sicuro abilita "Permetti connessioni insicure" nelle impostazioni dell'account
-service.gui.UPDATE=Aggiorna
service.gui.MOBILE_PHONE=Cellulare
service.gui.VIDEO_PHONE=Video
service.gui.WORK_PHONE=Lavoro
@@ -647,7 +613,6 @@ service.gui.callinfo.CALL_INFORMATION=Informazioni sulla chiamata
service.gui.callinfo.CALL_IDENTITY=Identità
service.gui.callinfo.PEER_COUNT=Numero di partecipanti
service.gui.callinfo.IS_CONFERENCE_FOCUS=Controllore della conferenza
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Cifratura attivata
service.gui.callinfo.CALL_TRANSPORT=Trasporto segnali di chiamata
service.gui.callinfo.CALL_DURATION=Durata
service.gui.callinfo.TLS_PROTOCOL=Protocollo TLS
@@ -661,7 +626,6 @@ service.gui.callinfo.AUDIO_INFO=Informazioni sull'audio
service.gui.callinfo.VIDEO_INFO=Informazioni sul video
service.gui.callinfo.LOCAL_IP=IP / Porta locali
service.gui.callinfo.REMOTE_IP=IP / Porta remoti
-service.gui.callinfo.BANDWITH=Larghezza di banda
service.gui.callinfo.LOSS_RATE=Tasso di perdita
service.gui.callinfo.RTT=RTT
service.gui.callinfo.JITTER=Jitter
@@ -671,10 +635,13 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=Protocollo di scambio della chiave
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=Tipo esteso del candidato ICE
service.gui.callinfo.ICE_STATE=Stato del processamento ICE
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=Raccolta dei canditati
service.gui.callinfo.ICE_STATE.RUNNING=Controlli di connettività
service.gui.callinfo.ICE_STATE.COMPLETED=Completato
service.gui.callinfo.ICE_STATE.FAILED=Fallito
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=IP / Porta locali
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=Indirizzo (IP / Porta) reflexive dell'host locale
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=Indirizzo (IP / Porta) relayed dell'host locale
@@ -695,15 +662,18 @@ service.gui.ALWAYS_TRUST=Accetta sempre questo certificato
service.gui.CERT_DIALOG_TITLE=Verifica certificato
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} non può verificare l''identità del server durante la connessione a<br><b>{1}</b>.<br><br> Il certificato non è affidabile, questo significa che l''identità del server non può essere verificata automaticamente.<br><br> Desideri continuare?<br> Per maggiori informazioni, clicca su "Mostra certificato".</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0} non può verificare l''identità del certificato del server.<br><br> Il certificato non è affidabile, questo significa che l''identità del server non può<br> essere verificata automaticamente. Desideri continuare?<br><br> Per maggiori informazioni, clicca su "Mostra certificato".</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} non può verificare l''identità del client che si sta collegando.<br><br> Il certificato non è affidabile, questo significa che l''identità del client non può<br> essere verificata automaticamente. Desideri accettare la connessione?<br><br> Per maggiori informazioni, clicca su "Mostra certificato".</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} non può verificare l''identità del nodo {1}.<br><br> Il certificato non è affidabile, questo significa che l''identità del nodo non può<br> essere verificata automaticamente. Desideri continuare la connessione?<br><br> Per maggiori informazioni, clicca su "Mostra certificato".</html>
service.gui.CONTINUE_ANYWAY=Continua comunque
service.gui.CERT_INFO_CHAIN=Catena dei certificati:
+service.gui.CERT_INFO_ISSUED_TO=Emesso a
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Nome comune:
service.gui.CERT_INFO_O=Organizzazione:
service.gui.CERT_INFO_C=Nazione:
service.gui.CERT_INFO_ST=Stato o provincia:
service.gui.CERT_INFO_L=Località:
+service.gui.CERT_INFO_ISSUED_BY=Emesso da
service.gui.CERT_INFO_OU=Unità organizzativa:
service.gui.CERT_INFO_VALIDITY=Validità
service.gui.CERT_INFO_ISSUED_ON=Rilasciato il:
@@ -716,12 +686,10 @@ service.gui.CERT_INFO_SIGN_ALG=Algoritmo firma:
service.gui.CERT_INFO_PUB_KEY_INFO=Informazioni sulla chiave pubblica
service.gui.CERT_INFO_ALG=Algoritmo:
service.gui.CERT_INFO_PUB_KEY=Chiave pubblica:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} bytes: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} bits
service.gui.CERT_INFO_EXP=Esponente:
service.gui.CERT_INFO_KEY_SIZE=Dimensione chiave:
service.gui.CERT_INFO_SIGN=Firma certificato:
-service.gui.CONTINUE=Continua
service.gui.SHOW_CERT=Mostra certificato
service.gui.HIDE_CERT=Nascondi certificato
@@ -744,12 +712,9 @@ service.gui.security.SECURE_AUDIO=Audio protetto
service.gui.security.AUDIO_NOT_SECURED=Audio non protetto
service.gui.security.SECURE_VIDEO=Video protetto
service.gui.security.VIDEO_NOT_SECURED=Video non protetto
-service.gui.security.NO_VIDEO=Video assente
-service.gui.security.CIPHER=Cifrario: {0}
service.gui.security.CALL_SECURED_TOOLTIP=Chiamata protetta. Per maggiori informazioni clicca qui.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Chiamata non sicura.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Premi qui per confrontare le chiavi di codifica con il tuo partner.
-service.gui.security.COMPARE_WITH_PARTNER=Confronta il codice con il tuo interlocutore e clicca sul lucchetto per confermare.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Confronta con l'interlocutore:
service.gui.security.STRING_COMPARED=Stringa confrontata!
@@ -767,20 +732,14 @@ service.gui.avatar.imagepicker.CLICK=Clicca e Sorridi
service.gui.avatar.imagepicker.IMAGE_FILES=File di immagine
service.gui.avatar.imagepicker.IMAGE_PICKER=Foto
service.gui.avatar.imagepicker.IMAGE_SIZE=Dimensione immagine
-service.gui.avatar.imagepicker.INITIALIZING=Inizializzazione
service.gui.avatar.imagepicker.RESET=Ripristina
service.gui.avatar.imagepicker.SET=Imposta
service.gui.avatar.imagepicker.TAKE_PHOTO=Scatta una foto
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Errore della webcam
service.gui.security.encryption.required=Cifratura necessaria!
service.protocol.ICE_FAILED=Impossibile stabilire una connessione (ICE fallito e nessun Relay trovato)
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
impl.protocol.sip.XCAP_ERROR_TITLE=Errore nell'archiviazione della lista contatti SIP
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=La risorsa non può essere letta {0}. Per {1}
@@ -810,9 +769,7 @@ impl.ldap.QUERY_CUSTOM=Query personalizzata
impl.ldap.QUERY_CUSTOM_HINT=Usa {0} come segnaposto per il termine di ricerca
impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=Aggiungi automaticamente i caratteri jolly ai termini della query
impl.ldap.QUERY_PHOTO_INLINE=Recupera la foto assieme agli altri attributi
-impl.ldap.NEW=Nuovo
impl.ldap.EDIT=modifica
-impl.ldap.REMOVE=Rimuovi
impl.ldap.ENABLED=Abilitato
impl.ldap.SERVER_NAME=Nome del server
impl.ldap.SERVER_NAME_EXAMPLE=Il mio server LDAP
@@ -845,6 +802,10 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=telefonoCasa
impl.ldap.PHONE_PREFIX=Prefisso telefonico
impl.ldap.PHONE_PREFIX_EXAMPLE=Es.: 00
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=Rubrica
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=Abilita la ricerca nella Rubrica di MacOSX
@@ -854,14 +815,12 @@ plugin.addrbook.DEFAULT_IM_APP=Imposta Jitsi come programma di messaggistica pre
plugin.addrbook.PREFIX=Specifica un prefisso per i numeri telefonici
plugin.addrbook.PREFIX_EXAMPLE=Es.: 00
plugin.addrbook.OUTLOOK_IS_NOT_DEFAULT_MAIL_CLIENT_TITLE=Errore nell'accesso ai contatti di Microsoft Outlook.
-plugin.addrbook.OUTLOOK_IS_NOT_DEFAULT_MAIL_CLIENT={0} non può accedere ai contatti di Microsoft Outlook perchè Outlook non è impostato come applicazione di posta predefinita.
+plugin.addrbook.OUTLOOK_IS_NOT_DEFAULT_MAIL_CLIENT={0} non può accedere ai contatti di Microsoft Outlook perché Outlook non è impostato come applicazione di posta predefinita.
plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT=Imposta Outlook come applicazione di posta predefinita
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Contatti Google
-impl.googlecontacts.NEW=Nuovo
impl.googlecontacts.EDIT=modifica
-impl.googlecontacts.REMOVE=Rimuovi
impl.googlecontacts.ENABLED=Abilitato
impl.googlecontacts.ACCOUNT_NAME=Nome account
impl.googlecontacts.SAVE=Salva
@@ -900,11 +859,8 @@ plugin.accountinfo.ORGANIZATION=Nome organizzazione:
plugin.accountinfo.JOB_TITLE=Qualifica:
plugin.accountinfo.ABOUT_ME=Informazioni su di me:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
-plugin.accountinfo.USER_PICTURES=Foto dell'utente
plugin.accountinfo.GLOBAL_ICON=Usa icona globale
plugin.accountinfo.LOCAL_ICON=Usa questa icona
-plugin.accountinfo.CHANGE=Cambia
-plugin.accountinfo.ONLY_MESSAGE=Solo messaggi
# connection info
plugin.connectioninfo.TITLE=Informazioni sulla connessione
@@ -924,49 +880,13 @@ plugin.aimaccregwizz.USERNAME=Nome utente AIM:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Nome utente e password
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Registra nuovo account
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Se non hai un account AIM, premi questo bottone per crearne uno nuovo.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Sovrascrivi le opzioni predefinite del server
# branding
plugin.branding.ABOUT_WINDOW_TITLE=Informazioni su {0}
plugin.branding.LOGO_MESSAGE=VoIP && Messaggistica Istantanea Open Source
-plugin.branding.LOADING=Caricamento in corso
plugin.branding.ABOUT_MENU_ENTRY=&Informazioni su...
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>{1} è sotto attivo sviluppo. La versione che stai utilizzando è sperimentale e POTREBBE NON funzionare come previsto. Consulta {2} per maggiori informazioni.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 Copyright <b>jitsi.org</b>. Tutti i diritti riservati. Visita <a href="https://jitsi.org">https://jitsi.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}><b>Jitsi</b> è distribuito sotto i termini della LGPL (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=Dizionari
-plugin.dictaccregwizz.ANY_DICTIONARY=Qualunque dizionario
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Qualunque dizionario da {0}
-plugin.dictaccregwizz.FIRST_MATCH=Prima corrispondenza
-plugin.dictaccregwizz.NO_MATCH=Nessuna corrispondenza
-plugin.dictaccregwizz.MATCH_RESULT=Nessuna definizione trovata per "{0}", forse intendevi:\n
-plugin.dictaccregwizz.INVALID_DATABASE=Il dizionario attuale "{0}" non esiste più sul server.
-plugin.dictaccregwizz.INVALID_STRATEGY=La strategia attuale non è disponibile sul server.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=Il protocollo Dict
-plugin.dictaccregwizz.HOST=Server
-plugin.dictaccregwizz.SERVER_INFO=Informazioni server
-plugin.dictaccregwizz.STRATEGY_SELECTION=Seleziona strategia
-plugin.dictaccregwizz.STRATEGY_LIST=Lista strategie:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Cerca strategie
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=Una strategia è utilizzata per cercare parole simili, se una traduzione non è stata trovata, grazie a differenti approcci. Ad esempio le strategie Prefix cercano parole che iniziano come la parola che vuoi tradurre.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Informazione account Dict
-plugin.dictaccregwizz.FIRST_ACCOUNT=Questa procedura guidata creerà il tuo primo account Dict per te su dict.org.\n\nPuoi aggiungere nuovi dizionari entrando nella Procedura guidata di registrazione account. Riempi il campo host con il dizionario che vuoi aggiungere.
-plugin.dictaccregwizz.THREAD_CONNECT=Sto tentando di connettermi al server
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=Connessione fallita: questo non è un server dict oppure il server è offline
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=Scaricamento strategie in corso
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Nessuna strategia trovata sul server
-plugin.dictaccregwizz.POPULATE_LIST=Sto popolando la lista
-plugin.dictaccregwizz.CLOSING_CONNECTION=Chiusura connessione in corso
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Per poter utilizzare la chat di Facebook devi creare un nome utente <br>dalla pagina "Impostazioni account" su Facebook.</a><br><br>Nota: Quando hai creato un nome utente devi effetturare il logout dalla pagina web <br>e potrebbe passare del tempo prima che tu possa effettuare il login con il nuovo nome utente!</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=Il protocollo Facebook
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Nome utente:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Nome utente e Password
+
+plugin.busylampfield.PICKUP=Raccogli chiamata
# generalconfig
plugin.generalconfig.AUTO_START=Esegui automaticamente {0} quando il computer viene avviato
@@ -977,9 +897,6 @@ plugin.generalconfig.SHOW_HISTORY=Mostra
plugin.generalconfig.HISTORY_SIZE=messaggi recenti nelle nuove chat
plugin.generalconfig.SEND_MESSAGES_WITH=Invia messaggi con:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=Poni la finestra di chat in primo piano
-plugin.generalconfig.ERROR_PERMISSION=Non hai permessi sufficienti per rimuovere l'avvio automatico
-plugin.generalconfig.TRANSPARENCY=Trasparenza
-plugin.generalconfig.ENABLE_TRANSPARENCY=Abilita trasparenza
plugin.generalconfig.DEFAULT_LANGUAGE=Lingua interfaccia
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=I cambiamenti effettuati saranno effettivi al prossimo avvio del programma.
plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0}% tradotto
@@ -1036,13 +953,19 @@ plugin.ircaccregwizz.HOST=Server:
plugin.ircaccregwizz.IRC_SERVER=Server
plugin.ircaccregwizz.EXAMPLE_SERVER=Es: chat.freenode.net
plugin.ircaccregwizz.USE_SECURE_CONNECTION=Usa connessione sicura
+plugin.ircaccregwizz.ENABLE_CONTACT_PRESENCE=Rileva presenza contatti
+plugin.ircaccregwizz.ENABLE_CHAT_ROOM_PRESENCE=Rileva presenze nella chat room
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE=Autenticazione SASL
+plugin.ircaccregwizz.ENABLE_SASL_AUTHENTICATION=Abilita autenticazione SASL
+plugin.ircaccregwizz.SASL_USERNAME=Nome utente
+plugin.ircaccregwizz.SASL_AUTHZ_ROLE=Ruolo
+plugin.ircaccregwizz.SASL_IRC_PASSWORD_USED=La password IRC sopra è usata per l'autenticazione SASL
+plugin.ircaccregwizz.RESOLVE_DNS_THROUGH_PROXY=Risolvi sempre i nomi DNS attraverso il proxy
# jabber accregwizz
-plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=Il protocollo XMPP
plugin.jabberaccregwizz.USERNAME=Nome utente XMPP
plugin.jabberaccregwizz.PASSWORD_CONFIRM=Conferma password
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=Nome utente e password
plugin.jabberaccregwizz.CSERVER=Server
plugin.jabberaccregwizz.SERVER=Connetti server
plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=Abilita keep alive
@@ -1058,13 +981,9 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Commento
plugin.jabberaccregwizz.RESOURCE=Risorsa
plugin.jabberaccregwizz.AUTORESOURCE=Genera la risorsa automaticamente
plugin.jabberaccregwizz.PRIORITY=Priorità
-plugin.jabberaccregwizz.XMPP_ERROR=Errore XMPP
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Errore XMPP sconosciuto ({0}). Controlla che il nome del server sia corretto.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Le password non corrispondono.
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Sovrascrivi le opzioni di default del server
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Opzioni avanzate
plugin.jabberaccregwizz.USE_ICE=Usa ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=Usa Jingle/ICE di Google (sperimentale)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=Scopri automaticamente i server STUN/TURN
plugin.jabberaccregwizz.SUPPORT_TURN=Abilita TURN
plugin.jabberaccregwizz.TURN_USERNAME=Nome utente TURN
@@ -1088,14 +1007,12 @@ plugin.jabberaccregwizz.EXISTING_ACCOUNT=Account XMPP esistente
plugin.jabberaccregwizz.DOMAIN_BYPASS_CAPS=Dominio per le chiamate GTalk
plugin.jabberaccregwizz.TELEPHONY_DOMAIN=Dominio telefonico
plugin.jabberaccregwizz.ALLOW_NON_SECURE=Permetti connessioni insicure
+plugin.jabberaccregwizz.DISABLE_CARBON=Disabilita le copie carbone dei messaggi
plugin.jabberaccregwizz.DTMF_AUTO=Auto: Scegli automaticamente tra RTP e Inband
plugin.jabberaccregwizz.SERVER_OPTIONS=Opzioni del server
plugin.jabberaccregwizz.CHANGE_PASSWORD=Cambia la password dell'account
-plugin.jabberaccregwizz.NEW_PASSWORD=Nuova password
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Conferma nuova password
plugin.jabberaccregwizz.PORT_FIELD_INVALID=Inserisci una porta del server valida per continuare
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=Devi essere loggato all'account prima di poter cambiare la password.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=Il campo della password è vuoto.
plugin.jabberaccregwizz.TLS_REQUIRED=La connessione non usa TLS, quindi non sarà effettuato il cambio della password.
plugin.jabberaccregwizz.PASSWORD_CHANGED=La password è stata cambiata correttamente
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=Questo server XMPP non supporta il cambio della password.
@@ -1109,25 +1026,9 @@ plugin.jabberaccregwizz.RESET=Ripristina
plugin.jabberaccregwizz.RESET_DESCRIPTION=Ripristina alle impostazioni globali
plugin.jabberaccregwizz.DISABLE_JINGLE=Disabilita Jingle (chiamate vocali e videochiamate tramite XMPP).
-# mailbox
-plugin.mailbox.OUTGOING=Messaggio in uscita:
-plugin.mailbox.INCOMING=Messaggi in arrivo:
-plugin.mailbox.WAIT_TIME=Attesa prima che la chiamata venga trasferita alla casella vocale
-plugin.mailbox.MAX_MESSAGE_TIME=Durata massima dei messaggi in arrivo
-plugin.mailbox.CONFIRM=Conferma
-plugin.mailbox.DEFAULTS=Default
-plugin.mailbox.MAILBOX=Casella di posta elettronica
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Un protocollo per connettersi e chattare su MSN.
-plugin.msnaccregwizz.USERNAME=Email:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=ID e password
-
# plugin manager
plugin.pluginmanager.INSTALL=Installa
plugin.pluginmanager.UNINSTALL=Disinstalla
-plugin.pluginmanager.UPDATE=Aggiorna
plugin.pluginmanager.PLUGINS=Plug-in
plugin.pluginmanager.URL=Url
plugin.pluginmanager.CHOOSE_FILE=Seleziona file
@@ -1152,7 +1053,6 @@ plugin.sipaccregwizz.SERVER_PORT=Porta server
plugin.sipaccregwizz.PROXY=Proxy
plugin.sipaccregwizz.PROXY_PORT=Porta del proxy
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Trasporto preferenziale
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Opzioni avanzate
plugin.sipaccregwizz.PROXY_OPTIONS=Opzioni del proxy
plugin.sipaccregwizz.PROXY_AUTO=Configura il proxy server automaticamente
plugin.sipaccregwizz.ENABLE_PRESENCE=Attiva presenza (SIMPLE)
@@ -1172,8 +1072,6 @@ plugin.sipaccregwizz.DTMF_AUTO=Auto: Scegli automaticamente tra RTP e Inband (no
plugin.sipaccregwizz.DTMF_RTP=RTP ( RFC2833 / RFC 4733 )
plugin.sipaccregwizz.DTMF_SIP_INFO=SIP INFO
plugin.sipaccregwizz.DTMF_INBAND=Inband
-plugin.sipaccregwizz.REGISTER=REGISTER
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Sovrascrivi le opzioni di default del server
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Abilita supporto per chiamate criptate
plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=Annuncia il supporto di ZRTP nel protocollo di segnalazione
plugin.sipaccregwizz.AUTH_NAME=Authorization name
@@ -1194,10 +1092,10 @@ plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=URI per il controllo della casella voca
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Le password non corrispondono.
plugin.sipaccregwizz.NO_CERTIFICATE=<nessuno> (usa l'autenticazione tradizionale)
plugin.sipaccregwizz.SAVP_OPTION=Indicazione RTP/SAVP
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=Off (annuncia solo il supporto per RTP/AVP)
plugin.sipaccregwizz.SAVP_OPTION_1=Obbligatorio (offri e accetta solo RTP/SAVP)
plugin.sipaccregwizz.SAVP_OPTION_2=Opzionale (preferisci RTP/SAVP a RTP/AVP, ma accetta entrambi)
-plugin.sipaccregwizz.ENABLE_SDES_ATTRIBUTE=Abilita il "Descrittore S" (conosciuto anche come SDES o SRTP)
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=Scegli i protocolli di cifratura da abilitare e la loro priorità (il più importante sopra):
plugin.sipaccregwizz.CIPHER_SUITES=Suite di cifratura abilitate:
plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>{0} cercherà automaticamente di cifrare tutte le chiamate mediante ZRTP e ci sarà una notifica sonora e visiva una volta che la connessione sicura sarà stabilità. Dovresti cambiare le impostazioni avanzate solo se sei consapevole di quello che stai facendo.</div></html>
@@ -1211,15 +1109,6 @@ plugin.skinmanager.DEFAULT_SKIN=Skin predefinita
plugin.skinmanager.ADD_NEW_SKIN=Aggiungi una nuova skin...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=La skin predefinita dell'applicazione.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=Un protocollo per collegarsi a macchine remote tramite SSH.
-plugin.sshaccregwizz.USERNAME=Account ID:
-plugin.sshaccregwizz.IDENTITY_FILE=File di identità:
-plugin.sshaccregwizz.KNOWN_HOSTS=Host conosciuti:
-plugin.sshaccregwizz.OPTIONAL=Opzionale
-plugin.sshaccregwizz.ACCOUNT_DETAILS=Dettagli account
-
# status update
plugin.autoaway.AUTO_STATUS=Stato di "assente" automatico
plugin.autoaway.ENABLE_CHANGE_STATUS=Cambia stato mentre sei assente
@@ -1239,6 +1128,7 @@ plugin.updatechecker.DIALOG_NOUPDATE_TITLE=Nessuna nuova versione
plugin.updatechecker.DIALOG_MISSING_UPDATE=L'installatore degli aggiornamenti è mancante.
# usersearch
+plugin.usersearch.USER_SEARCH=Cerca utente
# whiteboard
plugin.whiteboard.TITLE=Lavagna [Beta]
@@ -1266,22 +1156,6 @@ plugin.whiteboard.DESELECT=Deseleziona
plugin.whiteboard.DELETE=Cancella
plugin.whiteboard.PROPERTIES=Proprietà
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Collegati e chatta usando Yahoo!
-plugin.yahooaccregwizz.USERNAME=Nome utente:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=Nome utente e password
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=Il protocollo Zeroconf (Bonjour).
-plugin.zeroaccregwizz.FIRST_NAME=Nome:
-plugin.zeroaccregwizz.LAST_NAME=Cognome:
-plugin.zeroaccregwizz.EMAIL=Email:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=Ricorda contatti Bonjour?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=User ID e password
-plugin.zeroaccregwizz.USERID=User ID
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Il protocollo Google Talk
@@ -1295,19 +1169,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, the IP Telecommunications
plugin.iptelaccregwizz.USERNAME=Nome utente
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=Iscriviti a iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIP e chat
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Nome utente
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Reinserisci la password
plugin.sip2sipaccregwizz.EMAIL=Indirizzo e-mail
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=Per aiuto riguardo questo servizio visita<br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>L'indirizzo e-mail è usato per spedire messaggi vocali, <br>notifiche di chiamate perse e per recuperare la password smarrita</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>Per aiuto riguardo questo servizio visita <a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=Account sip2sip.info esistente
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Crea un account sip2sip.info gratuito
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP && Messaggistica Istantanea
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=Per aiuto riguardo questo servizio visita<br>http://ippi.fr
@@ -1316,6 +1182,7 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=Account ippi esistente
plugin.ippiaccregwizz.CREATE_ACCOUNT=Crea un account ippi gratuito
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Chiudi finestra chat
plugin.keybindings.CHAT_COPY=Copia
plugin.keybindings.CHAT_CUT=Taglia
@@ -1338,10 +1205,10 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=Nome
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=Scorciatoia primaria
plugin.keybindings.globalchooser.SHORTCUT_SECOND=Scorciatoia secondaria
plugin.keybindings.globalchooser.PRESS_BTN=Premi per impostare la scorciatoia
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=In attesa
plugin.keybindings.globalchooser.PUSH_TO_TALK=Push to talk
plugin.keybindings.globalchooser.ENABLE_SPECIAL=Abilita il rilevamento dei tasti speciali
plugin.keybindings.PLUGIN_NAME=Scorciatoie
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Chat
plugin.keybindings.MAIN=Principale
plugin.keybindings.GLOBAL=Scorciatoie globali
@@ -1369,6 +1236,7 @@ plugin.notificationconfig.tableheader.SOUND=Riproduci un suono attraverso il dis
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=Riproduci un suono attraverso il dispositivo audio usato per la voce
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=Riproduci un suono attraverso gli altoparlanti del PC
plugin.notificationconfig.tableheader.DESCRIPTION=Descrizione dell'evento
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Chiamata in arrivo
plugin.notificationconfig.event.SecurityMessage=Messaggio di sicurezza
plugin.notificationconfig.event.IncomingFile=File in arrivo
@@ -1470,6 +1338,7 @@ impl.neomedia.configform.VIDEO=Video
impl.neomedia.configform.H264=H.264
impl.neomedia.configform.H264.defaultIntraRefresh=Intra Refresh periodico
impl.neomedia.configform.H264.defaultProfile=Profilo predefinito per la codifica:
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=Baseline
impl.neomedia.configform.H264.defaultProfile.high=High
impl.neomedia.configform.H264.defaultProfile.main=Main
@@ -1500,7 +1369,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=Password attuale:
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Inserisci una nuova password:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Reinserisci la nuova password:
plugin.securityconfig.masterpassword.MP_TITLE=Password principale
-plugin.securityconfig.masterpassword.MP_NOT_SET=(non impostata)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=La password principale inserita non è corretta. Riprova.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=La password principale non è corretta!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Cambio password fallito
@@ -1516,7 +1384,6 @@ plugin.securityconfig.masterpassword.COL_PASSWORD=Password
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(sconosciuto)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(non posso decifrare)
plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=Password salvate
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=Rimuovi
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=Rimuovi tutte
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=Sei sicuro di voler rimuovere tutte le password?
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=Rimuovi tutte le password
@@ -1601,7 +1468,7 @@ plugin.otr.activator.unreadablemsgreceived={0} ti ha inviato un messaggio cifrat
plugin.otr.activator.requireencryption=Il tuo messaggio [{0}] non è stato inviato. È richiesta la messaggistica privata.
plugin.otr.activator.unreadablemsgreply=Hai inviato a {0} un messaggio criptato illeggibile. Per favore termina la conversazione privata con {1} o aggiornala.
plugin.otr.activator.fallbackmessage=<span style="font-weight: bold;">{0} vuole iniziare una <a href="http://en.wikipedia.org/wiki/Off-the-Record_Messaging">conversazione con cifratura Off-The-Record</a> con te. Il tuo software, però, non supporta la cifratura Off-The-Record. Per maggiori informazioni visita <a href="http://en.wikipedia.org/wiki/Off-the-Record_Messaging">http://en.wikipedia.org/wiki/Off-the-Record_Messaging</a> (pagina in inglese)</span>
-plugin.otr.activator.multipleinstancesdetected={0} è collegato su più di un dispositivo e OTR ha aperto diverse sessioni. Puoi selezionare a quale sessione inviare il messaggio dal menù qui in basso.
+plugin.otr.activator.multipleinstancesdetected=Il tuo amico {0} è collegato su più di un dispositivo e OTR ha aperto diverse sessioni. Puoi selezionare a quale sessione inviare il messaggio dal menù qui sotto.
plugin.otr.activator.msgfromanotherinstance={0} ti ha inviato un messaggio destinato ad un'altra sessione. Se sei collegato da più di un dispositivo, hai ricevuto il messaggio su uno di questi.
# global proxy plugin
@@ -1612,7 +1479,6 @@ plugin.globalproxy.PROXY_PORT=Porta
plugin.globalproxy.PROXY_USERNAME=Nome utente
plugin.globalproxy.PROXY_PASSWORD=Password
plugin.globalproxy.DESCRIPTION={0} userà le impostazioni proxy specificate per tutte le reti cui ti connetterai d''ora in poi. \nIl supporto per i server proxy è sperimentale e funziona solo con alcuni protocolli. Controlla la tabella sottostante per maggiori dettagli:
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOCKS4/5 </td><td> SOCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>XMPP</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
plugin.globalproxy.FWD_DNS=Usa il proxy anche per le richieste DNS
plugin.globalproxy.FWD_DNS_NOTE=Utile con Tor. Aiuta ad evitare fughe di informazioni tramite il DNS inoltrando tutto il traffico DNS al proxy Tor. Richiede il riavvio.
@@ -1629,9 +1495,11 @@ plugin.reconnectplugin.NETWORK_DOWN=Connessione di rete persa!
plugin.chatconfig.TITLE=Chat
plugin.chatconfig.replacement.TITLE=Immagini/Video:
plugin.chatconfig.replacement.ENABLE_SMILEY_STATUS=Attiva la sostituzione automatica degli smiley
-plugin.chatconfig.replacement.REPLACEMENT_TITLE=Attiva l'anteprima automatica di immagini e video
+plugin.chatconfig.replacement.REPLACEMENT_TITLE=Sostituisci immagini/video
plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS=Abilita
+plugin.chatconfig.replacement.ENABLE_REPLACEMENT_PROPOSAL=Disabilita (mostra anteprima del collegamento)
plugin.chatconfig.replacement.DISABLE_REPLACEMENT=Disabilita
+plugin.chatconfig.replacement.CONFIGURE_REPLACEMENT=Cambia impostazioni per la sostituzione di Immagini o Video
plugin.chatconfig.replacement.REPLACEMENT_SOURCES=Origini:
plugin.chatconfig.spellcheck.TITLE=Controllo ortografico
@@ -1648,7 +1516,6 @@ plugin.provisioning.RESTART_WARNING=Nota che i cambiamenti avranno effetto solo
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=Copia l'UUID negli appunti
plugin.provisioning.CLIPBOARD_FAILED=Si è verificato un errore nel copiare l'UUID negli appunti
-plugin.provisioning.EXIT_ON_FAIL=Esci dall'applicazione se il provisioning fallisce
plugin.provisioning.CREDENTIALS=Ultime credenziali salvate per il provisioning
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=Sei sicuro di voler rimuovere la password per il provisioning?
plugin.provisioning.PROV_FAILED=Il provisioning è fallito
@@ -1715,8 +1582,6 @@ util.dns.DNSSEC_WARNING=<html><div width="600">{0} ha provato a connettersi al s
#plugin spellcheck
plugin.spellcheck.TITLE=Ortografia e Grammatica
plugin.spellcheck.MENU=Mostra controllo ortografico
-plugin.spellcheck.LANG=Lingua
-plugin.spellcheck.EDIT_PERSONAL_DICT=Modifica
plugin.spellcheck.ENABLE_SPELL_CHECK=Attiva controllo ortografico
plugin.spellcheck.dialog.FIND=Trova successivo
plugin.spellcheck.dialog.REPLACE=Sostituisci
diff --git a/resources/languages/resources_ja.properties b/resources/languages/resources_ja.properties
index 2d45a75..fe2adb9 100644
--- a/resources/languages/resources_ja.properties
+++ b/resources/languages/resources_ja.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -31,43 +42,36 @@ service.gui.ACCOUNT=アカウント
service.gui.ACCOUNT_ME=ç§
service.gui.ACCOUNT_REGISTRATION_WIZARD=アカウント登録ウィザード
service.gui.ACCOUNTS=アカウント
-service.gui.ADD=追加 (&A)
-service.gui.ADD_ACCOUNT=アカウントを追加
+service.gui.ADD=追加(&A)
service.gui.ADD_CONTACT=コンタクトを追加 (&A)
service.gui.ADD_AUTHORIZED_CONTACT={0} をコンタクトリストã«è¿½åŠ ã—ã¾ã™
service.gui.ADD_CONTACT_TO_CONTACTLIST=ã“ã®ã‚³ãƒ³ã‚¿ã‚¯ãƒˆã‚’コンタクトリストã«è¿½åŠ 
-service.gui.ADD_CONTACT_TO=コンタクトを追加 (&A)
+service.gui.ADD_CONTACT_TO=コンタクトを追加ã™ã‚‹ (&A)
service.gui.ADD_CONTACT_ERROR={0} ã¨ã„ã†ã‚³ãƒ³ã‚¿ã‚¯ãƒˆã‚’追加ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚
service.gui.ADD_CONTACT_ERROR_TITLE=コンタクト追加エラー
service.gui.ADD_CONTACT_EXIST_ERROR=ID: {0} ã¯ã™ã§ã«ã‚³ãƒ³ã‚¿ã‚¯ãƒˆãƒªã‚¹ãƒˆã«å­˜åœ¨ã—ã¾ã™ã€‚
-service.gui.ADD_CONTACT_NETWORK_ERROR=コンタクトIDを追加è¦æ±‚ã«å¯¾ã—ã€ã‚µãƒ¼ãƒãƒ¼ãŒå¿œç­”ã—ã¾ã›ã‚“ã§ã—ãŸã€‚:{0}
-service.gui.ADD_CONTACT_NOT_SUPPORTED=コンタクトID:{0} を追加ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚æ“作ãŒã‚µãƒãƒ¼ãƒˆå¤–ã§ã™ã€‚
-service.gui.ADD_CONTACT_IDENTIFIER=下ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«è¿½åŠ ã—ãŸã„コンタクトã®IDを入力ã—ã¦ä¸‹ã•ã„。
-service.gui.ADD_CONTACT_WIZARD=コンタクト追加ウィザード
+service.gui.ADD_CONTACT_NETWORK_ERROR=コンタクト ID: {0} ã®è¿½åŠ ãƒªã‚¯ã‚¨ã‚¹ãƒˆã«å¯¾ã—ã€ã‚µãƒ¼ãƒãƒ¼ãŒå¿œç­”ã—ã¾ã›ã‚“ã§ã—ãŸã€‚
+service.gui.ADD_CONTACT_NOT_SUPPORTED=コンタクトID:{0} を追加ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®æ“作ã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。
service.gui.ADD_CONTACT_NOT_CONNECTED=コンタクト追加ã™ã‚‹ã«ã¯ã€ã‚µãƒ¼ãƒãƒ¼æŽ¥ç¶šãŒå¿…è¦ã§ã™ã€‚指定ã®ã‚µãƒ¼ãƒ“スプロãƒã‚¤ãƒ€ãƒ¼ã¸å†åº¦ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ãã ã•ã„。
service.gui.ADD_GROUP_LOCAL_ERROR={0} ã¨ã„ã†ã‚°ãƒ«ãƒ¼ãƒ—を追加ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ローカルI/Oã‚’æ“作中ã«å•é¡ŒãŒèµ·ã“ã‚Šã¾ã—ãŸã€‚
service.gui.ADD_GROUP_EXIST_ERROR={0} ã¨ã„ã†ã‚°ãƒ«ãƒ¼ãƒ—ã¯ã™ã§ã«ã‚³ãƒ³ã‚¿ã‚¯ãƒˆãƒªã‚¹ãƒˆã«å­˜åœ¨ã—ã¾ã™ã€‚ã»ã‹ã®åå‰ã‚’é¸æŠžã—ã¦ãã ã•ã„。
service.gui.ADD_GROUP_NET_ERROR={0}ã¨ã„ã†ã‚°ãƒ«ãƒ¼ãƒ—を追加ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯éšœå®³ã®ãŸã‚ã«å•é¡ŒãŒèµ·ã“ã‚Šã¾ã—ãŸã€‚ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯æŽ¥ç¶šã‚’確èªã®ã†ãˆã€å†åº¦ãŠè©¦ã—ãã ã•ã„。
service.gui.ADD_GROUP_ERROR={0} ã¨ã„ã†ã‚°ãƒ«ãƒ¼ãƒ—を追加ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚
service.gui.ADD_GROUP_EMPTY_NAME=グループåを空ã«ã™ã‚‹äº‹ã¯ã§ãã¾ã›ã‚“。
-service.gui.ADD_GROUP=グループを追加
-service.gui.ADD_SUBCONTACT=サブコンタクトを追加 (&A)
service.gui.ADDRESS=アドレス
service.gui.ADMINISTRATOR=管ç†è€…
service.gui.ADVANCED=アドãƒãƒ³ã‚¹ãƒ‰ (&A)
-service.gui.ALL=ã™ã¹ã¦ (&A)
service.gui.ALL_CONTACTS=ã™ã¹ã¦ã®ã‚³ãƒ³ã‚¿ã‚¯ãƒˆ (&A)
service.gui.ALTERNATE_ADDRESS=代用アドレス
service.gui.APPLY=é©ç”¨ (&A)
-service.gui.ARE_CALLING=ãŒã‚³ãƒ¼ãƒ«ã—ã¦ã„ã¾ã™...
+service.gui.ARE_CALLING={0}ãŒã‚³ãƒ¼ãƒ«ã—ã¦ã„ã¾ã™...
service.gui.ARE_NOW=ç¾åœ¨ {0} ã§ã™
service.gui.AT=ã§
service.gui.AUTHORIZE=æ‰¿èª (&A)
-service.gui.AUTHORIZATION_ACCEPTED=コンタクトã¯ã‚ãªãŸã®æ‰¿èªç”³è«‹ã‚’å—ã‘入れã¾ã—ãŸã€‚
+service.gui.AUTHORIZATION_ACCEPTED={0}ã¯ã‚ãªãŸã®æ‰¿èªç”³è«‹ã‚’å—ã‘入れã¾ã—ãŸã€‚
service.gui.AUTHENTICATION_FAILED={0}ã®èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸã€‚入力ã•ã‚ŒãŸãƒ‘スワードãŒé–“é•ã£ã¦ã„ã¾ã™ã€‚
-service.gui.AUTHENTICATION_REQUESTED=èªè¨¼ãŒæ±‚ã‚られã¦ã„ã¾ã™
service.gui.AUTHENTICATION_REQUESTED_SERVER=サーãƒ: {0} ã¯èªè¨¼ã‚’è¦æ±‚ã—ã¾ã—ãŸã€‚
-service.gui.AUTHENTICATION_REJECTED=コンタクトã¯ã‚ãªãŸã®æ‰¿èªç”³è«‹ã‚’æ‹’å¦ã—ã¾ã—ãŸã€‚
+service.gui.AUTHENTICATION_REJECTED={0}ã¯ã‚ãªãŸã®æ‰¿èªç”³è«‹ã‚’æ‹’å¦ã—ã¾ã—ãŸã€‚
service.gui.AUTHENTICATION_WINDOW_TITLE={0} èªè¨¼
service.gui.AUTHORIZATION_REQUESTED=承èªãŒæ±‚ã‚られã¦ã„ã¾ã™
service.gui.AUTHORIZATION_REQUESTED_INFO=コンタクト {0} ãŒã‚ãªãŸã®æ‰¿èªã‚’求ã‚ã¦ã„ã¾ã™ã€‚
@@ -75,10 +79,10 @@ service.gui.AUTHORIZATION_RESPONSE=承èªã®å¿œç­”
service.gui.AWAY_STATUS=ä¸åœ¨
service.gui.EXTENDED_AWAY_STATUS=長期ä¸åœ¨
service.gui.BAN=ç¦æ­¢ (&B)
-service.gui.BANNED=退出ã•ã›ã‚‰ã‚Œã¾ã—ãŸ
-service.gui.BAN_FAILED=ç¦æ­¢ã«å¤±æ•—
-service.gui.BAN_FAILED_GENERAL_ERROR=コンタクト: {0} ã‚’ç¦æ­¢ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚一般サーãƒã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚
-service.gui.BAN_FAILED_NOT_ALLOWED=コンタクト: {0} ã‚’ç¦æ­¢ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ルームã®ã‚ªãƒ¼ãƒŠãƒ¼ã¨ç®¡ç†è€…ã¯ç¦æ­¢ã§ãã¾ã›ã‚“。
+service.gui.BANNED=強制退出完了
+service.gui.BAN_FAILED=強制退出ã§ãã¾ã›ã‚“。
+service.gui.BAN_FAILED_GENERAL_ERROR={0}を強制退出ã§ãã¾ã›ã‚“。サーãƒã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚
+service.gui.BAN_FAILED_NOT_ALLOWED=コンタクト: {0} ã¯ãƒ«ãƒ¼ãƒ ã®ã‚ªãƒ¼ãƒŠãƒ¼ã¾ãŸã¯ç®¡ç†è€…ã®ãŸã‚ã€å¼·åˆ¶é€€å‡ºã§ãã¾ã›ã‚“。
service.gui.BAN_FAILED_NOT_ENOUGH_PERMISSIONS=コンタクト: {0} ã‚’ç¦æ­¢ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚権é™ãŒã‚ã‚Šã¾ã›ã‚“。
service.gui.BRB_MESSAGE=ãŸã ã„ã¾é€€å¸­ä¸­ã§ã™ãŒã€ã™ãã«æˆ»ã‚Šã¾ã™ã€‚
service.gui.BROWSE=ブラウズ
@@ -87,7 +91,7 @@ service.gui.BUSY_STATUS=å–ã‚Šè¾¼ã¿ä¸­
service.gui.CALL=コール
service.gui.CALL_CONTACT=コンタクトã«ã‚³ãƒ¼ãƒ«ã™ã‚‹
service.gui.CALL_FAILED=コールã«å¤±æ•—ã—ã¾ã—ãŸ
-service.gui.CALL_HISTORY_TOOL_TIP=コール履歴を表示ã™ã‚‹ã«ã¯ã“ã“をクリックã—ã¦ãã ã•ã„
+service.gui.CALL_HISTORY_TOOL_TIP=通話履歴を表示ã™ã‚‹ã«ã¯ã“ã“をクリックã—ã¦ãã ã•ã„
service.gui.CALL_HISTORY_GROUP_NAME=ç€ä¿¡å±¥æ­´
service.gui.CALL_VIA=次ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã§ã‚³ãƒ¼ãƒ«:
service.gui.CALL_NAME_OR_NUMBER=åå‰ã‹ç•ªå·ã§å‘¼ã³å‡ºã—
@@ -106,11 +110,11 @@ service.gui.CHANGE_NICKNAME_LABEL=æ–°ã—ã„ニックãƒãƒ¼ãƒ ã‚’下ã®ãƒ•ã‚£ãƒ¼ã
service.gui.CHANGE_NICKNAME_ERROR=ニックãƒãƒ¼ãƒ å¤‰æ›´ã‚¨ãƒ©ãƒ¼
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=ニックãƒãƒ¼ãƒ ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™
service.gui.CHANGE_VIDEO_QUALITY=相手å´ã®æ˜ åƒå“質を変更
-service.gui.CHAT_CONFERENCE_LABEL=会議
-service.gui.CHAT_CONFERENCE_ITEM_LABEL={0}''ã®ä¼šè­°
+service.gui.CHAT_CONFERENCE_ITEM_LABEL={0}ã®ä¼šè­°
service.gui.CHAT_ROOM_ALREADY_JOINED=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ : {0} ã«æ—¢ã«å‚加ã—ã¦ã„ã¾ã™ã€‚
service.gui.CHAT_ROOM_CONFIGURATION=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ : {0} 設定
service.gui.CHAT_ROOM_CONFIGURATION_FAILED=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ : {0} 設定フォームãŒå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚
+service.gui.CHAT_ROOM_CONFIGURATION_FORBIDDEN=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ  {0} ã®è¨­å®šã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã®ã‚ªãƒ¼ãƒŠãƒ¼ã®ã¿ãŒè¨­å®šç”»é¢ã‚’見ãŸã‚Šã€è¨­å®šã‚’変更ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
service.gui.CHAT_ROOM_CONFIGURATION_SUBMIT_FAILED=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ : {0} ã®è¨­å®šã‚’å映中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚
service.gui.CHAT_ROOM_CONFIGURATION_MEMBERS_EDIT_TITLE=メンãƒãƒ¼ãƒªã‚¹ãƒˆã‚’編集
service.gui.CHAT_ROOM_CONFIGURATION_MEMBERS_EDIT_DESCRIPTION=å³ã®ãƒªã‚¹ãƒˆã¯ã€ã“ã®ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã«ã„るメンãƒãƒ¼æ¨©é™ãŒã‚る人をå«ã‚“ã§ã„ã¾ã™ã€‚ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ãŒ"メンãƒãƒ¼ã®ã¿"ã®å ´åˆã€ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ã¿ãŒå‚加ã§ãã¾ã™ã€‚
@@ -119,18 +123,14 @@ service.gui.CHAT_ROOM_USER_LEFT={0} ã‹ã‚‰é€€å®¤ã—ã¾ã—ãŸ
service.gui.CHAT_ROOM_USER_KICKED={0} ã‹ã‚‰å¼·åˆ¶é€€å®¤ã•ã‚Œã¾ã—ãŸ
service.gui.CHAT_ROOM_USER_QUIT={0} ãŒçµ‚了ã—ã¾ã—ãŸ
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=メッセージé€ä¿¡ãŒç¦æ­¢ã•ã‚Œã¦ã„ã¾ã™(音声ã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸ)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=今後ã®ç‚ºã«ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã‚’ä¿å­˜
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=ä¿å­˜æ¸ˆãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã®ãƒªã‚¹ãƒˆã‹ã‚‰é¸æŠžã—ãŸãƒ«ãƒ¼ãƒ ã‚’削除
service.gui.CHAT_ROOM_NAME=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ å
service.gui.CLEAR_CUSTOM_MESSAGES=カスタムメッセージをクリア
service.gui.ROOM_NAME=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ 
-service.gui.AUTOJOIN=自動å‚加
service.gui.CHANGE_PASSWORD=パスワードを変更
service.gui.CHAT_ROOM_NAME_INFO=下ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«ä½œæˆã—ãŸã„ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ åを入力ã—ã¦ä¸‹ã•ã„。
service.gui.CHAT_ROOM_NOT_EXIST=サーãƒ: {1} ã«ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ : {0} ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚入力ã—ãŸãƒ«ãƒ¼ãƒ åã‚’ã”確èªãã ã•ã„。
service.gui.CHAT_ROOM_NOT_CONNECTED=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ : {0} ã«å‚加ã™ã‚‹ãŸã‚ã«ã¯ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ã„ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã«åŽ»ã‚‹ãŸã‚ã«ã¯ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ã„ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
-service.gui.CHAT_ROOM_NOT_JOINED=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã‚’æ“作ã™ã‚‹ãŸã‚ã«ã¯ãã®ãƒ«ãƒ¼ãƒ ã«å‚加ã—ã¦ã„ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
service.gui.CHAT_ROOM_OPTIONS=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã‚ªãƒ—ション
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ : {0} ã«å‚加ã™ã‚‹ã«ã¯ç™»éŒ²ãŒå¿…è¦ã§ã™ã€‚
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ : {0} ã¯ãƒ‘スワードをè¦æ±‚ã—ã¾ã—ãŸã€‚
@@ -144,27 +144,24 @@ service.gui.CHOOSE_NUMBER=番å·ã‚’é¸æŠž
service.gui.CHOOSE_ACCOUNT=アカウント一覧ã‹ã‚‰é¸æŠžã—ã¦ãã ã•ã„。
service.gui.CITY=市(区町æ‘)
service.gui.COUNTRY=国
-service.gui.SHOW_MORE_TOOLTIP=より詳細ã¯ã‚¯ãƒªãƒƒã‚¯
+service.gui.SHOW_MORE_TOOLTIP=æ›´ã«è©³ç´°ã‚’表示ã™ã‚‹ã«ã¯ã‚¯ãƒªãƒƒã‚¯
service.gui.CLEAR=テキストを消去
service.gui.CLOSE=é–‰ã˜ã‚‹ (&o)
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=2秒以内ã«æ–°ã—ã„メッセージをå—ã‘å–ã£ã¦ã„ã¾ã™ã€‚本当ã«ã“ã®ãƒãƒ£ãƒƒãƒˆã‚’é–‰ã˜ã¾ã™ã‹ï¼Ÿ
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=転é€ä¸­ã®ãƒ•ã‚¡ã‚¤ãƒ«ãŒã‚ã‚Šã¾ã™ã€‚ã“れらをキャンセルã—ã¦ã‚‚ã„ã„ã§ã™ã‹ï¼Ÿ
-service.gui.CONFIRM=確èª
service.gui.CONNECTED_STATUS=接続済ã¿
service.gui.CONNECTING=接続...
service.gui.CONNECTING_STATUS=接続...
service.gui.CONNECTING_EARLY_MEDIA_STATUS=接続...
service.gui.CONNECTION=接続...
-service.gui.CONNECTION_FAILED_MSG=次ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã§æŽ¥ç¶šã«å¤±æ•—ã—ã¾ã—ãŸ: ユーザå: {0}, サーãƒå: {1}. ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯æŽ¥ç¶šã‚’ã”確èªã€ã‚‚ã—ãã¯ã€ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ç®¡ç†è€…ã«å•ã„åˆã‚ã›ã¦ãã ã•ã„。
service.gui.CONNECTION_EXPIRED_MSG=ç¾åœ¨ã‚µãƒ¼ãƒ {0} ã¨ã¯æŽ¥ç¶šã—ã¦ã„ã¾ã›ã‚“。
service.gui.CONTACT_NAME=ID ã¾ãŸã¯ç•ªå·
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=é¸æŠžã—ãŸå•ã„åˆã‚ã›å…ˆ {0} ã¯é›»è©±ã‚’å—ã‘付ã‘ã¦ã„ã¾ã›ã‚“。
+service.gui.CONTACT_NAME_PROMPT=jane.doe@example.com
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=é¸æŠžã—ãŸå•ã„åˆã‚ã›å…ˆ {0} ã¯é›»è©±ã‚’å—ã‘付ã‘ã¦ã„ã¾ã›ã‚“。
service.gui.CONTACT_PAUSED_TYPING={0} ã¯ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸å…¥åŠ›ã‚’休止ã—ã¦ã„ã¾ã™
service.gui.CONTACT_TYPING={0} ã¯ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’入力ã—ã¦ã„ã¾ã™
service.gui.CONTACT_TYPING_SEND_FAILED=ãŠã£ã¨ã€ä»Šå…¥åŠ›ä¸­ãªã®ã§ {0} ã«é€šè©±ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚
service.gui.CONTACT_INFO=å•ã„åˆã‚ã›æƒ…å ± (&C)
-service.gui.CONTACTLIST=コンタクトリスト
service.gui.CONTACTS=å•ã„åˆã‚ã›
service.gui.COPY=コピーã™ã‚‹ (&C)
service.gui.COPY_LINK=リンクをコピーã™ã‚‹ (&l)
@@ -176,43 +173,47 @@ service.gui.CREATE_CHAT_ROOM_WIZARD=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ä½œæˆã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰
service.gui.CREATE_CONFERENCE_CALL=会議通話を開始...(&C)
service.gui.CREATE_GROUP=グループを作æˆã™ã‚‹ (&C)
service.gui.CREATE_GROUP_NAME=下ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«ä½œæˆã—ãŸã„グルームã®åå‰ã‚’入力ã—ã¦ãã ã•ã„。
-service.gui.CREATE_FIRST_GROUP_WIZARD=ã‚ãªãŸã®ã‚³ãƒ³ã‚¿ã‚¯ãƒˆãƒªã‚¹ãƒˆã¯ã²ã¨ã¤ã‚‚グループをå«ã‚“ã§ã„ã¾ã›ã‚“。åˆã‚ã«ã‚°ãƒ«ãƒ¼ãƒ—を作æˆã—ã¦ãã ã•ã„。(ファイル/グループ作æˆ)
service.gui.CREATE_VIDEO_BRIDGE=æ–°è¦ã®ãƒ“デオブリッジを作æˆ(&v)
service.gui.CREATE_VIDEO_BRIDGE_MENU=æ–°è¦ã®ãƒ“デオブリッジを作æˆ(&v)
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=ビデオ会議を作æˆ/å‚加
service.gui.CREATE_VIDEO_CONFERENCE=ã“ã®ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã«æ–°ã—ãビデオ会議を作æˆ
-service.gui.CONTACT_INFO_NOT_SUPPORTED=ã“ã®å•ã„åˆã‚ã›å…ˆã¯ã‚¦ã‚§ãƒ–å•ã„åˆã‚ã›ã‚’å—ã‘付ã‘ã¦ã„ã¾ã›ã‚“。
+service.gui.CONTACT_INFO_NOT_SUPPORTED=ã“ã®é€£çµ¡å…ˆã¯ã‚¦ã‚§ãƒ–å•ã„åˆã‚ã›ã‚’å—ã‘付ã‘ã¦ã„ã¾ã›ã‚“。
service.gui.CUT=カット (&u)
-service.gui.DATE=日付
service.gui.DELETE=削除ã™ã‚‹
service.gui.DENY=æ‹’å¦(&D)
service.gui.DESKTOP_SHARING_WARNING=<b>ç”»é¢å…±æœ‰ã‚’開始ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ</b> <br> OKをクリックã™ã‚‹ã¨ã€ã“ã®ä¼šè­°ã«å‚加中ã®å…¨ã¦ã®äººã«ç”»é¢ãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚
-service.gui.DIALPAD=ダイアルパッド
+service.gui.DESKTOP_SHARING_DIALOG_INDICATE=ç”»é¢ã‚’共有ã—ã¾ã™ã€‚
+service.gui.DIALPAD=ã‚ãªãŸã®ç”»é¢ã‚’共有中
service.gui.DISPLAY_NAME=表示å
+service.gui.DISPLAY_NAME_PROMPT=ジェーン ドゥ
service.gui.DISCONNECTED_STATUS=未接続
service.gui.DND_STATUS=ç€ä¿¡æ‹’å¦
service.gui.DO_NOT_ASK_AGAIN=次回ã¯èžã‹ãªã„
-service.gui.DO_NOT_SHOW_AGAIN=次回ã¯ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’表示ã—ãªã„
-service.gui.DOWNLOAD_NOW=ã™ãã«ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰(&D)
+service.gui.DO_NOT_SHOW_AGAIN=次回よりã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’表示ã—ãªã„
service.gui.DRAG_FOR_SHARING=ãªã‚“ã§ã‚‚共有ã—ãŸã„ã‚‚ã®ã‚’ã“ã“ã«ãƒ‰ãƒ©ãƒƒã‚°...
service.gui.DURATION=期間
+service.gui.DESTROY_CHATROOM=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã‚’削除ã™ã‚‹
+service.gui.DESTROY_MESSAGE=ä»–ã®å‚加者ã«é€šçŸ¥ã™ã‚‹ã«ã¯ã€ãã®ç†ç”±ã¨å‚加ã™ã‚‹ä»£æ›¿ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’入力ã—ã¦ãã ã•ã„。
service.gui.EDIT=編集ã™ã‚‹ (&E)
-service.gui.EMAIL=é›»å­ãƒ¡ãƒ¼ãƒ«:
-service.gui.EMAILS=é›»å­ãƒ¡ãƒ¼ãƒ«:
-service.gui.EMPTY_HISTORY=ヒストリを消去ã™ã‚‹ (&E)
+service.gui.EDITED_AT={0}ã§ç·¨é›†
+service.gui.EMAIL=Email
+service.gui.EMAILS=Email
+service.gui.EMPTY_HISTORY=履歴ãŒã‚ã‚Šã¾ã›ã‚“
+service.gui.ENABLE_DESKTOP_REMOTE_CONTROL=リモートデスクトップアプリを有効ã«ã™ã‚‹
+service.gui.ENABLE_TYPING_NOTIFICATIONS=ãƒãƒ£ãƒƒãƒˆå…¥åŠ›ä¸­ã®çŠ¶æ…‹ã‚’外部ã®äººã«çŸ¥ã‚‰ã›ã‚‹ï¼ˆãƒãƒ£ãƒƒãƒˆã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティをé€ä¿¡ï¼‰
+service.gui.END_CONFERENCE=会議を終了ã™ã‚‹
service.gui.ENTER_PHONE_NUMBER=電話番å·ã‚’入力ã—ã¦ãã ã•ã„
-service.gui.ENTER_NAME_OR_NUMBER=åå‰ã‹ç•ªå·ã§å‘¼ã³å‡ºã—
+service.gui.ENTER_NAME_OR_NUMBER=åå‰ã‚‚ã—ãã¯ç•ªå·ã‚’入力
service.gui.ERROR=エラー
service.gui.ERROR_WAS=エラーã§ã™ï¼š{0}
service.gui.ERROR_RECEIVED_FROM={0} ã‹ã‚‰ã‚¨ãƒ©ãƒ¼ã‚’å—ã‘å–ã‚Šã¾ã—ãŸ
service.gui.ESTIMATED_TIME=残り時間:
service.gui.EVENTS=イベント
service.gui.EXIT=終了 (&x)
-service.gui.EXTENDED_CRITERIA=æ‹¡å¼µæ¡ä»¶
service.gui.GENERAL=一般
service.gui.GENERAL_ERROR=一般エラー
service.gui.GROUP_NAME=グループå
-service.gui.FAILED_STATUS=コールã«å¤±æ•—ã—ã¾ã—ãŸ
+service.gui.FAILED_STATUS=コール失敗
service.gui.FAILED_TO_JOIN_CHAT_ROOM={0} ã¨ã„ã†ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã«å‚加ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚
service.gui.FAX=Fax
service.gui.FFC_STATUS=自由ã«ãƒãƒ£ãƒƒãƒˆã§ãã¾ã™
@@ -229,17 +230,19 @@ service.gui.FILE_SEND_FAILED=ファイルé€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ: {0}
service.gui.FILE_TOO_BIG=ã“ã®ãƒ—ロトコルã§é€ä¿¡ã§ãるファイル最大サイズを越ãˆã¦ã„ã¾ã™: {0}
service.gui.FILE_SEND_REFUSED={0} ã‹ã‚‰ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ‹’å¦ã•ã‚Œã¾ã—ãŸã€‚
service.gui.FILE_TRANSFER_REFUSED=ファイル転é€ãŒæ‹’å¦ã•ã‚Œã¾ã—ãŸã€‚
-service.gui.FILE_TRANSFER_NOT_SUPPORTED=é¸æŠžã—ãŸé€£çµ¡å…ˆã¯ã€ãƒ•ã‚¡ã‚¤ãƒ«è»¢é€ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。
+service.gui.FILE_TRANSFER_NOT_SUPPORTED=é¸æŠžã•ã‚ŒãŸé€£çµ¡å…ˆã¯ã€ãƒ•ã‚¡ã‚¤ãƒ«è»¢é€ã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。
+service.gui.FILE_TRANSFER_PREPARING={0}ã«ãƒ•ã‚¡ã‚¤ãƒ«é€ä¿¡æº–備中。ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„・・・
service.gui.FILE_TRANSFER_REQUEST_RECIEVED={0}ãŒã‚ãªãŸã¨ãƒ•ã‚¡ã‚¤ãƒ«ã‚’共有中
service.gui.FILE_DOES_NOT_EXIST=指定ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚削除ã•ã‚ŒãŸã‹ã€ç§»å‹•ã•ã‚Œã¾ã—ãŸã€‚
service.gui.FILE_OPEN_FAILED=ファイルを開ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚削除ã•ã‚ŒãŸã‹ã€ç§»å‹•ã•ã‚Œã¾ã—ãŸã€‚
-service.gui.FILE_OPEN_NOT_SUPPORTED=申ã—訳ã”ã–ã„ã¾ã›ã‚“ãŒã€ã“ã®ãƒ—ラットフォームã§ã¯ã€ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é–‹ãæ“作ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“。
+service.gui.FILE_OPEN_NOT_SUPPORTED=申ã—訳ã”ã–ã„ã¾ã›ã‚“。ã“ã®ãƒ—ラットフォームã§ã¯ã€ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é–‹ãæ“作ã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。
service.gui.FILE_OPEN_NO_PERMISSION=ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é–‹ã権é™ãŒã‚ã‚Šã¾ã›ã‚“。権é™ã‚’確èªã®ä¸Šã€å†åº¦è©¦ã—ã¦ãã ã•ã„。
service.gui.FILE_OPEN_NO_APPLICATION=ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚¿ã‚¤ãƒ—ã«é–¢é€£ã¥ã‘られãŸã‚¢ãƒ—リケーションãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚
-service.gui.FINISH=仕上ã’ã‚‹ (&F)
+service.gui.FINISH=終了ã™ã‚‹
service.gui.FOLDER_DOES_NOT_EXIST=ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’入れãŸãƒ•ã‚©ãƒ«ãƒ€ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚削除ã•ã‚ŒãŸã‹ã€ç§»å‹•ã•ã‚Œã¦ã„ã¾ã™ã€‚
service.gui.FOLDER_OPEN_FAILED=フォルダーを開ã‘ã¾ã›ã‚“ã§ã—ãŸ
service.gui.FOLDER_OPEN_NO_PERMISSION=ã“ã®ãƒ•ã‚©ãƒ«ãƒ€ã‚’é–‹ã権é™ãŒã‚ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚権é™ã‚’確èªã®ä¸Šã€å†åº¦è©¦ã—ã¦ãã ã•ã„。
+service.gui.FOLDER_OPEN_NO_APPLICATION=ã“ã®ãƒ•ã‚©ãƒ«ãƒ€ã‚’é–‹ãアプリケーションãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚
service.gui.FONT=フォント
service.gui.FONT_BOLD=ボールド
service.gui.FONT_COLOR=色
@@ -247,7 +250,12 @@ service.gui.FONT_FAMILY=ファミリー
service.gui.FONT_ITALIC=斜体
service.gui.FONT_SIZE=サイズ
service.gui.FONT_STYLE=スタイル
-service.gui.FONT_UNDERLINE=アンダーライン
+service.gui.FONT_UNDERLINE=下線
+service.gui.GRANT_OWNERSHIP=所有権ä¿æœ‰ä¸­â€¦
+service.gui.GRANT_ADMIN=管ç†æ¨©ä¿æœ‰ä¸­â€¦
+service.gui.GRANT_MODERATOR=議長権ä¿æœ‰ä¸­â€¦
+service.gui.GRANT_MEMBERSHIP=メンãƒãƒ¼æ¨©ä¿æœ‰ä¸­â€¦
+service.gui.GRANT_VOICE=音声を許å¯
service.gui.GUEST=ゲスト
service.gui.HANG_UP=切断
service.gui.HD_QUALITY=HDビデオ
@@ -268,7 +276,6 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=ローカルã«ä¿å­˜ã•ã‚Œã¦ã„るメãƒ
service.gui.HISTORY_REMOVE_ERROR=ローカルã«ä¿å­˜ã•ã‚Œã¦ã„るメッセージã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸã€‚
service.gui.HOME=ホーム
service.gui.HOME_PAGE=ホームページ
-service.gui.HOUR=時間
service.gui.ICE=ICE
service.gui.IDENTIFIER=識別å­
service.gui.IGNORE=無視ã™ã‚‹ (&I)
@@ -276,53 +283,58 @@ service.gui.INSERT_SMILEY=スマイリーを挿入
service.gui.INCOMING_CALL=次ã®ã¨ã“ã‚ã‹ã‚‰ç€ä¿¡: {0}
service.gui.INCOMING_SCREEN_SHARE=次ã®ã¨ã“ã‚ã‹ã‚‰ç”»é¢å…±æœ‰ãŒç€ä¿¡: {0}
service.gui.INCOMING_CALL_STATUS=ç€ä¿¡ä¸­ã§ã™
+service.gui.INCOMING_SCREEN_SHARE_STATUS=ç”»é¢å…±æœ‰ãŒç€ä¿¡ä¸­
+service.gui.INSTANT_MESSAGINGS=インスタントメッセンジャー
+service.gui.IM=インスタントメッセージ
+service.gui.INITIATING_CALL_STATUS=コール開始
service.gui.INVITATION=招待文
service.gui.INVITATION_RECEIVED=招待をå—ã‘ã¾ã—ãŸ
service.gui.INVITATION_RECEIVED_MSG={0} ã¯ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ : {1} ã«ã‚ãªãŸã‚’招待ã—ã¾ã—ãŸã€‚ã“ã®æ‹›å¾…ã‚’å—ã‘入れるã‹ã€æ‹’å¦ã™ã‚‹ã‹ã€ç„¡è¦–ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+service.gui.INVITATION_REJECTED={0}ã¯ã‚ãªãŸã®æ‹›å¾…ã‚’æ‹’å¦ã—ã¾ã—ãŸã€‚ç†ç”±ï¼š{1}.
service.gui.INVITE=招待 (&I)
service.gui.INVITE_CONTACT_MSG=ã“ã®ä¼šè©±ã«è¿½åŠ ã—ãŸã„コンタクトをé¸æŠžã—ã¦ã€æ‹›å¾…ã®ãƒœã‚¿ãƒ³ã‚’クリックã—ã¦ãã ã•ã„。
service.gui.INVITE_CONTACT_TO_CHAT=コンタクトをãƒãƒ£ãƒƒãƒˆã«æ‹›å¾…
-service.gui.INVITE_CONTACT_TO_CALL=コンタクトをãƒãƒ£ãƒƒãƒˆã«æ‹›å¾…
+service.gui.INVITE_CONTACT_TO_CALL=連絡先を招待
service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=連絡先をビデオブリッジã«æ‹›å¾…
service.gui.INVITE_REASON=招待ç†ç”±
-service.gui.IS_CALLING=コール中...
+service.gui.IS_CALLING={0}ãŒã‚³ãƒ¼ãƒ«ä¸­...
service.gui.IS_NOW={0} ã¯ç¾åœ¨ {1} ã§ã™ã€‚
-service.gui.JITSI_WARNING=SIPコミュニケーターã¯ã€Jitsiã«å称変更ã•ã‚Œã¾ã—ãŸã€‚<br/> 今後ã€æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«æ›´æ–°ã™ã‚‹å ´åˆã¯ã€Jitsiをダウンロードã™ã‚‹ã‚ˆã†ã«ã—ã¦ãã ã•ã„。<br/><br/>ã”迷惑をãŠæŽ›ã‘ã—ã¦ç”³ã—訳ã”ã–ã„ã¾ã›ã‚“。<br/><br/>Jitsi開発ãƒãƒ¼ãƒ 
-service.gui.JITSI_WARNING_TITLE=SIPコミュニケーターã¯ã€Jitsiã«ãªã‚Šã¾ã—ãŸã€‚
service.gui.JOIN=å‚加ã™ã‚‹ (&J)
service.gui.JOIN_AS=ã¨ã—ã¦å‚加 (&o)
service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=会議中ã®ãƒ“デオ会議ã«å‚加
service.gui.JOIN_VIDEO=ビデオã«å‚加
-service.gui.CLOSE_CHAT_ROOM_DIALOG=é–‰ã˜ã‚‹ (&o)
service.gui.JOB_TITLE=肩書ã
service.gui.JOIN_CHAT_ROOM=ãƒãƒ£ãƒƒãƒˆã«å‚加ã™ã‚‹... (&J)
service.gui.JOIN_CHAT_ROOM_TITLE=ãƒãƒ£ãƒƒãƒˆã«å‚加
service.gui.JOIN_CHAT_ROOM_NAME=å‚加ã—ãŸã„ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã‚’入力ã—ã¦ãã ã•ã„。
service.gui.JOIN_CHAT_ROOM_WIZARD=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ å‚加ウィザード
service.gui.JOIN_AUTOMATICALLY=自動的ã«å‚加
+service.gui.DONT_JOIN_AUTOMATICALLY=自動的ã«å‚加ã—ãªã„
service.gui.KICK=キック (&K)
service.gui.KICK_FAILED=キックã§ãã¾ã›ã‚“ã§ã—ãŸ
service.gui.KICK_FAILED_GENERAL_ERROR=コンタクト: {0} をキックã§ãã¾ã›ã‚“ã§ã—ãŸã€‚一般サーãƒã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚
service.gui.KICK_FAILED_NOT_ALLOWED=コンタクト: {0} をキックã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ルームã®ã‚ªãƒ¼ãƒŠãƒ¼ã¨ç®¡ç†è€…ã¯ã‚­ãƒƒã‚¯ã§ãã¾ã›ã‚“。
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=コンタクト: {0} をキックã§ãã¾ã›ã‚“ã§ã—ãŸã€‚権é™ãŒã‚ã‚Šã¾ã›ã‚“。
-service.gui.LAST=最終
-service.gui.LAST_NAME=姓:
+service.gui.LAST_NAME=姓
service.gui.LEAVE=去る (&L)
service.gui.LIMIT_REACHED_FOR_IP=ローカルã®IPアドレスã‹ã‚‰ç™»éŒ²ãŒå¤šã™ãŽã‚‹ã®ã§ã™ã€‚サーãƒãƒ¼: {0} ã¯ç™»éŒ²ã‚’オープンã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
-service.gui.LIST=最終
+service.gui.LIST=リスト
+service.gui.LOADING_ROOMS=部屋を読込中…
+service.gui.LOADING=読込中…
+service.gui.LOCALLY_ON_HOLD_STATUS=ä¿ç•™ä¸­
service.gui.LOGIN_NETWORK_ERROR=<DIV>ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã«éšœå®³ãŒã‚ã£ãŸãŸã‚ã€ã‚¢ã‚«ã‚¦ãƒ³ãƒˆ:<BR>ユーザå: {0}<BR>サーãƒå: {1}<BR>ã§ãƒ­ã‚°ã‚¤ãƒ³ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯æŽ¥ç¶šæ€§ã‚’確èªã—ã¦ãã ã•ã„。</DIV>
service.gui.LOGIN_GENERAL_ERROR=ユーザå: {0}, サーãƒå: {1} ã§ãƒ­ã‚°ã‚¤ãƒ³ã—よã†ã¨ã—ãŸã¨ã“ã‚エラーãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚
service.gui.LOGIN_INTERNAL_ERROR=アプリケーション内部エラーã®ãŸã‚ã€ãƒ¦ãƒ¼ã‚¶å: {0}, サーãƒå: {1} ã§ãƒ­ã‚°ã‚¤ãƒ³ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ãŠæ‰‹æ•°ã§ã™ãŒã€å•é¡Œã‚’ dev@sip-communicator.dev.java.net ã¾ã§ã”報告ãã ã•ã„。
service.gui.LOGIN_INVALID_PROPERTIES_ERROR=アカウント設定ã«å•é¡ŒãŒã‚ã‚‹ãŸã‚ã€ãƒ¦ãƒ¼ã‚¶å: {0}, サーãƒå: {1} ã§ãƒ­ã‚°ã‚¤ãƒ³ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚アカウント設定をã”確èªãã ã•ã„。
service.gui.LOGOFF_NOT_SUCCEEDED=ユーザå: {0}, サーãƒå: {1} ã§ãƒ­ã‚°ã‚ªãƒ•ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚
+service.gui.LOW_QUALITY=低å“質
service.gui.MEMBER=メンãƒãƒ¼
service.gui.MERGE_TO_CALL=å…¨ã¦ã®é€šè©±ã‚’çµ±åˆ
service.gui.MESSAGE=メッセージ
service.gui.MISSED_CALLS_TOOL_TIP=次ã®ã¨ã“ã‚ã‹ã‚‰ä¸åœ¨ç€ä¿¡:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= {0} ã‹ã‚‰ã‚‚
service.gui.MODERATOR=å¸ä¼šè€…
-service.gui.MORE=ã‚‚ã£ã¨è¦‹ã‚‹
-service.gui.MORE_LABEL=移動
+service.gui.MORE_LABEL=ã‚‚ã£ã¨
service.gui.MOVE=移動
service.gui.MOVE_SUBCONTACT=コンタクトを移動 (&o)
service.gui.MOVE_SUBCONTACT_MSG=é¸æŠžã—ãŸé€£çµ¡å…ˆã‚’移動ã—ãŸã„ã€é€£çµ¡å…ˆã‹ã‚°ãƒ«ãƒ¼ãƒ—ã‚’é¸æŠžã—ã¦ãã ã•ã„。
@@ -330,16 +342,21 @@ service.gui.MOVE_SUBCONTACT_FAILED=é¸æŠžã—ãŸã‚³ãƒ³ã‚¿ã‚¯ãƒˆã¯ç§»å‹•å…ƒã®ã‚³
service.gui.MOVE_SUBCONTACT_QUESTION=<DIV><B> {0} </B> ã‚’ <B> {1} </B> ã«ç§»å‹•ã—ã¾ã™ã‹ï¼Ÿ</DIV>
service.gui.MOVE_TO_GROUP=グループã«ç§»å‹•ã™ã‚‹ (&M)
service.gui.MOVE_CONTACT=コンタクトを移動
-service.gui.MOVE_CONTACT_ERROR=ã“ã®ã‚³ãƒ³ã‚¿ã‚¯ãƒˆã¯ç§»å‹•å‡ºæ¥ã¾ã›ã‚“ (&C)
service.gui.MSG_DELIVERY_FAILURE=上記ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¯é…é€ã§ãã¾ã›ã‚“ã§ã—ãŸ
-service.gui.MSG_DELIVERY_NOT_SUPPORTED=ã‚ãªãŸãŒä½¿ã£ã¦ã„るプロトコルã¯ã‚ªãƒ•ãƒ©ã‚¤ãƒ³ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。他ã®ãƒ—ロトコルを使ã£ã¦ã‚³ãƒ³ã‚¿ã‚¯ãƒˆã™ã‚‹ã‹ã€ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã«ãªã‚‹ã¾ã§ãŠå¾…ã¡ãã ã•ã„。
+service.gui.MSG_DELIVERY_NOT_SUPPORTED=ã‚ãªãŸãŒä½¿ã£ã¦ã„るプロトコルã¯ã‚ªãƒ•ãƒ©ã‚¤ãƒ³ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。他ã®ãƒ—ロトコルを使ã£ã¦ã‚³ãƒ³ã‚¿ã‚¯ãƒˆã™ã‚‹ã‹ã€ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã«ãªã‚‹ã¾ã§ãŠå¾…ã¡ãã ã•ã„。
service.gui.MSG_DELIVERY_INTERNAL_ERROR=内部エラーãŒç™ºç”Ÿã—ã¾ã—ãŸï¼š{0}。次ã®ã‚µã‚¤ãƒˆã«ã¦å•é¡Œã‚’報告ã—ã¦ãã ã•ã„: http://www.sip-communicator.org/index.php/Development/BugsAndIssues
service.gui.MSG_DELIVERY_ERROR=メッセージé€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸã€‚
service.gui.MSG_DELIVERY_UNKNOWN_ERROR=メッセージé€ä¿¡ä¸­ã«ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚
-service.gui.MSG_NOT_POSSIBLE=ãã®ã‚³ãƒ³ã‚¿ã‚¯ãƒˆã¨ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãƒ³ã‚°ãŒã§ãã¾ã›ã‚“(プロトコルã«ã‚ˆã£ã¦ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“)
+service.gui.MSG_DELIVERY_UNSUPPORTED_OPERATION=サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„æ“作ã§ã™
+service.gui.MSG_NOT_DELIVERED=ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯çŠ¶æ³ã‚’確èªã—å†åº¦è¡Œã£ã¦ãã ã•ã„。
+service.gui.MSG_NOT_POSSIBLE=ã“ã®é€£çµ¡å…ˆã¨ã¯ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã§ãã¾ã›ã‚“(プロトコルã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“)
service.gui.MSG_RECEIVED={0} ã¯ã‚ãªãŸã«ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’é€ã‚Šã¾ã—ãŸ
service.gui.MSG_SEND_CONNECTION_PROBLEM=メッセージをé€ã‚‹ãŸã‚ã«ã¯ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã§ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
service.gui.MULTIPLE_LOGINS=åŒã˜ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã§è¤‡æ•°å›žãƒ­ã‚°ã‚¤ãƒ³ã—ã¾ã—ãŸã€‚アカウント ユーザå: {0}, サーãƒå: {1} ã¯ç¾åœ¨æœªæŽ¥ç¶šã§ã™ã€‚
+service.gui.MY_CHAT_ROOMS=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã«å‚加
+service.gui.MY_CHAT_ROOMS_TITLE=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã«å‚加
+service.gui.MUTUALLY_ON_HOLD_STATUS=相互ä¿ç•™ä¸­
+service.gui.NAME=åå‰
service.gui.NETWORK=ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯
service.gui.NETWORK_FAILURE=ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯éšœå®³
service.gui.NEXT=次 (&N)
@@ -352,34 +369,73 @@ service.gui.NICKNAME=ニックãƒãƒ¼ãƒ 
service.gui.NO=ã„ã„ãˆ
service.gui.NONE=使用ã—ãªã„
service.gui.NO_CAMERA_AVAILABLE=利用å¯èƒ½ãªã‚«ãƒ¡ãƒ©ãŒã‚ã‚Šã¾ã›ã‚“。
-service.gui.NO_DESKTOP_SHARING_FOR_PROTOCOL=ã“ã®ãƒ—ロトコルã§ã¯ã€ãƒ‡ã‚¹ã‚¯ãƒˆãƒƒãƒ—共有ãŒã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“。
+service.gui.NO_DESKTOP_SHARING_FOR_PROTOCOL=ã“ã®ãƒ—ロトコルã§ã¯ã€ãƒ‡ã‚¹ã‚¯ãƒˆãƒƒãƒ—共有ã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。
service.gui.NO_VIDEO_ENCODINGS=設定ã§ãƒ“デオエンコードãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã›ã‚“。
-service.gui.NO_VIDEO_FOR_PROTOCOL=ã“ã®ãƒ—ロトコルã§ã¯ã€ãƒ“デオã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“。
+service.gui.NO_VIDEO_FOR_PROTOCOL=ã“ã®ãƒ—ロトコルã¯ã€æ˜ åƒã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。
service.gui.NO_AVAILABLE_ROOMS=ã“ã®ã‚µãƒ¼ãƒã®ãƒ«ãƒ¼ãƒ ãƒªã‚¹ãƒˆã¯ç¾åœ¨åˆ©ç”¨å‡ºæ¥ã¾ã›ã‚“。
service.gui.NO_CONTACTS_FOUND=連絡先ã®æ¤œç´¢çµæžœã¯ã‚ã‚Šã¾ã›ã‚“。{0} を呼ã³ã ã™ã«ã¯ã€Ctrl+Enterを押ã™ã‹ã€ä¸‹ã®ãƒœã‚¿ãƒ³ã‚’使用ã—ã¦ãã ã•ã„。
service.gui.NO_CONTACTS_FOUND_SHORT=連絡先ã®æ¤œç´¢çµæžœã¯ã‚ã‚Šã¾ã›ã‚“。
service.gui.NO_MESSAGE=メッセージãŒã‚ã‚Šã¾ã›ã‚“
service.gui.NO_GROUP_CHAT_ACCOUNT_AVAILABLE=複数ユーザãƒãƒ£ãƒƒãƒˆãŒåˆ©ç”¨å¯èƒ½ãªã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒã‚ã‚Šã¾ã›ã‚“。複数ユーザãƒãƒ£ãƒƒãƒˆã«å¯¾å¿œã—ãŸãƒ—ロトコルã«ã¤ã„ã¦ã¯ã€sip-communicator.org ã‚’ã”確èªãã ã•ã„。
+service.gui.NO_ONLINE_CONFERENCING_ACCOUNT=会議通話ã«åˆ©ç”¨ã§ãるアカウントãŒã‚ã‚Šã¾ã›ã‚“。会議通話ã«ä½¿ç”¨ã§ãるプロトコルã®è©³ç´°ãªæƒ…報を https://jitsi.org ã§ç¢ºèªã—ã¦ãã ã•ã„。
+service.gui.NO_ONLINE_TELEPHONY_ACCOUNT=音声通話ã™ã‚‹ãŸã‚ã«ã¯ã€å°‘ãªãã¨ã‚‚1ã¤ã¯ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã®é€šè©±ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒå¿…è¦ã§ã™ã€‚通話用ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ã€å†è©¦è¡Œã—ã¦ãã ã•ã„。
+service.gui.NOT_AUTHORIZED=許å¯ã•ã‚Œã¾ã›ã‚“
service.gui.NON_EMPTY_CHAT_WINDOW_CLOSE=未é€ä¿¡ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒã‚ã‚‹ãƒãƒ£ãƒƒãƒˆã‚’é–‰ã˜ã‚ˆã†ã¨ã—ã¦ã„ã¾ã™ã€‚本当ã«ã“ã®ãƒãƒ£ãƒƒãƒˆã‚’é–‰ã˜ã¾ã™ã‹ï¼Ÿ
service.gui.NON_EXISTING_USER_ID=サーム{0} ã«ã¯æŒ‡å®šã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶IDãŒå­˜åœ¨ã—ã¾ã›ã‚“。
+service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=コンタクトリストã«ã‚ã‚Šã¾ã›ã‚“
+service.gui.SD_QUALITY=å“質:通常
service.gui.OFFLINE=オフライン
service.gui.OK=OK (&O)
-service.gui.OLDER_CALLS=以å‰ã®ã‚³ãƒ¼ãƒ«
service.gui.ONLINE=オンライン
+service.gui.OPEN=é–‹ã
+service.gui.OPEN_FILE_FROM_IMAGE=ダブルクリック:ファイルを開ã
+service.gui.OPEN_FOLDER=フォルダを開ã
service.gui.OPEN_IN_BROWSER=ブラウザを開ã (&b)
service.gui.OPTIONS=オプション
+service.gui.OPEN_AUTOMATICALLY=メッセージã®ã¿é–‹ã
+service.gui.OPEN_ON_ACTIVITY=アクティビティを開ã
+service.gui.OPEN_ON_MESSAGE=メッセージã®ã¿é–‹ã
+service.gui.OPEN_ON_IMPORTANT_MESSAGE=é‡è¦ãªãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®ã¿é–‹ã
+service.gui.OR=ã¾ãŸã¯
+service.gui.ORGANIZATION=組織
+service.gui.OTHER=ãã®ä»–
+service.gui.chat.role.OWNER=所有者
service.gui.chat.role.ADMINISTRATOR=管ç†è€…
+service.gui.chat.role.MODERATOR=å¸ä¼šè€…
+service.gui.chat.role.MEMBER=メンãƒãƒ¼
+service.gui.chat.role.GUEST=ゲスト
+service.gui.chat.role.SILENT_MEMBER=サイレントメンãƒãƒ¼
+service.gui.chat.role.OUTCAST=å‚加ç¦æ­¢
+service.gui.OWNER=部屋ã®æ‰€æœ‰è€…
+service.gui.ON_MOBILE_TOOLTIP=モãƒã‚¤ãƒ«
service.gui.PASSWORD=パスワード
+service.gui.PASSWORD_CHANGE_FAILURE=パスワード変更ã«å¤±æ•—ã—ã¾ã—ãŸ
+service.gui.PASSWORD_CHANGE_SUCCESS=パスワードãŒå¤‰æ›´ã•ã‚Œã¾ã—ãŸ
service.gui.PASTE=貼付㑠(&P)
+service.gui.PERSONAL=個人的ãª
+service.gui.PORT=ãƒãƒ¼ãƒˆ
+service.gui.POSTAL_CODE=郵便番å·
+service.gui.PREFERENCES=環境設定
+service.gui.PREFIX=プレフィックス
+service.gui.PRESENCE=出席
+service.gui.PRESS_ENTER_FOR_SUGGESTIONS=æ案
+service.gui.PRESS_FOR_CALL_INFO=通話情報
+service.gui.PRESS_TO_OPEN_CRM=CRMアプリを開ã
service.gui.PREVIOUS=å‰
-service.gui.PREVIOUS_TOOLTIP=éŽåŽ»ã®ä¼šè©±ã‚’表示ã™ã‚‹
service.gui.PRINT=å°åˆ· (&P)
service.gui.PROACTIVE_NOTIFICATION=ãŒãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’入力ã—ã¦ã„ã¾ã™
+service.gui.PROBLEMS_ENCOUNTERED=å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸ
service.gui.PROTOCOL=プロトコル
+service.gui.PUT_OFF_HOLD=ä¿ç•™è§£é™¤
+service.gui.PUT_ON_HOLD=ä¿ç•™
service.gui.QUIT=終了 (&Q)
+service.gui.READY=準備
+service.gui.RECENT_MESSAGES=最近ã®ä¼šè©±
service.gui.REASON=ç†ç”±
+service.gui.RECEIVED={0}ãŒå—ã‘å–ã‚Šã¾ã—ãŸ
service.gui.RECONNECTION_LIMIT_EXCEEDED=サーãƒã¸ã®å†æŽ¥ç¶šãŒåˆ‡æ–­ã‹ã‚‰çŸ­ã™ãŽã¾ã—ãŸã€‚アカウント ユーザå: {0}, サーãƒå: {1} ã¯ä¸€æ™‚çš„ã«æ‹’å¦ã•ã‚Œã¾ã—ãŸã€‚ã—ã°ã‚‰ãé–“ã‚’ç½®ã„ã¦å†æŽ¥ç¶šã—ã¦ãã ã•ã„。
service.gui.RE_REQUEST_AUTHORIZATION=承èªã‚’è¦æ±‚ (&R)
+service.gui.REFERRED_STATUS=照会
service.gui.REJECT=æ‹’å¦ (&R)
service.gui.REMEMBER_PASSWORD=パスワードを記録ã™ã‚‹
service.gui.REMOVE=å–り除ã (&R)
@@ -387,77 +443,158 @@ service.gui.REMOVE_ACCOUNT=アカウントをå–り除ã (&R)
service.gui.REMOVE_ACCOUNT_MESSAGE=本当ã«ã“ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’å–り除ãã¾ã™ã‹?
service.gui.REMOVE_CONTACT=サブコンタクトをå–り除ã (&R)
service.gui.REMOVE_CONTACT_TEXT=<DIV>本当㫠<B> {0} </B> をコンタクトリストã‹ã‚‰ <BR> å–り除ãã¾ã™ã‹?</DIV>
+service.gui.REMOVE_CONTACT_NOT_CONNECTED=ã“ã®ã‚³ãƒ³ã‚¿ã‚¯ãƒˆã‚’å–り除ãã«ã¯ãƒ­ã‚°ã‚¤ãƒ³ãŒå¿…è¦ã§ã™ã€‚ログインã—ã¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。
service.gui.REMOVE_GROUP=グループをå–り除ã (&R)
+service.gui.REMOTELY_ON_HOLD_STATUS=リモートãŒä¿ç•™ä¸­
service.gui.RENAME=åå‰ã‚’変更 (&R)
service.gui.RENAME_CONTACT=コンタクトã®åå‰ã‚’変更 (&n)
service.gui.RENAME_CONTACT_WIZARD=指定ã—ãŸã‚³ãƒ³ã‚¿ã‚¯ãƒˆã«å¯¾ã—ã¦åˆ©ç”¨ã™ã‚‹åå‰ã‚’下ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«å…¥åŠ›ã—ã¦ãã ã•ã„。
service.gui.RENAME_GROUP=グループã®åå‰ã‚’変更 (&n)
service.gui.RENAME_GROUP_INFO=指定ã—ãŸã‚°ãƒ«ãƒ¼ãƒ—ã«å¯¾ã—ã¦åˆ©ç”¨ã™ã‚‹åå‰ã‚’下ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«å…¥åŠ›ã—ã¦ãã ã•ã„。
+service.gui.RENAME_CLEAR_USER_DEFINED=復元
+service.gui.RINGING_STATUS=呼ã³å‡ºã—中
service.gui.REQUEST=è¦æ±‚ (&R)
service.gui.REQUEST_AUTHORIZATION=承èªã‚’è¦æ±‚ (&R)
service.gui.REQUEST_AUTHORIZATION_MSG=承èªãŒå¿…è¦ãªãŸã‚ã€{0} をコンタクトリストã«è¿½åŠ ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚次ã«æ‰¿èªè¦è«‹ã‚’入力ã—ã¦ãã ã•ã„。
service.gui.RETRY=å†è©¦è¡Œ
-service.gui.ROOT_GROUP=ルートグループ
+service.gui.REVOKE_OWNERSHIP=所有権をå–り消ã™
+service.gui.REVOKE_ADMIN=管ç†è€…ã‚’å–り消ã™
+service.gui.REVOKE_MODERATOR=å¸ä¼šè€…ã‚’å–り消ã™
+service.gui.REVOKE_MEMBERSHIP=メンãƒãƒ¼ã‚’å–り消ã™
+service.gui.REVOKE_VOICE=音声をå–り消ã™
service.gui.SAVE=ä¿å­˜ (&S)
service.gui.SEARCH=検索 (&S)
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=é¸æŠžã—ãŸã‚µãƒ¼ãƒã«å­˜åœ¨ã™ã‚‹ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã‚’表示ã™ã‚‹ã«ã¯ä¸‹ã®ãƒœã‚¿ãƒ³ã‚’クリックã—ã¦ãã ã•ã„。ãã—ã¦ã€å‚加ã—ãŸã„ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã‚’é¸æŠžã—「å‚加ã€ãƒœã‚¿ãƒ³ã‚’クリックã—ã¦ãã ã•ã„。
-service.gui.SELECT_ACCOUNT=アカウントをé¸æŠž
+service.gui.SEARCH_STRING_CONTACT_SOURCE=コンタクトをã•ãŒã™
+service.gui.SECURITY=セキュリティ
service.gui.SELECT_COLOR=色をé¸æŠžã™ã‚‹
service.gui.SELECT_GROUP=グループé¸æŠž
-service.gui.SELECT_GROUP_WIZARD_MSG=次ã®ãƒªã‚¹ãƒˆã¯ã‚ãªãŸã®ã‚³ãƒ³ã‚¿ã‚¯ãƒˆãƒªã‚¹ãƒˆã«å«ã¾ã‚Œã‚‹ã‚°ãƒ«ãƒ¼ãƒ—ã®ãƒªã‚¹ãƒˆã§ã™ã€‚æ–°ã—ã„コンタクトを追加ã—ãŸã„グループをé¸æŠžã—ã¦ãã ã•ã„。
-service.gui.SELECT_GROUP_WIZARD=グループ指定
+service.gui.SELECT_NO_GROUP=グループãŒã‚ã‚Šã¾ã›ã‚“
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=次ã®ãƒªã‚¹ãƒˆã¯è¤‡æ•°ãƒ¦ãƒ¼ã‚¶ãƒãƒ£ãƒƒãƒˆæ©Ÿèƒ½ã‚’サãƒãƒ¼ãƒˆã™ã‚‹ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ãƒªã‚¹ãƒˆã§ã™ã€‚ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã‚’作æˆã«ä½¿ç”¨ã—ãŸã„アカウントをé¸æŠžã—ã¦ãã ã•ã„。
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=次ã®ãƒªã‚¹ãƒˆã¯ç™»éŒ²ã—ã¦ã„ã‚‹ã™ã¹ã¦ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ãƒªã‚¹ãƒˆã§ã™ã€‚æ–°ã—ã„コンタクトã¨é€šä¿¡ã™ã‚‹ã®ã«åˆ©ç”¨ã—ãŸã„アカウントをé¸æŠžã—ã¦ãã ã•ã„。
-service.gui.SELECT_PROVIDERS_WIZARD=アカウントé¸æŠž
+service.gui.SELECT_VIDEO_CONFERENCE=ビデオ会議をé¸æŠžã™ã‚‹
+service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=リストã‹ã‚‰ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã‚’é¸æŠžã—ã€OKã§è¿½åŠ ã™ã‚‹
service.gui.SEND=é€ã‚‹ (&S)
service.gui.SEND_FILE=ファイルをé€ã‚‹ (&f)
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=ã“ã®ã‚³ãƒ³ã‚¿ã‚¯ãƒˆã«é–¢ã™ã‚‹æƒ…å ±ãŒã‚ã‚Šã¾ã›ã‚“。
service.gui.SEND_MESSAGE=メッセージをé€ã‚‹ (&S)
-service.gui.SEND_AS_SMS=SMSã¨ã—ã¦é€ã‚‹
+service.gui.SEND_PRIVATE_MESSAGE=プライベートメッセージをé€ä¿¡
service.gui.SEND_SMS=SMSã‚’é€ã‚‹ (&e)
service.gui.SEND_SMS_DETAILS=国際通話ã®å½¢å¼ã§ç•ªå·ã‚’入力ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ 例ãˆã°ã€ã‚¤ã‚®ãƒªã‚¹ã®å ´åˆ +44 ã§å§‹ã¾ã‚Šã€+447777000000 ã¨ãªã‚Šã¾ã™ã€‚
-service.gui.SEND_SMS_NOT_SUPPORTED=é¸æŠžã—ãŸãƒ—ロトコルã¯SMSメッセージをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。
+service.gui.SEND_SMS_NOT_SUPPORTED=é¸æŠžã—ãŸãƒ—ロトコルã¯SMSメッセージã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。
+service.gui.SMS=SMS
+service.gui.SEND_VIA=経由ã—ã¦é€ã‚‹
+service.gui.SENT=é€ä¿¡
+service.gui.SERVER_CHAT_ROOMS=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã‚µãƒ¼ãƒãƒ¼
+service.gui.SET_GLOBAL_STATUS=グローãƒãƒ«ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã®è¨­å®š
service.gui.SET_STATUS_MESSAGE=状態メッセージを設定
+service.gui.SET_SUBJECT=件åを設定
service.gui.SETTINGS=設定 (&S)
+service.gui.SHARE_DESKTOP=ç”»é¢å…±æœ‰
+service.gui.SHARE_DESKTOP_WITH_CONTACT=コンタクト先ã¨ãƒ‡ã‚¹ã‚¯ãƒˆãƒƒãƒ—共有
+service.gui.SHARE_FULL_SCREEN=フルスクリーン
+service.gui.SHARE_REGION=領域共有
+service.gui.SHOW=表示
+service.gui.SHOW_CONTACT_LIST_TOOL_TIP=表示を履歴ã‹ã‚‰ã‚³ãƒ³ã‚¿ã‚¯ãƒˆãƒªã‚¹ãƒˆã¸åˆ‡ã‚Šæ›¿ãˆã‚‹ã«ã¯ã“ã¡ã‚‰ã‚’クリック
+service.gui.SHOW_MORE=æ›´ã«è¦‹ã›ã‚‹
service.gui.SHOW_OFFLINE_CONTACTS=オフラインã®ã‚³ãƒ³ã‚¿ã‚¯ãƒˆã‚’表示
+service.gui.SIGN_IN=サインイン
service.gui.SMS_SUCCESSFULLY_SENT=SMSメッセージãŒé€ä¿¡ã§ãã¾ã—ãŸ!
service.gui.SMS_SEND_CONNECTION_PROBLEM=SMSメッセージをé€ä¿¡ã™ã‚‹ã«ã¯SMSプロãƒã‚¤ãƒ€ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«æŽ¥ç¶šã—ã¦ã„ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
service.gui.SPECIFY_REASON=下ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«ã“ã®æ“作ã®ç†ç”±ã‚’指定ã§ãã¾ã™ã€‚
+service.gui.SPECIFY_SERVER=アカウントã®ã‚µãƒ¼ãƒãƒ¼éƒ¨åˆ†ã‚’指定ã—ã¦ã—ã¦ãã ã•ã„。
+service.gui.SOUND_OFF=音をオフã«ã™ã‚‹
+service.gui.SOUND_ON=音をオンã«ã™ã‚‹
+service.gui.START_SHARING=シェア開始
+service.gui.STATUS=ステータス
service.gui.STATUS_CHANGED_CHAT_MESSAGE={0} ã«ãªã‚Šã¾ã—ãŸ
service.gui.STATUS_CHANGE_GENERAL_ERROR=一般エラーã®ãŸã‚ã€æ¬¡ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®çŠ¶æ…‹ã‚’変更ã§ãã¾ã›ã‚“ã§ã—ãŸ: ユーザå {0}, サーãƒå {1}.
service.gui.STATUS_CHANGE_NETWORK_FAILURE=ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã«å•é¡ŒãŒã‚ã‚‹ãŸã‚ã€æ¬¡ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®çŠ¶æ…‹ã‚’変更ã§ãã¾ã›ã‚“ã§ã—ãŸ: ユーザå {0}, サーãƒå {1}.
service.gui.STATUS_MESSAGE_INFO=下ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«ã‚ãªãŸãŒä½¿ã„ãŸã„æ–°ã—ã„メッセージを指定ã§ãã¾ã™ã€‚
+service.gui.STOP_SHARING=シェアåœæ­¢
+service.gui.STREET=ストリート
service.gui.SUBJECT=件å
service.gui.SUMMARY=概è¦
-service.gui.TODAY=今日
+service.gui.TELEPHONY=通話方å¼
service.gui.TOOLS=ツール (&T)
service.gui.TRANSFER=è»¢é€ (&f)
-service.gui.TO=ã¸: (&T)
+service.gui.TO=転é€ã—ãŸã„連絡先ã®åå‰ã‚’é¸æŠžã€è»¢é€ã—ã¾ã™ã€‚
+service.gui.TRANSFER_CALL_MSG=転é€ã—ãŸã„連絡先ã®åå‰ã‚’é¸æŠžã—ã€è»¢é€ã‚’クリックã—ã¾ã™ã€‚
service.gui.TRANSFER_CALL_TITLE=コールを転é€
+service.gui.TRANSFER_CALL_TO=ã¸è»¢é€
service.gui.TRANSPARENCY_NOT_ENABLED=é€æ˜Žæ€§ã‚’ç¾åœ¨ã®æ§‹æˆã§ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¾ã›ã‚“。
service.gui.TYPE_YOUR_REQUEST=ã‚ãªãŸã®è¦æ±‚ã‚’ã“ã“ã«å…¥åŠ›ã—ã¦ãã ã•ã„
+service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=ã“ã®é€šè©±ã§ã¯ãƒ“デオã®å“質を変更ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚
service.gui.USER_IDENTIFIER=ユーザID:
service.gui.USER_EXISTS_ERROR=ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯æ—¢ã«é¸æŠžã•ã‚ŒãŸãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã«å­˜åœ¨ã™ã‚‹ã€‚ã»ã‹ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¾ãŸã¯ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚’é¸æŠžã—ã¦ãã ã•ã„。
+service.gui.USERNAME_NULL=ユーザーãƒãƒ¼ãƒ ã¨ãƒ‘スワードを入力ã—ã¦ãã ã•ã„
+service.gui.WEBPAGE=ウェブサイトを開ã
service.gui.ACCOUNT_CREATION_FAILED=アカウントを作æˆå‡ºæ¥ã¾ã›ã‚“ã§ã—ãŸ: {0}
service.gui.UNKNOWN=ä¸æ˜Žãªãƒ¦ãƒ¼ã‚¶
+service.gui.UNKNOWN_STATUS=ä¸æ˜ŽãªçŠ¶æ…‹
service.gui.UNREGISTERED_MESSAGE=次ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸ: ユーザå: {0}, サーãƒå: {1}。ã‚ãªãŸã¯ç¾åœ¨ã‚ªãƒ•ãƒ©ã‚¤ãƒ³ã§ã™ã€‚
+service.gui.USE_PROVISIONING=オンライン設定を利用
+service.gui.VALUE=値
+service.gui.VIDEO_CALL=&ビデオ通話
+service.gui.VIA=経由
service.gui.VIEW=表示ã™ã‚‹ (&V)
service.gui.VIEW_HISTORY=履歴を表示 (&h)
+service.gui.VIEW_SMILEYS=ビュー&スマイリー
service.gui.VIEW_TOOLBAR=ツールãƒãƒ¼ã‚’見る (&t)
+service.gui.VIEW_SIMPLE_CHAT_THEME=シンプルãƒãƒ£ãƒƒãƒˆãƒ†ãƒ¼ãƒžãƒ“ュー
+service.gui.VOICEMAIL_NEW_URGENT_OLD_RECEIVED=æ–°ã—ã„ {0} (急㎠{1}) 㨠å¤ã„メッセージ {2}
+service.gui.VOICEMAIL_NEW_URGENT_RECEIVED=æ–°ã—ã„ {0} (急㎠{1}) 㨠メッセージ {2}
+service.gui.VOICEMAIL_NEW_OLD_RECEIVED=æ–°ã—ã„ {0} 㨠å¤ã„メッセージ {1}
+service.gui.VOICEMAIL_NEW_RECEIVED={0}æ–°ã—ã„メッセージ
+service.gui.VOICEMAIL_OLD_RECEIVED={0}å‰ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸
service.gui.VOICEMAIL_NO_MESSAGES=メッセージãŒã‚ã‚Šã¾ã›ã‚“
+service.gui.VOICEMAIL_TITLE=音声メッセージ
+service.gui.VOICEMAIL_TOOLTIP=ã‹ã‚‰éŸ³å£°ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸
+service.gui.VOICEMAIL_TIP=メッセージをèžãã«ã¯ã‚³ãƒ¼ãƒ«ãƒœã‚¿ãƒ³ã‚’押ã—ã¦ãã ã•ã„
+service.gui.VOICEMAIL_TIP_NO_ACCOUNT=アカウントウィザード中㫠ボイスメールをãƒã‚§ãƒƒã‚¯ã™ã‚‹ URI を設定ã—ã¦ãã ã•ã„
+service.gui.VOLUME_CONTROL_TOOL_TIP=音é‡ã‚’調節ã™ã‚‹
+service.gui.WAITING_AUTHORIZATION=承èªå¾…機中
service.gui.WARNING=警告
service.gui.YES=ã¯ã„
-service.gui.YESTERDAY=昨日
-service.gui.EXISTING_ACCOUNT_ERROR=入力ã—ãŸã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒæ—¢ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¦ã„る。
+service.gui.NEW_GMAIL_HEADER=ã‚ãªãŸã® {0} <a href="{1}">å—ä¿¡ç®±</a>:<br/> ã«æ–°ã—ã„メッセージãŒå±Šã„ã¦ã„ã¾ã™:<br/>
+service.gui.NEW_GMAIL_MANY_HEADER=ã‚ãªãŸã® {0} <a href="{1}">å—ä¿¡ç®±</a> ã« {2} 通ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒå±Šã„ã¦ã„ã¾ã™:<br/>
+service.gui.NEW_GMAIL_FOOTER=<a href="{0}">å—ä¿¡ç®±</a> ã«æœªèª­ã®ä¼šè©±ãŒã‚ã‚Šã¾ã™ã€‚<br/>
+service.gui.NEW_GMAIL_MANY_FOOTER=<a href="{0}">å—ä¿¡ç®±</a> ã« {1}ã¤ã®æœªèª­ã®ä¼šè©±ãŒã‚ã‚Šã¾ã™ã€‚<br/>
+service.gui.ACTIVATE=承èª
+service.gui.DEACTIVATE=無効化
+service.gui.NEW=æ–°
service.gui.ENTER_FULL_SCREEN_TOOL_TIP=フルスクリーン
service.gui.EXIT_FULL_SCREEN_TOOL_TIP=フルスクリーン
+service.gui.HOLD_BUTTON_TOOL_TIP=ä¿ç•™åˆ‡ã‚Šæ›¿ãˆ
+service.gui.MUTE_BUTTON_TOOL_TIP=ä¿ç•™ã‚’切り替ãˆã‚‹ã‹ã€ãƒžã‚¤ã‚¯éŸ³é‡èª¿æ•´ãƒœã‚¿ãƒ³ã‚’押ã™
+service.gui.PARK=パークä¿ç•™
+service.gui.PARKING_SLOT=パークä¿ç•™æž :
+service.gui.PARK_BUTTON_TOOL_TIP=呼ã³å‡ºã—をパークä¿ç•™
+service.gui.RECORD_BUTTON_TOOL_TIP=記録を調整ã™ã‚‹
+service.gui.LOCAL_VIDEO_BUTTON_TOOL_TIP=映åƒã‚’調節ã™ã‚‹
+service.gui.SHOW_LOCAL_VIDEO_BUTTON_TOOL_TIP=映åƒã®è¡¨ç¤º/éžè¡¨ç¤º
+service.gui.SHOW_HIDE_PEERS_TOOL_TIP=å‚加者リストã®è¡¨ç¤º/éžè¡¨ç¤º
service.gui.TRANSFER_BUTTON_TOOL_TIP=転é€é›»è©±
+service.gui.TRANSFER_TO=ã¸ç§»ã™
service.gui.SECURITY_INFO=セキュリティ情報
service.gui.SECURITY_WARNING=セキュリティ警告
service.gui.SECURITY_ERROR=セキュリティエラー
-service.gui.PHONE=電話番語:
-service.gui.PHONES=電話番語:
-
+service.gui.SPEED=スピード:
+service.gui.SILENT_MEMBER=無音ã®å‚加者
+service.gui.NON_SECURE_CONNECTION=アカウント {0} ã§ã¯å®‰å…¨ã‚’確ä¿ã—ã¦æŽ¥ç¶šã§ãã¾ã›ã‚“。暗å·åŒ–ã•ã‚Œã¦ã„ãªã„接続ã§ã‚‚よã„å ´åˆã¯ã€ã‚¢ã‚«ã‚¦ãƒ³ãƒˆè¨­å®šã§ "æš—å·åŒ–ã•ã‚Œã¦ã„ãªã„接続を許å¯" ã«ãƒã‚§ãƒƒã‚¯ã—ã¦ãã ã•ã„。
+service.gui.MOBILE_PHONE=モãƒã‚¤ãƒ«
+service.gui.VIDEO_PHONE=映åƒ
+service.gui.WORK_PHONE=会社
+service.gui.PHONE=電話番語
+service.gui.PHONES=電話番å·
+service.gui.EDIT_NOT_SUPPORTED=アカウント編集ã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。
+service.gui.SHOW_PREVIEW=(プレビュー表示)
+service.gui.SHOW_PREVIEW_WARNING_DESCRIPTION=ã“ã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’表示ã—続ã‘ã¾ã™ã‹ï¼Ÿã“ã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã§ã¯ã‚ãªãŸã‚’特定ã™ã‚‹ã“ã¨ãŒã§ããªã„ãŸã‚ã€ç‰¹å®šå¯èƒ½ãªã‚¤ãƒ¡ãƒ¼ã‚¸/映åƒã‚’検討ã—ã¦ãã ã•ã„。
+service.gui.SHOW_PREVIEW_DIALOG_TITLE=イメージ表示/映åƒãƒ—レビュー
+
+service.gui.ZID_NAME_SET=ZRTP識別å­:
+service.gui.ZID_NAME_NOT_SET=ZRTP識別å­ãŒè¨­å®šã•ã‚Œã¦ã„ã¾ã›ã‚“。
+service.gui.ZID_NAME_BUTTON=クリックã—ã¦ZRTP識別åを設定ã™ã‚‹ã€‚
+service.gui.ZID_NAME_DIALOG=ZRTP識別å­ã‚’編集
+service.gui.ZID_NAME_UNEXPECTED=ZRTP識別å­ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。<br>
service.gui.JANUARY=1月
service.gui.FEBRUARY=2月
@@ -472,23 +609,129 @@ service.gui.OCTOBER=10月
service.gui.NOVEMBER=11月
service.gui.DECEMBER=12月
-
-
-
+service.gui.callinfo.TECHNICAL_CALL_INFO=技術的ãªé€šè©±ã®æƒ…å ±
+service.gui.callinfo.CALL_INFORMATION=通話情報
+service.gui.callinfo.CALL_IDENTITY=アイデンティティ
+service.gui.callinfo.PEER_COUNT=å‚加者数
+service.gui.callinfo.IS_CONFERENCE_FOCUS=会議ã®ç„¦ç‚¹
+service.gui.callinfo.CALL_DURATION=通話時間
+service.gui.callinfo.TLS_PROTOCOL=TLS プロトコル
+service.gui.callinfo.TLS_CIPHER_SUITE=TLS æš—å·åŒ–æ–¹å¼
+service.gui.callinfo.TLS_CERTIFICATE_CONTENT=TLSサーãƒãƒ¼è¨¼æ˜Žæ›¸ã®å†…容ã¯ä¸‹è¨˜ã«è¡¨ç¤ºã—ã¦ã„ã¾ã™ã€‚
+service.gui.callinfo.VIEW_CERTIFICATE=証明書を表示
+service.gui.callinfo.CODEC=コーデック / サンプリングレート
+service.gui.callinfo.NA=該当ãªã—
+service.gui.callinfo.VIDEO_SIZE=映åƒã‚µã‚¤ã‚º
+service.gui.callinfo.AUDIO_INFO=音声情報
+service.gui.callinfo.VIDEO_INFO=映åƒæƒ…å ±
+service.gui.callinfo.LOCAL_IP=ローカルIP / ãƒãƒ¼ãƒˆ
+service.gui.callinfo.REMOTE_IP=リモートIP / ãƒãƒ¼ãƒˆ
+service.gui.callinfo.BANDWITH=帯域
+service.gui.callinfo.LOSS_RATE=速度低下
+service.gui.callinfo.RTT=RTT
+service.gui.callinfo.JITTER=Jitter
+service.gui.callinfo.MEDIA_STREAM_TRANSPORT_PROTOCOL=メディアストリームトランスãƒãƒ¼ãƒˆãƒ—ロトコル
+service.gui.callinfo.MEDIA_STREAM_RTP=RTP
+service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
+service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=Key exchangeプロトコル
+service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=ICE candidate拡張型
+service.gui.callinfo.ICE_STATE=ICE 処ç†çŠ¶æ…‹
+
+#enum values from IceProcessingState
+service.gui.callinfo.ICE_STATE.WAITING=candidatesã‚’ã¾ã¨ã‚ã‚‹
+service.gui.callinfo.ICE_STATE.RUNNING=接続性確èª
+service.gui.callinfo.ICE_STATE.COMPLETED=æˆåŠŸ
+service.gui.callinfo.ICE_STATE.FAILED=失敗
+
+service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=ローカルホストIP / ãƒãƒ¼ãƒˆ
+service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=ローカルループãƒãƒƒã‚¯ IP/ãƒãƒ¼ãƒˆ
+service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=ローカル中継 IP/ãƒãƒ¼ãƒˆ
+service.gui.callinfo.ICE_REMOTE_HOST_ADDRESS=リモートホスト IP / ãƒãƒ¼ãƒˆ
+service.gui.callinfo.ICE_REMOTE_REFLEXIVE_ADDRESS=リモートループãƒãƒƒã‚¯ IP / ãƒãƒ¼ãƒˆ
+service.gui.callinfo.ICE_REMOTE_RELAYED_ADDRESS=リモート中継 IP / ãƒãƒ¼ãƒˆ
+service.gui.callinfo.TOTAL_HARVESTING_TIME=åˆè¨ˆé›†è¨ˆæ™‚é–“
+service.gui.callinfo.HARVESTING_TIME=集計時間
+service.gui.callinfo.DISCARDED_PERCENT=パケットã¯ç¾åœ¨å»ƒæ£„ã•ã‚Œã¦ã„ã¾ã™ã€‚
+service.gui.callinfo.JITTER_BUFFER_DELAY=Jitterãƒãƒƒãƒ•ã‚¡ãƒ¼
+
+service.gui.ALWAYS_TRUST=常ã«ã“ã®è¨¼æ˜Žæ›¸ã‚’使用ã™ã‚‹
+service.gui.CERT_DIALOG_TITLE=証明書を検証
+service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html><b>{1}</b>ã¸ã®æŽ¥ç¶šæ™‚ã« {0} ã§ã‚µãƒ¼ãƒãƒ¼è¨¼æ˜Žæ›¸ã‚’<br>検証ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚<br><br> 証明書ãŒä¿¡é ¼ã•ã‚Œã¦ã„ãªã„ãŸã‚ã€è‡ªå‹•çš„ã«ã‚µãƒ¼ãƒãƒ¼è¨¼æ˜Žæ›¸ã‚’検証ã§ãã¾ã›ã‚“。<br><br>接続を続ã‘ã¾ã™ã‹ã€‚<br><br>"証明書を表示" をクリックã—ã¦è©³ç´°ã‚’確èªã—ã¦ãã ã•ã„。</html>
+service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html> {0} ã§ã‚µãƒ¼ãƒãƒ¼è¨¼æ˜Žæ›¸ã‚’検証ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚<br><br> 証明書ãŒä¿¡é ¼ã•ã‚Œã¦ã„ãªã„ãŸã‚ã€è‡ªå‹•çš„ã«ã‚µãƒ¼ãƒãƒ¼è¨¼æ˜Žæ›¸ã‚’検証ã§ãã¾ã›ã‚“。<br><br>接続を続ã‘ã¾ã™ã‹ã€‚<br><br>"証明書を表示" をクリックã—ã¦è©³ç´°ã‚’確èªã—ã¦ãã ã•ã„。</html>
+service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html> {0} ã§ç›¸æ‰‹å´ {1} ã®è¨¼æ˜Žæ›¸ã‚’検証ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚<br><br> 証明書ãŒä¿¡é ¼ã•ã‚Œã¦ã„ãªã„ãŸã‚ã€è‡ªå‹•çš„ã«ã‚µãƒ¼ãƒãƒ¼è¨¼æ˜Žæ›¸ã‚’検証ã§ãã¾ã›ã‚“。<br><br>接続を続ã‘ã¾ã™ã‹ã€‚<br><br>"証明書を表示" をクリックã—ã¦è©³ç´°ã‚’確èªã—ã¦ãã ã•ã„。</html>
+service.gui.CONTINUE_ANYWAY=ã¨ã«ã‹ã続行ã™ã‚‹
+service.gui.CERT_INFO_CHAIN=証明書ãƒã‚§ãƒ¼ãƒ³:
+service.gui.CERT_INFO_ISSUED_TO=発行先
+
+#service.gui.CERT_INFO_ are combined from Rdn names
+service.gui.CERT_INFO_CN=一般å:
+service.gui.CERT_INFO_O=団体:
+service.gui.CERT_INFO_C=国å:
+service.gui.CERT_INFO_ST=県å:
+service.gui.CERT_INFO_L=地域å:
+service.gui.CERT_INFO_ISSUED_BY=発行
+service.gui.CERT_INFO_OU=部署:
+service.gui.CERT_INFO_VALIDITY=有効性
+service.gui.CERT_INFO_ISSUED_ON=より開始
+service.gui.CERT_INFO_EXPIRES_ON=ã«çµ‚了
+service.gui.CERT_INFO_FINGERPRINTS=指紋
+service.gui.CERT_INFO_CERT_DETAILS=証明書情報
+service.gui.CERT_INFO_SER_NUM=シリアルNo.
+service.gui.CERT_INFO_VER=ãƒãƒ¼ã‚¸ãƒ§ãƒ³
+service.gui.CERT_INFO_SIGN_ALG=ç½²åアルゴリズム:
+service.gui.CERT_INFO_PUB_KEY_INFO=公開éµæƒ…å ±
+service.gui.CERT_INFO_ALG=アルゴリズム:
+service.gui.CERT_INFO_PUB_KEY=公開éµ
+service.gui.CERT_INFO_KEY_BITS_PRINT={0} ビット
+service.gui.CERT_INFO_EXP=エクスãƒãƒ¼ãƒãƒ³ãƒˆ
+service.gui.CERT_INFO_KEY_SIZE=éµã‚µã‚¤ã‚º
+service.gui.CERT_INFO_SIGN=ç½²å
+service.gui.SHOW_CERT=証明書を表示
+service.gui.HIDE_CERT=証明書をéžè¡¨ç¤º
+
+service.gui.AUTO_ANSWER=自動応答ã€å‘¼ã³å‡ºã—転é€
+service.gui.AUTO_ANSWER_LABEL=自動応答
+service.gui.AUTO_ANSWER_ALL_CALLS=å…¨ã¦ã®å‘¼ã³å‡ºã—
+service.gui.AUTO_ANSWER_ALERT_INFO_FIELDS=å¿…è¦ãªå‘¼ã³å‡ºã—ã®ã¿ã€‚("自動応答†㫠"Alert-Info" ãŒå«ã¾ã‚Œã¦ã„ã‚‹å ´åˆ)
+service.gui.AUTO_ANSWER_CUSTOM_FIELDS=次ã®é …ç›®ã¨å€¤ã®å ´åˆã®å‘¼ã³å‡ºã—
+service.gui.AUTO_ANSWER_FIELD=項目/ヘッダー:
+service.gui.AUTO_ANSWER_VALUE=値:
+service.gui.AUTO_ANSWER_DESCR_VLUE=å…¨ã¦ç©ºæ¬„ã®ã¾ã¾
+service.gui.AUTO_ANSWER_FWD_CALLS=ç€ä¿¡è»¢é€
+service.gui.AUTO_ANSWER_VIDEO=映åƒ
+
+service.gui.security.SECURE_AUDIO=安全ãªæ˜ åƒ
+service.gui.security.AUDIO_NOT_SECURED=音声ã¯å®‰å…¨ã§ã¯ã‚ã‚Šã¾ã›ã‚“
+service.gui.security.SECURE_VIDEO=安全ãªæ˜ åƒ
+service.gui.security.VIDEO_NOT_SECURED=安全ã§ãªã„映åƒã§ã™ã€‚
+service.gui.security.CALL_SECURED_TOOLTIP=通話ã¯å®‰å…¨ã§ã™ã€‚詳細確èªã¯ã“ã¡ã‚‰ã‚’クリック。
+service.gui.security.CALL_NOT_SECURED_TOOLTIP=安全ã§ãªã„通話ã§ã™ã€‚
# keep the following string short
+service.gui.avatar.REMOVE_ICON=ç¾åœ¨ã®ç”»åƒã‚’削除ã™ã‚‹
# service.gui.avatar.imagepicker
service.gui.avatar.imagepicker.CANCEL=キャンセル (&C)
+service.gui.avatar.imagepicker.CHOOSE_FILE=é¸æŠž
+service.gui.avatar.imagepicker.CLICK=クリックã¨ã‚¹ãƒžã‚¤ãƒ«
+service.gui.avatar.imagepicker.IMAGE_FILES=イメージファイル
+service.gui.avatar.imagepicker.IMAGE_PICKER=ç”»åƒ
+service.gui.avatar.imagepicker.IMAGE_SIZE=ç”»åƒã‚µã‚¤ã‚º
+service.gui.avatar.imagepicker.RESET=リセット
+service.gui.avatar.imagepicker.SET=設定
+service.gui.avatar.imagepicker.TAKE_PHOTO=写真を撮る
+service.gui.security.encryption.required=æš—å·åŒ–ã—ã¦ãã ã•ã„ï¼
+service.protocol.ICE_FAILED=接続を確立ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚(ICE失敗・リレーãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“)
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
+impl.protocol.sip.XCAP_ERROR_UNAUTHORIZED=xcapã§ä½¿ç”¨ã™ã‚‹ãƒ¦ãƒ¼ã‚¶ãƒ¼åã‚‚ã—ãã¯ãƒ‘スワードãŒé–“é•ã£ã¦ã„ã¾ã™ã€‚ç†ç”±ï¼š {0}
# systray
+impl.systray.SET_STATUS=ステータスを設定ã™ã‚‹
+impl.systray.FAILED_TO_OPEN_ADD_CONTACT_DIALOG=コンタクト追加ダイアログを開ã‘ã¾ã›ã‚“。
+impl.swingnotification.POPUP_MESSAGE_HANDLER= {0}ãƒãƒƒãƒ—アップ
+impl.growlnotification.POPUP_MESSAGE_HANDLER=Growl notification
# New Account Dialog
impl.gui.main.account.DEFAULT_PAGE_TITLE=ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚’é¸æŠžã™ã‚‹
@@ -498,151 +741,401 @@ impl.gui.main.account.DUMMY_PROTOCOL_DESCRIPTION=ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚’é¸æŠžã™ã
# LDAP
impl.ldap.GENERAL=一般
impl.ldap.EDIT=編集ã™ã‚‹ (&E)
-impl.ldap.REMOVE=å–り除ã (&R)
+impl.ldap.ENABLED=有効
+impl.ldap.SERVER_NAME=サーãƒãƒ¼å
+impl.ldap.SERVER_NAME_EXAMPLE=LDAPサーãƒãƒ¼
+impl.ldap.SERVER_HOSTNAME=ホストå
+impl.ldap.USE_SSL=SSLを使用ã™ã‚‹
+impl.ldap.AUTH_NONE=使用ã—ãªã„
+impl.ldap.SCOPE_ONE=ã²ã¨ã¤
impl.ldap.SAVE=ä¿å­˜ (&S)
impl.ldap.CANCEL=キャンセル (&C)
+impl.ldap.SERVER_PORT=ãƒãƒ¼ãƒˆ
impl.ldap.PASSWORD=パスワード
+impl.ldap.MAIL_FIELD_NAME=メール入力箇所
+impl.ldap.WORKPHONE_FIELD_NAME=会社ã®é›»è©±ç•ªå·å…¥åŠ›ç®‡æ‰€
+impl.ldap.MOBILEPHONE_FIELD_NAME=æºå¸¯é›»è©±ç•ªå·å…¥åŠ›ç®‡æ‰€
+impl.ldap.HOMEPHONE_FIELD_NAME=電話番å·å…¥åŠ›ç®‡æ‰€
impl.ldap.MAIL_FIELD_EXAMPLE=é›»å­ãƒ¡ãƒ¼ãƒ«:
+impl.ldap.WORKPHONE_FIELD_EXAMPLE=会社ã®é›»è©±ç•ªå·
+impl.ldap.MOBILEPHONE_FIELD_EXAMPLE=æºå¸¯é›»è©±ç•ªå·
+impl.ldap.HOMEPHONE_FIELD_EXAMPLE=電話番å·
+
+# SIP Protocol
+
+#Jabber Protocol
# Address book plugin
+plugin.addrbook.ADDRESS_BOOKS=アドレス帳
# Google Contacts
impl.googlecontacts.EDIT=編集ã™ã‚‹ (&E)
-impl.googlecontacts.REMOVE=å–り除ã (&R)
+impl.googlecontacts.ENABLED=有効
impl.googlecontacts.SAVE=ä¿å­˜ (&S)
impl.googlecontacts.CANCEL=キャンセル (&C)
impl.googlecontacts.PASSWORD=パスワード
# account info
+plugin.accountinfo.TITLE=アカウント情報
plugin.accountinfo.DISPLAY_NAME=表示å
plugin.accountinfo.FIRST_NAME=åå‰:
plugin.accountinfo.MIDDLE_NAME=ミドルãƒãƒ¼ãƒ :
plugin.accountinfo.LAST_NAME=姓:
+plugin.accountinfo.NICKNAME=ニックãƒãƒ¼ãƒ 
plugin.accountinfo.AGE=å¹´é½¢:
plugin.accountinfo.BDAY=誕生日:
plugin.accountinfo.GENDER=性:
plugin.accountinfo.CITY=市(区町æ‘)
+plugin.accountinfo.POST=郵便番å·
plugin.accountinfo.COUNTRY=国
plugin.accountinfo.EMAIL=é›»å­ãƒ¡ãƒ¼ãƒ«:
+plugin.accountinfo.WORK_EMAIL=メールアドレス(会社):
plugin.accountinfo.PHONE=電話番語:
+plugin.accountinfo.WORK_PHONE=電話番å·ï¼ˆä¼šç¤¾ï¼‰:
+plugin.accountinfo.MOBILE_PHONE=電話番å·ï¼ˆæºå¸¯ï¼‰:
plugin.accountinfo.JOB_TITLE=肩書ã
+plugin.accountinfo.ABOUT_ME=ã‚ãŸã—ã«ã¤ã„ã¦:
# connection info
+plugin.connectioninfo.TITLE=接続情報
# contact info
+plugin.contactinfo.TITLE=コンタクト詳細
+plugin.contactinfo.USER_PICTURES=ユーザーã®å†™çœŸ
+plugin.contactinfo.USER_STATUS_MESSAGE=メッセージステータス
# aimaccregwizz
+plugin.aimaccregwizz.USERNAME_AND_PASSWORD=ユーザーåã¨ãƒ‘スワード
# branding
plugin.branding.ABOUT_WINDOW_TITLE={0}ã«ã¤ã„ã¦
plugin.branding.ABOUT_MENU_ENTRY=ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…å ± (&A)
-# Dict protocol
-
-# facebookaccregwizz
# generalconfig
+plugin.generalconfig.AUTO_START=コンピュータ起動時㫠{0} を起動
+plugin.generalconfig.GROUP_CHAT_MESSAGES=グループãƒãƒ£ãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’1ã¤ã®ç”»é¢ã§è¡¨ç¤º
+plugin.generalconfig.LOG_HISTORY=ãƒãƒ£ãƒƒãƒˆå±¥æ­´ã®ãƒ­ã‚°
+plugin.generalconfig.SHOW_HISTORY=表示
+plugin.generalconfig.HISTORY_SIZE=æ–°ã—ã„ãƒãƒ£ãƒƒãƒˆã®ç¾åœ¨ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸
+plugin.generalconfig.SEND_MESSAGES_WITH=メッセージをé€ä»˜ã™ã‚‹å…ˆ:
+plugin.generalconfig.BRING_WINDOW_TO_FRONT=ãƒãƒ£ãƒƒãƒˆã‚¦ã‚¤ãƒ³ãƒ‰ã‚¦ã‚’手å‰ã«æŒã£ã¦ãã‚‹
+plugin.generalconfig.DEFAULT_LANGUAGE=言語設定
+plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=変更ã¯æ¬¡å›žã®èµ·å‹•æ™‚ã«æœ‰åŠ¹ã«ãªã‚Šã¾ã™
+plugin.generalconfig.ERROR_PORT_NUMBER=誤ã£ãŸãƒãƒ¼ãƒˆNo.
+plugin.generalconfig.CHECK_FOR_UPDATES=起動時ã«æ›´æ–°ã‚’確èª
+plugin.generalconfig.LEAVE_CHATROOM_ON_WINDOW_CLOSE=ウインドウを閉ã˜ãŸã¨ãã«ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã‚’抜ã‘ã‚‹
+plugin.generalconfig.SHOW_RECENT_MESSAGES=最近ã®ä¼šè©±ã‚’表示ã™ã‚‹ï¼ˆãƒãƒ£ãƒƒãƒˆå±¥æ­´ã«ã‚ˆã‚‹ï¼‰
+plugin.generalconfig.REMOVE_SPECIAL_PHONE_SYMBOLS=電話番å·ã‚’呼ã³å‡ºã™å‰ã«ã€ç‰¹æ®Šè¨˜å·ã‚’削除
+plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS=電話番å·ã®æ–‡å­—を変æ›
+plugin.generalconfig.SIP_CALL_CONFIG=SIP
+plugin.generalconfig.XMPP_CONFIG=XMPP
+plugin.generalconfig.OPUS_AUDIO_BANDWIDTH=サンプリングレート
# gibberish accregwizz
+plugin.gibberishaccregwizz.USERNAME=ユーザーID
# icqaccregwizz
# irc accregwizz
+plugin.ircaccregwizz.PROTOCOL_NAME=IRC
+plugin.ircaccregwizz.PROTOCOL_DESCRIPTION=IRCプロトコル
+plugin.ircaccregwizz.USERNAME_AND_PASSWORD=IDã¨ãƒ‘スワード
+plugin.ircaccregwizz.USERNAME=ニックãƒãƒ¼ãƒ 
+plugin.ircaccregwizz.HOST=ホストå
+plugin.ircaccregwizz.IRC_SERVER=サーãƒãƒ¼
+plugin.ircaccregwizz.ENABLE_CONTACT_PRESENCE=連絡先ã®ãƒ—レゼンスを有効ã«ã—ã¾ã™
+plugin.ircaccregwizz.ENABLE_CHAT_ROOM_PRESENCE=ãƒãƒ£ãƒƒãƒˆãƒ«ãƒ¼ãƒ ã§ã®ãƒ—レゼンスを有効ã«ã—ã¾ã™
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE={0} èªè¨¼
+plugin.ircaccregwizz.ENABLE_SASL_AUTHENTICATION=SASLèªè¨¼ã‚’有効ã«ã—ã¾ã™
+plugin.ircaccregwizz.SASL_USERNAME=ユーザーå
# jabber accregwizz
-
-# mailbox
-plugin.mailbox.CONFIRM=確èª
-
-# msn accregwizz
-plugin.msnaccregwizz.USERNAME=é›»å­ãƒ¡ãƒ¼ãƒ«:
+plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
+plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=XMPPプロトコル
+plugin.jabberaccregwizz.USERNAME=XMPPå
+plugin.jabberaccregwizz.PASSWORD_CONFIRM=パスワードを確èª
+plugin.jabberaccregwizz.CSERVER=サーãƒãƒ¼
+plugin.jabberaccregwizz.SERVER=サーãƒãƒ¼ã¸æŽ¥ç¶šã™ã‚‹
+plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=キープアライブå¯èƒ½
+plugin.jabberaccregwizz.ENABLE_GMAIL_NOTIFICATIONS=Gmailã®æ–°ã—ã„メッセージã®é€šçŸ¥ã‚’有効
+plugin.jabberaccregwizz.ENABLE_GOOGLE_CONTACTS_SOURCE=Googleã®é€£çµ¡å…ˆã®æ¤œç´¢ã‚’有効ã«ã—ã¾ã™
+plugin.jabberaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=フリーSIPアカウントを作æˆã™ã‚‹
+plugin.jabberaccregwizz.SERVER_COLUMN=サーãƒãƒ¼
+plugin.jabberaccregwizz.COMMENT_COLUMN=コメント
+plugin.jabberaccregwizz.RESOURCE=リソース
+plugin.jabberaccregwizz.PRIORITY=優先度
+plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=未確èªã®XMPPエラー({0}).サーãƒãƒ¼åãŒæ­£ã—ã„ã‹ç¢ºèªã—ã¦ãã ã•ã„。
+plugin.jabberaccregwizz.NOT_SAME_PASSWORD=パスワードãŒä¸€è‡´ã—ã¾ã›ã‚“。
+plugin.jabberaccregwizz.USE_ICE=ICEを使用ã™ã‚‹
+plugin.jabberaccregwizz.SUPPORT_TURN=TURN対応
+plugin.jabberaccregwizz.TURN_USERNAME=TURNã®ã‚µãƒ¼ãƒãƒ¼å
+plugin.jabberaccregwizz.IP_ADDRESS=IPアドレス
+plugin.jabberaccregwizz.ADD_STUN_SERVER=STUNサーãƒãƒ¼ã‚’追加ã™ã‚‹
+plugin.jabberaccregwizz.EDIT_STUN_SERVER=STUNサーãƒãƒ¼ã‚’編集ã™ã‚‹
+plugin.jabberaccregwizz.ADDITIONAL_STUN_SERVERS=別ã®STUNサーãƒãƒ¼
+plugin.jabberaccregwizz.NO_STUN_ADDRESS=続ã‘ã‚‹ã«ã¯æœ‰åŠ¹ãªSTUNサーãƒãƒ¼ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’埋ã‚ã¦ãã ã•ã„。
+plugin.jabberaccregwizz.NO_STUN_USERNAME=続ã‘ã‚‹ã«ã¯æœ‰åŠ¹ãªSTUNサーãƒãƒ¼ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼åを埋ã‚ã¦ãã ã•ã„。
+plugin.jabberaccregwizz.STUN_ALREADY_EXIST=指定ã•ã‚ŒãŸSTUNサーãƒãƒ¼ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™ã€‚
+plugin.jabberaccregwizz.JID_ADDRESS=IPアドレス
+plugin.jabberaccregwizz.SERVER_OPTIONS=サーãƒãƒ¼ã‚ªãƒ—ション
+plugin.jabberaccregwizz.PORT_FIELD_INVALID=続ã‘ã‚‹ã«ã¯æœ‰åŠ¹ãªãƒãƒ¼ãƒˆNo.を埋ã‚ã¦ãã ã•ã„。
+plugin.jabberaccregwizz.TLS_REQUIRED=ã“ã®æŽ¥ç¶šã¯ãƒ‘スワードを変更ã—ãªã„TLSを使用ã—ã¾ã›ã‚“。
+plugin.jabberaccregwizz.PASSWORD_CHANGED=パスワードã¯æ­£å¸¸ã«å¤‰æ›´ã•ã‚Œã¾ã—ãŸã€‚
+plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=ãã®XMPPサーãƒãƒ¼ã¯ãƒ‘スワード変更ã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。
+plugin.jabberaccregwizz.ENTER_NEW_PASSWORD=å…¨ã¦ã«æ–°ã—ã„パスワードを入力ã—ã¦ãã ã•ã„:
+plugin.jabberaccregwizz.ENCODINGS=エンコーディング
+plugin.jabberaccregwizz.AUDIO=音声
+plugin.jabberaccregwizz.VIDEO=映åƒ
+plugin.jabberaccregwizz.RESET=リセット
# plugin manager
+plugin.pluginmanager.INSTALL=インストール
+plugin.pluginmanager.PLUGINS=プラグイン
+plugin.pluginmanager.URL=URL
+plugin.pluginmanager.CHOOSE_FILE=é¸æŠžã—ãŸãƒ•ã‚¡ã‚¤ãƒ«
+plugin.pluginmanager.SHOW_SYSTEM_BUNDLES=プラグインを表示
+plugin.pluginmanager.SYSTEM=システム
+plugin.pluginmanager.NEW=æ–°
# simple accregwizz
+plugin.simpleaccregwizz.LOGIN_USERNAME=ユーザーå
+plugin.simpleaccregwizz.SIGNUP=登録ã¯ãŠæ¸ˆã¿ã§ã™ã‹ï¼Ÿ
+plugin.simpleaccregwizz.SPECIAL_SIGNUP=登録ã¯ãŠæ¸ˆã¿ã§ã™ã‹ï¼Ÿç™»éŒ²ã¯ã“ã¡ã‚‰ã‚’クリック
# sipaccregwizz
+plugin.sipaccregwizz.PROTOCOL_NAME=SIP
+plugin.sipaccregwizz.PROTOCOL_DESCRIPTION=SIPプロトコル
+plugin.sipaccregwizz.USERNAME=SIP id
+plugin.sipaccregwizz.USERNAME_AND_PASSWORD=ユーザーåã¨ãƒ‘スワード
+plugin.sipaccregwizz.CLIENT_CERTIFICATE=クライアントTLS証明書
+plugin.sipaccregwizz.REGISTRAR=登録
+plugin.sipaccregwizz.SERVER_PORT=サーãƒãƒ¼ãƒãƒ¼ãƒˆ
+plugin.sipaccregwizz.PROXY=プロキシ
+plugin.sipaccregwizz.PROXY_PORT=プロキシãƒãƒ¼ãƒˆ
+plugin.sipaccregwizz.PROXY_OPTIONS=プロキシオプション
+plugin.sipaccregwizz.ENABLE_PRESENCE=プレゼンスを有効ã«ã—ã¾ã™(SIMPLE)
+plugin.sipaccregwizz.KEEP_ALIVE=キープアライブ機能
+plugin.sipaccregwizz.KEEP_ALIVE_METHOD=キープアライブメソッド
+plugin.sipaccregwizz.KEEP_ALIVE_INTERVAL=キープアライブã®é–“éš”
+plugin.sipaccregwizz.KEEP_ALIVE_INTERVAL_INFO=1〜3600秒ã®é–“
+plugin.sipaccregwizz.DTMF=DTMF
+plugin.sipaccregwizz.DTMF_METHOD=DTMFメソッド
+plugin.sipaccregwizz.DTMF_RTP=RTP ( RFC2833 / RFC 4733 )
+plugin.sipaccregwizz.DTMF_SIP_INFO=SIP情報
+plugin.sipaccregwizz.DTMF_INBAND=インãƒãƒ³ãƒ‰é€šä¿¡
+plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=通話を暗å·åŒ–ã™ã‚‹ãŸã‚ã®ã‚µãƒãƒ¼ãƒˆã‚’有効ã«ã—ã¾ã™
+plugin.sipaccregwizz.AUTH_NAME=承èªå
plugin.sipaccregwizz.DISPLAY_NAME=表示å
+plugin.sipaccregwizz.CREATE_ACCOUNT=フリーSIPアカウントを作æˆã™ã‚‹
+plugin.sipaccregwizz.CREATE_ACCOUNT_TITLE=アカウントを作æˆã™ã‚‹
+plugin.sipaccregwizz.XCAP_OPTIONS=コンタクトリストã®ã‚ªãƒ—ション
+plugin.sipaccregwizz.XCAP_USER=ユーザー
plugin.sipaccregwizz.XCAP_PASSWORD=パスワード
+plugin.sipaccregwizz.VOICEMAIL=ボイスメール
+plugin.sipaccregwizz.NOT_SAME_PASSWORD=パスワードãŒä¸€è‡´ã—ã¾ã›ã‚“
+#used from SecurityPanel
+plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=有効ãªæš—å·åŒ–プロトコルã¨ãã®å„ªå…ˆåº¦ï¼ˆä¸Šã®ãƒ—ロトコルãŒå„ªå…ˆï¼‰ã‚’é¸æŠžï¼š
+plugin.sipaccregwizz.CIPHER_SUITES=有効ãªæš—å·ã‚»ãƒƒãƒˆï¼š
+plugin.sipaccregwizz.ZRTP_OPTION=ZRTPオプション
# skin manager
-# ssh accregwizz
-plugin.sshaccregwizz.OPTIONAL=オプション
-
# status update
+plugin.autoaway.ENABLE_CHANGE_STATUS=離席ã—ãŸæ™‚ã«çŠ¶æ…‹ã‚’変更
+plugin.autoaway.AWAY_MINUTES=離席中ã¨è¡¨ç¤ºã•ã‚Œã‚‹ã¾ã§ã®æ™‚é–“(分):
# updatechecker
+plugin.updatechecker.DIALOG_TITLE=アップデートã™ã‚‹
+plugin.updatechecker.BUTTON_DOWNLOAD=ダウンロード
plugin.updatechecker.BUTTON_CLOSE=é–‰ã˜ã‚‹ (&o)
+plugin.updatechecker.BUTTON_INSTALL=インストール
+plugin.updatechecker.UPDATE_MENU_ENTRY=アップデートを確èª
+plugin.updatechecker.DIALOG_NOUPDATE_TITLE=æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã‚ã‚Šã¾ã›ã‚“。
# usersearch
+plugin.usersearch.USER_SEARCH=ユーザー検索
# whiteboard
+plugin.whiteboard.TITLE=ホワイトボード[β版]
+plugin.whiteboard.MENU_ITEM=ホワイトボード
+plugin.whiteboard.NOT_SUPPORTED=ホワイトボードã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。
+plugin.whiteboard.OPEN=é–‹ã
+plugin.whiteboard.SELECT=é¸æŠž
+plugin.whiteboard.IMAGE=ç”»åƒ
+plugin.whiteboard.POLYGON=ãƒãƒªã‚´ãƒ³
+plugin.whiteboard.FILLEDPOLYGON=ãƒãƒªã‚´ãƒ³å¤±æ•—
plugin.whiteboard.COLOR=色
plugin.whiteboard.MODIFICATION=通知
+plugin.whiteboard.GRID=グリッド
plugin.whiteboard.DELETE=削除ã™ã‚‹
-# yahoo accregwizz
-
-# zero accregwizz
-plugin.zeroaccregwizz.FIRST_NAME=åå‰:
-plugin.zeroaccregwizz.LAST_NAME=姓:
-plugin.zeroaccregwizz.EMAIL=é›»å­ãƒ¡ãƒ¼ãƒ«:
-
# gtalk accregwizz
# iptel accregwizz
-
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=ã“ã®ã‚µãƒ¼ãƒ“スã«ã¤ã„ã¦ã¯ã€<br>http://wiki.sip2sip.info を見ã¦ãã ã•ã„。
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>ã“ã®ã‚µãƒ¼ãƒ“スã«ã¤ã„ã¦ã¯ã€<a href=''>http://wiki.sip2sip.info</a>を見ã¦ãã ã•ã„</html>
+plugin.iptelaccregwizz.USERNAME=ユーザーå
# ippi accregwizz
+plugin.sip2sipaccregwizz.USERNAME=ユーザーå
+plugin.sip2sipaccregwizz.RETYPE_PASSWORD=パスワードをå†åº¦å…¥åŠ›ã—ã¦ãã ã•ã„
+plugin.sip2sipaccregwizz.EMAIL=メールアドレス
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=ã“ã®ã‚µãƒ¼ãƒ“スã«ã¤ã„ã¦ã¯ã€<br>http://ippi.fr を見ã¦ãã ã•ã„。
plugin.ippiaccregwizz.INFO_NOTE=<html>ã“ã®ã‚µãƒ¼ãƒ“スã«ã¤ã„ã¦ã¯ã€ <a href=''>http://ippi.fr</a>を見ã¦ãã ã•ã„</html>
+plugin.ippiaccregwizz.CREATE_ACCOUNT=フリーSIPアカウントを作æˆã™ã‚‹
# key binding chooser
+#in new ChatWindow() -> manipulated
+plugin.keybindings.CHAT_CLOSE=ãƒãƒ£ãƒƒãƒˆã‚¦ã‚¤ãƒ³ãƒ‰ã‚¦ã‚’é–‰ã˜ã‚‹
plugin.keybindings.CHAT_COPY=コピーã™ã‚‹ (&C)
plugin.keybindings.CHAT_CUT=カット (&u)
+plugin.keybindings.CHAT_OPEN_HISTORY=履歴を開ã
+plugin.keybindings.CHAT_OPEN_SMILIES=スマイリーを開ã
plugin.keybindings.CHAT_PASTE=貼付㑠(&P)
plugin.keybindings.MAIN_RENAME=コンタクトã®åå‰ã‚’変更 (&n)
+plugin.keybindings.OPEN_HISTORY=履歴表示
+plugin.keybindings.OPEN_SMILIES=スマイリー表示
+plugin.keybindings.globalchooser.ANSWER_CALL=応答ã™ã‚‹
+plugin.keybindings.globalchooser.HANGUP_CALL=通話終了
+plugin.keybindings.globalchooser.ANSWER_HANGUP_CALL=応答/終了
+plugin.keybindings.globalchooser.SHOW_CONTACTLIST=コンタクトリスト表示
+plugin.keybindings.globalchooser.MUTE_CALLS=消音
+plugin.keybindings.globalchooser.SHORTCUT_NAME=åå‰
+plugin.keybindings.globalchooser.ENABLE_SPECIAL=特殊キーã®æ¤œå‡ºã‚’有効ã«ã—ã¾ã™
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=ãƒãƒ£ãƒƒãƒˆ
# Notification Configuration Form
+plugin.notificationconfig.ENABLE_NOTIF=有効
+plugin.notificationconfig.TURN_ON_ALL=å…¨ã¦æœ‰åŠ¹ã«ã™ã‚‹
+plugin.notificationconfig.TURN_OFF_ALL=å…¨ã¦ç„¡åŠ¹ã«ã™ã‚‹
+plugin.notificationconfig.POPUP_NOTIF_HANDLER=ãƒãƒƒãƒ—アップ通知ã®ç¨®é¡ž
+plugin.notificationconfig.SOUND_FILE=次ã®ãƒ•ã‚¡ã‚¤ãƒ«:
+plugin.notificationconfig.PROGRAM_FILE=プログラムファイル:
+plugin.notificationconfig.tableheader.ENABLE=ã“ã®æ©Ÿèƒ½ã‚’有効・無効ã«ã™ã‚‹
+plugin.notificationconfig.tableheader.POPUP=メッセージボックスを表示ã™ã‚‹
+#NotificationsTable constants
+plugin.notificationconfig.event.IncomingCall=ç€ä¿¡ä¸­ã§ã™
+plugin.notificationconfig.event.IncomingFile=ç€ä¿¡ä¸­ã§ã™
+plugin.notificationconfig.event.Dialing=ダイヤル中
+plugin.notificationconfig.event.BusyCall=話ã—中
plugin.notificationconfig.event.HangUp=切断
+plugin.notificationconfig.event.DTMFTone.A=DTMFトーンA
+plugin.notificationconfig.event.DTMFTone.B=DTMFトーンB
+plugin.notificationconfig.event.DTMFTone.C=DTMFトーンC
+plugin.notificationconfig.event.DTMFTone.D=DTMFトーンD
+plugin.notificationconfig.event.DTMFTone.0=DTMFトーン0
+plugin.notificationconfig.event.DTMFTone.1=DTMFトーン1
+plugin.notificationconfig.event.DTMFTone.2=DTMFトーン2
+plugin.notificationconfig.event.DTMFTone.3=DTMFトーン3
+plugin.notificationconfig.event.DTMFTone.4=DTMFトーン4
+plugin.notificationconfig.event.DTMFTone.5=DTMFトーン5
+plugin.notificationconfig.event.DTMFTone.6=DTMFトーン6
+plugin.notificationconfig.event.DTMFTone.7=DTMFトーン7
+plugin.notificationconfig.event.DTMFTone.8=DTMFトーン8
+plugin.notificationconfig.event.DTMFTone.9=DTMFトーン9
+plugin.notificationconfig.event.DTMFTone.*=DTMFトーン*
+plugin.notificationconfig.event.DTMFTone.#=DTMFトーン#
+plugin.notificationconfig.event.NewSelectedDevice=æ–°ãŸã«é¸æŠžã•ã‚ŒãŸæ©Ÿå™¨
# ZRTP Securing
# ZRTP Configuration
impl.media.security.zrtp.TITLE=コール
+impl.media.security.zrtp.PUB_KEYS=公開éµ
+impl.media.security.zrtp.HASHES=ãƒãƒƒã‚·ãƒ¥
+impl.media.security.zrtp.SAS_TYPES=SASタイプ
+impl.media.security.zrtp.STANDARD=標準
+impl.media.security.zrtp.ZRTP_NINJA=ZRTP Ninja
# Profiler4J
+impl.media.configform.AUDIO=オーディオ機器(&A):
+impl.media.configform.AUDIO_IN=マイク入力(&I):
impl.media.configform.AUDIO_NOTIFY=通知
-
-
+impl.media.configform.AUDIO_OUT=スピーカー出力(&O):
+impl.media.configform.AUTOMATICGAINCONTROL=自動マイク調整
+impl.media.configform.DENOISE=ノイズ抑制を有効ã«ã™ã‚‹
+impl.media.configform.DEVICES=端末
+impl.media.configform.ECHOCANCEL=エコーキャンセレーションを有効ã«ã™ã‚‹
+impl.media.configform.ENCODINGS=エンコーディング
+impl.media.configform.NO_AVAILABLE_AUDIO_DEVICE=音声用機器ãŒã‚ã‚Šã¾ã›ã‚“。何ã‹æŽ¥ç¶šã—ã¦ãã ã•ã„。
+impl.media.configform.NO_PREVIEW=プレビュー
+impl.media.configform.VIDEO_MORE_SETTINGS=セッティング詳細
+impl.media.configform.VIDEO_RESOLUTION=映åƒã®è§£åƒåº¦
+impl.media.configform.AUDIO_DEVICE_SELECTED_AUDIO_IN=マイク用ã«æ–°ã—ã„機器ãŒé¸æŠžã•ã‚Œã¾ã—ãŸ:
+impl.media.configform.AUDIO_DEVICE_SELECTED_AUDIO_OUT=スピーカー用ã®æ–°ã—ã„機器ãŒé¸æŠžã•ã‚Œã¾ã—ãŸ:
+impl.media.configform.AUDIO_DEVICE_SELECTED_AUDIO_NOTIFICATIONS=通知用ã®æ–°ã—ã„機器ãŒé¸æŠžã•ã‚Œã¾ã—ãŸ:
+impl.media.configform.VIDEO_DEVICE_SELECTED=ビデオ用ã®æ–°ã—ã„機器ãŒé¸æŠžã•ã‚Œã¾ã—ãŸ:
+
+impl.neomedia.configform.AUDIO=オーディオ
+impl.neomedia.configform.VIDEO=映åƒ
+
+#in JNIEncoder
+impl.neomedia.configform.H264.defaultProfile.high=高ã„
+impl.neomedia.configform.H264.preferredKeyFrameRequester.rtcp=RTCP
+impl.neomedia.configform.H264.preferredKeyFrameRequester.signaling=シグナリング
# The callrecordingconfig plugin was never really committed into trunk and its
# ConfigurationForm was actually put in the neomedia bundle.
+plugin.callrecordingconfig.CALL_RECORDING_CONFIG=通話を記録ã™ã‚‹
+plugin.callrecordingconfig.CALL_SAVED=通話ã®ä¿å­˜ã«æˆåŠŸ
# Security configuration form title
+plugin.securityconfig.TITLE=セキュリティ
plugin.securityconfig.masterpassword.TITLE=パスワード
+plugin.securityconfig.masterpassword.SAVED_PASSWORDS=パスワードをä¿å­˜ã—ã¾ã—ãŸ
+plugin.securityconfig.masterpassword.CURRENT_PASSWORD=ç¾åœ¨ã®ãƒ‘スワード
plugin.securityconfig.masterpassword.REENTER_PASSWORD=パスワードを記録ã™ã‚‹
+plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=パスワードãŒä¸€è‡´ã—ã¾ã›ã‚“。やり直ã—ã¦ãã ã•ã„。
+plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=パスワード変更ã«å¤±æ•—ã—ã¾ã—ãŸ
+plugin.securityconfig.masterpassword.MP_CHANGE_SUCCESS_MSG=マスターパスワードを正常ã«å‰Šé™¤ã—ã¾ã—ãŸã€‚
+plugin.securityconfig.masterpassword.MP_REMOVE_SUCCESS_MSG=マスターパスワードを正常ã«å‰Šé™¤ã—ã¾ã—ãŸã€‚
+plugin.securityconfig.masterpassword.COL_NAME=åå‰
plugin.securityconfig.masterpassword.COL_PASSWORD=パスワード
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=å–り除ã (&R)
+plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=ä¿å­˜ã•ã‚ŒãŸãƒ‘スワード
+plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=全削除
+plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=本当ã«å…¨ã¦ã®ãƒ‘スワードを削除ã—ã¦å®œã—ã„ã§ã™ã‹ï¼Ÿ
+plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=全パスワードを削除
+plugin.securityconfig.masterpassword.SHOW_PASSWORDS_BUTTON=パスワードを表示ã™ã‚‹
+plugin.securityconfig.masterpassword.HIDE_PASSWORDS_BUTTON=パスワードを隠ã™
# otr plugin
+plugin.otr.menu.TITLE=安全性ã®é«˜ã„ãƒãƒ£ãƒƒãƒˆ
+plugin.otr.menu.CB_ENABLE=プライベートメッセージを有効ã«ã™ã‚‹
+plugin.otr.menu.CB_REQUIRE=プライベートメッセージを有効ã«ã™ã‚‹
+plugin.otr.menu.CB_RESET=リセット
+plugin.otr.menu.OTR_TOOLTIP=OTRã§æš—å·åŒ–ã•ã‚ŒãŸãƒãƒ£ãƒƒãƒˆ
+plugin.otr.authbuddydialog.AUTHENTICATION_METHOD=ã©ã®ã‚ˆã†ã«èªè¨¼ã—ã¾ã™ã‹ï¼Ÿ
+plugin.otr.authbuddydialog.AUTHENTICATION_METHOD_QUESTION=èªè¨¼ã®è³ªå•
plugin.otr.authbuddydialog.CANCEL=キャンセル (&C)
plugin.otr.authbuddydialog.HELP=ヘルプ (&H)
+plugin.otr.authbuddydialog.I_HAVE=ã‚ã‚Šã¾ã™
+plugin.otr.authbuddydialog.I_HAVE_NOT=ã‚ã‚Šã¾ã›ã‚“
+plugin.otr.smpprogressdialog.AUTHENTICATION_SUCCESS=èªè¨¼æˆåŠŸï¼
+plugin.otr.smpprogressdialog.AUTHENTICATION_FAIL=èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸã€‚
+plugin.otr.configform.CB_ENABLE=プライベートメッセージを有効ã«ã™ã‚‹
+plugin.otr.configform.CB_REQUIRE=プライベートメッセージを有効ã«ã™ã‚‹
plugin.otr.configform.GENERATE=生æˆ
plugin.otr.configform.REGENERATE=å†ç”Ÿæˆ
+plugin.otr.configform.FINGERPRINT=指紋
+plugin.otr.configform.VERIFY_FINGERPRINT=指紋èªè¨¼
+plugin.otr.configform.FORGET_FINGERPRINT=指紋を忘れã¾ã—ãŸ
plugin.otr.configform.COLUMN_NAME_CONTACT=å•ã„åˆã‚ã›
+plugin.otr.configform.COLUMN_NAME_VERIFIED_STATUS=証明
plugin.otr.configform.COLUMN_VALUE_VERIFIED_TRUE=ã¯ã„
plugin.otr.configform.COLUMN_VALUE_VERIFIED_FALSE=ã„ã„ãˆ
+plugin.otr.activator.unencryptedmsgreceived=メッセージ暗å·åŒ–ã•ã‚Œãšã«å—ã‘å–られã¾ã—ãŸã€‚
+plugin.otr.activator.requireencryption=メッセージ [{0}]ã¯é€ä¿¡ã•ã‚Œã¾ã›ã‚“ã§ã—ãŸã€‚プライベートメッセージã®é€ä¿¡ãŒè¦æ±‚ã•ã‚Œã¾ã—ãŸã€‚
# global proxy plugin
+plugin.globalproxy.GLOBAL_PROXY_CONFIG=グローãƒãƒ«ãƒ—ロキシ
+plugin.globalproxy.PROXY_TYPE=プロキシタイプ
+plugin.globalproxy.PROXY_ADDRESS=プロキシサーãƒãƒ¼
+plugin.globalproxy.PROXY_PORT=プロキシãƒãƒ¼ãƒˆ
+plugin.globalproxy.PROXY_USERNAME=プロキシå
+plugin.globalproxy.PROXY_PASSWORD=プロキシパスワード
#plugin.globalproxy.PROTOCOL_SUPPORT
# plugin reconnect
@@ -652,25 +1145,39 @@ plugin.reconnectplugin.CONNECTION_FAILED_MSG=次ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã§æŽ¥ç¶šã«å¤
#plugin chat config
plugin.chatconfig.TITLE=ãƒãƒ£ãƒƒãƒˆ
+plugin.chatconfig.replacement.ENABLE_SMILEY_STATUS=絵文字置æ›ã‚’有効ã«ã™ã‚‹
+plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS=有効
#provisioning plugin
+plugin.provisioning.ENABLE_DISABLE=プロビジョニングを有効ã«ã™ã‚‹
# packet logging service
+plugin.loggingutils.ENABLE_DISABLE=パケットã®ãƒ­ã‚°è¨˜éŒ²ã‚’有効ã«ã™ã‚‹
+plugin.loggingutils.PACKET_LOGGING_RTP=RTP
# dns config plugin
+plugin.dnsconfig.chkBackupDnsEnabled.text=DNS正引ãã®ä¸¦åˆ—化を有効ã«ã™ã‚‹
+plugin.dnsconfig.lblBackupResolver.text=ホストå
+plugin.dnsconfig.lblBackupPort.text=ãƒãƒ¼ãƒˆ
+plugin.dnsconfig.dnssec.chkEnabled=DNSSEC正引ãを有効ã«ã™ã‚‹
+plugin.dnsconfig.dnssec.ENABLE_FAILED_MSG=DNSSECを使用å¯èƒ½ãªçŠ¶æ…‹ã«å¤‰æ›´ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚
net.java.sip.communicator.util.dns.SecureResolveMode.IgnoreDnssec=無視ã™ã‚‹ (&I)
net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.Deny=æ‹’å¦(&D)
#plugin spellcheck
-plugin.spellcheck.EDIT_PERSONAL_DICT=編集ã™ã‚‹ (&E)
+plugin.spellcheck.ENABLE_SPELL_CHECK=スペルãƒã‚§ãƒƒã‚¯ã‚’有効ã«ã™ã‚‹
+plugin.spellcheck.DICT_ERROR_TITLE=辞書切り替ãˆã‚¨ãƒ©ãƒ¼
#Certificate configuration plugin
plugin.certconfig.KEYSTORE=ファイル (&F)
plugin.certconfig.KEYSTORE_PASSWORD=パスワード
+plugin.certconfig.REVOCATION_CHECK_ENABLED=CRL (証明書排除リスト) ãƒã‚§ãƒƒã‚¯ãŒæœ‰åŠ¹
+plugin.certconfig.REVOCATION_OCSP_ENABLED=OCSP (オンライン証明書ステータスプロトコル) ãƒã‚§ãƒƒã‚¯ãŒæœ‰åŠ¹
# Phone number contact source plugin
# properties editor
#Thunderbird address book plugin
+plugin.thunderbird.ENABLED=有効
diff --git a/resources/languages/resources_lt.properties b/resources/languages/resources_lt.properties
index 188d04a..2685111 100644
--- a/resources/languages/resources_lt.properties
+++ b/resources/languages/resources_lt.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -25,46 +36,39 @@
# from your system's language, pass the language code to ant:
# ant -Duser.language=xx run
-service.gui.ABOUT=Apie
-service.gui.ACCEPT=Sutinku
+service.gui.ABOUT=&Apie
+service.gui.ACCEPT=&Priimti
service.gui.ACCOUNT=Paskyra
service.gui.ACCOUNT_ME=AÅ¡
service.gui.ACCOUNT_REGISTRATION_WIZARD=Paskyros registravimo vedlys
service.gui.ACCOUNTS=Paskyros
-service.gui.ADD=PridÄ—ti
-service.gui.ADD_ACCOUNT=PridÄ—ti paskyrÄ…
-service.gui.ADD_CONTACT=PridÄ—ti kontaktÄ…
-service.gui.ADD_CONTACT_TO=Pridėti kontaktą į
+service.gui.ADD=&PridÄ—ti
+service.gui.ADD_CONTACT=&PridÄ—ti kontaktÄ…
+service.gui.ADD_CONTACT_TO=&Pridėti kontaktą į
service.gui.ADD_CONTACT_ERROR=Nepavyko pridÄ—ti kontakto, kurio id: {0}
service.gui.ADD_CONTACT_ERROR_TITLE=Klaida pridedant kontaktÄ…
-service.gui.ADD_CONTACT_EXIST_ERROR=Kontaktas ''{0}'' jau yra jūsų kontaktų sąraše.
-service.gui.ADD_CONTACT_IDENTIFIER=Žemiau esanÄiame lauke įveskite kontakto, kurį norite pridÄ—ti, identifikatorių.
-service.gui.ADD_CONTACT_WIZARD=Kontakto pridÄ—jimo vedlys.
+service.gui.ADD_CONTACT_EXIST_ERROR=Kontaktas {0} jau yra jūsų kontaktų sąraše.
service.gui.ADD_GROUP_LOCAL_ERROR=Nepavyko pridėti grupės: {0}. Įvyko vietinė įvesties/išvesties klaida.
-service.gui.ADD_GROUP_EXIST_ERROR={0} jau yra jūsų kontaktų sąraše. Pasirinkite kitą pavadinimą.
-service.gui.ADD_GROUP_NET_ERROR=Nepavyko pridėti grupės: {0}. Įvyko tinklo klaida. Patikrinkite savo tinklo jungtį ir pabandykite iš naujo.
+service.gui.ADD_GROUP_EXIST_ERROR=Grupė {0} jau yra jūsų kontaktų sąraše. Pasirinkite kitą pavadinimą.
+service.gui.ADD_GROUP_NET_ERROR=Nepavyko pridėti grupės: {0}. Įvyko tinklo klaida. Patikrinkite savo tinklo ryšį ir bandykite dar kartą.
service.gui.ADD_GROUP_ERROR=Nepavyko pridÄ—ti grupÄ—s: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=GrupÄ—s pavadinimas negali bÅ«ti tuÅ¡Äias.
-service.gui.ADD_GROUP=Sukurti grupÄ™
-service.gui.ADD_SUBCONTACT=PridÄ—ti kontaktÄ… kontakte
service.gui.ADMINISTRATOR=administratorius
service.gui.ADVANCED=papildomi nustatymai
-service.gui.ALL=Visi
-service.gui.ALL_CONTACTS=Visi kontaktai
-service.gui.APPLY=Taikyti
+service.gui.ALL_CONTACTS=&Visi kontaktai
+service.gui.APPLY=&Taikyti
service.gui.ARE_CALLING=skambina...
service.gui.ARE_NOW=JÅ«s dabar esate {0}
service.gui.AT=prie
service.gui.AUTHORIZATION_ACCEPTED=kontaktas priėmė jūsų kvietimą.
service.gui.AUTHENTICATION_FAILED=Autentifikacija nepavyko. Įvestas neteisingas slaptažodis.
-service.gui.AUTHENTICATION_REQUESTED=Reikalinga autentifikacija
-service.gui.AUTHENTICATION_REQUESTED_SERVER=Serveris {0} paprašė jūsų autentifikacijos
+service.gui.AUTHENTICATION_REQUESTED_SERVER=Serveris {0} paprašė jūsų nustatyti tapatybę.
service.gui.AUTHENTICATION_REJECTED=kontaktas atmetė jūsų kvietimą.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} kvietimas
service.gui.AUTHORIZATION_REQUESTED=Reikalingas kvietimo priÄ—mimas.
service.gui.AUTHORIZATION_REQUESTED_INFO=Kontaktas {0} prašo jūsų sutikimo.
service.gui.AUTHORIZATION_RESPONSE=Sutikimo atsakymas
-service.gui.AWAY_STATUS=Išėjęs
+service.gui.AWAY_STATUS=Pasišalinęs
service.gui.BAN=&Uždrausti
service.gui.BAN_FAILED=Uždraudimas nepavyko
service.gui.BAN_FAILED_GENERAL_ERROR={0} Uždraudimas nepavyko. Įvyko serverio klaida.
@@ -96,12 +100,10 @@ service.gui.CHAT_ROOM_USER_KICKED=buvo išmestas iš {0}
service.gui.CHAT_ROOM_USER_QUIT=išėjo iš {0}
service.gui.CHAT_ROOM_NAME=Pokalbių kambario pavadinimas
service.gui.ROOM_NAME=Pakalbių Kambarys
-service.gui.AUTOJOIN=Automatinis prisijungimas
service.gui.CHAT_ROOM_NAME_INFO=Žemiau esanÄiame lauke įveskite kuriamo pokalbių kambario pavadinimÄ….
service.gui.CHAT_ROOM_NOT_EXIST={0} kambarys nerastas {1} serveryje. Prašau patikrinti ar teisingai įvedėte pavadinimą.
service.gui.CHAT_ROOM_NOT_CONNECTED=Jūs turite būti užsiregistravęs, jei norite prisijungti prie {0} pokalbių kambario.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Jūs turite būti užsiregistravęs, jei norite palikti pokalbių kambarį.
-service.gui.CHAT_ROOM_NOT_JOINED=Turite būti prisijungęs prie pokalbių kambario, jei norite atlikti tolimesnius veiksmus su juo.
service.gui.CHAT_ROOM_OPTIONS=Pokalbių kambario nustatymai
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Norint prisijungti prie {0} pokalbių kambario reikalinga registracija.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD={0} pokalbių kambarys reikalauja slaptažodžio.
@@ -115,9 +117,7 @@ service.gui.CONNECTING=Jungiamasi...
service.gui.CONNECTING_STATUS=Jungtis
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Jungiamasi...
service.gui.CONNECTION=Jungtis
-service.gui.CONNECTION_FAILED_MSG=Įvyko klaida bandant prisijungti šiai paskyrai: Vartotojo vardas: {0}, Serverio vardas: {1}. Patikrinkite savo tinklo jungtį arba susisiekite su tinklo administratoriumi.
service.gui.CONNECTION_EXPIRED_MSG=Jūs esate atsijungęs nuo {0} serverio.
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Pasirinktas kontaktas nepalaiko telefoninių pokalbių.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Pasirinktas kontaktas nepalaiko konferenciniu pokalbių kambarių.
service.gui.CONTACT_PAUSED_TYPING={0} stabtelėjo rašant žinutę
service.gui.CONTACT_TYPING={0} rašo žinutę
@@ -130,23 +130,25 @@ service.gui.CREATE_CHAT_ROOM=&Sukurti pokalbių kambarį...
service.gui.CREATE_CHAT_ROOM_ERROR=Nepavyko sukurti {0} pokalbių kambario.
service.gui.CREATE_CHAT_ROOM_WIZARD=Pokalbių kambario kūrimo vedlys
service.gui.CREATE_CONFERENCE_CALL=&Pradėti konferencinį skambutį...
-service.gui.CREATE_CONFERENCE_CHAT=&Pradėti konferencinį pokalbių kambarį...
service.gui.CREATE_GROUP=&Sukurti grupÄ™...
service.gui.CREATE_GROUP_NAME=Žemiau esanÄiame lauke įveskite kuriamos grupÄ—s pavadinimÄ….
-service.gui.CREATE_FIRST_GROUP_WIZARD=Jūsų kontaktų sąraše nėra jokių grupių. Pirma sukurkite grupę (Failas/Sukurti grupę).
service.gui.FAILED_STATUS=Skambutis nepavyko
service.gui.IS_CALLING=skambina...
-service.gui.CLOSE_CHAT_ROOM_DIALOG=Uždaryti
service.gui.KICK_FAILED_GENERAL_ERROR={0} Uždraudimas nepavyko. Įvyko serverio klaida.
service.gui.KICK_FAILED_NOT_ALLOWED={0} Uždraudimas nepavyko. Kambario savininkas ir administratorius negali būti uždraustas.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS={0} Uždraudimas nepavyko. Jūs neturite reikalingų teisių.
+service.gui.chat.role.ADMINISTRATOR=administratorius
+
+#enum values from IceProcessingState
-service.gui.security.COMPARE_WITH_PARTNER=Palyginkite su partneriu ir paspauskite ant užrakto patvirtinimui.
+#service.gui.CERT_INFO_ are combined from Rdn names
+
+
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Palyginkite su parnteriu: {0}
@@ -155,9 +157,6 @@ service.gui.avatar.imagepicker.CANCEL=&Panaikinti
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
# systray
@@ -167,6 +166,10 @@ service.gui.avatar.imagepicker.CANCEL=&Panaikinti
# LDAP
impl.ldap.CANCEL=&Panaikinti
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
# Google Contacts
@@ -183,9 +186,6 @@ impl.googlecontacts.CANCEL=&Panaikinti
# branding
plugin.branding.ABOUT_MENU_ENTRY=Apie
-# Dict protocol
-
-# facebookaccregwizz
# generalconfig
@@ -194,23 +194,19 @@ plugin.branding.ABOUT_MENU_ENTRY=Apie
# icqaccregwizz
# irc accregwizz
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE={0} kvietimas
# jabber accregwizz
-# mailbox
-
-# msn accregwizz
-
# plugin manager
# simple accregwizz
# sipaccregwizz
+#used from SecurityPanel
# skin manager
-# ssh accregwizz
-
# status update
# updatechecker
@@ -220,23 +216,20 @@ plugin.updatechecker.BUTTON_CLOSE=Uždaryti
# whiteboard
-# yahoo accregwizz
-
-# zero accregwizz
-
# gtalk accregwizz
# iptel accregwizz
-# sip2sip accregwizz
-
# ippi accregwizz
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_COPY=&Kopijuoti
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Pokalbis
# Notification Configuration Form
+#NotificationsTable constants
# ZRTP Securing
@@ -249,6 +242,7 @@ impl.media.security.zrtp.TITLE=Skambinti
+#in JNIEncoder
# The callrecordingconfig plugin was never really committed into trunk and its
# ConfigurationForm was actually put in the neomedia bundle.
diff --git a/resources/languages/resources_lv.properties b/resources/languages/resources_lv.properties
index df516a6..df76ce1 100644
--- a/resources/languages/resources_lv.properties
+++ b/resources/languages/resources_lv.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Es
service.gui.ACCOUNT_REGISTRATION_WIZARD=Konta reÄ£istrÄcijas vednis
service.gui.ACCOUNTS=Konti
service.gui.ADD=&Pievienot
-service.gui.ADD_ACCOUNT=Pievienot kontu
service.gui.ADD_CONTACT=&Pievienot kontaktu
service.gui.ADD_AUTHORIZED_CONTACT=Pievienot kontaktu {0} jūsu kontaktu sarakstam
service.gui.ADD_CONTACT_TO=&Pievienot kontaktu
@@ -41,26 +51,20 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Kontaktu pievienošanas kļūda
service.gui.ADD_CONTACT_EXIST_ERROR=Persona {0} jau eksistÄ“ jÅ«su kontaktu sarakstÄ.
service.gui.ADD_CONTACT_NETWORK_ERROR=Serveris neatbildēja uz personas pievienošanas pieprasījumu ar id: {0}.
service.gui.ADD_CONTACT_NOT_SUPPORTED=NeizdevÄs pievienot kontaktu ar id: {0}. OperÄcija netiek atbalstÄ«ta.
-service.gui.ADD_CONTACT_IDENTIFIER=LauciÅ†Ä zemÄk ievadiet pievienojamÄ kontakta identifikatoru.
-service.gui.ADD_CONTACT_WIZARD=Kontakta pievienošanas vednis
service.gui.ADD_CONTACT_NOT_CONNECTED=Lai pievienotu kontaktu jÄbÅ«t izveidotam savienojumam. LÅ«dzu pieslÄ“dzaties izvÄ“lÄ“tajam provaiderim un mÄ“Ä£iniet vÄ“l.
service.gui.ADD_GROUP_LOCAL_ERROR=NeizdevÄs pievienot grupu ar nosaukumu: {0}. GadijÄs kļūme IO operÄcijas laikÄ.
service.gui.ADD_GROUP_EXIST_ERROR=Grupa {0} jau eksistÄ“ jÅ«su kontaktu sarakstÄ. LÅ«dzu izvÄ“laties citu nosaukumu.
service.gui.ADD_GROUP_NET_ERROR=NeizdevÄs pievienot grupu ar nosaukumu: {0}. GadijÄs tÄ«kla problÄ“ma. LÅ«dzu pÄrbaudiet tÄ«kla savienojumu un atkÄrtojiet darbÄ«bu.
service.gui.ADD_GROUP_ERROR=NeizdevÄs pievienot grupu ar nosaukumu: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=JÄnorÄda grupas nosaukums
-service.gui.ADD_GROUP=Izveidot grupu
-service.gui.ADD_SUBCONTACT=&Pievienot apakškontaktu
service.gui.ADMINISTRATOR=administrators
service.gui.ADVANCED=&Papildus
-service.gui.ALL=&Visi
service.gui.ALL_CONTACTS=&Visi kontakti
service.gui.APPLY=&Pielietot
service.gui.ARE_NOW=JÅ«s esat {0}
service.gui.AT=uz
service.gui.AUTHORIZE=&Autorizēt
service.gui.AUTHENTICATION_FAILED=AutentifikÄcija neizdevÄs {0}. IevadÄ«tÄ parole nebija derÄ«ga.
-service.gui.AUTHENTICATION_REQUESTED=PieprasÄ«ta autentifikÄcija
service.gui.AUTHENTICATION_REQUESTED_SERVER=Serveris {0} pieprasÄ«ja autentifikÄciju.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} autentifikÄcija
service.gui.AUTHORIZATION_REQUESTED=PieprasÄ«ta autorizÄcija
@@ -103,13 +107,11 @@ service.gui.CHAT_ROOM_USER_KICKED=izmests no {0}
service.gui.CHAT_ROOM_USER_QUIT={0} pameta
service.gui.CHAT_ROOM_NAME=Tērzēšanas istabas nosaukums
service.gui.ROOM_NAME=Tērzēšanas istaba
-service.gui.AUTOJOIN=Autopievienoties
service.gui.CHANGE_PASSWORD=Mainīt paroli
service.gui.CHAT_ROOM_NAME_INFO=LauciÅ†Ä zemÄk ievadiet izveidojamÄs tÄ“rzÄ“Å¡anas istabas nosaukumu.
service.gui.CHAT_ROOM_NOT_EXIST=ServerÄ« {1} nav atrasta Istaba {0}. LÅ«dzu pÄrbaudiet vai ievadÄ«jÄt istabas nosaukumu pareizi.
service.gui.CHAT_ROOM_NOT_CONNECTED=Jums jÄbÅ«t pieslÄ“gtam, lai pievienotos {0} tÄ“rzÄ“Å¡anas istabai.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Lai pamestu tÄ“rzÄ“Å¡anas istabu jums jÄbÅ«t pieslÄ“gtam.
-service.gui.CHAT_ROOM_NOT_JOINED=Jums jÄbÅ«t pieslÄ“gtam tÄ“rzÄ“Å¡anas istabai, lai veiktu kÄdas operÄcijas tajÄ.
service.gui.CHAT_ROOM_OPTIONS=Tērzēšanas istabas opcijas
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Lai pievienotos tÄ“rzÄ“Å¡anas istabai {0} ir nepiecieÅ¡ama reÄ£istrÄcija.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Tērzēšanas istaba {0} pieprasa paroli.
@@ -122,22 +124,18 @@ service.gui.CLEAR=Attīrīt
service.gui.CLOSE=Ai&zvērt
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=JÅ«s saņēmÄt jaunu ziņu 2 sekundes atpakaļ. Vai tieÅ¡Äm vÄ“laties aizvÄ“rt Å¡o tÄ“rzÄ“Å¡anas logu?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=Ir aktÄ«vas failu piegÄdes. Vai piekrÄ«tat tÄs atcelt?
-service.gui.CONFIRM=ApstiprinÄt
service.gui.CONNECTED_STATUS=Savienots
service.gui.CONNECTING=Savienojos...
service.gui.CONNECTING_STATUS=Savienojas
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Savienojas*
service.gui.CONNECTION=Savienojums
-service.gui.CONNECTION_FAILED_MSG=NeizdevÄs savienoties ar sekojoÅ¡u kontu: LietotÄjs: {0}, Serveris: {1}. LÅ«dzu pÄrbaudiet tÄ«kla savienojumu vai arÄ« lÅ«dziet palÄ«dzÄ«bu tÄ«kla administratoram.
service.gui.CONNECTION_EXPIRED_MSG=Patreiz esiet atslēgts no servera {0}.
service.gui.CONTACT_NAME=ID vai Numurs
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Izvēlētais kontakts {0} neatbalsta zvanīšanu.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Izvēlētais kontakts {0} neatbalsta tērzēšanas konferences saraksti.
service.gui.CONTACT_PAUSED_TYPING={0} pÄrstÄja rakstÄ«t ziņu
service.gui.CONTACT_TYPING={0} raksta ziņu
service.gui.CONTACT_TYPING_SEND_FAILED=uh-oh... mÄ“s nevarÄ“jÄm nosakaidrot kad jÅ«s rakstÄ«jÄt {0}
service.gui.CONTACT_INFO=&Kontakta info
-service.gui.CONTACTLIST=Kontaktu lists
service.gui.CONTACTS=Kontakti
service.gui.COPY=&Kopēt
service.gui.COPY_LINK=Kopēt &saiti
@@ -147,15 +145,12 @@ service.gui.CREATE_CHAT_ROOM=&Izveidot tērzēšanas istabu...
service.gui.CREATE_CHAT_ROOM_ERROR=NeizdevÄs izveidot {0} tÄ“rzÄ“Å¡anas istabu.
service.gui.CREATE_CHAT_ROOM_WIZARD=Izveidot tērzēšanas istabas vedni
service.gui.CREATE_CONFERENCE_CALL=&Izveidot konfrences izsaukumu...
-service.gui.CREATE_CONFERENCE_CHAT=&Veidot konferences tērzēšanu
service.gui.CREATE_GROUP=&Izveidot grupu...
service.gui.CREATE_GROUP_NAME=LauciÅ†Ä zemÄk norÄdiet veidojamÄs grupas nosaukumu.
-service.gui.CREATE_FIRST_GROUP_WIZARD=JÅ«su kontaktos nav nevienas grupas. LÅ«dzu vispirms izveidojiet grupu (Faili/Izveidot grupu).
service.gui.CREATE_VIDEO_BRIDGE=Izveidot &video tiltu...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Izveidot &video tiltu...
service.gui.CONTACT_INFO_NOT_SUPPORTED=Å is kontakts neatbalsta web kontaktu info
service.gui.CUT=&Izgriezt
-service.gui.DATE=Datums
service.gui.DELETE=Dzēst
service.gui.DENY=&Aizliegt
service.gui.DESKTOP_SHARING_WARNING=<b>Vai vÄ“laties sÄkt ekrÄna kopÄ«goÅ¡anu?</b><br> Ja noklikÅ¡Ä·inÄsiet OK, citi cilvÄ“ki redzÄ“s jÅ«su ekrÄnu.
@@ -165,7 +160,6 @@ service.gui.DISCONNECTED_STATUS=Atvienots
service.gui.DND_STATUS=Lūdzu netraucēt
service.gui.DO_NOT_ASK_AGAIN=Vairs nejautÄt
service.gui.DO_NOT_SHOW_AGAIN=NerÄdÄ«t vairÄk Å¡o paziņojumu.
-service.gui.DOWNLOAD_NOW=&LejuplÄdÄ“t tagad
service.gui.DRAG_FOR_SHARING=Velciet visu ko vēlaties kopīgot...
service.gui.DURATION=ilgums
service.gui.EDIT=&Labot
@@ -180,7 +174,6 @@ service.gui.ERROR_WAS=Kļūda: {0}
service.gui.ESTIMATED_TIME=Novērtētais laiks:
service.gui.EVENTS=Notikumi
service.gui.EXIT=I&ziet
-service.gui.EXTENDED_CRITERIA=PaplaÅ¡inÄt kritÄ“riju
service.gui.GENERAL_ERROR=VispÄrÄ«ga kļūda
service.gui.GROUP_NAME=Grupas nosaukums
service.gui.FAILED_STATUS=Zvans neizdevÄs
@@ -234,7 +227,6 @@ service.gui.HIDE_OFFLINE_CONTACTS=Paslēpt kontaktus bezsaistē
service.gui.HIDE_MAIN_WINDOW=<DIV>KlikÅ¡Ä·inot X loga pogu, neizbeigs aplikÄcijas darbu, bet tikai <BR> to paslÄ“ps. Ja vÄ“laties beigt aplikÄcijas darbu izvÄ“laties Fails/Iziet</DIV>
service.gui.HISTORY=&VÄ“sture
service.gui.HISTORY_CONTACT=VÄ“sture - {0}
-service.gui.HOUR=Stunda
service.gui.ICE=ICE
service.gui.IDENTIFIER=Identifikators
service.gui.IGNORE=&Ignorēt
@@ -253,11 +245,8 @@ service.gui.INVITE_CONTACT_TO_CALL=UzaicinÄt kontaktus zvanam
service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=UzaicinÄt kontaktus video tiltam
service.gui.INVITE_REASON=UzaicinÄjuma iemesls
service.gui.IS_NOW={0} patreiz ir {1}
-service.gui.JITSI_WARNING=SIP Communicator nesen tika pÄrsaukts par Jitsi.<br/>Ja vÄ“laties, lai jÅ«su versija bÅ«tu atjauninÄta, lejuplÄdÄ“jiet Jitsi tagad.<br/><br/>MÄ“s ļoti atvainojamies par sagÄdÄtajÄm neÄ“rtÄ«bÄm.<br/><br/>Jitsi izstrÄdÄtÄju komanda
-service.gui.JITSI_WARNING_TITLE=SIP Communicator pÄrtop par Jitsi
service.gui.JOIN=&Pievienoties
service.gui.JOIN_AS=P&ievienoties kÄ
-service.gui.CLOSE_CHAT_ROOM_DIALOG=A&izvērt
service.gui.JOIN_CHAT_ROOM=&Pievienoties tērzēšanas istabai...
service.gui.JOIN_CHAT_ROOM_TITLE=Pievienoties tērzēšanas istabai
service.gui.JOIN_CHAT_ROOM_NAME=Lūdzu ievadiet tērzēšanas istabas nosaukumu, kurai vēlaties pievienoties.
@@ -272,9 +261,13 @@ service.gui.SHOW_OFFLINE_CONTACTS=Paslēpt kontaktus bezsaistē
+#enum values from IceProcessingState
+
+
+
+#service.gui.CERT_INFO_ are combined from Rdn names
-service.gui.security.NO_VIDEO=HD video
# keep the following string short
# service.gui.avatar.imagepicker
@@ -282,9 +275,6 @@ service.gui.avatar.imagepicker.CANCEL=&Atlikt
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
# systray
@@ -295,6 +285,10 @@ service.gui.avatar.imagepicker.CANCEL=&Atlikt
impl.ldap.EDIT=&Labot
impl.ldap.CANCEL=&Atlikt
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
# Google Contacts
@@ -312,9 +306,6 @@ impl.googlecontacts.CANCEL=&Atlikt
# branding
plugin.branding.ABOUT_MENU_ENTRY=&Par programmu
-# Dict protocol
-
-# facebookaccregwizz
# generalconfig
@@ -326,22 +317,16 @@ plugin.branding.ABOUT_MENU_ENTRY=&Par programmu
# jabber accregwizz
-# mailbox
-plugin.mailbox.CONFIRM=ApstiprinÄt
-
-# msn accregwizz
-
# plugin manager
# simple accregwizz
# sipaccregwizz
plugin.sipaccregwizz.DISPLAY_NAME=RÄdÄ«t ar vÄrdu
+#used from SecurityPanel
# skin manager
-# ssh accregwizz
-
# status update
# updatechecker
@@ -353,24 +338,21 @@ plugin.updatechecker.BUTTON_CLOSE=Ai&zvērt
plugin.whiteboard.COLOR=KrÄsa
plugin.whiteboard.DELETE=Dzēst
-# yahoo accregwizz
-
-# zero accregwizz
-
# gtalk accregwizz
# iptel accregwizz
-# sip2sip accregwizz
-
# ippi accregwizz
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_COPY=&Kopēt
plugin.keybindings.CHAT_CUT=&Izgriezt
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Tērzēšana
# Notification Configuration Form
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=IenÄkoÅ¡ais zvans
plugin.notificationconfig.event.IncomingFile=IenÄkoÅ¡ais zvans
plugin.notificationconfig.event.HangUp=Nolikt klausuli
@@ -386,6 +368,7 @@ impl.media.security.zrtp.TITLE=Zvanīt
+#in JNIEncoder
# The callrecordingconfig plugin was never really committed into trunk and its
# ConfigurationForm was actually put in the neomedia bundle.
@@ -418,7 +401,6 @@ net.java.sip.communicator.util.dns.SecureResolveMode.IgnoreDnssec=&Ignorēt
net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.Deny=&Aizliegt
#plugin spellcheck
-plugin.spellcheck.EDIT_PERSONAL_DICT=&Labot
#Certificate configuration plugin
diff --git a/resources/languages/resources_mk.properties b/resources/languages/resources_mk.properties
index cd47b3d..57dff6d 100644
--- a/resources/languages/resources_mk.properties
+++ b/resources/languages/resources_mk.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,23 +43,24 @@ service.gui.ACCOUNT_ME=ЈаÑ
service.gui.ACCOUNT_REGISTRATION_WIZARD=Волшебник за региÑтрирање на Ñметка
service.gui.ACCOUNTS=Сметки
service.gui.ADD=Додај
-service.gui.ADD_ACCOUNT=Додај Ñметка
service.gui.ADD_CONTACT=Додај
service.gui.ADD_CONTACT_TO=Додади контакт во
service.gui.ADD_CONTACT_ERROR=ÐеуÑпешно додавање на контактот: {0}
service.gui.ADD_CONTACT_ERROR_TITLE=Грешка при додавање на контакт
service.gui.ADD_CONTACT_EXIST_ERROR=Контактот {0} веќе поÑтои во твојата контакт лиÑта.
-service.gui.ADD_CONTACT_IDENTIFIER=Во даденото поле внеÑи го контактот кој Ñакаш да го додадеш во твојата контакт лиÑта
-service.gui.ADD_CONTACT_WIZARD=Волшебник за додавање на контакт
service.gui.ADD_GROUP_LOCAL_ERROR=Грешка при креирањето на група Ñо име {0} . Проблемот Ñе јави на локалена IO операција.
service.gui.ADD_GROUP_EXIST_ERROR=Групата {0} веќе поÑтои во твојата контакт лиÑта. Ве молиме одберете друго име.
-service.gui.ADD_SUBCONTACT=Додај
service.gui.ALL_CONTACTS=Додај
service.gui.CALL_CONTACT=Додај
+#enum values from IceProcessingState
+
+
+
+#service.gui.CERT_INFO_ are combined from Rdn names
# keep the following string short
@@ -57,9 +69,6 @@ service.gui.CALL_CONTACT=Додај
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
# systray
@@ -68,6 +77,10 @@ service.gui.CALL_CONTACT=Додај
# LDAP
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
# Google Contacts
@@ -83,9 +96,6 @@ service.gui.CALL_CONTACT=Додај
# branding
plugin.branding.ABOUT_MENU_ENTRY=&За програмот
-# Dict protocol
-
-# facebookaccregwizz
# generalconfig
@@ -97,20 +107,15 @@ plugin.branding.ABOUT_MENU_ENTRY=&За програмот
# jabber accregwizz
-# mailbox
-
-# msn accregwizz
-
# plugin manager
# simple accregwizz
# sipaccregwizz
+#used from SecurityPanel
# skin manager
-# ssh accregwizz
-
# status update
# updatechecker
@@ -119,21 +124,18 @@ plugin.branding.ABOUT_MENU_ENTRY=&За програмот
# whiteboard
-# yahoo accregwizz
-
-# zero accregwizz
-
# gtalk accregwizz
# iptel accregwizz
-# sip2sip accregwizz
-
# ippi accregwizz
# key binding chooser
+#in new ChatWindow() -> manipulated
+#Enum KeybindingSet.Category
# Notification Configuration Form
+#NotificationsTable constants
# ZRTP Securing
@@ -145,6 +147,7 @@ plugin.branding.ABOUT_MENU_ENTRY=&За програмот
+#in JNIEncoder
# The callrecordingconfig plugin was never really committed into trunk and its
# ConfigurationForm was actually put in the neomedia bundle.
diff --git a/resources/languages/resources_nl.properties b/resources/languages/resources_nl.properties
index 120c5b3..c08fc0e 100644
--- a/resources/languages/resources_nl.properties
+++ b/resources/languages/resources_nl.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Mezelf
service.gui.ACCOUNT_REGISTRATION_WIZARD=Account Registratie Gids
service.gui.ACCOUNTS=Accounts
service.gui.ADD=&Toevoegen
-service.gui.ADD_ACCOUNT=Voeg account toe
service.gui.ADD_CONTACT=&Voeg contactpersoon toe
service.gui.ADD_AUTHORIZED_CONTACT={0} toevoegen aan uw contactenlijst
service.gui.ADD_CONTACT_TO_CONTACTLIST=Contactpersoon toevoegen aan mijn contactenlijst
@@ -42,20 +52,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Contact toevoegingsfout
service.gui.ADD_CONTACT_EXIST_ERROR=De contactpersoon {0} bestaat al in uw contactenlijst.
service.gui.ADD_CONTACT_NETWORK_ERROR=De server heeft niet geantwoord op het verzoek om contactpersoon met id: {0} toe te voegen.
service.gui.ADD_CONTACT_NOT_SUPPORTED=Het toevoegen van contactpersoon met id: {0} is mislukt. Methode wordt niet ondersteund.
-service.gui.ADD_CONTACT_IDENTIFIER=Vul in onderstaand veld de identificatie van het contact dat u toe wilt voegen in.
-service.gui.ADD_CONTACT_WIZARD=Voeg contact toe gids
service.gui.ADD_CONTACT_NOT_CONNECTED=Je dient verbonden te zijn om een contactpersoon toe te voegen. Meld je aan op de geselecteerde provider en probeer opnieuw.
service.gui.ADD_GROUP_LOCAL_ERROR=Mislukt om een groep met naam {0} toe te voegen. Het probleem gebeurde tijdens een lokale IO operatie.
service.gui.ADD_GROUP_EXIST_ERROR=De groep {0} bestaat al, gelieve een andere naam te kiezen.
service.gui.ADD_GROUP_NET_ERROR=Mislukt om de groep met naam {0} toe te voegen. Het probleem gebeurde door een netwerkfout. Bekijk uw verbinding en probeer het opnieuw.
service.gui.ADD_GROUP_ERROR=Mislukt om de groep met naam {0} toe te voegen.
service.gui.ADD_GROUP_EMPTY_NAME=De naam van de groep mag niet leeg zijn.
-service.gui.ADD_GROUP=Maak een groep
-service.gui.ADD_SUBCONTACT=&Voeg subcontact toe
service.gui.ADDRESS=Adres
service.gui.ADMINISTRATOR=administrator
service.gui.ADVANCED=&Geavanceerd
-service.gui.ALL=&Alles
service.gui.ALL_CONTACTS=&Alle contacten
service.gui.ALTERNATE_ADDRESS=Alternatief adres
service.gui.APPLY=&Toepassen
@@ -65,7 +70,6 @@ service.gui.AT=te
service.gui.AUTHORIZE=&Autoriseren
service.gui.AUTHORIZATION_ACCEPTED={0} heeft uw autorisatieverzoek geaccepteerd.
service.gui.AUTHENTICATION_FAILED=Authenticatie mislukt voor {0}. Het opgegeven wachtwoord is niet geldig.
-service.gui.AUTHENTICATION_REQUESTED=Authenticatie gevraagd
service.gui.AUTHENTICATION_REQUESTED_SERVER=De {0} server heeft uw authenticatie gevraagd.
service.gui.AUTHENTICATION_REJECTED={0} heeft uw autorisatieverzoek afgewezen.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} authenticatie
@@ -107,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=In onderstaand veld kan je je nieuwe nickname
service.gui.CHANGE_NICKNAME_ERROR=Fout tijdens het wijzigen van nickname
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Nickname bestaat al
service.gui.CHANGE_VIDEO_QUALITY=Wijzig videokwaliteit
-service.gui.CHAT_CONFERENCE_LABEL=Conferenties
service.gui.CHAT_CONFERENCE_ITEM_LABEL={0}'s conferentie
service.gui.CHAT_ROOM_ALREADY_JOINED=U zit al in chatroom {0}.
service.gui.CHAT_ROOM_CONFIGURATION={0} chatroom configuratie
@@ -121,18 +124,14 @@ service.gui.CHAT_ROOM_USER_LEFT=heeft {0} verlaten
service.gui.CHAT_ROOM_USER_KICKED=is buitengesmeten bij {0}
service.gui.CHAT_ROOM_USER_QUIT=is gestopt met {0}
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=Berichten verzenden is verboden (stem ontnomen)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Slaat de chat ruimte op voor toekomstig gebruik
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Verwijdert de geselecteerde ruimte uit de lijst van opgeslagen ruimtes.
service.gui.CHAT_ROOM_NAME=Chatroom naam
service.gui.CLEAR_CUSTOM_MESSAGES=Schoon aangepaste berichten op.
service.gui.ROOM_NAME=Chatroom
-service.gui.AUTOJOIN=Autojoin
service.gui.CHANGE_PASSWORD=Wijzig wachtwoord
service.gui.CHAT_ROOM_NAME_INFO=Vul de naam van de chatroom in in onderstaand veld.
service.gui.CHAT_ROOM_NOT_EXIST=De chatroom {0} is niet gevonden op server {1}. Controleer of de ingevoerde naam correct is.
service.gui.CHAT_ROOM_NOT_CONNECTED=U moet ingelogd zijn om deel te nemen aan chatroom {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=U moet ingelogd zijn om een chatroom te verlaten.
-service.gui.CHAT_ROOM_NOT_JOINED=U moet deelnemen aan een chatroom om er verdere operaties mee te kunnen doen.
service.gui.CHAT_ROOM_OPTIONS=Chat room opties.
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=De {0} chatroom verplicht registratie voor u deel kunt nemen.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=De {0} chatroom heeft een wachtwoord gevraagd.
@@ -151,22 +150,18 @@ service.gui.CLEAR=Wissen
service.gui.CLOSE=&Sluiten
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=U heeft minder dan 2 seconden geleden een nieuw bericht ontvangen. Weet u zeker dat u deze chat wilt sluiten?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=U heeft actieve bestandsoverdrachten. Weet u zeker dat u deze wilt annuleren?
-service.gui.CONFIRM=Bevestig
service.gui.CONNECTED_STATUS=Verbonden
service.gui.CONNECTING=Verbinden...
service.gui.CONNECTING_STATUS=Verbinden
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Verbinden*
service.gui.CONNECTION=Verbinding
-service.gui.CONNECTION_FAILED_MSG=Verbinding mislukt voor de volgende account: Gebruikersnaam: {0}, Servernaam: {1}. Controleer uw netwerkverbinding, of neem contact op met uw beheerder voor meer informatie.
service.gui.CONNECTION_EXPIRED_MSG=U bent momenteel niet meer verbonden met de {0} server.
service.gui.CONTACT_NAME=ID of nummer
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Het gekozen {0} contact ondersteunt geen telefonie.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Het gekozen {0} contact ondersteunt geen chat conferenties.
service.gui.CONTACT_PAUSED_TYPING={0} heeft het typen gepauzeerd
service.gui.CONTACT_TYPING={0} is een bericht aan het typen
service.gui.CONTACT_TYPING_SEND_FAILED=oh-oh ... we konden {0} niet vertellen dat je aan het typen bent
service.gui.CONTACT_INFO=&Contact info
-service.gui.CONTACTLIST=Contactenlijst
service.gui.CONTACTS=Contacten
service.gui.COPY=&Kopiëren
service.gui.COPY_LINK=&Link kopiëren
@@ -176,17 +171,14 @@ service.gui.CREATE_CHAT_ROOM=&Creëer een chatroom...
service.gui.CREATE_CHAT_ROOM_ERROR=Mislukt om chatroom {0} te creëren.
service.gui.CREATE_CHAT_ROOM_WIZARD=Creëer chatroom gids
service.gui.CREATE_CONFERENCE_CALL=&Creëer een conference call...
-service.gui.CREATE_CONFERENCE_CHAT=&Creëer een conference chat...
service.gui.CREATE_GROUP=&Creëer groep...
service.gui.CREATE_GROUP_NAME=Vul de naam van de te creëren groep in in onderstaand veld.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Uw contactenlijst bevat geen groepen. Maak eerst een groep (Bestand/Creëer groep).
service.gui.CREATE_VIDEO_BRIDGE=Maak een &videobrug...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Maak een &videobrug
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Maak / bezoek videoconferentie
service.gui.CREATE_VIDEO_CONFERENCE=Maak een nieuwe videoconferentie voor deze chatruimte
service.gui.CONTACT_INFO_NOT_SUPPORTED=Dit contact ondersteunt geen web contactinformatie.
service.gui.CUT=&Knippen
-service.gui.DATE=Datum
service.gui.DELETE=Verwijderen
service.gui.DENY=&Afwijzen
service.gui.DESKTOP_SHARING_WARNING=<b>Weet u zeker dat u schermdeling wilt starten?</b><br>Als u op OK klikt zal iedereen in dit gesprek uw scherm zien.
@@ -197,7 +189,6 @@ service.gui.DISCONNECTED_STATUS=Niet verbonden
service.gui.DND_STATUS=Niet storen
service.gui.DO_NOT_ASK_AGAIN=Niet opnieuw vragen
service.gui.DO_NOT_SHOW_AGAIN=Toon dit bericht niet opnieuw
-service.gui.DOWNLOAD_NOW=&Download nu
service.gui.DRAG_FOR_SHARING=Sleep hier alles wat u wilt delen...
service.gui.DURATION=duur
service.gui.DESTROY_CHATROOM=Verwijder de chatruimte
@@ -218,7 +209,6 @@ service.gui.ERROR_RECEIVED_FROM=Foutmelding ontvangen van {0}
service.gui.ESTIMATED_TIME=Geschatte tijd:
service.gui.EVENTS=Gebeurtenissen
service.gui.EXIT=&Exit
-service.gui.EXTENDED_CRITERIA=Uitgebreide criteria
service.gui.GENERAL=Algemeen
service.gui.GENERAL_ERROR=Algemene fout
service.gui.GROUP_NAME=Groepsnaam
@@ -260,7 +250,6 @@ service.gui.FONT_ITALIC=Cursief
service.gui.FONT_SIZE=Grootte
service.gui.FONT_STYLE=Stijl
service.gui.FONT_UNDERLINE=Onderlijnen
-service.gui.FROM={0} van {1}
service.gui.GRANT_OWNERSHIP=Geef eigenaarsrecht...
service.gui.GRANT_ADMIN=Geef administratorrecht...
service.gui.GRANT_MODERATOR=Geef moderatorrecht
@@ -286,7 +275,6 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=Weet je zeker dat je alle lokaal opgeslag
service.gui.HISTORY_REMOVE_ERROR=Fout tijdens het verwijderen van lokaal opgeslagen berichten.
service.gui.HOME=Thuis
service.gui.HOME_PAGE=Thuispagina
-service.gui.HOUR=Uur
service.gui.ICE=ICE
service.gui.IDENTIFIER=Identificatie
service.gui.IGNORE=&Negeren
@@ -310,13 +298,10 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Nodig contactpersonen uit voor videob
service.gui.INVITE_REASON=Uitnodiginsreden
service.gui.IS_CALLING={0} belt ...
service.gui.IS_NOW={0} is nu {1}
-service.gui.JITSI_WARNING=SIP Communicator is hernoemd naar Jitsi.<br />Als u een recente versie wilt behouden, download Jitsi dan nu.<br /><br />We bieden onze excuses aan voor eventuele ongemakken die dit met zich meebrengt.<br /><br />Het Jitsi Ontwikkelaars Team
-service.gui.JITSI_WARNING_TITLE=SIP Communicator wordt Jitsi
service.gui.JOIN=&Binnengaan
service.gui.JOIN_AS=&Binnengaan als
service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=Neem deel aan een bestaande videoconferentie
service.gui.JOIN_VIDEO=Neem deel aan video
-service.gui.CLOSE_CHAT_ROOM_DIALOG=&Sluiten
service.gui.JOB_TITLE=Werktitel
service.gui.JOIN_CHAT_ROOM=Werktitel
service.gui.JOIN_CHAT_ROOM_TITLE=Ga chatroom binnen
@@ -329,7 +314,6 @@ service.gui.KICK_FAILED=Buitengooien mislukt
service.gui.KICK_FAILED_GENERAL_ERROR=Mislukt om {0} buiten te gooien. Er is een serverfout gebeurd.
service.gui.KICK_FAILED_NOT_ALLOWED=Mislukt om {0} buiten te gooien. De eigenaar en administrator van de chatroom kunnen niet buitengegooid worden.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Mislukt om {0} buiten te gooien. U heeft geen privileges om dat te doen.
-service.gui.LAST=Laatste
service.gui.LAST_NAME=Achternaam
service.gui.LEAVE=&Verlaten
service.gui.LIMIT_REACHED_FOR_IP=U heeft teveel bestaande registraties van het lokale IP-adres en de server {0} accepteert geen extra registraties.
@@ -349,7 +333,6 @@ service.gui.MESSAGE=Bericht
service.gui.MISSED_CALLS_TOOL_TIP=Gemiste oproepen van:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= en {0} meer
service.gui.MODERATOR=moderator
-service.gui.MORE=Toon meer
service.gui.MORE_LABEL=Meer
service.gui.MOVE=Verplaats
service.gui.MOVE_SUBCONTACT=&Verplaats contact
@@ -358,7 +341,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=Het gekozen contact is dezelfde als \n de ges
service.gui.MOVE_SUBCONTACT_QUESTION=Weet u zeker dat u {0} naar {1} wilt verplaatsen?
service.gui.MOVE_TO_GROUP=&Verplaats naar groep
service.gui.MOVE_CONTACT=Verplaats Contact
-service.gui.MOVE_CONTACT_ERROR=&Contact kan niet verplaatst worden
service.gui.MSG_DELIVERY_FAILURE=Bovenstaand bericht kon niet afgeleverd worden.
service.gui.MSG_DELIVERY_NOT_SUPPORTED=Het protocol dat je gebruikt ondersteunt geen offline berichten. Je kunt proberen de contactpersoon te bereiken via een ander protocol of wachten tot hij/zij online komt.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Er is een interne fout opgetreden. Dit is waarschijnlijk een bug. Gelieve dit te rapporteren op http://www.jitsi.org/index.php/Development/BugsAndIssues.
@@ -372,7 +354,6 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=U dient verbonden te zijn voor u bericht
service.gui.MULTIPLE_LOGINS=U bent meer dan één keer ingelogd met hetzelfde account. De account: Gebruikersnaam: {0}, Servernaam{1} is momenteel niet verbonden.
service.gui.MY_CHAT_ROOMS=Chatruimte toevoegen
service.gui.MY_CHAT_ROOMS_TITLE=Chatruimte toevoegen
-service.gui.MUTE=Mute
service.gui.MUTUALLY_ON_HOLD_STATUS=Wederzijds on hold
service.gui.NAME=Naam
service.gui.NETWORK=Netwerk
@@ -404,7 +385,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=NietInContactenlijst
service.gui.SD_QUALITY=Standaard kwaliteit
service.gui.OFFLINE=Offline
service.gui.OK=&OK
-service.gui.OLDER_CALLS=Oudere telefoongesprekken
service.gui.ONLINE=Online
service.gui.OPEN=Open
service.gui.OPEN_FILE_FROM_IMAGE=Dubbelklik om bestand te openen.
@@ -416,7 +396,6 @@ service.gui.OPEN_ON_ACTIVITY=Openen bij activiteit
service.gui.OPEN_ON_MESSAGE=Alleen openen bij berichten
service.gui.OPEN_ON_IMPORTANT_MESSAGE=Alleen openen bij belangrijke berichten
service.gui.OR=of
-service.gui.OR_ENTER_PHONE_NUMBER=Of voer hier een telefoonnummer in...
service.gui.ORGANIZATION=Organisatie
service.gui.OTHER=Anders
service.gui.chat.role.OWNER=Eigenaar
@@ -442,7 +421,6 @@ service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Enter' voor suggesties
service.gui.PRESS_FOR_CALL_INFO=Klik voor gespreksinformatie
service.gui.PRESS_TO_OPEN_CRM=Klik om CRM-applicatie te openen
service.gui.PREVIOUS=Vorig
-service.gui.PREVIOUS_TOOLTIP=Blader door oudere conversaties
service.gui.PRINT=&Print
service.gui.PROACTIVE_NOTIFICATION=is een bericht aan het schrijven
service.gui.PROBLEMS_ENCOUNTERED=Problemen tegengekomen
@@ -458,7 +436,6 @@ service.gui.RECONNECTION_LIMIT_EXCEEDED=U heeft te snel de verbinding met de ser
service.gui.RE_REQUEST_AUTHORIZATION=&Opnieuw om autorisatie vragen
service.gui.REFERRED_STATUS=Verwezen
service.gui.REJECT=&Weigeren
-service.gui.REMIND_ME_LATER=Herinner mij later
service.gui.REMEMBER_PASSWORD=Wachtwoord herinneren
service.gui.REMOVE=&Verwijderen
service.gui.REMOVE_ACCOUNT=&Verwijder account
@@ -484,29 +461,20 @@ service.gui.REVOKE_ADMIN=Beheerder intrekken
service.gui.REVOKE_MODERATOR=Moderator intrekken
service.gui.REVOKE_MEMBERSHIP=Deelname intrekken
service.gui.REVOKE_VOICE=Stemgebruik intrekken
-service.gui.ROOT_GROUP=Hoofd groep
service.gui.SAVE=&Opslaan
-service.gui.SAVE_AS_DEFAULT=Als standaard opslaan
service.gui.SEARCH=&Zoeken
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Klik op de knop hieronder om alle bestaande chat rooms te tonen in de geselecteerde server. Selecteer vervolgens degene waar u deel aan wilt nemen en klik op de deelname knop.
service.gui.SEARCH_STRING_CONTACT_SOURCE=Gezocht contactpersoon
service.gui.SECURITY=Beveiliging
-service.gui.SELECT_ACCOUNT=Selecteer account
service.gui.SELECT_COLOR=Selecteer kleur
service.gui.SELECT_GROUP=Selecteer groep
-service.gui.SELECT_GROUP_WIZARD_MSG=De lijst hieronder bevat alle groepen in uw contactenlijst. Selecteer degene waar u het nieuwe contact wilt toevoegen.
service.gui.SELECT_NO_GROUP=Geen groep
-service.gui.SELECT_GROUP_WIZARD=Specificeer groep
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=De lijst hieronder bevat alle accounts die de meervoudige gebruikers chat functionaliteit gebruiken. Selecteer degene die u wilt gebruiken om uw chat room te maken.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=De lijst hieronder bevat alle geregistreerde accounts. Selecteer degene die u wilt gebruiken om te communiceren met het nieuwe contact.
-service.gui.SELECT_PROVIDERS_WIZARD=Selecteer account
service.gui.SELECT_VIDEO_CONFERENCE=Kies videoconferentie
service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Kies een chatruimte uit de lijst en druk op OK om deze toe te voegen.
service.gui.SEND=&Versturen
service.gui.SEND_FILE=Verstuur &bestand
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Er is geen informatie voor dit contact.
service.gui.SEND_MESSAGE=&Verstuur een bericht
-service.gui.SEND_AS_SMS=Verstuur als SMS
service.gui.SEND_PRIVATE_MESSAGE=Persoonlijk bericht versturen
service.gui.SEND_SMS=&Verstuur SMS
service.gui.SEND_SMS_DETAILS=Denk er aan dat u het nummer in internationaal formaat moet invoeren, bijvoorbeeld beginnend met +44 voor het Verenigd Koninkrijk, +447777000000
@@ -545,7 +513,6 @@ service.gui.STREET=Straat
service.gui.SUBJECT=Onderwerp
service.gui.SUMMARY=Samenvatting
service.gui.TELEPHONY=Telefonie
-service.gui.TODAY=Vandaag
service.gui.TOOLS=&Gereedschap
service.gui.TRANSFER=&Overdracht
service.gui.TO=&Aan:
@@ -555,7 +522,6 @@ service.gui.TRANSFER_CALL_TO=Overdragen aan:
service.gui.TRANSPARENCY_NOT_ENABLED=Transparantie is niet ondersteund door uw huidige configuratie.
service.gui.TYPE_YOUR_REQUEST=Typ uw verzoek hier
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Het is niet gelukt om de videokwaliteit voor dit gesprek te wijzigen.
-service.gui.UNMUTE=Mute opheffen
service.gui.USER_IDENTIFIER=Gebruiker identificator:
service.gui.USER_EXISTS_ERROR=Deze gebruiker bestaat reeds op het geselecteerde netwerk. Kies een andere gebruiker of netwerk.
service.gui.USERNAME_NULL=Voer uw gebruikersnaam en wachtwoord in.
@@ -568,7 +534,6 @@ service.gui.USE_PROVISIONING=Gebruik online provisioning.
service.gui.VALUE=Waarde
service.gui.VIDEO_CALL=&Video gesprek
service.gui.VIA=via
-service.gui.VIA_SMS=Via SMS
service.gui.VIEW=&Weergeven
service.gui.VIEW_HISTORY=Bekijk &geschiedenis
service.gui.VIEW_SMILEYS=Bekijk &smileys
@@ -588,9 +553,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=Volume aanpassen
service.gui.WAITING_AUTHORIZATION=Wacht op autorisatie
service.gui.WARNING=Waarschuwing
service.gui.YES=Ja
-service.gui.YESTERDAY=Gisteren
-service.gui.EXISTING_ACCOUNT_ERROR=Het opgegeven account is reeds geïnstalleerd.
-service.gui.NEW_MAIL=<b>U heeft één nieuw email bericht</b><br/><b>Van:</b> {0} {1} <br/><b>Onderwerp:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=U heeft een nieuw email bericht in uw {0} <a href="{1}">inbox</a>:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=U heeft {2} nieuwe email berichten ontvangen in uw {0} <a href="{1}">inbox</a>:<br/>
service.gui.NEW_GMAIL_FOOTER=één ongelezen bericht in uw <a href="{0}">inbox</a>.<br/>
@@ -614,7 +576,6 @@ service.gui.SECURITY_ERROR=Beveiligingsfout
service.gui.SPEED=Snelheid:
service.gui.SILENT_MEMBER=stil lid
service.gui.NON_SECURE_CONNECTION=Er kan geen beveiligde verbinding gemaakt worden voor account {0}. Als je verbinding wilt maken met een niet-beveiligide server, vink dan "Niet-beveiligde verbindingen toestaan" aan in accountinstellingen.
-service.gui.UPDATE=Update
service.gui.MOBILE_PHONE=Mobiel
service.gui.VIDEO_PHONE=Video
service.gui.WORK_PHONE=Werk
@@ -649,12 +610,10 @@ service.gui.callinfo.CALL_INFORMATION=Telefoongesprekinformatie
service.gui.callinfo.CALL_IDENTITY=Identiteit
service.gui.callinfo.PEER_COUNT=Aantal deelnemers
service.gui.callinfo.IS_CONFERENCE_FOCUS=Focus van conferentie
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Encryptie ingeschakeld
service.gui.callinfo.CALL_TRANSPORT=Transportprotocol
service.gui.callinfo.CALL_DURATION=Duur van het telefoongesprek
service.gui.callinfo.TLS_PROTOCOL=TLS-protocol
service.gui.callinfo.TLS_CIPHER_SUITE=TLS encryptiesuite
-service.gui.callinfo.TLS_SERVER_CERTIFICATE_CHAIN=Certificatenketen van de TLS server
service.gui.callinfo.TLS_CERTIFICATE_CONTENT=De inhoud van het TLS servercertificaat wordt hieronder getoond.
service.gui.callinfo.VIEW_CERTIFICATE=Certificaat weergeven
service.gui.callinfo.CODEC=Codec / Frequentie
@@ -664,7 +623,6 @@ service.gui.callinfo.AUDIO_INFO=Audio-info
service.gui.callinfo.VIDEO_INFO=Video-info
service.gui.callinfo.LOCAL_IP=Lokaal IP-adres / poort
service.gui.callinfo.REMOTE_IP=Tegenpartij IP / Poort
-service.gui.callinfo.BANDWITH=Bandbreedte
service.gui.callinfo.LOSS_RATE=Verliesratio
service.gui.callinfo.RTT=RTT
service.gui.callinfo.JITTER=Jitter
@@ -674,10 +632,13 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=Sleuteluitwisselingsprotocol
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=ICE kandidaat uitgebreid type
service.gui.callinfo.ICE_STATE=ICE verwerkingsstatus
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=Kandidaten verzamelen
service.gui.callinfo.ICE_STATE.RUNNING=Verbindingscontroles
service.gui.callinfo.ICE_STATE.COMPLETED=Voltooid
service.gui.callinfo.ICE_STATE.FAILED=Gefaald
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=Lokaal IP-adres / poort
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=Lokaal reflexief IP-adres / poort
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=Lokaal doorgestuurd IP-adres / poort
@@ -698,11 +659,12 @@ service.gui.ALWAYS_TRUST=Dit certificaat altijd vertrouwen
service.gui.CERT_DIALOG_TITLE=Controleer certificaat
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} kan de identiteit van de server niet verifiëren tijdens de verbindingspoging <br> naar {1}. Het certificaat is niet vertrouwd, wat betekent dat de serveridentiteit niet <br> automatisch kan worden vastgesteld. Wilt u verder gaan met het opzetten van deze verbinding? <br><br> Voor meer informatie, klik op ''Certificaat weergeven''.</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0} kan de identiteit van de server niet verifiëren tijdens verbindingspoging <br> naar {1}. Het certificaat is niet vertrouwd, wat betekent dat de serveridentiteit niet <br> automatisch kan worden vastgesteld. Wilt u verder gaan met het opzetten van deze verbinding? <br><br> Voor meer informatie, klik op ''Toon Certificaat''.</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} kan de identiteit van de verbinding makende cliënt niet vaststellen. <br><br> Het certificaat is niet vertrouwd, wat betekent dat de cliëntidentiteit niet <br> automatisch kan worden vastgesteld. Wilt u deze verbinding accepteren? <br><br> Voor meer informatie, klik op ''Toon certificaat''. </html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} kan de identiteit van de verbinding makende cliënt niet vaststellen. <br><br> Het certificaat is niet vertrouwd, wat betekent dat de cliëntidentiteit niet <br> automatisch kan worden vastgesteld. Wilt u deze verbinding accepteren? <br><br> Voor meer informatie, klik op ''Certificaat weergeven''. </html>
service.gui.CONTINUE_ANYWAY=Toch doorgaan
service.gui.CERT_INFO_CHAIN=Certificatenketen:
service.gui.CERT_INFO_ISSUED_TO=Uitgegeven aan
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Algemene naam:
service.gui.CERT_INFO_O=Organisatie:
service.gui.CERT_INFO_C=Land Naam:
@@ -721,12 +683,10 @@ service.gui.CERT_INFO_SIGN_ALG=Handtekeningsalgorithme
service.gui.CERT_INFO_PUB_KEY_INFO=Info over publieke sleutel
service.gui.CERT_INFO_ALG=Algorithme:
service.gui.CERT_INFO_PUB_KEY=Publieke sleutel:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} bytes: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} bits
service.gui.CERT_INFO_EXP=Exponent:
service.gui.CERT_INFO_KEY_SIZE=Sleutelgrootte:
service.gui.CERT_INFO_SIGN=Handtekening:
-service.gui.CONTINUE=Verder
service.gui.SHOW_CERT=Weergeven certificaat
service.gui.HIDE_CERT=Verbergen certificaat
@@ -749,12 +709,9 @@ service.gui.security.SECURE_AUDIO=Beveiligde audio
service.gui.security.AUDIO_NOT_SECURED=Audio niet beveiligd
service.gui.security.SECURE_VIDEO=Beveiligde video
service.gui.security.VIDEO_NOT_SECURED=Video niet beveiligd
-service.gui.security.NO_VIDEO=Geen video
-service.gui.security.CIPHER=Codering: {0}
service.gui.security.CALL_SECURED_TOOLTIP=Telefoongesprek beveiligd. Klik hier voor meer informatie.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Telefoongesprek niet beveiligd.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Klik hier om het beveiligingsgeheim te vergelijken met je partner.
-service.gui.security.COMPARE_WITH_PARTNER=Vergelijk met uw partner en klik het padlock om te bevestigen.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Vergelijk met je partner: {0}
service.gui.security.STRING_COMPARED=Regel vergeleken!
@@ -772,20 +729,14 @@ service.gui.avatar.imagepicker.CLICK=Klik en lach
service.gui.avatar.imagepicker.IMAGE_FILES=Afbeeldingsbestanden
service.gui.avatar.imagepicker.IMAGE_PICKER=Afbeelding
service.gui.avatar.imagepicker.IMAGE_SIZE=Afbeeldingsgrootte
-service.gui.avatar.imagepicker.INITIALIZING=Initialiseren
service.gui.avatar.imagepicker.RESET=Reset
service.gui.avatar.imagepicker.SET=Instellen
service.gui.avatar.imagepicker.TAKE_PHOTO=Neem een foto
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Webcam fout
service.gui.security.encryption.required=Encryptie verplicht!
service.protocol.ICE_FAILED=Kan verbinding niet tot stand brengen (ICE mislukt en geen relay beschikbaar)
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
impl.protocol.sip.XCAP_ERROR_TITLE=Fout in opslag van SIP contactenlijst
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=Resource {0} kan niet gelezen worden. Voor {1}
@@ -815,9 +766,7 @@ impl.ldap.QUERY_CUSTOM=Aangepast zoeken
impl.ldap.QUERY_CUSTOM_HINT=Gebruik {0} als plaatsvervanger voor de zoekterm.
impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=Automatisch wildcards toevoegen aan zoekterm
impl.ldap.QUERY_PHOTO_INLINE=Foto samen met andere attributen ophalen.
-impl.ldap.NEW=Nieuw
impl.ldap.EDIT=bewerken
-impl.ldap.REMOVE=Verwijderen
impl.ldap.ENABLED=Actief
impl.ldap.SERVER_NAME=Servernaam
impl.ldap.SERVER_NAME_EXAMPLE=Mijn LDAP server
@@ -850,6 +799,10 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=homePhone
impl.ldap.PHONE_PREFIX=Telefoonvoorvoegsel
impl.ldap.PHONE_PREFIX_EXAMPLE=Vb.: 00
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=Adresboek
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=MacOSX adresboek doorzoeken inschakelen
@@ -864,9 +817,7 @@ plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT=Maak Outlook de standaard email
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Google contacten
-impl.googlecontacts.NEW=Nieuw
impl.googlecontacts.EDIT=bewerken
-impl.googlecontacts.REMOVE=Verwijderen
impl.googlecontacts.ENABLED=Actief
impl.googlecontacts.ACCOUNT_NAME=Accountnaam
impl.googlecontacts.SAVE=Opslaan
@@ -905,11 +856,8 @@ plugin.accountinfo.ORGANIZATION=Naam van organisatie:
plugin.accountinfo.JOB_TITLE=Werktitel:
plugin.accountinfo.ABOUT_ME=Over Mij:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
-plugin.accountinfo.USER_PICTURES=Gebruikersfoto's
plugin.accountinfo.GLOBAL_ICON=Globaal icoon gebruiken
plugin.accountinfo.LOCAL_ICON=Gebruik dit icoon:
-plugin.accountinfo.CHANGE=Veranderen
-plugin.accountinfo.ONLY_MESSAGE=Alleen berichten
# connection info
plugin.connectioninfo.TITLE=Verbindingsinformatie
@@ -929,49 +877,12 @@ plugin.aimaccregwizz.USERNAME=AIM schermnaam:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Scherm naam en wachtwoord
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Registreer nieuw account
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Heeft u geen AIM account, klik dan op deze knop om er een aan te maken.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Overschrijf standaard server opties
# branding
plugin.branding.ABOUT_WINDOW_TITLE=Over {0}
plugin.branding.LOGO_MESSAGE=Open Source VoIP && Instant Messaging
-plugin.branding.LOADING=Laden
plugin.branding.ABOUT_MENU_ENTRY=&Over
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>Het {1} wordt momenteel actief ontwikkeld. De versie die u nu draait is slechts experimenteel en werkt MOGELIJK niet zoals verwacht. Raadpleeg {2} voor meer informatie.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 Copyright jitsi.org. Alle rechten voorbehouden. Bezoek <a href="http://jitsi.org">http://jitsi.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}>Jitsi wordt gedistribueerd onder de voorwaarden van de LGPL (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=Woordenboeken
-plugin.dictaccregwizz.ANY_DICTIONARY=Willekeurig woordenboek
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Willekeurig woordenboek van {0}
-plugin.dictaccregwizz.FIRST_MATCH=Eerste resultaat
-plugin.dictaccregwizz.NO_MATCH=Geen resultaat
-plugin.dictaccregwizz.MATCH_RESULT=Geen definities gevonden voor ''{0}'', misschien bedoeld u:\n
-plugin.dictaccregwizz.INVALID_DATABASE=Het huidige woordenboek ''{0}'' bestaat niet langer op de server.
-plugin.dictaccregwizz.INVALID_STRATEGY=De huidige strategie is niet beschikbaar op de server.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=Het Dict dienst protocol
-plugin.dictaccregwizz.HOST=Host
-plugin.dictaccregwizz.SERVER_INFO=Serverinformatie
-plugin.dictaccregwizz.STRATEGY_SELECTION=Strategie selectie
-plugin.dictaccregwizz.STRATEGY_LIST=Lijst van strategieën:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Zoek binnen strategieën
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=Strategieën worden gebruikt vergelijkbare woorden te vinden, wanneer een vertaling niet gevonden is, dankzij verschillende methodes. Bijvoorbeeld de Prefix strategie zoekt woorden die beginnen met het woord dat u zou willen vertalen.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Dict account informatie
-plugin.dictaccregwizz.FIRST_ACCOUNT=Deze wizard maakt uw eerste Dict account aan op dict.org.\n\nU kunt nieuwe woordenboeken toevoegen door naar de Account Registratie Wizard te gaan. Vul het host veld met het woordenboek dat u toe wilt voegen.
-plugin.dictaccregwizz.THREAD_CONNECT=Probeert verbinding te maken met de server
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=Verbindingspoging mislukt, dit is geen dict server of de server is offline
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=Ophalen strategieën
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Geen strategie gevonden op de server
-plugin.dictaccregwizz.POPULATE_LIST=Lijst aan het vullen
-plugin.dictaccregwizz.CLOSING_CONNECTION=Verbinding aan het sluiten
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Om Facebook Chat te kunnen gebruiken, is het noodzakelijk een ''Gebruikersnaam'' aan te maken <br> in uw ''Account instellingen'' pagina op Facebook.</a><br><br>Aantekening: Wanneer u een gebruikersnaam aangemaakt heeft, moet u uitloggen van de webpagina >br> en kan het even duren voordat u in staat bent in te loggen met uw nieuwe gebruikersnaam!</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=Het Facebook Chat protocol
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Gebruikersnaam:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Gebruikersnaam en wachtwoord:
+
# generalconfig
plugin.generalconfig.AUTO_START={0} automatisch starten wanneer de computer opnieuw opstart
@@ -982,9 +893,6 @@ plugin.generalconfig.SHOW_HISTORY=Toon
plugin.generalconfig.HISTORY_SIZE=recente berichten in nieuwe chats
plugin.generalconfig.SEND_MESSAGES_WITH=Verstuur berichten met:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=Breng chat venster naar de voorgrond
-plugin.generalconfig.ERROR_PERMISSION=U heeft niet voldoende privileges om automatisch starten te verwijderen.
-plugin.generalconfig.TRANSPARENCY=Transparantie
-plugin.generalconfig.ENABLE_TRANSPARENCY=Transparantie aanzetten
plugin.generalconfig.DEFAULT_LANGUAGE=Interfacetaal
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Uw wijzigingen worden effectief na de volgende herstart.
plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0} % vertaald
@@ -1043,13 +951,13 @@ plugin.ircaccregwizz.EXAMPLE_SERVER=Vb.: chat.freenode.net
plugin.ircaccregwizz.USE_SECURE_CONNECTION=Gebruik beveiligde verbinding
plugin.ircaccregwizz.ENABLE_CONTACT_PRESENCE=Contactpersoonaanwezigheid inschakelen
plugin.ircaccregwizz.ENABLE_CHAT_ROOM_PRESENCE=Aanwezigheid in chatruimte inschakelen
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE={0} authenticatie
+plugin.ircaccregwizz.SASL_USERNAME=Gebruikersnaam
# jabber accregwizz
-plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=Het XMPP protocol
plugin.jabberaccregwizz.USERNAME=XMPP-gebruikersnaam
plugin.jabberaccregwizz.PASSWORD_CONFIRM=Bevestig wachtwoord
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=ID en wachtwoord
plugin.jabberaccregwizz.CSERVER=Server
plugin.jabberaccregwizz.SERVER=Verbind met server
plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=Activeer keep alive
@@ -1065,13 +973,9 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Commentaar
plugin.jabberaccregwizz.RESOURCE=Bron
plugin.jabberaccregwizz.AUTORESOURCE=Genereer bron automatisch
plugin.jabberaccregwizz.PRIORITY=Prioriteit
-plugin.jabberaccregwizz.XMPP_ERROR=XMPP fout
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Onbekende XMPP-fout. ({0}) Controleer of de servernaam correct is.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=De wachtwoorden komen niet overeen.
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Overschrijf standaard server opties
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Geavanceerde opties
plugin.jabberaccregwizz.USE_ICE=Gebruik ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=Gebruik Google's Jingle/ICE (experimenteel)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=Ontdek STUN/TURN servers automatisch
plugin.jabberaccregwizz.SUPPORT_TURN=Ondersteun TURN
plugin.jabberaccregwizz.TURN_USERNAME=TURN gebruikersnaam
@@ -1099,11 +1003,8 @@ plugin.jabberaccregwizz.DISABLE_CARBON=Berichtkopiën uitschakelen
plugin.jabberaccregwizz.DTMF_AUTO=Auto: Kies automatisch tussen RTP en in-band
plugin.jabberaccregwizz.SERVER_OPTIONS=Server-opties
plugin.jabberaccregwizz.CHANGE_PASSWORD=Wijzig account-wachtwoord
-plugin.jabberaccregwizz.NEW_PASSWORD=Nieuw wachtwoord
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Bevestig wachtwoord
plugin.jabberaccregwizz.PORT_FIELD_INVALID=Vul een geldig poortnummer in om door te gaan.
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=Het account moet ingelogd zijn om het wachtwoord te kunnen wijzigen.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=Het wachtwoord is leeg.
plugin.jabberaccregwizz.TLS_REQUIRED=De verbinding is niet beveiligd. De wachtwoordwijziging wordt niet uitgevoerd.
plugin.jabberaccregwizz.PASSWORD_CHANGED=Het wachtwoord is succesvol gewijzigd.
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=Het wijzigen van het wachtwoord wordt op deze XMPP-server niet ondersteund.
@@ -1117,25 +1018,9 @@ plugin.jabberaccregwizz.RESET=Reset
plugin.jabberaccregwizz.RESET_DESCRIPTION=Resetten naar globale instellingen
plugin.jabberaccregwizz.DISABLE_JINGLE=Jingle uitschakelen (audio en video gesprekken met XMPP).
-# mailbox
-plugin.mailbox.OUTGOING=Uitgaand bericht:
-plugin.mailbox.INCOMING=Binnenkomende berichten:
-plugin.mailbox.WAIT_TIME=Wachttijd voordat telefoongesprek naar Voicemail wordt doorverwezen
-plugin.mailbox.MAX_MESSAGE_TIME=Maximale binnenkomende gesprekstijd
-plugin.mailbox.CONFIRM=Bevestig
-plugin.mailbox.DEFAULTS=Standaardinstellingen
-plugin.mailbox.MAILBOX=Mailbox
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Een protocol om verbinding te maken en gesprekken te voeren op de MSN dienst.
-plugin.msnaccregwizz.USERNAME=Email:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=ID en wachtwoord
-
# plugin manager
plugin.pluginmanager.INSTALL=Installeren
plugin.pluginmanager.UNINSTALL=Deïnstalleren
-plugin.pluginmanager.UPDATE=Update
plugin.pluginmanager.PLUGINS=Plug-ins
plugin.pluginmanager.URL=Url
plugin.pluginmanager.CHOOSE_FILE=Selecteer bestand
@@ -1160,7 +1045,6 @@ plugin.sipaccregwizz.SERVER_PORT=Server poort
plugin.sipaccregwizz.PROXY=Proxy
plugin.sipaccregwizz.PROXY_PORT=Proxy poort
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Voorkeurstransport
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Geavanceerde opties
plugin.sipaccregwizz.PROXY_OPTIONS=Proxy opties
plugin.sipaccregwizz.PROXY_AUTO=Configureer proxy automatisch
plugin.sipaccregwizz.ENABLE_PRESENCE=Activeer aanwezigheid (SIMPLE)
@@ -1180,8 +1064,6 @@ plugin.sipaccregwizz.DTMF_AUTO=Auto: Kies automatisch tussen RTP en in-band (gee
plugin.sipaccregwizz.DTMF_RTP=RTP ( RFC2833 / RFC 4733 )
plugin.sipaccregwizz.DTMF_SIP_INFO=SIP INFO
plugin.sipaccregwizz.DTMF_INBAND=In-band
-plugin.sipaccregwizz.REGISTER=REGISTREREN
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Overschrijf standaard server opties
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Activeer ondersteuning voor gecodeerde telefoongesprekken
plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=Indicatie van ondersteuning voor ZRTP in signaling-protocol
plugin.sipaccregwizz.AUTH_NAME=Autorisatienaam
@@ -1202,10 +1084,10 @@ plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=URI voor Voicemail-controle
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Uw wachtwoorden komen niet overeen.
plugin.sipaccregwizz.NO_CERTIFICATE=<geen> (gebruik reguliere authenticatie)
plugin.sipaccregwizz.SAVP_OPTION=RTP/SAVP-indicatie
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=Uitgeschakeld (indicatie alleen RTP/AVP)
plugin.sipaccregwizz.SAVP_OPTION_1=Verplicht (bied aan en accepteer enkel RTP/SAVP)
plugin.sipaccregwizz.SAVP_OPTION_2=Optioneel (biedt RTP/SAVP eerst aan, daarna RTP/AVP)
-plugin.sipaccregwizz.ENABLE_SDES_ATTRIBUTE=S-Descriptor inschakelen (staat ook bekend als SDES of SRTP)
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=Kies ingeschakelde encryptieprotocollen en hun prioriteit (bovenste protocol eerst):
plugin.sipaccregwizz.CIPHER_SUITES=Ingeschakelde codeersuites:
plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>{0} zal automatisch proberen al je gesprekken te beveiligen met ZRTP en jullie zullen beide een melding zien en horen als de beveiligide verbinding in stand gebracht is. Je zou de geavanceerde instellingen hieronder alleen moeten wijzigen als je goed weet wat je doet.</div></html>
@@ -1219,15 +1101,6 @@ plugin.skinmanager.DEFAULT_SKIN=Standaard skin
plugin.skinmanager.ADD_NEW_SKIN=Voeg nieuwe skin toe...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=De standaard skin voor de applicatie.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=Een protocol om verbinding te maken met externe machines over SSH.
-plugin.sshaccregwizz.USERNAME=Account ID:
-plugin.sshaccregwizz.IDENTITY_FILE=Identiteitsbestand:
-plugin.sshaccregwizz.KNOWN_HOSTS=Bekende hosts:
-plugin.sshaccregwizz.OPTIONAL=Optioneel
-plugin.sshaccregwizz.ACCOUNT_DETAILS=Accountdetails
-
# status update
plugin.autoaway.AUTO_STATUS=Automatisch Weg
plugin.autoaway.ENABLE_CHANGE_STATUS=Verander status tijdens weg zijn
@@ -1275,22 +1148,6 @@ plugin.whiteboard.DESELECT=Deselecteren
plugin.whiteboard.DELETE=Verwijderen
plugin.whiteboard.PROPERTIES=Eigenschappen
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Een protocol om verbinding te maken en gesprekken te voeren op de Yahoo!-dienst.
-plugin.yahooaccregwizz.USERNAME=Gebruikersnaam:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=ID en wachtwoord:
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=Het Zeroconf (Bonjour) dienst protocol.
-plugin.zeroaccregwizz.FIRST_NAME=Voornaam:
-plugin.zeroaccregwizz.LAST_NAME=Achternaam:
-plugin.zeroaccregwizz.EMAIL=Email:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=Onthouden Bonjour contacten?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=ID en wachtwoord
-plugin.zeroaccregwizz.USERID=Gebruikers ID
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Het Google Talk protocol
@@ -1304,19 +1161,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, het IP Telecommunicatie P
plugin.iptelaccregwizz.USERNAME=Gebruikersnaam
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=lid worden van iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIP en chat
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Gebruikersnaam
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Voor wachtwoord opnieuw in
plugin.sip2sipaccregwizz.EMAIL=Email adres
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=Voor help over deze dienst bezoek<br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>Het email adres wordt gebruikt om voicemail berichten te versturen,<br>gemiste oproep notificaties en om een verloren wachtwoord te herstellen</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>Voor help over deze dienst bezoek <a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=Bestaand ip2sip.info account
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Maak een gratis sip2sip.info account aan
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP && Instant Messaging
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=Voor help over deze dienst bezoek<br>http://ippi.fr
@@ -1325,6 +1174,7 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=Bestaand ippi account
plugin.ippiaccregwizz.CREATE_ACCOUNT=Maak een gratis ippi account aan
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Sluit chat venster
plugin.keybindings.CHAT_COPY=Kopiëren
plugin.keybindings.CHAT_CUT=Knippen
@@ -1347,10 +1197,10 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=Naam
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=Primaire sneltoets
plugin.keybindings.globalchooser.SHORTCUT_SECOND=Secundaire sneltoets
plugin.keybindings.globalchooser.PRESS_BTN=Druk om sneltoets in te stellen
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=Wachten
plugin.keybindings.globalchooser.PUSH_TO_TALK=Indrukken om te spreken
plugin.keybindings.globalchooser.ENABLE_SPECIAL=Detectie van speciale toetsen inschakelen
plugin.keybindings.PLUGIN_NAME=Toetsenconfiguratie
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Chat
plugin.keybindings.MAIN=Main
plugin.keybindings.GLOBAL=Globale sneltoetsen
@@ -1378,6 +1228,7 @@ plugin.notificationconfig.tableheader.SOUND=Speel geluid af via het meldingenapp
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=Speel geluid af via afspeelapparaat
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=Speel een geluid af via PC speaker-apparaat
plugin.notificationconfig.tableheader.DESCRIPTION=Beschrijving van gebeurtenis
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Binnenkomend gesprek
plugin.notificationconfig.event.SecurityMessage=Beveiligingsbericht
plugin.notificationconfig.event.IncomingFile=Binnenkomend bestand
@@ -1479,6 +1330,7 @@ impl.neomedia.configform.VIDEO=Video
impl.neomedia.configform.H264=H.264
impl.neomedia.configform.H264.defaultIntraRefresh=Periodieke intra-refresh
impl.neomedia.configform.H264.defaultProfile=Standaard profiel om in te coderen:
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=Baseline
impl.neomedia.configform.H264.defaultProfile.high=Hoog
impl.neomedia.configform.H264.defaultProfile.main=Algemeen
@@ -1509,7 +1361,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=Huidig wachtwoord:
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Voer nieuw wachtwoord in:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Voer wachtwoord opnieuw in:
plugin.securityconfig.masterpassword.MP_TITLE=Hoofd wachtwoord:
-plugin.securityconfig.masterpassword.MP_NOT_SET=(niet ingesteld)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=U heeft niet het correcte hoofd wachtwoord ingevoerd. Probeer het opnieuw.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=Het hoofd wachtwoord is niet correct!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Wachtwoordwijziging niet geslaagd
@@ -1525,7 +1376,6 @@ plugin.securityconfig.masterpassword.COL_PASSWORD=Wachtwoord
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(onbekend)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(kan niet decoderen)
plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=Opgeslagen wachtwoorden
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=Verwijderen
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=Verwijder alle
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=Weet u zeker dat u alle wachtwoorden wilt verwijderen?
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=Verwijder alle wachtwoorden
@@ -1621,7 +1471,6 @@ plugin.globalproxy.PROXY_PORT=Proxy poort
plugin.globalproxy.PROXY_USERNAME=Proxy gebruikersnaam
plugin.globalproxy.PROXY_PASSWORD=Proxy wachtwoord
plugin.globalproxy.DESCRIPTION={0} gebruikt de bovenstaande proxy instellingen voor alle netwerken waarmee u (opnieuw) verbinding maakt vanaf nu.\n Proxy ondersteuning is momenteel experimenteel en werkt alleen met sommige protocollen. Bekijk de tabel hieronder voor meer details:
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>XMPP</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
plugin.globalproxy.FWD_DNS=Ook DNS proxy'en
plugin.globalproxy.FWD_DNS_NOTE=Nuttig voor Tor. Dit helpt voorkomen dat DNS verzoeken lekken door alle DNS-verkeer te herleiden naar de Tor-proxy. Herstart nodig.
@@ -1659,7 +1508,6 @@ plugin.provisioning.RESTART_WARNING=Merk op dat uw wijzigingen pas van kracht wo
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=Kopieer UUID naar klembord
plugin.provisioning.CLIPBOARD_FAILED=Kopiëren van UUID naar klembord mislukt
-plugin.provisioning.EXIT_ON_FAIL=Sluit de applicatie als provisioning faalt
plugin.provisioning.CREDENTIALS=Laatste opgeslagen provisioning-aanmeldgegevens
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=Weet je zeker dat je het provisioning-wachtwoord wilt verwijderen?
plugin.provisioning.PROV_FAILED=Provisioning is gefaald
@@ -1726,8 +1574,6 @@ util.dns.DNSSEC_WARNING=<html><div width="600">{0} heeft geprobeerd om te verbin
#plugin spellcheck
plugin.spellcheck.TITLE=Spelling en Grammatica
plugin.spellcheck.MENU=Toon Spelling en Grammatica
-plugin.spellcheck.LANG=Taal
-plugin.spellcheck.EDIT_PERSONAL_DICT=&Bewerken
plugin.spellcheck.ENABLE_SPELL_CHECK=Spellingscontrole inschakelen
plugin.spellcheck.dialog.FIND=Volgende zoeken
plugin.spellcheck.dialog.REPLACE=Vervangen
diff --git a/resources/languages/resources_pl.properties b/resources/languages/resources_pl.properties
index 04611e8..a5fac15 100644
--- a/resources/languages/resources_pl.properties
+++ b/resources/languages/resources_pl.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -26,36 +37,30 @@
# ant -Duser.language=xx run
service.gui.ABOUT=&O programie
-service.gui.ACCEPT=&Zaakceptuj
+service.gui.ACCEPT=&Akceptuj
service.gui.ACCOUNT=Konto
service.gui.ACCOUNT_ME=Ja
-service.gui.ACCOUNT_REGISTRATION_WIZARD=Kreator rejestracji konta
+service.gui.ACCOUNT_REGISTRATION_WIZARD=Asystent tworzenia konta
service.gui.ACCOUNTS=Konta
service.gui.ADD=&Dodaj
-service.gui.ADD_ACCOUNT=Dodaj konto
service.gui.ADD_CONTACT=&Dodaj kontakt
-service.gui.ADD_AUTHORIZED_CONTACT=Dodaj {0} do listy kontaktów
+service.gui.ADD_AUTHORIZED_CONTACT=Dodaj {0} do swojej listy kontaktów
service.gui.ADD_CONTACT_TO_CONTACTLIST=Dodaj ten kontakt do mojej listy kontaktów
service.gui.ADD_CONTACT_TO=&Dodaj kontakt do
service.gui.ADD_CONTACT_ERROR=Nie udało się dodać kontaktu o identyfikatorze: {0}
service.gui.ADD_CONTACT_ERROR_TITLE=BÅ‚Ä…d przy dodawaniu kontaktu
-service.gui.ADD_CONTACT_EXIST_ERROR=Ten kontakt już jest na liście kontaktów.
-service.gui.ADD_CONTACT_NETWORK_ERROR=Serwer nie odpowiedział na żądanie dodania kontaktu o identyfikatorze: {0}
-service.gui.ADD_CONTACT_NOT_SUPPORTED=Próba dodania kontaktu o identyfikatorze {0} została zakończona niepowodzeniem. Operacja nie jest obsługiwana.
-service.gui.ADD_CONTACT_IDENTIFIER=W polu poniżej wprowadź identyfikator kontaktu, którego chcesz dodać.
-service.gui.ADD_CONTACT_WIZARD=Kreator dodawania kontaktu
+service.gui.ADD_CONTACT_EXIST_ERROR=Kontakt {0} już jest na Twojej liście kontaktów.
+service.gui.ADD_CONTACT_NETWORK_ERROR=Serwer nie odpowiedział na żądanie dodania kontaktu o identyfikatorze: {0}.
+service.gui.ADD_CONTACT_NOT_SUPPORTED=Próba dodania kontaktu o identyfikatorze: {0} zakończona niepowodzeniem. Operacja nie jest obsługiwana.
service.gui.ADD_CONTACT_NOT_CONNECTED=Musisz być połączony aby dodać kontakt. Zaloguj się do wybranego dostawcy i spróbuj ponownie.
service.gui.ADD_GROUP_LOCAL_ERROR=Nie udało się dodać grupy o nazwie: {0}. Wystąpił błąd lokalnej operacji wejścia/wyjścia.
service.gui.ADD_GROUP_EXIST_ERROR=Grupa {0} już jest na twojej liście kontaktów. Wybierz inną nazwę.
service.gui.ADD_GROUP_NET_ERROR=Nie udało się dodać grupy o nazwie: {0}. Problem wystąpił z powodu awarii sieci. Sprawdź połączenie z Internetem i spróbuj ponownie.
service.gui.ADD_GROUP_ERROR=Nie udało się dodać grupy o nazwie: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=Nazwa grupy nie może być pusta.
-service.gui.ADD_GROUP=Utwórz grupę
-service.gui.ADD_SUBCONTACT=&Dodaj kontakt podrzędny
service.gui.ADDRESS=Adres
service.gui.ADMINISTRATOR=administrator
service.gui.ADVANCED=&Zaawansowane
-service.gui.ALL=&Wszystkie
service.gui.ALL_CONTACTS=&Wszystkie kontakty
service.gui.ALTERNATE_ADDRESS=Adres alternatywny
service.gui.APPLY=&Zastosuj
@@ -63,9 +68,8 @@ service.gui.ARE_CALLING={0} dzwoniÄ…...
service.gui.ARE_NOW=JesteÅ› teraz {0}
service.gui.AT=w
service.gui.AUTHORIZE=&Autoryzuj
-service.gui.AUTHORIZATION_ACCEPTED=Użytkownik {0} zaakceptował twoją prośbę o autoryzację.
+service.gui.AUTHORIZATION_ACCEPTED={0} zaakceptował twoją prośbę o autoryzację.
service.gui.AUTHENTICATION_FAILED=Błąd uwierzytelniania dla {0}. Wprowadzone hasło jest nieprawidłowe.
-service.gui.AUTHENTICATION_REQUESTED=Prośba o Uwierzytelnienie
service.gui.AUTHENTICATION_REQUESTED_SERVER=Serwer {0} zażądał uwierzytelnienia.
service.gui.AUTHENTICATION_REJECTED={0} odrzucił twoją prośbę o autoryzację.
service.gui.AUTHENTICATION_WINDOW_TITLE=uwierzytelnianie {0}
@@ -74,32 +78,32 @@ service.gui.AUTHORIZATION_REQUESTED_INFO=Kontakt {0} zażądał autoryzacji.
service.gui.AUTHORIZATION_RESPONSE=Odpowiedź na autoryzację
service.gui.AWAY_STATUS=Zaraz wracam
service.gui.EXTENDED_AWAY_STATUS=Nieobecny na dłużej
-service.gui.BAN=&Zabroń wstępu
+service.gui.BAN=Za&blokuj
service.gui.BANNED=Zablokowany
-service.gui.BAN_FAILED=Niepowodzenie blokady
+service.gui.BAN_FAILED=Nieudana blokada
service.gui.BAN_FAILED_GENERAL_ERROR=Niepowodzenie blokady {0}. Ogólny błąd serwera.
service.gui.BAN_FAILED_NOT_ALLOWED=Niepowodzenie blokady {0}. Właściciel/administrator pokoju nie mogą być zablokowani.
service.gui.BAN_FAILED_NOT_ENOUGH_PERMISSIONS=Niepowodzenie blokady {0}. Nie masz wystarczających uprawnień.
-service.gui.BRB_MESSAGE=Zaraz wracam.
+service.gui.BRB_MESSAGE=Nie ma mnie, ale za niedługo wrócę
service.gui.BROWSE=PrzeglÄ…daj
service.gui.BUSY_MESSAGE=Przepraszam, jestem zajęty.
service.gui.BUSY_STATUS=Zajęty
-service.gui.CALL=Telefon
+service.gui.CALL=Zadzwoń
service.gui.CALL_CONTACT=Zadzwoń do kontaktu
service.gui.CALL_FAILED=Połączenie nieudane
-service.gui.CALL_HISTORY_TOOL_TIP=Kliknij tu, by zobaczyć historię połączeń.
+service.gui.CALL_HISTORY_TOOL_TIP=Kliknij tutaj, aby zobaczyć historię połączeń.
service.gui.CALL_HISTORY_GROUP_NAME=Historia połączeń
service.gui.CALL_VIA=Zadzwoń przez:
service.gui.CALL_NAME_OR_NUMBER=Wprowadź nazwę kontaktu lub numer
service.gui.CALL_NOT_SUPPORTING_PARTICIPANT=To połączenie obsługuje tylko uczestników z sieci {0} i twoje konto {1}. {2} nie zawiera żadnych adresów z tej sieci ani konta.
-service.gui.CALL_WITH=Zadzwoń z
+service.gui.CALL_WITH=Zadzwoń za pomocą
service.gui.CALL_NO_AUDIO_DEVICE=Karta dźwiękowa nie została skonfigurowana.
service.gui.CALL_NO_AUDIO_CODEC=Nie włączyłeś żadnych kodeków dźwiękowych.
-service.gui.CALL_NO_DEVICE_CODECS_Q=Czy chcesz kontynuować rozmowę ?
+service.gui.CALL_NO_DEVICE_CODECS_Q=Czy chcesz kontynuować rozmowę?
service.gui.CANCEL=&Anuluj
service.gui.CHAT=Czat
service.gui.CHANGE_FONT=Zmień czcionkę
-service.gui.CHANGE_ROOM_SUBJECT=Zmień temat pokoju...
+service.gui.CHANGE_ROOM_SUBJECT=Zmień temat rozmowy
service.gui.CHANGE_ROOM_SUBJECT_LABEL=W polu poniżej możesz wprowadzić nowy temat dla tego pokoju.
service.gui.CHANGE_NICK=Zmień pseudonim
service.gui.CHANGE_NICKNAME=Zmień pseudonim...
@@ -107,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=W polu poniżej możesz wprowadzić twój nowy
service.gui.CHANGE_NICKNAME_ERROR=Błąd podczas zmieniania nazwy użytkownika
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Ta nazwa użytkownika już istnieje
service.gui.CHANGE_VIDEO_QUALITY=Zmień jakość zdalnego video
-service.gui.CHAT_CONFERENCE_LABEL=Konferencje
service.gui.CHAT_CONFERENCE_ITEM_LABEL=Konferencja {0}
service.gui.CHAT_ROOM_ALREADY_JOINED=Już przyłączyłeś się do pokoju rozmów {0}.
service.gui.CHAT_ROOM_CONFIGURATION=Konfiguracja pokoju czatu {0}
@@ -121,18 +124,14 @@ service.gui.CHAT_ROOM_USER_LEFT={0} wyszedł
service.gui.CHAT_ROOM_USER_KICKED=został wyrzucony z {0}
service.gui.CHAT_ROOM_USER_QUIT={0} wyszedł
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=Wysyłanie wiadomości zostało zablokowane(ograniczono uprawnienia).
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Zapamiętuje pokój rozmów.
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Usuwa wybrany pokój z listy zapisanych pokoi.
service.gui.CHAT_ROOM_NAME=Nazwa pokoju rozmów
service.gui.CLEAR_CUSTOM_MESSAGES=Wyczyść własne wiadomości
service.gui.ROOM_NAME=Pokoje czatu
-service.gui.AUTOJOIN=Autodołączanie
service.gui.CHANGE_PASSWORD=Zmień hasło
service.gui.CHAT_ROOM_NAME_INFO=W poniższym polu wprowadź nazwę grupy, którą chcesz utworzyć.
service.gui.CHAT_ROOM_NOT_EXIST=Pokój {0} nie został znaleziony na serwerze {1}. Zweryfikuj czy wprowadziłeś poprawną nazwę.
service.gui.CHAT_ROOM_NOT_CONNECTED=Musisz być zalogowany aby dołączyć do pokoju czatowego {0}
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Musisz być zalogowany aby opuścić pokój czatowy.
-service.gui.CHAT_ROOM_NOT_JOINED=Musisz być połączony z pokojem rozmów, aby móc wykonywać dalsze operacje z nim związane.
service.gui.CHAT_ROOM_OPTIONS=Opcje pokojów czatu
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Ten pokój czatu {0} wymaga rejestracji.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Pokój czatu {0} poprosił o hasło.
@@ -151,21 +150,18 @@ service.gui.CLEAR=Wyczyść
service.gui.CLOSE=&Zamknij
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Odebrano nową wiadomość mniej niż 2 sekundy temu. Czy na pewno chcesz zamknąć ten czat?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=Masz aktywne transfery plików. Czy na pewno chcesz je przerwać?
-service.gui.CONFIRM=Potwierdź
service.gui.CONNECTED_STATUS=Połączono
service.gui.CONNECTING=ÅÄ…czÄ™...
service.gui.CONNECTING_STATUS=ÅÄ…czenie
service.gui.CONNECTING_EARLY_MEDIA_STATUS=ÅÄ…czÄ™*
service.gui.CONNECTION=Połączenie
-service.gui.CONNECTION_FAILED_MSG=Nieudana próba połączenia z serwerem dla konta: {0}, nazwa serwera: {1}. Sprawdź połączenie sieciowe lub skontaktuj się z administratorem sieci, aby uzyskać więcej informacji.
service.gui.CONNECTION_EXPIRED_MSG=Nie masz połączenia z serwerem {0}.
service.gui.CONTACT_NAME=Identyfikator użytkownika lub numer telefonu
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Wybrany kontakt {0} nie obsługuje telefonii.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Wybrany kontakt {0} nie obsługuje czatu podczas konferencji.
service.gui.CONTACT_PAUSED_TYPING={0} przerwał pisanie
service.gui.CONTACT_TYPING={0} pisze
+service.gui.CONTACT_TYPING_SEND_FAILED=uh-oh...nie możemy poinformować {0} że pisałeś
service.gui.CONTACT_INFO=&O kontakcie
-service.gui.CONTACTLIST=Lista kontaktów
service.gui.CONTACTS=Kontakty
service.gui.COPY=&Kopiuj
service.gui.COPY_LINK=&Kopiuj link
@@ -175,17 +171,14 @@ service.gui.CREATE_CHAT_ROOM=&Utwórz pokój czatu...
service.gui.CREATE_CHAT_ROOM_ERROR=Nie udało się utworzyć pokoju czatu {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=Kreator tworzenia pokoju czatu
service.gui.CREATE_CONFERENCE_CALL=&Utwórz telekonferencję...
-service.gui.CREATE_CONFERENCE_CHAT=&Utwórz czat grupowy...
service.gui.CREATE_GROUP=&Utwórz grupę...
service.gui.CREATE_GROUP_NAME=W poniższym polu wprowadź nazwę grupy, którą chcesz utworzyć.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Twoja lista kontaktów nie zawiera żadnej grupy. Najpierw utwórz grupę (Plik/Utwórz grupę).
service.gui.CREATE_VIDEO_BRIDGE=Utwórz most &video
service.gui.CREATE_VIDEO_BRIDGE_MENU=Utwórz most &wideo.
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Stwórz/przyłącz się do wideokonferencji
service.gui.CREATE_VIDEO_CONFERENCE=Utwórz wideokonferencję dla tego pokoju rozmów
service.gui.CONTACT_INFO_NOT_SUPPORTED=Ten kontakt nie obsługuje sieciowej informacji o kontakcie
service.gui.CUT=&Wytnij
-service.gui.DATE=Data
service.gui.DELETE=Usuń
service.gui.DENY=O&dmów
service.gui.DESKTOP_SHARING_WARNING=<b>Czy na pewno chcesz włączyć udostępnianie ekranu?</b> <br>Kliknięcie OK pozwoli obecnym rozmówcom zobaczyć twój ekran.
@@ -196,7 +189,6 @@ service.gui.DISCONNECTED_STATUS=Rozłączony
service.gui.DND_STATUS=Nie przeszkadzać
service.gui.DO_NOT_ASK_AGAIN=Nie pytaj więcej
service.gui.DO_NOT_SHOW_AGAIN=Nie wyświetlaj więcej tej wiadomości
-service.gui.DOWNLOAD_NOW=&Pobierz teraz
service.gui.DRAG_FOR_SHARING=Przeciągnij tutaj, aby udostępnić...
service.gui.DURATION=czas trwania rozmowy
service.gui.DESTROY_CHATROOM=Skasuj pokój rozmów
@@ -217,7 +209,6 @@ service.gui.ERROR_RECEIVED_FROM=Otrzymano błąd od {0}
service.gui.ESTIMATED_TIME=Przewidywany czas:
service.gui.EVENTS=Zdarzenia
service.gui.EXIT=&Wyjście
-service.gui.EXTENDED_CRITERIA=Rozszerzone kryteria
service.gui.GENERAL=Ogólne
service.gui.GENERAL_ERROR=Błąd ogólny
service.gui.GROUP_NAME=Nazwa grupy
@@ -259,7 +250,6 @@ service.gui.FONT_ITALIC=Kursywa
service.gui.FONT_SIZE=Rozmiar
service.gui.FONT_STYLE=Styl
service.gui.FONT_UNDERLINE=Podkreślenie
-service.gui.FROM={0} z {1}
service.gui.GRANT_OWNERSHIP=Przyznaj prawa właściciela...
service.gui.GRANT_ADMIN=Przyznaj prawa administratora...
service.gui.GRANT_MODERATOR=Przyznaj prawa moderatora...
@@ -285,14 +275,14 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=Czy na pewno chcesz trwale usunąć wszys
service.gui.HISTORY_REMOVE_ERROR=Błąd przy usuwaniu wiadomości.
service.gui.HOME=Telefon domowy
service.gui.HOME_PAGE=Strona domowa
-service.gui.HOUR=Godzina
service.gui.ICE=ICE
service.gui.IDENTIFIER=Identyfikator
service.gui.IGNORE=&Ignoruj
service.gui.INSERT_SMILEY=Wstaw emotikonÄ™
service.gui.INCOMING_CALL=Rozmowa przychodzÄ…ca od: {0}
-service.gui.INCOMING_SCREEN_SHARE=Rozmowa przychodzÄ…ca od: {0}
+service.gui.INCOMING_SCREEN_SHARE=Przychodzący ekran współdzielony otrzymany od: {0}
service.gui.INCOMING_CALL_STATUS=Połączenie przychodzące
+service.gui.INSTANT_MESSAGINGS=Komunikatory Internetowe
service.gui.IM=IM
service.gui.INITIATING_CALL_STATUS=Nawiązuję połączenie
service.gui.INVITATION=Tekst zaproszenia
@@ -305,15 +295,12 @@ service.gui.INVITE_CONTACT_TO_CHAT=ZaproÅ› kontakty do czatu.
service.gui.INVITE_CONTACT_TO_CALL=ZaproÅ› kontakty do rozmowy.
service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=ZaproÅ› kontakty do mostu wideo
service.gui.INVITE_REASON=Powód zaproszenia
-service.gui.IS_CALLING=dzwoni...
+service.gui.IS_CALLING={0} dzwoni...
service.gui.IS_NOW={0} jest teraz {1}
-service.gui.JITSI_WARNING=SIP Communicator zmienił nazwę na Jitsi. <br/> Jeśli chcesz, aby Twoja wersja w dalszym ciągu była aktualizowana pobierz Jitsi teraz. <br/> Przepraszamy za wszelkie niedogodności. <br/> Jitsi dev Team
-service.gui.JITSI_WARNING_TITLE=SIP Communicator staje siÄ™ Jitsi
service.gui.JOIN=&Dołącz się
service.gui.JOIN_AS=D&ołącz się jako
service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=Dołącz do istniejącej konferencji wideo
service.gui.JOIN_VIDEO=Połącz z wideo
-service.gui.CLOSE_CHAT_ROOM_DIALOG=Z&amknij
service.gui.JOB_TITLE=Zawód
service.gui.JOIN_CHAT_ROOM=&Dołącz do kanału...
service.gui.JOIN_CHAT_ROOM_TITLE=Dołącz do kanału
@@ -326,28 +313,33 @@ service.gui.KICK_FAILED=Wyrzucenie nie powiodło się
service.gui.KICK_FAILED_GENERAL_ERROR=Wyrzucenie nie powiodło się {0}. Wystąpił ogólny błąd serwera.
service.gui.KICK_FAILED_NOT_ALLOWED=Wyrzucenie nie powiodło się {0}. Właściciel i administrator pokoju nie mogą zostać wyrzuceni.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Wyrzucenie nie powiodło się {0}. Nie masz wystarczających praw, by to zrobić.
-service.gui.LAST=Ostatni
service.gui.LAST_NAME=Nazwisko
service.gui.LEAVE=&Wyjdź
service.gui.LIMIT_REACHED_FOR_IP=Masz zbyt wiele istniejących połączeń z lokalnego adresu IP i serwer {0} nie pozwala na utworzenie kolejnych.
service.gui.LIST=Lista
service.gui.LOADING_ROOMS=Wczytuję kanały...
+service.gui.LOADING=Åadowanie...
+service.gui.LOCALLY_ON_HOLD_STATUS=Lokalnie zawieszone
+service.gui.LOGIN_NETWORK_ERROR=Nie można zalogować się na konto: Nazwa użytkownika: {0}, nazwa serwera: {1}, z powodu awarii sieci. Proszę sprawdzić swoje połączenie sieciowe.
service.gui.LOGIN_GENERAL_ERROR=Wystąpił błąd podczas logowania na konto: nazwa użytkownika: {0}, nazwa serwera: {1}:{2}.
+service.gui.LOGIN_INTERNAL_ERROR=Wystąpił błąd podczas logowania się na konto: Nazwa użytkownika: {0}, nazwa serwera: {1}. Jest to najprawdopodobniej wewnętrzny błąd aplikacji. Proszę zgłosić problem do naszych programistów (dev@jitsi.java.net).
+service.gui.LOGIN_INVALID_PROPERTIES_ERROR=Nie można zalogować się na konto: Nazwa użytkownika: {0}, nazwa serwera: {1}, ze względu na problem z konfiguracją konta. Proszę sprawdzić konfigurację swojego konta.
service.gui.LOGOFF_NOT_SUCCEEDED=Wystąpił błąd podczas wylogowywania z konta: nazwa użytkownika: {0}, nazwa serwera: {1}.
+service.gui.LOW_QUALITY=Niska jakość
service.gui.MEMBER=członek
+service.gui.MERGE_TO_CALL=Złącz wszystkie połączenia
service.gui.MESSAGE=Wiadomość
service.gui.MISSED_CALLS_TOOL_TIP=Nieodebrane rozmowy od:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= i {0} innych
service.gui.MODERATOR=moderator
-service.gui.MORE=Pokaż więcej
-service.gui.MORE_LABEL=PrzenieÅ›
+service.gui.MORE_LABEL=Więcej
service.gui.MOVE=PrzenieÅ›
service.gui.MOVE_SUBCONTACT=&PrzenieÅ› kontakt
service.gui.MOVE_SUBCONTACT_MSG=Zaznacz kontakt lub grupę, do których chcesz przenieść wybrany kontakt.
+service.gui.MOVE_SUBCONTACT_FAILED=Kontakt wybrany przez ciebie jest taki sam jak \n źródłowy. Proszę wybrać inny kontakt!
service.gui.MOVE_SUBCONTACT_QUESTION=Czy na pewno chcesz przenieść {0} do {1}?
service.gui.MOVE_TO_GROUP=&PrzenieÅ› do grupy
service.gui.MOVE_CONTACT=&PrzenieÅ› kontakt
-service.gui.MOVE_CONTACT_ERROR=&Kontakt nie może zostać przeniesiony
service.gui.MSG_DELIVERY_FAILURE=Powyższa wiadomość nie może być dostarczona
service.gui.MSG_DELIVERY_NOT_SUPPORTED=Protokół, którego używasz nie obsługuje wiadomości w trybie offline. Należy poczekać, aż {0} będzie znowu dostępny.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Wystąpił błąd wewnętrzny. Możesz pomóc go naprawić zgłaszając go tutaj http://jitsi.org/Developement/BugsAndIssues.
@@ -361,7 +353,6 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=Musisz mieć połączenie z siecią, że
service.gui.MULTIPLE_LOGINS=Jesteś zalogowany więcej niż jeden raz z tego samego konta. Użytkownik: {0}, serwer: {1} jest aktualnie odłączony.
service.gui.MY_CHAT_ROOMS=Dodaj pokój rozmów
service.gui.MY_CHAT_ROOMS_TITLE=Moje pokoje rozmów
-service.gui.MUTE=Wycisz
service.gui.MUTUALLY_ON_HOLD_STATUS=Obustronnie zawieś połączenie
service.gui.NAME=Nazwa
service.gui.NETWORK=Sieć
@@ -376,6 +367,10 @@ service.gui.NICKNAME=Nick:
service.gui.NO=Nie
service.gui.NONE=Brak
service.gui.NO_CAMERA_AVAILABLE=Brak dostępnej kamery
+service.gui.NO_DESKTOP_SHARING_FOR_PROTOCOL=Udostępnianie pulpitu nie jest obsługiwane przez ten protokół
+service.gui.NO_VIDEO_ENCODINGS=Brak kodeka wideo dla wybranej konfiguracji
+service.gui.NO_VIDEO_FOR_PROTOCOL=Wideo nie jest wspierane przez ten protokół
+service.gui.NO_AVAILABLE_ROOMS=Lista pokoi dla tego serwera nie jest aktualnie dostępna.
service.gui.NO_CONTACTS_FOUND=Nie znaleziono pasujących kontaktów. Naciśnij Ctrl+Enter, aby zadzwonić do {0} lub użyj poniższych przycisków.
service.gui.NO_CONTACTS_FOUND_SHORT=Nie znaleziono pasujących kontaktów.
service.gui.NO_MESSAGE=Brak wiadomości
@@ -384,7 +379,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=Spoza listy kontaktów
service.gui.SD_QUALITY=Standartowa jakość
service.gui.OFFLINE=Niedostępny
service.gui.OK=&OK
-service.gui.OLDER_CALLS=Starsze połączenia
service.gui.ONLINE=Dostępny
service.gui.OPEN=Otwórz
service.gui.OPEN_FILE_FROM_IMAGE=Podwójne kliknięcie otworzy plik.
@@ -396,30 +390,40 @@ service.gui.OPEN_ON_ACTIVITY=otwórz kiedy aktywny
service.gui.OPEN_ON_MESSAGE=Tylko dla wiadomości
service.gui.OPEN_ON_IMPORTANT_MESSAGE=Tylko dla ważnych wiadomości
service.gui.OR=lub
-service.gui.OR_ENTER_PHONE_NUMBER=Lub wprowadź tu number telefonu...
service.gui.ORGANIZATION=Organizacja
service.gui.OTHER=Inne
service.gui.chat.role.OWNER=Właściciel
service.gui.chat.role.ADMINISTRATOR=administrator
-service.gui.chat.role.MODERATOR=moderator
-service.gui.chat.role.MEMBER=członek
+service.gui.chat.role.MODERATOR=Moderator
+service.gui.chat.role.MEMBER=Członek
+service.gui.chat.role.GUEST=Gość
service.gui.OWNER=właściciel pokoju
service.gui.PASSWORD=Hasło
service.gui.PASSWORD_CHANGE_FAILURE=Zmiana hasła nie powiodła się
service.gui.PASSWORD_CHANGE_SUCCESS=Hasło główne zostało zmienione
service.gui.PASTE=&Wklej
+service.gui.PERSONAL=Osobiste
service.gui.PORT=Port
+service.gui.POSTAL_CODE=Kod pocztowy
service.gui.PREFERENCES=Ustawienia
+service.gui.PREFIX=Przedrostek
service.gui.PRESENCE=Dostępność
service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Enter' wyświetli propozycje
+service.gui.PRESS_FOR_CALL_INFO=Naciśnij aby uzyskać informację o połączeniu
service.gui.PREVIOUS=Poprzedni
-service.gui.PREVIOUS_TOOLTIP=Przeglądaj starsze połączenia
service.gui.PRINT=&Drukuj
service.gui.PROACTIVE_NOTIFICATION=pisze wiadomość
+service.gui.PROBLEMS_ENCOUNTERED=Napotkane problemy
service.gui.PROTOCOL=Protokół
+service.gui.PUT_OFF_HOLD=ZawieÅ›
+service.gui.PUT_ON_HOLD=ZawieÅ›
service.gui.QUIT=&Zakończ
service.gui.READY=Gotowe
+service.gui.RECENT_MESSAGES=Ostatnie konwersacje/rozmowy
service.gui.REASON=Powód
+service.gui.RECEIVED={0} otrzymał
+service.gui.RE_REQUEST_AUTHORIZATION=Ponownie poproÅ› o autoryzacjÄ™
+service.gui.REFERRED_STATUS=Odnosi siÄ™
service.gui.REJECT=&Odrzuć
service.gui.REMEMBER_PASSWORD=Zapamiętaj hasło
service.gui.REMOVE=&Usuń
@@ -427,28 +431,30 @@ service.gui.REMOVE_ACCOUNT=&Usuń konto
service.gui.REMOVE_ACCOUNT_MESSAGE=Czy na pewno chcesz usunąć to konto?
service.gui.REMOVE_CONTACT=&Usuń kontakt
service.gui.REMOVE_CONTACT_TEXT=<DIV>Czy na pewno chcesz usunąć <B> {0} </B><BR>z listy kontaktów?</DIV>
+service.gui.REMOVE_CONTACT_NOT_CONNECTED=Musisz być połączony w celu usunięcia tego kontaktu. Zaloguj się i spróbuj ponownie.
service.gui.REMOVE_GROUP=&Usuń grupę
+service.gui.REMOTELY_ON_HOLD_STATUS=Zdalnie zawieszony
service.gui.RENAME=&Zmień nazwę
service.gui.RENAME_CONTACT=&Zmień nazwę kontaktu
service.gui.RENAME_CONTACT_WIZARD=W poniższym polu wpisz nazwę, którą chcesz używać dla tego kontaktu.
service.gui.RENAME_GROUP=&Zmień nazwę grupy
service.gui.RENAME_GROUP_INFO=W poniższym polu wpisz nazwę, którą chcesz używać dla tej grupy.
+service.gui.RENAME_CLEAR_USER_DEFINED=Przywróć
+service.gui.RINGING_STATUS=Dzwoni
+service.gui.REQUEST=&Żądanie
+service.gui.REQUEST_AUTHORIZATION=&PoproÅ› o autoryzacjÄ™
service.gui.RETRY=Ponów
service.gui.SAVE=&Zapisz
service.gui.SEARCH=&Wyszukiwanie
+service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Kliknij przycisk poniżej, aby zobaczyć wszystkie czaty istniejące na wybranym serwerze. Następnie wybierz jeden do którego chcesz dołączyć i kliknij przycisk połącz.
+service.gui.SEARCH_STRING_CONTACT_SOURCE=Wyszukane kontakty
service.gui.SECURITY=Zabezpieczenia
-service.gui.SELECT_ACCOUNT=Wybierz konto
service.gui.SELECT_COLOR=Wybierz kolor
service.gui.SELECT_GROUP=Wybierz grupÄ™
-service.gui.SELECT_GROUP_WIZARD_MSG=Poniższa lista zawiera wszystkie grupy z twojej listy kontaktów. Wybierz tę, do której chcesz dodać nowy kontakt.
service.gui.SELECT_NO_GROUP=Brak grup
-service.gui.SELECT_GROUP_WIZARD=Określ grupę
-service.gui.SELECT_PROVIDERS_WIZARD=Wybierz konto
service.gui.SEND=&Wyślij
service.gui.SEND_FILE=Wyślij &plik
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Brak informacji o tym kontakcie.
service.gui.SEND_MESSAGE=&Wyślij wiadomość
-service.gui.SEND_AS_SMS=Wyślij jako SMS
service.gui.SEND_SMS=W&yślij SMS
service.gui.SEND_SMS_DETAILS=Pamiętaj, że należy wpisywać numery z kodem kraju; dla Polski +48 (np. +48777000000)
service.gui.SEND_SMS_NOT_SUPPORTED=Wybrany protokół nie obsługuje SMS-ów.
@@ -468,6 +474,11 @@ service.gui.TOOLS=Na&rzędzia
service.gui.TO=&Do:
service.gui.UNKNOWN=Nieznany użytkownik
service.gui.VIDEO_CALL=&Rozmowa wideo
+service.gui.VIEW=&Widok
+service.gui.VIEW_HISTORY=Pokaż &historię
+service.gui.VIEW_SMILEYS=Pokaz &buźki
+service.gui.VIEW_TOOLBAR=Pokaż &pasek narzedzi
+service.gui.VIEW_SIMPLE_CHAT_THEME=prosty motyw/widok czatu
service.gui.VOICEMAIL_NEW_OLD_RECEIVED={0} nowych i {1} starych wiadomości
service.gui.VOICEMAIL_NEW_RECEIVED={0} nowych wiadomości
service.gui.VOICEMAIL_OLD_RECEIVED={0} starych wiadomości
@@ -475,15 +486,12 @@ service.gui.VOICEMAIL_NO_MESSAGES=Brak wiadomości.
service.gui.VOLUME_CONTROL_TOOL_TIP=Reguluj głośność
service.gui.WARNING=Ostrzeżenie
service.gui.YES=Tak
-service.gui.YESTERDAY=Wczoraj
-service.gui.EXISTING_ACCOUNT_ERROR=Wybrane konto zostało już zainstalowane.
service.gui.ACTIVATE=WÅ‚Ä…cz
service.gui.DEACTIVATE=Wyłącz
service.gui.NEW=Nowa
service.gui.ENTER_FULL_SCREEN_TOOL_TIP=Włącz tryb pełnoekranowy
service.gui.EXIT_FULL_SCREEN_TOOL_TIP=Wyłącz tryb pełnoekranowy
service.gui.SHOW_LOCAL_VIDEO_BUTTON_TOOL_TIP=Pokaż/ukryj lokalne wideo
-service.gui.UPDATE=Aktualizuj
service.gui.VIDEO_PHONE=Wideo
service.gui.PHONE=Telefon
service.gui.PHONES=Telefony
@@ -502,10 +510,15 @@ service.gui.OCTOBER=PAŹ
service.gui.NOVEMBER=LIS
service.gui.DECEMBER=GRU
-service.gui.callinfo.VIEW_CERTIFICATE=Pokaż certyfikat
+service.gui.callinfo.VIEW_CERTIFICATE=Wyświetl certyfikat
service.gui.callinfo.MEDIA_STREAM_RTP=RTP
service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
+#enum values from IceProcessingState
+
+
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_O=Organizacja:
service.gui.CERT_INFO_C=Kraj:
service.gui.CERT_INFO_ST=Region:
@@ -518,11 +531,9 @@ service.gui.CERT_INFO_VER=Wersja:
service.gui.CERT_INFO_SIGN_ALG=Algorytm podpisu:
service.gui.CERT_INFO_ALG=Algorytm:
service.gui.CERT_INFO_PUB_KEY=Klucz publiczny:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} bajtów: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} bitów
service.gui.CERT_INFO_KEY_SIZE=Długość klucza:
service.gui.CERT_INFO_SIGN=Podpis:
-service.gui.CONTINUE=Kontynuuj
service.gui.SHOW_CERT=Pokaż certyfikat
service.gui.HIDE_CERT=Ukryj certyfikat
@@ -541,14 +552,9 @@ service.gui.avatar.imagepicker.IMAGE_PICKER=Obraz
service.gui.avatar.imagepicker.RESET=Resetuj
service.gui.avatar.imagepicker.SET=Ustaw
service.gui.avatar.imagepicker.TAKE_PHOTO=Zrób zdjęcie
-service.gui.avatar.imagepicker.WEBCAM_ERROR=BÅ‚Ä…d kamery internetowej
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
# systray
@@ -562,9 +568,7 @@ impl.gui.main.account.DUMMY_PROTOCOL_DESCRIPTION=wybierz sieć
# LDAP
impl.ldap.CONFIG_FORM_TITLE=Konfiguracja LDAP
impl.ldap.GENERAL=Ogólne
-impl.ldap.NEW=Nowy
impl.ldap.EDIT=edytuj
-impl.ldap.REMOVE=Usuń
impl.ldap.ENABLED=WÅ‚Ä…czony
impl.ldap.SERVER_NAME=Nazwa serwera
impl.ldap.SERVER_NAME_EXAMPLE=Mój serwer LDAP
@@ -580,6 +584,10 @@ impl.ldap.PASSWORD=Hasło
impl.ldap.MAIL_FIELD_EXAMPLE=E-mail:
impl.ldap.MAILSUFFIX_FIELD_EXAMPLE=@domena.org (nie zapomnij dodać '@')
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=Książka adresowa
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=Włącz wyszukiwanie w książce adresowej MacOSX
@@ -587,9 +595,7 @@ plugin.addrbook.ENABLE_MICROSOFT_OUTLOOK=WÅ‚Ä…cz wyszukiwanie Microsoft Outlook
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Kontakty Google
-impl.googlecontacts.NEW=Nowy
impl.googlecontacts.EDIT=edytuj
-impl.googlecontacts.REMOVE=Usuń
impl.googlecontacts.ENABLED=WÅ‚Ä…czony
impl.googlecontacts.ACCOUNT_NAME=Nazwa konta
impl.googlecontacts.SAVE=Zapisz
@@ -607,11 +613,12 @@ plugin.accountinfo.NICKNAME=Nick:
plugin.accountinfo.AGE=Wiek:
plugin.accountinfo.BDAY=Data urodzenia:
plugin.accountinfo.GENDER=Płeć:
+plugin.accountinfo.CITY=Miasto
+plugin.accountinfo.POST=Kod pocztowy
+plugin.accountinfo.COUNTRY=Kraj
plugin.accountinfo.EMAIL=E-mail:
plugin.accountinfo.PHONE=Telefon:
-plugin.accountinfo.USER_PICTURES=Zdjęcia użytkownika
-plugin.accountinfo.CHANGE=Zmień
-plugin.accountinfo.ONLY_MESSAGE=Tylko wiadomości
+plugin.accountinfo.JOB_TITLE=Zawód
# connection info
@@ -626,27 +633,11 @@ plugin.aimaccregwizz.USERNAME=Nazwa ekranowa AIM:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Nazwa użytkownika i hasło
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Zarejestruj nowe konto:
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Jeżeli nie masz konta AIM, kliknij ten przycisk, żeby je utworzyć.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Nie uwzględniaj domyślnych opcji serwera
# branding
plugin.branding.ABOUT_WINDOW_TITLE=O {0}
plugin.branding.ABOUT_MENU_ENTRY=&O programie
-# Dict protocol
-service.protocol.DICTIONARIES=SÅ‚owniki
-plugin.dictaccregwizz.ANY_DICTIONARY=Dowolny słownik
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Dowolny słownik z {0}
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=Protokół Dict
-plugin.dictaccregwizz.SERVER_INFO=Informacje o serwerze
-plugin.dictaccregwizz.STRATEGY_SELECTION=Wybór strategii
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Informacje o koncie Dict
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=Protokół czatu Facebook
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Nazwa użytkownika:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Nazwa użytkownika i hasło
# generalconfig
plugin.generalconfig.AUTO_START=Uruchom automatycznie {0} po uruchomieniu systemu
@@ -654,8 +645,6 @@ plugin.generalconfig.LOG_HISTORY=Zapisuj historię czatów
plugin.generalconfig.SHOW_HISTORY=Wyświetl
plugin.generalconfig.HISTORY_SIZE=ostatnich wiadomości w nowym czacie
plugin.generalconfig.SEND_MESSAGES_WITH=Wysyłaj wiadomości po naciśnięciu:
-plugin.generalconfig.TRANSPARENCY=Przezroczystość
-plugin.generalconfig.ENABLE_TRANSPARENCY=Włącz przezroczystość
plugin.generalconfig.DEFAULT_LANGUAGE=Język interfejsu
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Zmiany zostanÄ… zastosowane po ponownym uruchomieniu programu.
plugin.generalconfig.SIP_CLIENT_PORT=Port klienta SIP
@@ -686,11 +675,12 @@ plugin.ircaccregwizz.INFO_PASSWORD=Większość serwerów IRC nie wymaga hasła.
plugin.ircaccregwizz.USE_DEFAULT_PORT=Używaj domyślnego portu
plugin.ircaccregwizz.HOST=Nazwa hosta:
plugin.ircaccregwizz.IRC_SERVER=Serwer
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE=uwierzytelnianie {0}
+plugin.ircaccregwizz.SASL_USERNAME=Nazwa użytkownika
# jabber accregwizz
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=Protokół XMPP
plugin.jabberaccregwizz.PASSWORD_CONFIRM=Potwierdź hasło
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=Nazwa użytkownika i hasło
plugin.jabberaccregwizz.CSERVER=Serwer
plugin.jabberaccregwizz.NEW_ACCOUNT_TITLE=Rejestracja nowego konta XMPP
plugin.jabberaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Utwórz darmowe konto XMPP
@@ -699,13 +689,9 @@ plugin.jabberaccregwizz.CHOOSE=&Wybierz
plugin.jabberaccregwizz.SERVER_COLUMN=Serwer
plugin.jabberaccregwizz.COMMENT_COLUMN=Komentarz
plugin.jabberaccregwizz.PRIORITY=Priorytet
-plugin.jabberaccregwizz.XMPP_ERROR=BÅ‚Ä…d XMPP
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Nieznany błąd XMPP. Sprawdź, czy nazwa serwera jest poprawna.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Podane hasła nie są takie same.
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Przestaw domyślne opcje serwera
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Opcje zaawansowane
plugin.jabberaccregwizz.USE_ICE=Używaj ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=Używaj Google Jingle/ICE (funkcja eksperymentalna)
plugin.jabberaccregwizz.TURN_USERNAME=Nazwa użytkownika TURN
plugin.jabberaccregwizz.IP_ADDRESS=Adres IP
plugin.jabberaccregwizz.ADD_STUN_SERVER=Dodaj serwer STUN
@@ -716,29 +702,14 @@ plugin.jabberaccregwizz.NO_STUN_USERNAME=Wpisz ważną nazwę użytkownika serwe
plugin.jabberaccregwizz.JID_ADDRESS=Adres JID
plugin.jabberaccregwizz.USE_UPNP=Używaj UPnP
plugin.jabberaccregwizz.EXISTING_ACCOUNT=IstniejÄ…ce konto XMPP
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Potwierdź nowe hasło
plugin.jabberaccregwizz.ENCODINGS=Kodowania
plugin.jabberaccregwizz.AUDIO=Audio
plugin.jabberaccregwizz.VIDEO=Wideo
plugin.jabberaccregwizz.RESET=Resetuj
-# mailbox
-plugin.mailbox.OUTGOING=Wiadomość wychodząca:
-plugin.mailbox.INCOMING=Wiadomości przychodzące:
-plugin.mailbox.CONFIRM=Potwierdź
-plugin.mailbox.DEFAULTS=Domyślne
-plugin.mailbox.MAILBOX=Skrzynka pocztowa
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Protokół do połączeń i czatu w usłudze MSN.
-plugin.msnaccregwizz.USERNAME=E-mail:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=Nazwa użytkownika i hasło
-
# plugin manager
plugin.pluginmanager.INSTALL=Zainstaluj
plugin.pluginmanager.UNINSTALL=Odinstaluj
-plugin.pluginmanager.UPDATE=Aktualizuj
plugin.pluginmanager.PLUGINS=Wtyczki
plugin.pluginmanager.URL=URL
plugin.pluginmanager.CHOOSE_FILE=Wybierz plik
@@ -761,10 +732,8 @@ plugin.sipaccregwizz.REGISTRAR=Rejestrator
plugin.sipaccregwizz.SERVER_PORT=Port serwera
plugin.sipaccregwizz.PROXY=Serwer pośredniczący
plugin.sipaccregwizz.PROXY_PORT=Port serwera pośredniczącego
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Opcje zaawansowane
plugin.sipaccregwizz.PROXY_OPTIONS=Opcje serwera
plugin.sipaccregwizz.PROXY_AUTO=Konfiguruj pośrednika automatycznie
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Uchyl domyślne opcje serwera
plugin.sipaccregwizz.DISPLAY_NAME=Wyświetlana nazwa
plugin.sipaccregwizz.EXISTING_ACCOUNT=IstniejÄ…ce konto SIP
plugin.sipaccregwizz.CREATE_ACCOUNT=Utwórz darmowe konto SIP
@@ -773,6 +742,7 @@ plugin.sipaccregwizz.CLIST_TYPE=Typ
plugin.sipaccregwizz.XCAP_USER=Użytkownik
plugin.sipaccregwizz.XCAP_PASSWORD=Hasło
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Podane hasła nie są takie same.
+#used from SecurityPanel
# skin manager
plugin.skinmanager.SKINS=Skórki
@@ -780,13 +750,6 @@ plugin.skinmanager.DEFAULT_SKIN=Skórka domyślna
plugin.skinmanager.ADD_NEW_SKIN=Dodaj nową skórkę...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=Skórka domyślna programu.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=Protokół nawiązywania połączeń ze zdalnymi maszynami przez SSH.
-plugin.sshaccregwizz.USERNAME=Identyfikator konta:
-plugin.sshaccregwizz.OPTIONAL=Opcjonalny
-plugin.sshaccregwizz.ACCOUNT_DETAILS=Szczegóły konta
-
# status update
plugin.autoaway.AUTO_STATUS=Automatyczny status "nie ma mnie"
plugin.autoaway.ENABLE_CHANGE_STATUS=Zmień status, kiedy odejdę od komputera
@@ -825,21 +788,6 @@ plugin.whiteboard.DESELECT=Odznacz
plugin.whiteboard.DELETE=Usuń
plugin.whiteboard.PROPERTIES=Właściwości
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Protokół czatu w usłudze Yahoo.
-plugin.yahooaccregwizz.USERNAME=Nazwa użytkownika:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=Nazwa użytkownika i hasło
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=Protokół usługi Zeroconf (Bonjour)
-plugin.zeroaccregwizz.FIRST_NAME=ImiÄ™:
-plugin.zeroaccregwizz.LAST_NAME=Nazwisko:
-plugin.zeroaccregwizz.EMAIL=E-mail:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=Zapamiętać kontakty Bonjour?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=Nazwa użytkownika i hasło
-plugin.zeroaccregwizz.USERID=Nazwa użytkownika
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Protokół Google Talk
plugin.googletalkaccregwizz.USERNAME=Nazwa użytkownika Google Talk
@@ -852,18 +800,10 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, portal IP Telecommunicati
plugin.iptelaccregwizz.USERNAME=Nazwa użytkownika
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=Zarejestruj siÄ™ na iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIP i czat
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Nazwa użytkownika
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Wprowadź hasło ponownie
plugin.sip2sipaccregwizz.EMAIL=Adres e-mail
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=Informacje o tej usłudze pod adresem<br>http://wiki.sip2sip.info
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>Informacje o tej usłudze znajdziesz pod adresem <a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=IstniejÄ…ce konto sip2sip.info
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Utwórz konto sip2sip.info
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP && komunikator internetowy
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=Informacje o tej usłudze pod adresem<br>http://ippi.fr
@@ -872,6 +812,7 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=IstniejÄ…ce konto ippi
plugin.ippiaccregwizz.CREATE_ACCOUNT=Utwórz darmowe konto ippi
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Zamknij okno czatu
plugin.keybindings.CHAT_COPY=Kopiuj
plugin.keybindings.CHAT_CUT=Wytnij
@@ -887,6 +828,7 @@ plugin.keybindings.OPEN_HISTORY=Wyświetl historię
plugin.keybindings.OPEN_SMILIES=Pokaż emotikony
plugin.keybindings.globalchooser.SHORTCUT_NAME=Nazwa
plugin.keybindings.PLUGIN_NAME=Skróty klawiszowe
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Czat
plugin.keybindings.MAIN=Główne
@@ -902,6 +844,7 @@ plugin.notificationconfig.EXEC_PROG=Uruchom program:
plugin.notificationconfig.DISPLAY_POPUP=Wyświetl wiadomość w wyskakującym oknie
plugin.notificationconfig.POPUP_NOTIF_HANDLER=Typ wyskakujących powiadomień
plugin.notificationconfig.tableheader.EXECUTE=Uruchom program
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Połączenie przychodzące
plugin.notificationconfig.event.IncomingFile=Połączenie przychodzące
plugin.notificationconfig.event.IncomingMessage=Wiadomości przychodzące
@@ -950,6 +893,7 @@ impl.neomedia.configform.AUDIO=Audio
impl.neomedia.configform.VIDEO=Wideo
impl.neomedia.configform.H264=H.264
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.main=Główne
impl.neomedia.configform.H264.preferredKeyFrameRequester.rtcp=RTCP
@@ -974,7 +918,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=Obecne hasło:
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Wprowadź nowe hasło:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Wprowadź hasło ponownie:
plugin.securityconfig.masterpassword.MP_TITLE=Hasło główne
-plugin.securityconfig.masterpassword.MP_NOT_SET=(nieustawione)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=Nie wprowadzono poprawnego hasła głównego. Spróbuj ponownie.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=Hasło główne nie jest poprawne.
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Zmiana hasła nie powiodła się
@@ -988,7 +931,6 @@ plugin.securityconfig.masterpassword.COL_NAME=Nazwa
plugin.securityconfig.masterpassword.COL_PASSWORD=Hasło
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(nieznany)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(nie mogę rozszyfrować)
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=Usuń
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=Usuń wszystkie
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=Czy na pewno chcesz usunąć wszystkie hasła?
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=Usuń wszystkie hasła
@@ -1034,7 +976,6 @@ plugin.globalproxy.PROXY_ADDRESS=Serwer proxy
plugin.globalproxy.PROXY_PORT=Port proxy
plugin.globalproxy.PROXY_USERNAME=Login proxy
plugin.globalproxy.PROXY_PASSWORD=Hasło proxy
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>XMPP</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
# plugin reconnect
@@ -1077,10 +1018,9 @@ plugin.dnsconfig.PARALLEL_DNS=Równoległy DNS
plugin.dnsconfig.lblBackupResolver.text=Nazwa hosta
plugin.dnsconfig.lblBackupPort.text=Port
net.java.sip.communicator.util.dns.SecureResolveMode.IgnoreDnssec=Ignoruj
+net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.Deny=O&dmów
#plugin spellcheck
-plugin.spellcheck.LANG=Język
-plugin.spellcheck.EDIT_PERSONAL_DICT=Edycja
plugin.spellcheck.ENABLE_SPELL_CHECK=WÅ‚Ä…cz sprawdzanie pisowni
plugin.spellcheck.dialog.FIND=Znajdź następny
plugin.spellcheck.dialog.REPLACE=ZastÄ…p
diff --git a/resources/languages/resources_pt.properties b/resources/languages/resources_pt.properties
index 3f959e5..037763c 100644
--- a/resources/languages/resources_pt.properties
+++ b/resources/languages/resources_pt.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Eu
service.gui.ACCOUNT_REGISTRATION_WIZARD=Assistente de criação de contas
service.gui.ACCOUNTS=Contas
service.gui.ADD=&Adicionar
-service.gui.ADD_ACCOUNT=Adicionar conta
service.gui.ADD_CONTACT=&Adicionar contato
service.gui.ADD_AUTHORIZED_CONTACT=Adicionar {0} a sua lista de contatos
service.gui.ADD_CONTACT_TO_CONTACTLIST=Adicionar este contato à sua lista
@@ -42,20 +52,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Erro na adição do contato
service.gui.ADD_CONTACT_EXIST_ERROR=O contato {0} já existe na sua lista de contatos.
service.gui.ADD_CONTACT_NETWORK_ERROR=O servidor não respondeu ao seu pedido de adição de contato com o id: {0}.
service.gui.ADD_CONTACT_NOT_SUPPORTED=Falha ao adicionar o contato de ID: {0}. Operação não suportada.
-service.gui.ADD_CONTACT_IDENTIFIER=Insira no campo abaixo o identificador do contato que pretende adicionar.
-service.gui.ADD_CONTACT_WIZARD=Assistente para adicionar contato
service.gui.ADD_CONTACT_NOT_CONNECTED=Você precisa de estar conectado para poder adicionar um contacto. Por favor registre-se no provedor selecionado e tente novamente.
service.gui.ADD_GROUP_LOCAL_ERROR=Não foi possível adicionar o grupo com o nome: {0}. O problema ocorreu durante uma operação de IO local.
service.gui.ADD_GROUP_EXIST_ERROR=O grupo {0} já existe na sua lista de contatos. Escolha outro nome.
service.gui.ADD_GROUP_NET_ERROR=Não foi possível adicionar o grupo com o nome: {0}. O problema ocorreu devido a uma falha de rede. Por favor verifique a sua conexão de rede e tente de novo.
service.gui.ADD_GROUP_ERROR=Não foi possível adicionar o grupo com o nome: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=O nome do grupo não pode estar vazio.
-service.gui.ADD_GROUP=Criar grupo
-service.gui.ADD_SUBCONTACT=&Adicionar subcontato
service.gui.ADDRESS=Endereço
service.gui.ADMINISTRATOR=administrador
service.gui.ADVANCED=&Avançadas
-service.gui.ALL=&Todos
service.gui.ALL_CONTACTS=&Todos os contactos
service.gui.ALTERNATE_ADDRESS=Endereço alternativo
service.gui.APPLY=&Aplicar
@@ -65,7 +70,6 @@ service.gui.AT=em
service.gui.AUTHORIZE=&Autorizar
service.gui.AUTHORIZATION_ACCEPTED={0} rejeitou o seu pedido de autorização.
service.gui.AUTHENTICATION_FAILED=Falha na autenticação da conta para {0}. A senha utilizada é inválida.
-service.gui.AUTHENTICATION_REQUESTED=Pedido de autorização submetido
service.gui.AUTHENTICATION_REQUESTED_SERVER=O {0} servidor pede que se autentique.
service.gui.AUTHENTICATION_REJECTED={0} rejeitou o seu pedido de autorização.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} autenticação
@@ -107,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=No campo em baixo, pode inserir a sua nova alc
service.gui.CHANGE_NICKNAME_ERROR=Erro ao alterar a alcunha
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Nome já existe
service.gui.CHANGE_VIDEO_QUALITY=Mudar a qualidade do video remoto
-service.gui.CHAT_CONFERENCE_LABEL=Conferencias
service.gui.CHAT_CONFERENCE_ITEM_LABEL={0}''s conferencia
service.gui.CHAT_ROOM_ALREADY_JOINED=Já está participando na sala {0}.
service.gui.CHAT_ROOM_CONFIGURATION=configuração da sala {0}
@@ -121,18 +124,14 @@ service.gui.CHAT_ROOM_USER_LEFT={0} saiu da sala
service.gui.CHAT_ROOM_USER_KICKED={0} foi expulso da sala
service.gui.CHAT_ROOM_USER_QUIT={0} saiu da sala
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=O envio da mensagem foi negado (voz não permitida)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Salvar a sala de conversa para usos futuros
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Eliminar a sala de conversa selecionada da lista de salas salvas
service.gui.CHAT_ROOM_NAME=Nome da sala
service.gui.CLEAR_CUSTOM_MESSAGES=Limpar mensagens personalizadas
service.gui.ROOM_NAME=Sala de conversa
-service.gui.AUTOJOIN=Participar automaticamente
service.gui.CHANGE_PASSWORD=Mudar password
service.gui.CHAT_ROOM_NAME_INFO=Insira no campo abaixo o nome da sala que pretende criar.
service.gui.CHAT_ROOM_NOT_EXIST=A sala {0} não foi encontrada no servidor {1}. Por favor verifique se inseriu o nome correctamente.
service.gui.CHAT_ROOM_NOT_CONNECTED=Precisa estar ligado para poder entrar na sala {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Precisa estar ligado para poder sair de uma sala.
-service.gui.CHAT_ROOM_NOT_JOINED=Você tem de estar a participar numa sala para poder realizar operações sobre ela.
service.gui.CHAT_ROOM_OPTIONS=Opções da sala
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Precisa estar registado para poder entrar na sala {0}.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=A sala {0} necessita que insira uma palavra-passe.
@@ -150,22 +149,18 @@ service.gui.CLEAR=Limpar
service.gui.CLOSE=Fechar
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Você recebeu uma nova mensagem há menos de 2 segundos. Tem a certeza que deseja fechar esta conversa?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=Você tem transferências de ficheiros activas. Tem a certeza que as deseja cancelar?
-service.gui.CONFIRM=Confirmar
service.gui.CONNECTED_STATUS=Ligação estabelecida
service.gui.CONNECTING=Ligando-se...
service.gui.CONNECTING_STATUS=Ligando-se
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Conectando*
service.gui.CONNECTION=Ligação
-service.gui.CONNECTION_FAILED_MSG=A ligação falhou para a seguinte conta: Nome de utilizador: {0}, Nome do servidor: {1}. POr favor verifique a sua ligação de rede ou contacte o seu administrador de rede para mais informação.
service.gui.CONNECTION_EXPIRED_MSG=Você encontra-se de momento desligado do servidor {0}.
service.gui.CONTACT_NAME=ID ou número
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=O contacto {0} não suporta chamadas.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=O contacto {0} não suporta conferências de mensagens escritas.
service.gui.CONTACT_PAUSED_TYPING={0} parou de escrever a mensagem
service.gui.CONTACT_TYPING={0} está a escrever uma messagem
service.gui.CONTACT_TYPING_SEND_FAILED=hoooo... não conseguimos dizer se {0} está a escrever
service.gui.CONTACT_INFO=&Informação do contacto
-service.gui.CONTACTLIST=Lista de contato
service.gui.CONTACTS=Contactos
service.gui.COPY=&Copiar
service.gui.COPY_LINK=Copiar &hiperligação
@@ -175,17 +170,14 @@ service.gui.CREATE_CHAT_ROOM=&Criar sala de conversa...
service.gui.CREATE_CHAT_ROOM_ERROR=Falha na criação da sala com o nome: {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=Assistente de criação de sala
service.gui.CREATE_CONFERENCE_CALL=&Criar uma chamada com múltiplos participantes...
-service.gui.CREATE_CONFERENCE_CHAT=&Iniciar uma conversa com múltiplos participantes...
service.gui.CREATE_GROUP=&Criar grupo...
service.gui.CREATE_GROUP_NAME=Insira no campo abaixo o nome do grupo que pretende criar.
-service.gui.CREATE_FIRST_GROUP_WIZARD=A sua lista de contactos não contêm grupos. Por favor primeiro crie um grupo (Ficheiro/Criar grupo).
service.gui.CREATE_VIDEO_BRIDGE=Criar uma ligação de video...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Criar uma ligação de video
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Crie / Junte-se a uma videoconferencia
service.gui.CREATE_VIDEO_CONFERENCE=Crie uma nova videoconferencia para esta sala de conversa
service.gui.CONTACT_INFO_NOT_SUPPORTED=Este contacto não suporta informação de contacto via web
service.gui.CUT=C&ortar
-service.gui.DATE=Data
service.gui.DELETE=Apagar
service.gui.DENY=&Negar
service.gui.DESKTOP_SHARING_WARNING=<b>Tem a certeza que deseja iniciar o compartilhamento de tela?</b> <br> Clique em OK para as pessoas nesta conversa verem sua tela.
@@ -195,7 +187,6 @@ service.gui.DISCONNECTED_STATUS=Desconectado
service.gui.DND_STATUS=Não perturbar
service.gui.DO_NOT_ASK_AGAIN=Não pergunte de novo
service.gui.DO_NOT_SHOW_AGAIN=Não mostrar esta mensagem novamente
-service.gui.DOWNLOAD_NOW=&Baixar agora
service.gui.DRAG_FOR_SHARING=Arraste para aqui qualquer coisa que deseje partilhar...
service.gui.DURATION=duração
service.gui.DESTROY_CHATROOM=Destruir sala de conversação
@@ -216,7 +207,6 @@ service.gui.ERROR_RECEIVED_FROM=Erro recebido de {0}
service.gui.ESTIMATED_TIME=Tempo estimado:
service.gui.EVENTS=Eventos
service.gui.EXIT=S&air
-service.gui.EXTENDED_CRITERIA=Critérios alargados
service.gui.GENERAL=Geral
service.gui.GENERAL_ERROR=Erro geral
service.gui.GROUP_NAME=Nome do grupo
@@ -258,7 +248,6 @@ service.gui.FONT_ITALIC=Itálico
service.gui.FONT_SIZE=Tamanho
service.gui.FONT_STYLE=Estilo
service.gui.FONT_UNDERLINE=Sublinhado
-service.gui.FROM={0} de {1}
service.gui.GRANT_OWNERSHIP=Conceder a posse...
service.gui.GRANT_ADMIN=Conceder administrador...
service.gui.GRANT_MODERATOR=Conceder categoria de moderador
@@ -284,12 +273,12 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=Tem certeza que deseja remover permanente
service.gui.HISTORY_REMOVE_ERROR=Erro ao remover as mensagens armazenadas localmente.
service.gui.HOME=Casa
service.gui.HOME_PAGE=Página inicial
-service.gui.HOUR=Hora
service.gui.ICE=ICE
service.gui.IDENTIFIER=Identificador
service.gui.IGNORE=&Ignorar
service.gui.INSERT_SMILEY=Inserir smiley
service.gui.INCOMING_CALL=Chamadas recebidas de: {0}
+service.gui.INCOMING_SCREEN_SHARE=Chamadas recebidas de: {0}
service.gui.INCOMING_CALL_STATUS=Chamada recebida
service.gui.INSTANT_MESSAGINGS=IM's
service.gui.IM=IM
@@ -306,13 +295,10 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Convidar contactos para a videoconfer
service.gui.INVITE_REASON=Razão do convite
service.gui.IS_CALLING={0} está a chamar...
service.gui.IS_NOW={0} está {1}
-service.gui.JITSI_WARNING=O SIP Communicator foi recentemente renomeado para Jitsi.<br/>Se pretender manter a sua versão actualizada, faça o download do Jitsi agora.<br/><br/>Pedimos desculpa por qualquer inconveniente que possa causar-lhe.<br/><br/>A equipa de desenvolvimento do Jisti
-service.gui.JITSI_WARNING_TITLE=O SIP Comunicator tornou-se Jitsi
service.gui.JOIN=&Entrar
service.gui.JOIN_AS=E&ntrar como
service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=Associar-se a uma videoconferência existente
service.gui.JOIN_VIDEO=Juntar video
-service.gui.CLOSE_CHAT_ROOM_DIALOG=F&echar
service.gui.JOB_TITLE=Cargo
service.gui.JOIN_CHAT_ROOM=&Entrar no chat room...
service.gui.JOIN_CHAT_ROOM_TITLE=Entrar no chat room
@@ -325,7 +311,6 @@ service.gui.KICK_FAILED=Falha na expulsão
service.gui.KICK_FAILED_GENERAL_ERROR=Falha na expulsão {0}. Um erro geral do servidor ocorreu.
service.gui.KICK_FAILED_NOT_ALLOWED=Falha na expulsão {0}. Não foi possível expulsar o proprietário e o administrador da sala.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Falha na expulsão {0}. Voçê não tem previlégios para a operação desejada.
-service.gui.LAST=Último
service.gui.LAST_NAME=Apelido
service.gui.LEAVE=&Abandonar
service.gui.LIMIT_REACHED_FOR_IP=Você tem demasiados registos em uso a partir do mesmo endereço IP local, o {0} servidor não permite abrir mais registos.
@@ -345,7 +330,6 @@ service.gui.MESSAGE=Mensagem
service.gui.MISSED_CALLS_TOOL_TIP=Chamadas perdidas de:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= e {0} mais
service.gui.MODERATOR=moderador
-service.gui.MORE=Ver mais
service.gui.MORE_LABEL=Mais
service.gui.MOVE=Mover
service.gui.MOVE_SUBCONTACT=M&over contacto
@@ -354,7 +338,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=O contato que escolheu é o mesmo que o \n co
service.gui.MOVE_SUBCONTACT_QUESTION=Tem a certeza que pretende mover {0} para {1}?
service.gui.MOVE_TO_GROUP=&Mover para o grupo
service.gui.MOVE_CONTACT=M&over Subcontato
-service.gui.MOVE_CONTACT_ERROR=&Não é possível mover o contacto
service.gui.MSG_DELIVERY_FAILURE=Não foi possível entregar a mensagem acima
service.gui.MSG_DELIVERY_NOT_SUPPORTED=O protocolo que está a usar não suporta mensagens em offline. Pode tentar alcançar {0} usando outro protocolo ou esperar até que ele/ela fique disponível.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Um erro interno ocorreu. Isto é provavelmente um bug. Por favor informe em: https://jitsi.org/Development/BugsAndIssues.
@@ -368,7 +351,6 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=Necessita estar ligado para poder enviar
service.gui.MULTIPLE_LOGINS=Ligou mais de uma vez com a mesma conta. A conta seguinte: Nome de usuário: {0}, Nome do servidor: {1} encontra-se desligada de momento.
service.gui.MY_CHAT_ROOMS=Adicionar sala de conversação
service.gui.MY_CHAT_ROOMS_TITLE=Adicionar sala de conversação
-service.gui.MUTE=Silenciar
service.gui.MUTUALLY_ON_HOLD_STATUS=Ambos em espera
service.gui.NAME=Nome
service.gui.NETWORK=Rede
@@ -379,6 +361,7 @@ service.gui.NEW_MESSAGE=Nova mensagem
service.gui.NEW_NAME=Novo nome
service.gui.NEW_STATUS_MESSAGE=Nova mensagem de estado
service.gui.NEW_STATUS_MESSAGE_SAVE=Guardar como mensagem personalizada
+service.gui.NICKNAME=Alcunha
service.gui.NO=Não
service.gui.NONE=Nenhum
service.gui.NO_CAMERA_AVAILABLE=Nenhuma câmara disponivel
@@ -399,7 +382,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=Nao está na lista de contactos
service.gui.SD_QUALITY=Qualidade normal
service.gui.OFFLINE=Desligado
service.gui.OK=&OK
-service.gui.OLDER_CALLS=Chamadas antigas
service.gui.ONLINE=Ligado
service.gui.OPEN=Abrir
service.gui.OPEN_FILE_FROM_IMAGE=Duplo clique para abrir o ficheiro.
@@ -411,9 +393,12 @@ service.gui.OPEN_ON_ACTIVITY=Aberto em actividade
service.gui.OPEN_ON_MESSAGE=Aberto apenas com mensagem
service.gui.OPEN_ON_IMPORTANT_MESSAGE=Aberto apenas com mensagens importantes
service.gui.OR=ou
-service.gui.OR_ENTER_PHONE_NUMBER=Ou insira o número de telefone aqui...
service.gui.ORGANIZATION=Organização
service.gui.OTHER=Outro
+service.gui.chat.role.ADMINISTRATOR=administrador
+service.gui.chat.role.MODERATOR=moderador
+service.gui.chat.role.MEMBER=membro
+service.gui.chat.role.SILENT_MEMBER=membro silencioso
service.gui.OWNER=dono da sala
service.gui.ON_MOBILE_TOOLTIP=(no telemóvel)
service.gui.PASSWORD=Palavra-passe
@@ -430,7 +415,6 @@ service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Enter' para sugestões
service.gui.PRESS_FOR_CALL_INFO=Prima para informações de chamada
service.gui.PRESS_TO_OPEN_CRM=Prima para abrir a aplicação de CRM
service.gui.PREVIOUS=Anterior
-service.gui.PREVIOUS_TOOLTIP=Procure conversações antigas
service.gui.PRINT=&Imprimir
service.gui.PROACTIVE_NOTIFICATION=está escrevendo uma mensagem
service.gui.PROBLEMS_ENCOUNTERED=Encontrados problemas
@@ -446,7 +430,6 @@ service.gui.RECONNECTION_LIMIT_EXCEEDED=Voçê está ligando e religando-se ao s
service.gui.RE_REQUEST_AUTHORIZATION=Voltar a pedir autorização
service.gui.REFERRED_STATUS=Mencionados
service.gui.REJECT=&Rejeitar
-service.gui.REMIND_ME_LATER=Lembrar-me mais tarde
service.gui.REMEMBER_PASSWORD=Lembrar palavra-chave
service.gui.REMOVE=&Remover
service.gui.REMOVE_ACCOUNT=&Remover conta
@@ -472,29 +455,20 @@ service.gui.REVOKE_ADMIN=Retirar estado de administrador
service.gui.REVOKE_MODERATOR=Retirar estado de moderador
service.gui.REVOKE_MEMBERSHIP=Retirar estado de membro
service.gui.REVOKE_VOICE=Retirar voz
-service.gui.ROOT_GROUP=Grupo raiz
service.gui.SAVE=&Salvar
-service.gui.SAVE_AS_DEFAULT=Salvar como por defeito
service.gui.SEARCH=&Buscar
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Clique no botão de baixo para mostrar todos os chat rooms existentes no servidor selecionado. Depois escolha o chat room que pretende participar e clique no botão Entrar.
service.gui.SEARCH_STRING_CONTACT_SOURCE=Contacto procurado
service.gui.SECURITY=Segurança
-service.gui.SELECT_ACCOUNT=Escolher conta
service.gui.SELECT_COLOR=Escolher cor
service.gui.SELECT_GROUP=Escolher grupo
-service.gui.SELECT_GROUP_WIZARD_MSG=A lista abaixo contém todos os grupos a sua Lista de Contatos. Escolha um grupo aonde gostaria de adicionar o novo contato.
service.gui.SELECT_NO_GROUP=Sem grupo
-service.gui.SELECT_GROUP_WIZARD=Escolher grupo
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=A lista abaixo contém todas as contas que suportam a função de chat com múltiplos usuários. Selecione a lista que pretende usar para a criação do seu chat room.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=A lista abaixo contém todas as contas registadas. Selecione uma das listas que pretende usar para se comunicar com o novo contato.
-service.gui.SELECT_PROVIDERS_WIZARD=Selecionar conta
service.gui.SELECT_VIDEO_CONFERENCE=Seleccionar videoconferencia
service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Seleccione uma conversação da lista e pressione OK para a adicionar.
service.gui.SEND=&Enviar
service.gui.SEND_FILE=E&nviar ficheiro
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Não existe informação sobre este contato.
service.gui.SEND_MESSAGE=&Enviar uma mensagem
-service.gui.SEND_AS_SMS=Enviar como SMS
service.gui.SEND_PRIVATE_MESSAGE=Enviar uma mensagem privada
service.gui.SEND_SMS=Enviar SMS
service.gui.SEND_SMS_DETAILS=Lembre-se que tem de introduzir o numero no formato internacional; iniciar com +44 para UK; por exemplo: +447777000000
@@ -533,7 +507,6 @@ service.gui.STREET=Rua
service.gui.SUBJECT=Assunto
service.gui.SUMMARY=Sumário
service.gui.TELEPHONY=Telefonia
-service.gui.TODAY=Hoje
service.gui.TOOLS=&Ferramentas
service.gui.TRANSFER=Transferencia
service.gui.TO=&Para:
@@ -543,7 +516,6 @@ service.gui.TRANSFER_CALL_TO=Transferir para:
service.gui.TRANSPARENCY_NOT_ENABLED=Transparência não é suportada pela configuração actual.
service.gui.TYPE_YOUR_REQUEST=Escreva o seu pedido aqui
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Não fomos capazes de alterar a qualidade do vídeo para esta chamada.
-service.gui.UNMUTE=Ativar som
service.gui.USER_IDENTIFIER=Identificador do utilizador:
service.gui.USER_EXISTS_ERROR=Este utilizador já existe na rede seleccionada. Escolha outro utilizador ou outra rede.
service.gui.USERNAME_NULL=Preencha com o seu nome de utilizador e password.
@@ -556,7 +528,6 @@ service.gui.USE_PROVISIONING=Use provisionamento online
service.gui.VALUE=Valor
service.gui.VIDEO_CALL=&Chamada de vídeo
service.gui.VIA=via
-service.gui.VIA_SMS=Via SMS
service.gui.VIEW=&Visualizar
service.gui.VIEW_HISTORY=Mostrar &histórico
service.gui.VIEW_SMILEYS=Mostrar &smileys
@@ -576,9 +547,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=Ajustar o volume
service.gui.WAITING_AUTHORIZATION=A aguardar autorização
service.gui.WARNING=Aviso
service.gui.YES=Sim
-service.gui.YESTERDAY=Ontem
-service.gui.EXISTING_ACCOUNT_ERROR=A conta que introduziu já está instalada.
-service.gui.NEW_MAIL=<b>Tem novo Correio!</b><br/><b>De:</b> {0} {1} <br/><b>Assunto:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=Recebeu novo correio no seu {0} <a href="{1}">inbox</a>:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=Recebeu {2} novas mensagens na sua {0} <a href="{1}">inbox</a>:<br/>
service.gui.NEW_GMAIL_FOOTER=mais uma conversação por ler na sua <a href="{0}">inbox</a>.<br/>
@@ -602,7 +570,6 @@ service.gui.SECURITY_ERROR=Erro de segurança
service.gui.SPEED=Velocidade:
service.gui.SILENT_MEMBER=membro silencioso
service.gui.NON_SECURE_CONNECTION=Pode ser feira uma conexão não segura pela conta {0}. Se pretender conectar-se a um servidor não seguro, marque "Permitir conexão não segura" na sua configuração da conta
-service.gui.UPDATE=Actualizar
service.gui.MOBILE_PHONE=Telemóvel
service.gui.VIDEO_PHONE=Vídeo
service.gui.WORK_PHONE=Trabalho
@@ -637,12 +604,10 @@ service.gui.callinfo.CALL_INFORMATION=Informação de chamada
service.gui.callinfo.CALL_IDENTITY=Identidade
service.gui.callinfo.PEER_COUNT=Contador de participante
service.gui.callinfo.IS_CONFERENCE_FOCUS=Realçar conferencia
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Encriptação activa
service.gui.callinfo.CALL_TRANSPORT=Transporte da chamada de sinalização
service.gui.callinfo.CALL_DURATION=Duração da chamada
service.gui.callinfo.TLS_PROTOCOL=Protocolo TLS
service.gui.callinfo.TLS_CIPHER_SUITE=Arquivo de cifras do TLS
-service.gui.callinfo.TLS_SERVER_CERTIFICATE_CHAIN=Chave de certificação do servidor TLS
service.gui.callinfo.TLS_CERTIFICATE_CONTENT=O conteudo do certificado do servidor TLS é apresentado abaixo.
service.gui.callinfo.VIEW_CERTIFICATE=Mostrar certificado
service.gui.callinfo.CODEC=Codec / Frequencia
@@ -662,10 +627,13 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=Protocolo de troca de chaves
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=Candidado ICE de tipo extendido
service.gui.callinfo.ICE_STATE=Estado de Processamento ICE
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=Reunir candidatos
service.gui.callinfo.ICE_STATE.RUNNING=Verificações de ligação
service.gui.callinfo.ICE_STATE.COMPLETED=Terminado
service.gui.callinfo.ICE_STATE.FAILED=Falhou
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=Computador local IP / Porta
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=Reflexção local IP / Porta
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=Retransmissão local IP / Porta
@@ -686,9 +654,10 @@ service.gui.ALWAYS_TRUST=Sempre confiar neste certificado
service.gui.CERT_DIALOG_TITLE=Verificar Certificado
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} não foi possivel verificar a identidade do servidor durante a ligação a<br><b>{1}</b>.<br><br> O certificado não é confiavel, o quer quer dizer que a identidade do servidor não pode ser verificada automaticamente.<br><br> Deseja continuar com a ligação?<br> Para mais informações, clique em "Mostrar Certificado".</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0} não foi possivel verificar a identidade do certificado do servidor.<br><br> O certificado não é confiavel, o que quer dizer que a identidade do servidor não pode<br> ser verificada automaticamente. Deseja continuar com a ligação?<br><br> Para mais informações clique em "Mostrar Certificado".</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} não é possivel a identidade do cliente.<br><br> O certificado não é confiavel, o que quer dizer que a identidade do cliente não pode<br> ser verificada automaticamente. Deseja aceitar a ligação?<br><br> Para mais informação, clique em "Mostrar Certificado".</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} não é possiver verificar a identidade da origem {1}.<br><br> O certificado não é confiavel, o que quer dizer que a identidade da origem não pode ser <br> verificada automaticamente. Deseja prosseguir com a ligação?<br><br> Para mais informações, clique em "Mostrar Certificado".</html>
service.gui.CONTINUE_ANYWAY=Continuar na mesma
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Nome Comum:
service.gui.CERT_INFO_O=Organização:
service.gui.CERT_INFO_C=Nome do País:
@@ -705,12 +674,10 @@ service.gui.CERT_INFO_SIGN_ALG=Algoritmo usado para a assinatura:
service.gui.CERT_INFO_PUB_KEY_INFO=Informações de Chave Pública
service.gui.CERT_INFO_ALG=Algoritmo:
service.gui.CERT_INFO_PUB_KEY=Chave Publica:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} bytes: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} bits
service.gui.CERT_INFO_EXP=Expoente:
service.gui.CERT_INFO_KEY_SIZE=Tamanho da Chave:
service.gui.CERT_INFO_SIGN=Assinatura:
-service.gui.CONTINUE=Continuar
service.gui.SHOW_CERT=Mostrar Certificado
service.gui.HIDE_CERT=Esconder Certificado
@@ -733,12 +700,9 @@ service.gui.security.SECURE_AUDIO=Audio seguro
service.gui.security.AUDIO_NOT_SECURED=Audio não seguro
service.gui.security.SECURE_VIDEO=Video seguro
service.gui.security.VIDEO_NOT_SECURED=Video não seguro
-service.gui.security.NO_VIDEO=Sem video
-service.gui.security.CIPHER=Cifra: {0}
service.gui.security.CALL_SECURED_TOOLTIP=Chamada segura. Para mais informações carregue aqui.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Chamada não segura.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Prima aqui pata comparar a sua segurança com a do seu parceiro.
-service.gui.security.COMPARE_WITH_PARTNER=Verifique com o parceiro, e clique no cadeado para confirmar.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Comparar com o parceiro:
service.gui.security.STRING_COMPARED=String comparada!
@@ -756,20 +720,14 @@ service.gui.avatar.imagepicker.CLICK=Clique e Sorria
service.gui.avatar.imagepicker.IMAGE_FILES=Ficheiros de imagem
service.gui.avatar.imagepicker.IMAGE_PICKER=Imagem
service.gui.avatar.imagepicker.IMAGE_SIZE=Tamanho da imagem
-service.gui.avatar.imagepicker.INITIALIZING=Inicializando
service.gui.avatar.imagepicker.RESET=Repor
service.gui.avatar.imagepicker.SET=Definir
service.gui.avatar.imagepicker.TAKE_PHOTO=Tirar fotografia
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Erro da camara
service.gui.security.encryption.required=É requerida encriptação!
service.protocol.ICE_FAILED=Não foi possivel estabelecer ligação (Falha de ICE e encaminhamento não encontrado)
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
impl.protocol.sip.XCAP_ERROR_TITLE=Erro no arquivo de contactos SIP
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=O recurso não pode ser lido {0}. Para {1}
@@ -799,9 +757,7 @@ impl.ldap.QUERY_CUSTOM=Consulta personalizada
impl.ldap.QUERY_CUSTOM_HINT=Use {0} como um espaço reservado para o termo de pesquisa.
impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=Adicionar automaticamente expressoes para termos de procura
impl.ldap.QUERY_PHOTO_INLINE=Trazer foto juntamento com outros atributos.
-impl.ldap.NEW=Novo
impl.ldap.EDIT=editar
-impl.ldap.REMOVE=Remover
impl.ldap.ENABLED=Activo
impl.ldap.SERVER_NAME=Nome do servidor
impl.ldap.SERVER_NAME_EXAMPLE=Servidor LDAP
@@ -834,6 +790,10 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=telefoneCasa
impl.ldap.PHONE_PREFIX=Prefixo telefonico
impl.ldap.PHONE_PREFIX_EXAMPLE=Ex.: 00
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=Livro de endereços
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=Activar procura no Livro de Endereços do MacOSX
@@ -848,9 +808,7 @@ plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT=Definir o Outlook como cliente
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Contactos do Google
-impl.googlecontacts.NEW=Novo
impl.googlecontacts.EDIT=Alterar
-impl.googlecontacts.REMOVE=Remover
impl.googlecontacts.ENABLED=Activo
impl.googlecontacts.ACCOUNT_NAME=Nome da conta
impl.googlecontacts.SAVE=Salvar
@@ -869,6 +827,7 @@ plugin.accountinfo.DISPLAY_NAME=Mostrar nome:
plugin.accountinfo.FIRST_NAME=Nome Próprio:
plugin.accountinfo.MIDDLE_NAME=Nome do Meio:
plugin.accountinfo.LAST_NAME=Apelido:
+plugin.accountinfo.NICKNAME=Alcunha:
plugin.accountinfo.URL=URL:
plugin.accountinfo.AGE=Idade:
plugin.accountinfo.BDAY=Data de Nascimento:
@@ -888,11 +847,8 @@ plugin.accountinfo.ORGANIZATION=Nome da Organização
plugin.accountinfo.JOB_TITLE=Cargo:
plugin.accountinfo.ABOUT_ME=Acerca de mim:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
-plugin.accountinfo.USER_PICTURES=Imagens do utilizador
plugin.accountinfo.GLOBAL_ICON=Usar icone global
plugin.accountinfo.LOCAL_ICON=Usar este icone:
-plugin.accountinfo.CHANGE=Modificar
-plugin.accountinfo.ONLY_MESSAGE=Só mensagens
# connection info
plugin.connectioninfo.TITLE=Informações da Ligação
@@ -912,46 +868,11 @@ plugin.aimaccregwizz.USERNAME=Nome de utilizador do AIM:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Nome de usuário e senha
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Registrar nova conta
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Caso você não tenha uma conta AIM, clique neste botão para criar uma.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Substituir as opções predefinidas no servidor
# branding
plugin.branding.LOGO_MESSAGE=Open Source VoIP && Instant Messaging
-plugin.branding.LOADING=Carregando
plugin.branding.ABOUT_MENU_ENTRY=&Sobre
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>A {1} está actualmente em activo desenvolvimento. A versão que está a usar é apenas experimental e PODE NÃO FUNCIONAR como se espera. Contacte {2} para mais informação.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 Copyright <b>jitsi.org</b>. Todos os direitos reservados. Visite <a href="https://jitsi.org">https://jitsi.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}><b>Jitsi</b> é distribuido sob o termos LGPL (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=Dicionários
-plugin.dictaccregwizz.ANY_DICTIONARY=Qualquer Dicionario
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Qualquer Dicionario de {0}
-plugin.dictaccregwizz.FIRST_MATCH=Primeira equivalência
-plugin.dictaccregwizz.NO_MATCH=Nenhuma equivalência
-plugin.dictaccregwizz.MATCH_RESULT=Nenhumas definições encontradas para "{0}", talvez queira dizer:\n
-plugin.dictaccregwizz.INVALID_DATABASE=O dicionario actual "{0}" já não existe no servidor.
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=O protocolo do serviço AIM
-plugin.dictaccregwizz.HOST=Servidor
-plugin.dictaccregwizz.SERVER_INFO=Informações do servidor
-plugin.dictaccregwizz.STRATEGY_SELECTION=Seleccionar estrategia
-plugin.dictaccregwizz.STRATEGY_LIST=Lista de estrategias:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Procurar estrategias
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=A estrategia é usada para procurar palavras semelhantes, se a tradução não for encontrada, graças a diferentes abordagens. Por exemplo, as estratégias de prefixo irá procurar palavras que começam como a palavra que se traduziria.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Informação da conta Dict
-plugin.dictaccregwizz.FIRST_ACCOUNT=Este assistente ajuda-o a criar a sua primeira conta Dict em dict.org.\n\nPode adicionar um novo dicionario, indo ao Assistente de Registo de Conta. Preencha o campo de entrada com dicionário que gostaria de adicionar.
-plugin.dictaccregwizz.THREAD_CONNECT=A tentar ligar ao servidor
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=Tentativa de conexção falhada, não é um servidor dict ou o servidor não está acessivel.
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=A obter estrategias
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Não foram encontradas estratégias no servidor
-plugin.dictaccregwizz.POPULATE_LIST=Preenchendo a lista
-plugin.dictaccregwizz.CLOSING_CONNECTION=Fechando a conexão
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Para poder usar a Conversação por Facebook você precisa de criar um "Utilizador" <br> e ativar a Conversação a partir de Definições de Conta na página do Facebook.</a><br><br>Nota: Quando você cria um utilizador, você tem que fechar a sessão na página web <br> e pode demorar algum tempo até que possa entrar com o seu novo utilizador!</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=O protocolo de Conversação do Facebook
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Nome do usuário:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Nome do usuário e senha
+
# generalconfig
plugin.generalconfig.AUTO_START=Início automático {0} após o computador reiniciar
@@ -960,9 +881,6 @@ plugin.generalconfig.LOG_HISTORY=Gravar histórico das conversas
plugin.generalconfig.SHOW_HISTORY=Mostrar
plugin.generalconfig.HISTORY_SIZE=mensagens recentes em novas conversas
plugin.generalconfig.BRING_WINDOW_TO_FRONT=Trazer a janela de conversação para a frente
-plugin.generalconfig.ERROR_PERMISSION=Não tem previlegios suficientes para remover o arranque automatico
-plugin.generalconfig.TRANSPARENCY=Transparencia
-plugin.generalconfig.ENABLE_TRANSPARENCY=Activar transparencia
plugin.generalconfig.DEFAULT_LANGUAGE=Idioma da interface
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=As suas alterações terão efeito no proximo reinicio.
plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0}% traduzido
@@ -972,6 +890,7 @@ plugin.generalconfig.SIP_SSL_PROTOCOLS=Activar os protocolos SSL/TLS
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS=Converter letras em números de telefone
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS_EXAMPLE=Exemplo: +1-800-MEUNUMERO -> +1-800-638686376
plugin.generalconfig.SIP_CALL_CONFIG=SIP
+plugin.generalconfig.XMPP_CONFIG=XMPP
plugin.generalconfig.OPUS_CONFIG=Opus
plugin.generalconfig.OPUS_AUDIO_BANDWIDTH=Taxa de amostragem:
plugin.generalconfig.OPUS_BITRATE=Taxa media da codificação (kbps):
@@ -1000,6 +919,7 @@ plugin.icqaccregwizz.REGISTER_NEW_ACCOUNT=Registar uma conta nova
plugin.ircaccregwizz.PROTOCOL_NAME=IRC
plugin.ircaccregwizz.PROTOCOL_DESCRIPTION=Protocolo IRC.
plugin.ircaccregwizz.USERNAME_AND_PASSWORD=UIN e palavra-passe
+plugin.ircaccregwizz.USERNAME=Alcunha
plugin.ircaccregwizz.INFO_PASSWORD=A maioria dos servidores IRC não requerem password.
plugin.ircaccregwizz.AUTO_NICK_CHANGE=Alterar automaticamente a alcunha quando já estiver a ser usada
plugin.ircaccregwizz.USE_DEFAULT_PORT=Usar a porta predefinida
@@ -1007,13 +927,14 @@ plugin.ircaccregwizz.HOST=Nome da máquina:
plugin.ircaccregwizz.IRC_SERVER=Servidor
plugin.ircaccregwizz.EXAMPLE_SERVER=Exemplo: chat.freenode.net
plugin.ircaccregwizz.USE_SECURE_CONNECTION=Usar conexão segura
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE={0} autenticação
+plugin.ircaccregwizz.SASL_USERNAME=Nome do utilizador
# jabber accregwizz
plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=O protocolo XMPP
plugin.jabberaccregwizz.USERNAME=Nome de Usuário do XMPP
plugin.jabberaccregwizz.PASSWORD_CONFIRM=Confirmar senha
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=ID e Senha
plugin.jabberaccregwizz.CSERVER=Servidor
plugin.jabberaccregwizz.SERVER=Conectar ao Servidor
plugin.jabberaccregwizz.ENABLE_GMAIL_NOTIFICATIONS=Ativar notificações do Gmail para novas mensagens
@@ -1042,11 +963,8 @@ plugin.jabberaccregwizz.AUTO_DISCOVER_JN=Auto-descobrir retransmissões de Jingl
plugin.jabberaccregwizz.ADD_JINGLE_NODE=Adicionar Jingle Node
plugin.jabberaccregwizz.EDIT_JINGLE_NODE=Editar Jingle Node
plugin.jabberaccregwizz.JID_ADDRESS=Endereço JID
-plugin.jabberaccregwizz.NEW_PASSWORD=Nova senha
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Confirmar nova senha
plugin.jabberaccregwizz.PORT_FIELD_INVALID=Por favor, entre com um número de porta válida para continuar.
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=A conta tem que ser registrada antes de mudar a senha.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=A senha está vazia.
plugin.jabberaccregwizz.TLS_REQUIRED=A conexão não usa TLS, assim não tentará uma mudança de senha.
plugin.jabberaccregwizz.PASSWORD_CHANGED=A senha foi alterada com sucesso.
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=Seu servidor XMPP não suporte mudanças de senha
@@ -1055,21 +973,9 @@ plugin.jabberaccregwizz.VIDEO=Vídeo
plugin.jabberaccregwizz.RESET=Repor
plugin.jabberaccregwizz.DISABLE_JINGLE=Desativar Jingle (chamadas de áudio e vídeo com XMPP).
-# mailbox
-plugin.mailbox.CONFIRM=Confirmar
-plugin.mailbox.DEFAULTS=Padrões
-plugin.mailbox.MAILBOX=Caixa de Correio
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Um protocolo para conectar no serviço MSN.
-plugin.msnaccregwizz.USERNAME=E-mail:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=ID e Senha
-
# plugin manager
plugin.pluginmanager.INSTALL=Instalar
plugin.pluginmanager.UNINSTALL=Desinstalar
-plugin.pluginmanager.UPDATE=Actualizar
plugin.pluginmanager.PLUGINS=Plugins
plugin.pluginmanager.URL=URL
plugin.pluginmanager.NEW=Novo
@@ -1078,6 +984,8 @@ plugin.pluginmanager.NEW=Novo
plugin.simpleaccregwizz.LOGIN_USERNAME=Nome do utilizador
# sipaccregwizz
+plugin.sipaccregwizz.PROTOCOL_NAME=SIP
+plugin.sipaccregwizz.PROTOCOL_DESCRIPTION=O protocolo XMPP
plugin.sipaccregwizz.USERNAME=ID SIP
plugin.sipaccregwizz.USERNAME_AND_PASSWORD=Nome do usuário e senha
plugin.sipaccregwizz.CLIENT_CERTIFICATE=Certificado TLS do cliente
@@ -1086,7 +994,6 @@ plugin.sipaccregwizz.SERVER_PORT=Porta do Servidor
plugin.sipaccregwizz.PROXY=Proxy
plugin.sipaccregwizz.PROXY_PORT=Porta do proxy
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Transporte preferido
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Opções avançadas
plugin.sipaccregwizz.PROXY_OPTIONS=Opções de Proxy
plugin.sipaccregwizz.PROXY_AUTO=Configurar proxy automaticamente
plugin.sipaccregwizz.ENABLE_PRESENCE=Ativar presença (SIMPLES)
@@ -1101,17 +1008,15 @@ plugin.sipaccregwizz.KEEP_ALIVE_INTERVAL_INFO=Entre 1 e 3600 segundos
plugin.sipaccregwizz.DISPLAY_NAME=Mostrar o nome
plugin.sipaccregwizz.CREATE_ACCOUNT=Criar nova conta XMPP
plugin.sipaccregwizz.XCAP_PASSWORD=Palavra-passe
+#used from SecurityPanel
# skin manager
-# ssh accregwizz
-plugin.sshaccregwizz.USERNAME=Informação da Conta ID:
-plugin.sshaccregwizz.OPTIONAL=Configurar
-
# status update
# updatechecker
plugin.updatechecker.BUTTON_CLOSE=Fechar
+plugin.updatechecker.BUTTON_INSTALL=Instalar
# usersearch
@@ -1121,41 +1026,33 @@ plugin.whiteboard.COLOR=Cor
plugin.whiteboard.MODIFICATION=Notificações
plugin.whiteboard.DELETE=Apagar
-# yahoo accregwizz
-plugin.yahooaccregwizz.USERNAME=Nome do usuário:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=UIN e palavra-passe
-
-# zero accregwizz
-plugin.zeroaccregwizz.FIRST_NAME=Nome:
-plugin.zeroaccregwizz.LAST_NAME=Apelido:
-plugin.zeroaccregwizz.EMAIL=E-mail:
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=UIN e palavra-passe
-
# gtalk accregwizz
# iptel accregwizz
plugin.iptelaccregwizz.USERNAME=Nome do utilizador
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.USERNAME=Nome do utilizador
-
# ippi accregwizz
+plugin.sip2sipaccregwizz.USERNAME=Nome do utilizador
plugin.ippiaccregwizz.CREATE_ACCOUNT=Criar nova conta XMPP
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_COPY=Copiar
plugin.keybindings.CHAT_CUT=C&ortar
plugin.keybindings.CHAT_PASTE=Colar
plugin.keybindings.MAIN_RENAME=Re&nomear contato
plugin.keybindings.globalchooser.SHORTCUT_NAME=Nome
plugin.keybindings.PLUGIN_NAME=Teclas de atalho
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Conversar
# Notification Configuration Form
plugin.notificationconfig.ENABLE_NOTIF=Activo
plugin.notificationconfig.DESCRIPTION=Descrição
+plugin.notificationconfig.RESTORE=Restaurar padrões
plugin.notificationconfig.SOUND_FILE=Ficheiro de som:
plugin.notificationconfig.BROWSE_SOUND=Escolha um ficheiro de som
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Chamada recebida
plugin.notificationconfig.event.IncomingFile=Chamada recebida
plugin.notificationconfig.event.HangUp=Desligar
@@ -1173,9 +1070,11 @@ impl.media.security.zrtp.PUB_KEYS=Chaves publicas
impl.media.configform.AUDIO_NOTIFY=&Notificações:
impl.media.configform.VIDEO_RESOLUTION=Resolução do vídeo
+impl.media.configform.VIDEO_RESET=Restaurar padrões
impl.neomedia.configform.VIDEO=Vídeo
+#in JNIEncoder
impl.neomedia.configform.H264.preferredKeyFrameRequester.rtcp=RTP
# The callrecordingconfig plugin was never really committed into trunk and its
@@ -1193,7 +1092,6 @@ plugin.securityconfig.masterpassword.MP_CHANGE_SUCCESS_MSG=Alteração da passwo
plugin.securityconfig.masterpassword.MP_REMOVE_SUCCESS_MSG=Alteração da password com sucesso
plugin.securityconfig.masterpassword.COL_NAME=Nome
plugin.securityconfig.masterpassword.COL_PASSWORD=Palavra-passe
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=Remover
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=Remover todas as senhas
plugin.securityconfig.masterpassword.SHOW_PASSWORDS_BUTTON=Mostrar Senhas
plugin.securityconfig.masterpassword.HIDE_PASSWORDS_BUTTON=Esconder Senhas
@@ -1215,6 +1113,7 @@ plugin.otr.authbuddydialog.I_HAVE_NOT=Eu não tenho
plugin.otr.configform.MY_PRIVATE_KEYS=Minhas Chaves Privadas
plugin.otr.configform.GENERATE=Gerar
plugin.otr.configform.REGENERATE=Gerar novamente
+plugin.otr.configform.FINGERPRINT=Digitais
plugin.otr.configform.COLUMN_NAME_CONTACT=Contatos
plugin.otr.configform.COLUMN_NAME_VERIFIED_STATUS=Confirmado
plugin.otr.configform.COLUMN_VALUE_VERIFIED_TRUE=Sim
@@ -1257,7 +1156,7 @@ net.java.sip.communicator.util.dns.SecureResolveMode.IgnoreDnssec=Ignorar
net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.Deny=&Recusar
#plugin spellcheck
-plugin.spellcheck.EDIT_PERSONAL_DICT=Editar
+plugin.spellcheck.UNINSTALL_DICTIONARY=Desinstalar
#Certificate configuration plugin
diff --git a/resources/languages/resources_pt_BR.properties b/resources/languages/resources_pt_BR.properties
index 1769ea8..f8e335b 100644
--- a/resources/languages/resources_pt_BR.properties
+++ b/resources/languages/resources_pt_BR.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -29,42 +40,36 @@ service.gui.ABOUT=&Sobre
service.gui.ACCEPT=&Aceitar
service.gui.ACCOUNT=Conta
service.gui.ACCOUNT_ME=Eu
-service.gui.ACCOUNT_REGISTRATION_WIZARD=Utilitário para registro de contas
+service.gui.ACCOUNT_REGISTRATION_WIZARD=Assistente para registro de contas
service.gui.ACCOUNTS=Contas
service.gui.ADD=&Adicionar
-service.gui.ADD_ACCOUNT=Adicionar conta
service.gui.ADD_CONTACT=&Adicionar contato
service.gui.ADD_AUTHORIZED_CONTACT=Adicionar {0} à sua lista de contatos
-service.gui.ADD_CONTACT_TO_CONTACTLIST=Adicionar contato à sua lista de contatos
-service.gui.ADD_CONTACT_TO=&Adicionar contato
+service.gui.ADD_CONTACT_TO_CONTACTLIST=Adicionar o contato à sua lista de contatos
+service.gui.ADD_CONTACT_TO=&Adicionar contato para
service.gui.ADD_CONTACT_ERROR=Falha ao adicionar o contato com a id: {0}
service.gui.ADD_CONTACT_ERROR_TITLE=Erro ao adicionar contato
service.gui.ADD_CONTACT_EXIST_ERROR=O contato {0}, já está na sua lista de contatos.
service.gui.ADD_CONTACT_NETWORK_ERROR=O servidor não respondeu a sua requisição para adicionar o contato com a id: {0}.
service.gui.ADD_CONTACT_NOT_SUPPORTED=Falha ao adicionar contato com a id: {0}. Operação não suportada.
-service.gui.ADD_CONTACT_IDENTIFIER=Insira no campo abaixo a identificação do contato que você deseja adicionar.
-service.gui.ADD_CONTACT_WIZARD=Utilitário para adicionar contato
service.gui.ADD_CONTACT_NOT_CONNECTED=É preciso estar conectado para que seja possível adicionar um contato. Por favor, conecte-se ao serviço selecionado e tente novamente.
service.gui.ADD_GROUP_LOCAL_ERROR=Falha ao adicionar grupo com o nome: {0}. O problema ocorreu durante uma operação de E/S local.
service.gui.ADD_GROUP_EXIST_ERROR=O grupo {0} já existe na sua lista de contatos. Por favor escolha outro nome.
service.gui.ADD_GROUP_NET_ERROR=Falha ao adicionar grupo com o nome: {0}. O problema ocorreu devido a uma falha na rede. Por favor, verifique sua conexão com a rede e tente novamente.
service.gui.ADD_GROUP_ERROR=Falha ao adicionar grupo com o nome: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=O nome do grupo não pode ser deixado em branco.
-service.gui.ADD_GROUP=Criar grupo
-service.gui.ADD_SUBCONTACT=&Adicionar subcontato
service.gui.ADDRESS=Endereço
service.gui.ADMINISTRATOR=administrador
service.gui.ADVANCED=&Avançado
-service.gui.ALL=&Tudo
service.gui.ALL_CONTACTS=&Todos os contatos
service.gui.ALTERNATE_ADDRESS=Endereço alternativo
service.gui.APPLY=&Aplicar
service.gui.ARE_CALLING={0} estão chamando...
service.gui.ARE_NOW=Você agora é {0}
+service.gui.AT=em
service.gui.AUTHORIZE=&Autorizar
service.gui.AUTHORIZATION_ACCEPTED={0} aceitou o seu pedido de autorização.
service.gui.AUTHENTICATION_FAILED=A autenticação para {0} falhou. A senha inserida é inválida.
-service.gui.AUTHENTICATION_REQUESTED=Autenticação requisitada
service.gui.AUTHENTICATION_REQUESTED_SERVER=O servidor {0}, requisitou sua autenticação.
service.gui.AUTHENTICATION_REJECTED={0} rejeitou seu pedido de autorização.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} autenticação
@@ -106,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=Você pode inserir seu novo apelido no campo a
service.gui.CHANGE_NICKNAME_ERROR=Erro ao mudar o apelido
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Este apelido já existe
service.gui.CHANGE_VIDEO_QUALITY=Mudar a qualidade do vídeo remoto
-service.gui.CHAT_CONFERENCE_LABEL=Conferências
service.gui.CHAT_CONFERENCE_ITEM_LABEL=Conferência de {0}
service.gui.CHAT_ROOM_ALREADY_JOINED=Você já está na sala de conversação {0}.
service.gui.CHAT_ROOM_CONFIGURATION=Configuração da sala de conversação {0}
@@ -120,18 +124,14 @@ service.gui.CHAT_ROOM_USER_LEFT=saiu de {0}
service.gui.CHAT_ROOM_USER_KICKED=foi expulso de {0}
service.gui.CHAT_ROOM_USER_QUIT=saiu de {0}
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=Envio de mensagem proibido (fala revogada)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Salva a sala de conversação para uso futuro
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Remove a sala selecionada da lista de salas salvas
service.gui.CHAT_ROOM_NAME=Nome da sala de conversação
service.gui.CLEAR_CUSTOM_MESSAGES=Limpar mensagens personalizadas
service.gui.ROOM_NAME=Sala de conversação
-service.gui.AUTOJOIN=Entrar automaticamente
service.gui.CHANGE_PASSWORD=Alterar a senha
service.gui.CHAT_ROOM_NAME_INFO=Coloque o nome da nova sala de conversação no campo abaixo.
service.gui.CHAT_ROOM_NOT_EXIST=A sala {0} não foi encontrada no servidor {1}. Por favor verifique se o nome digitado está correto.
service.gui.CHAT_ROOM_NOT_CONNECTED=Você precisa estar logado para entrar na sala de conversação {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Você precisa estar conectado para poder deixar a sala de conversação.
-service.gui.CHAT_ROOM_NOT_JOINED=Você precisa entrar na sala de conversação para poder fazer alterações.
service.gui.CHAT_ROOM_OPTIONS=Opções de sala de conversação
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=A sala de conversação {0}, requer um registro para poder entrar.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=A sala de conversação {0} requisitou uma senha.
@@ -150,22 +150,20 @@ service.gui.CLEAR=Limpar
service.gui.CLOSE=F&echar
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Você recebeu uma nova mensagem a menos de 2 segundos. Você tem certeza que deseja fechar esta janela?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=Você tem transferências de arquivo ativas. Tem certeza que deseja cancelar elas?
-service.gui.CONFIRM=Confirmar
service.gui.CONNECTED_STATUS=Conectado
service.gui.CONNECTING=Conectando...
service.gui.CONNECTING_STATUS=Conectando
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Conectando*
service.gui.CONNECTION=Conexão
-service.gui.CONNECTION_FAILED_MSG=A conexão falhou para as seguintes contas: Nome de usuário: {0}, Nome do servidor: {1}. Por favor, verifique suas conexões de rede ou fale com o administrador para mais informações.
service.gui.CONNECTION_EXPIRED_MSG=Você está desconectado do servidor {0}, neste momento.
service.gui.CONTACT_NAME=ID ou número
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=O contato escolhido [(0)] não suporta telefonia.
+service.gui.CONTACT_NAME_PROMPT=joao.silva@exemplo.com
+service.gui.CONTACT_NAME_INFO=Adicione um endereço de mensageiro instantâneo (como joao.ninguem@exemplo.com) ou número VoIP
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=O usuário escolhido [{0}] não tem suporte para conversas em conferência.
service.gui.CONTACT_PAUSED_TYPING={0} parou de digitar a mensagem
service.gui.CONTACT_TYPING={0} está digitando uma mensagem
-service.gui.CONTACT_TYPING_SEND_FAILED=O-ou... Não foi possível informar à {0} que você estava digitando
-service.gui.CONTACT_INFO=Informação do &contato
-service.gui.CONTACTLIST=Lista de contatos
+service.gui.CONTACT_TYPING_SEND_FAILED=Ooops!... Não foi possível informar {0} que você estava digitando
+service.gui.CONTACT_INFO=Informações do &contato
service.gui.CONTACTS=Contatos
service.gui.COPY=&Copiar
service.gui.COPY_LINK=Copiar &endereço
@@ -175,34 +173,34 @@ service.gui.CREATE_CHAT_ROOM=&Criar sala de conversação...
service.gui.CREATE_CHAT_ROOM_ERROR=Falha ao criar a sala de conversação {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=Utilitário de sala de conversação
service.gui.CREATE_CONFERENCE_CALL=&Criar uma chamada em conferência...
-service.gui.CREATE_CONFERENCE_CHAT=&Criar uma conversa em conferência...
service.gui.CREATE_GROUP=&Criar grupo...
service.gui.CREATE_GROUP_NAME=No campo abaixo coloque o nome do grupo que deseja criar.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Sua lista de contatos não contém nenhum grupo. Por favor crie um grupo primeiro (Arquivo/Criar grupo).
service.gui.CREATE_VIDEO_BRIDGE=Criar uma ponte de &vídeo...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Criar uma ponte de &vídeo
-service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Criar ou entrar em uma conferência com vídeo
+service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Criar/entrar videoconferência
service.gui.CREATE_VIDEO_CONFERENCE=Criar uma nova conferência de vídeo para esta sala de conversação
service.gui.CONTACT_INFO_NOT_SUPPORTED=Este contato não suporta informações de contato da web
service.gui.CUT=&Recortar
-service.gui.DATE=Data
service.gui.DELETE=Excluir
service.gui.DENY=&Negar
service.gui.DESKTOP_SHARING_WARNING=<b>Você tem certeza que deseja iniciar o compartilhamento de área de trabalho?</b> <br> Clicar em OK permitirá que os participantes desta chamada vejam sua área de trabalho.
service.gui.DESKTOP_SHARING_DIALOG_INDICATE=Você está compartilhando sua tela
service.gui.DIALPAD=Discador
service.gui.DISPLAY_NAME=Exibir nome
+service.gui.DISPLAY_NAME_PROMPT=João Silva
+service.gui.DISPLAY_NAME_INFO=Dê um nome a este contato. Se deixado em branco será usado o endereço de MI ou número VoIP. (Opcional)
service.gui.DISCONNECTED_STATUS=Desconectado
service.gui.DND_STATUS=Não perturbe
service.gui.DO_NOT_ASK_AGAIN=Não perguntar novamente
service.gui.DO_NOT_SHOW_AGAIN=Não mostrar esta mensagem novamente
-service.gui.DOWNLOAD_NOW=&Transferir agora
service.gui.DRAG_FOR_SHARING=Arraste aqui tudo que deseja compartilhar...
service.gui.DURATION=duração
service.gui.DESTROY_CHATROOM=Destruir sala de conversação
service.gui.DESTROY_MESSAGE=Para informar outros participantes, por favor, entre uma razão e uma sala alternativa para entrarem.
service.gui.EDIT=&Editar
service.gui.EDITED_AT=editado em {0}
+service.gui.EMAIL=E-mail
+service.gui.EMAILS=E-mails
service.gui.EMPTY_HISTORY=&Histórico vazio
service.gui.ENABLE_DESKTOP_REMOTE_CONTROL=Ativar controle remoto da área de trabalho
service.gui.ENABLE_TYPING_NOTIFICATIONS=Informar aos outros quando estiver escrevendo uma mensagem (envia atividade da conversa)
@@ -215,12 +213,12 @@ service.gui.ERROR_RECEIVED_FROM=Erro recebido de {0}
service.gui.ESTIMATED_TIME=Tempo estimado:
service.gui.EVENTS=Eventos
service.gui.EXIT=&Sair
-service.gui.EXTENDED_CRITERIA=Critério estendido
service.gui.GENERAL=Geral
service.gui.GENERAL_ERROR=Erro genérico
service.gui.GROUP_NAME=Nome do grupo
service.gui.FAILED_STATUS=A chamada falhou
service.gui.FAILED_TO_JOIN_CHAT_ROOM=Falha ao entrar na sala de conversação com o nome: {0}.
+service.gui.FAX=Fax
service.gui.FFC_STATUS=Disponível para conversar
service.gui.FILE=&Arquivo
service.gui.FILE_WAITING_TO_ACCEPT=Aguardando aceitação de arquivo para {0}.
@@ -240,10 +238,13 @@ service.gui.FILE_TRANSFER_PREPARING=Preparando transferência de arquivo com {0}
service.gui.FILE_TRANSFER_REQUEST_RECIEVED={0} está compartilhando um arquivo com você.
service.gui.FILE_DOES_NOT_EXIST=O arquivo especificado não pode ser encontrado. Foi deletado ou movido.
service.gui.FILE_OPEN_FAILED=Falha ao abrir o arquivo. O arquivo pode ter sido excluído ou movido.
+service.gui.FILE_OPEN_NOT_SUPPORTED=Desculpe-nos, a operação com arquivo aberto não é suportada na plataforma atual
service.gui.FILE_OPEN_NO_PERMISSION=Você não tem permissões suficientes para abrir este arquivo. Por favor, verifique suas permissões de leitura e tente novamente.
service.gui.FILE_OPEN_NO_APPLICATION=Não foi possível encontrar um aplicativo associado a este tipo de arquivo.
service.gui.FINISH=&Finalizar
+service.gui.FOLDER_DOES_NOT_EXIST=A pasta contendo este arquivo não foi encontrada. Ou ela foi apagada ou foi movida.
service.gui.FOLDER_OPEN_FAILED=Falha ao abrir o diretório.
+service.gui.FOLDER_OPEN_NO_PERMISSION=Você não tem permissões suficientes para abrir este arquivo. Por favor verifique suas permissões de leitura e tente de novo.
service.gui.FOLDER_OPEN_NO_APPLICATION=Não foi possível encontrar um aplicativo para abrir este diretório.
service.gui.FONT=Fonte
service.gui.FONT_BOLD=Negrito
@@ -253,132 +254,621 @@ service.gui.FONT_ITALIC=Itálico
service.gui.FONT_SIZE=Tamanho
service.gui.FONT_STYLE=Estilo
service.gui.FONT_UNDERLINE=Sublinhar
-service.gui.FROM={0} de {1}
+service.gui.GRANT_OWNERSHIP=Conceder a posse...
+service.gui.GRANT_ADMIN=Dar permissão de administrador
+service.gui.GRANT_MODERATOR=Dar permissão de moderador
+service.gui.GRANT_MEMBERSHIP=Conceder ao membro participação
+service.gui.GRANT_VOICE=Conceder voz
service.gui.GUEST=visitante
service.gui.HANG_UP=Desligar
service.gui.HD_QUALITY=Vídeo HD
service.gui.HELP=Aj&uda
service.gui.HIDE=Ocultar
service.gui.HIDE_OFFLINE_CONTACTS=Ocultar contatos desconectados
+service.gui.HIDE_MAIN_WINDOW=<DIV>Clicando no botão da janela X não irá fechar o aplicativo, mas somente <BR> escondê-lo. Se você deseja sair do aplicativo, escolha Arquivo/Fechar.</DIV>
+service.gui.HISTORY=&Histórico
+service.gui.HISTORY_CONTACT=Histórico - {0}
service.gui.HISTORY_TOGGLE_PER_CONTACT=Desativar histórico para este contato
service.gui.HISTORY_TOGGLE_PER_CHATROOM=Desativar histórico para esta sala de conversação
service.gui.HISTORY_TOGGLE_ALL=Desativar histórico para todas as conversas e contatos
service.gui.HISTORY_ERASE_PER_CONTACT=Apagar todo o histórico para este contato
+service.gui.HISTORY_ERASE_PER_CHATROOM=Apagar todo o histórico desta sala de conversação
service.gui.HISTORY_ERASE_ALL=Apagar todo o histórico de conversação em {0}
+service.gui.HISTORY_REMOVE_PER_CONTACT_WARNING=Tem a certeza que deseja remover definitivamente todas as mensagens guardadas localmente para {0}?
+service.gui.HISTORY_REMOVE_ALL_WARNING=Tem certeza que deseja remover permanentemente todas as mensagens armazenadas localmente?
+service.gui.HISTORY_REMOVE_ERROR=Erro ao remover as mensagens armazenadas localmente.
+service.gui.HOME=Inicio
+service.gui.HOME_PAGE=Página Inicial
+service.gui.ICE=ICE
+service.gui.IDENTIFIER=Identificador
+service.gui.IGNORE=&Ignorar
service.gui.INSERT_SMILEY=Inserir emoticon
service.gui.INCOMING_CALL=Chamada recebida de: {0}
service.gui.INCOMING_SCREEN_SHARE=Compartilhamento de tela recebido de: {0}
+service.gui.INCOMING_CALL_STATUS=Recebendo chamada
+service.gui.INCOMING_SCREEN_SHARE_STATUS=Compartilhar a tela de entrada
+service.gui.INSTANT_MESSAGINGS=IM's
+service.gui.IM=IM
+service.gui.INITIATING_CALL_STATUS=Chamada inicializada
+service.gui.INVITATION=Texto de convite
+service.gui.INVITATION_RECEIVED=Convite recebido
service.gui.INVITATION_RECEIVED_MSG={0} convidou você para a sala de conversação {1}. Você pode aceitar, rejeitar ou ignorar este convite.
service.gui.INVITATION_REJECTED={0} rejeitou o seu convite para entrar na sala de conversação. Razão: {1}.
+service.gui.INVITE=&Convidar
service.gui.INVITE_CONTACT_MSG=Selecione os contatos que você gostaria de adicionar à esta conversa, e então clique Convidar.
+service.gui.INVITE_CONTACT_TO_CHAT=Convidar contato para chat
+service.gui.INVITE_CONTACT_TO_CALL=Convidar contactos para chamada
+service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Convide contatos para a videoconferência
service.gui.INVITE_REASON=Recebendo chamada de {0}...
service.gui.IS_CALLING={0} e está ligando...
service.gui.IS_NOW={0} é agora {1}
-service.gui.JITSI_WARNING=O SIP Communicator recentemente foi renomeado para Jitsi. <br/> Se você deseja que sua versão permaneça atualizada, por favor baixe o Jitsi agora.<br/><br/> Nos desculpamos por qualquer inconveniência que isso possa causar. <br/><br/> Grupo de desenvolvimento do Jitsi
+service.gui.JOIN=&Juntar
+service.gui.JOIN_AS=J&untar como
service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=Participar de uma vídeo conferência já existente
+service.gui.JOIN_VIDEO=Juntar video
+service.gui.JOB_TITLE=Cargo
+service.gui.JOIN_CHAT_ROOM=&Entrar na sala de bate-papo...
+service.gui.JOIN_CHAT_ROOM_TITLE=Entrar na sala de bate-papo
service.gui.JOIN_CHAT_ROOM_NAME=Por favor, digite o nome da sala de conversação que você gostaria de entrar.
+service.gui.JOIN_CHAT_ROOM_WIZARD=Assistente para entrar na sala de bate-papo
+service.gui.JOIN_AUTOMATICALLY=Entrar automáticamente
+service.gui.DONT_JOIN_AUTOMATICALLY=Não entrar automáticamente
+service.gui.KICK=&Expulsar
+service.gui.KICK_FAILED=Falha na expulsão
service.gui.KICK_FAILED_GENERAL_ERROR=Falha ao expulsar {0}. Ocorreu um erro genérico do servidor.
+service.gui.KICK_FAILED_NOT_ALLOWED=Falha na expulsão {0}. O proprietário e o administrador da sala não pode ser expulso.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Falha ao expulsar {0}. Você não tem privilégios suficientes para fazer isto.
+service.gui.LAST_NAME=Sobrenome
+service.gui.LEAVE=&Sair
+service.gui.LIMIT_REACHED_FOR_IP=Você tem muitos registos em uso do mesmo endereço IP local, o {0} servidor não permite abrir mais registos.
+service.gui.LIST=Lista
service.gui.LOADING_ROOMS=Carregando salas...
service.gui.LOADING=Carregando...
+service.gui.LOCALLY_ON_HOLD_STATUS=Chamada local em espera
+service.gui.LOGIN_NETWORK_ERROR=Impossível logar: Usuário: {0}, Nome do Servidor: {1}, devido a uma falha de rede. Verifique a conexão de rede.
+service.gui.LOGIN_GENERAL_ERROR=Um erro ocorreu enquanto tentava logar-se com a conta: Nome de usuário: {0}, Nome do servidor: {1}:{2}.
+service.gui.LOGIN_INTERNAL_ERROR=Ocorreu um erro quando se tentava logar com a conta: Usuário: {0}, Servidor: {1}. Isto deve-se provavelmente a um erro interno da aplicação. Reporte o problema a nossa equipe de desenvolvimento (dev@jitsi.java.net).
+service.gui.LOGIN_INVALID_PROPERTIES_ERROR=Impossível se conectar com a conta: Usuário: {0}, Servidor: {1}, devido a um erro de configuração. Por favor, verifique a configuração de sua conta.
+service.gui.LOGOFF_NOT_SUCCEEDED=Um erro ocorreu enquanto tentava se desconectar da conta: Nome do usuário: {0}, Nome do servidor: {1}.
service.gui.LOW_QUALITY=Baixa qualidade
service.gui.MEMBER=membro
+service.gui.MERGE_TO_CALL=Juntar todas as chamadas
+service.gui.MESSAGE=Mensagem
service.gui.MISSED_CALLS_TOOL_TIP=Chamadas perdidas de:
+service.gui.MISSED_CALLS_MORE_TOOL_TIP= e {0} mais
service.gui.MODERATOR=moderador
+service.gui.MORE_LABEL=Mais
+service.gui.MOVE=Mover
+service.gui.MOVE_SUBCONTACT=M&over contato
+service.gui.MOVE_SUBCONTACT_MSG=Selecione o contato ou o grupo onde você deseja mover o contato selecionado.
+service.gui.MOVE_SUBCONTACT_FAILED=O contato escolhido é o mesmo que \n o contato de origem. Por favor, escolha outro contato!
service.gui.MOVE_SUBCONTACT_QUESTION=Você tem certeza que deseja mover {0} para {1}?
service.gui.MOVE_TO_GROUP=&Mover para o grupo
+service.gui.MOVE_CONTACT=Mover Contato
+service.gui.MSG_DELIVERY_FAILURE=Não foi possível entregar a mensagem acima
+service.gui.MSG_DELIVERY_NOT_SUPPORTED=O protocolo que você está usando não suporta mensagens offline. Você pode tentar alcançar {0} através de outro protocolo ou aguardar até que ele/ela fique disponível.
+service.gui.MSG_DELIVERY_INTERNAL_ERROR=Um erro interno ocorreu. Isto é provavelmente um bug. Por favor informe em: https://jitsi.org/Development/BugsAndIssues.
+service.gui.MSG_DELIVERY_ERROR=Falhou ao enviar a mensagem.
+service.gui.MSG_DELIVERY_UNKNOWN_ERROR=Um erro desconhecido ocorreu durante o envio de sua mensagem.
+service.gui.MSG_DELIVERY_UNSUPPORTED_OPERATION=Operação não suportada.
+service.gui.MSG_NOT_DELIVERED=Ocorreu um problema de rede. Verifique a sua configuração de rede e tente novamente.
+service.gui.MSG_NOT_POSSIBLE=Mensagens não são possíveis para este contato (não é suportado pelo protocolo)
+service.gui.MSG_RECEIVED={0} escreveu
+service.gui.MSG_SEND_CONNECTION_PROBLEM=Você precisa estar conectado para poder enviar mensagens.
+service.gui.MULTIPLE_LOGINS=Você se conectou mais de uma vez com a mesma conta. A conta seguinte: Nome do Usuário: {0}, Nome do Servidor: {1} encontra-se desconectada no momento.
service.gui.MY_CHAT_ROOMS=Adicionar sala de conversação
service.gui.MY_CHAT_ROOMS_TITLE=Adicionar sala de conversação
+service.gui.MUTUALLY_ON_HOLD_STATUS=Ambos em espera
+service.gui.NAME=Nome
+service.gui.NETWORK=Rede
+service.gui.NETWORK_FAILURE=Falha de rede
+service.gui.NEXT=Pró&ximo
service.gui.NEW_ACCOUNT=Adicionar uma &nova conta...
+service.gui.NEW_MESSAGE=Nova mensagem
+service.gui.NEW_NAME=Novo nome
+service.gui.NEW_STATUS_MESSAGE=Nova mensagem de status
+service.gui.NEW_STATUS_MESSAGE_SAVE=Salvar como mensagem personalizada
+service.gui.NICKNAME=Apelido
+service.gui.NO=Não
+service.gui.NONE=Nenhum
service.gui.NO_CAMERA_AVAILABLE=Nenhuma câmera disponível
+service.gui.NO_DESKTOP_SHARING_FOR_PROTOCOL=Compartilhamento de tela não é suportado por este protocolo
+service.gui.NO_VIDEO_ENCODINGS=Nehuma codificação de vídeo foi selecionada na configuração.
+service.gui.NO_VIDEO_FOR_PROTOCOL=O vídeo não é suportado por este protocolo
+service.gui.NO_AVAILABLE_ROOMS=A lista de salas deste servidor não está disponível no momento.
+service.gui.NO_CONTACTS_FOUND=Não foram encontrados contatos. Pressione Ctrl+Enter para chamar {0} ou use os botões abaixo.
+service.gui.NO_CONTACTS_FOUND_SHORT=Não foram encontrados contatos.
+service.gui.NO_MESSAGE=Sem mensagem
+service.gui.NO_GROUP_CHAT_ACCOUNT_AVAILABLE=Não foi encontrada nenhuma conta que suporte conversações de múltiplos usuários. Consulte jitsi.org para mais informações sobre quais protocolos suportam conversações de múltiplos usuários.
+service.gui.NO_ONLINE_CONFERENCING_ACCOUNT=Nenhuma conta de conferência disponível. Consulte https://jitsi.org para mais informações sobre quais protocolos suportam conferências.
+service.gui.NO_ONLINE_TELEPHONY_ACCOUNT=É necessária pelo menos uma conta telefônica online conectada para fazer a chamada. Por favor conecte-se a uma de suas contas telefônicas e tente novamente.
+service.gui.NOT_AUTHORIZED=Não autorizado
+service.gui.NON_EMPTY_CHAT_WINDOW_CLOSE=Você está tentando fechar uma janela de conversação com uma mensagem não enviada. Tem certeza que quer fechar esta janela de conversação?
+service.gui.NON_EXISTING_USER_ID=O servidor {0} não reconhece o id de usuário especificado.
+service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=Não está na lista de contatos
+service.gui.SD_QUALITY=Qualidade normal
service.gui.OFFLINE=Desconectado
+service.gui.OK=&OK
service.gui.ONLINE=Disponível
+service.gui.OPEN=Abrir
+service.gui.OPEN_FILE_FROM_IMAGE=Duplo clique para abrir o arquivo.
+service.gui.OPEN_FOLDER=Abrir pasta
+service.gui.OPEN_IN_BROWSER=A&brir no navegador
service.gui.OPTIONS=Opções
+service.gui.OPEN_AUTOMATICALLY=Abrir esta sala automaticamente quando
+service.gui.OPEN_ON_ACTIVITY=Aberto em atividade
+service.gui.OPEN_ON_MESSAGE=Abrir somente com mensagem
+service.gui.OPEN_ON_IMPORTANT_MESSAGE=Abrir apenas com mensagens importantes
+service.gui.OR=ou
+service.gui.ORGANIZATION=Empresa
+service.gui.OTHER=Outro
+service.gui.chat.role.OWNER=Proprietário
service.gui.chat.role.ADMINISTRATOR=Administrador
service.gui.chat.role.MODERATOR=Moderador
service.gui.chat.role.MEMBER=Membro
+service.gui.chat.role.GUEST=Convidado
+service.gui.chat.role.SILENT_MEMBER=Silenciar membro
+service.gui.chat.role.OUTCAST=Proibido de entrar
+service.gui.OWNER=dono da sala
+service.gui.ON_MOBILE_TOOLTIP=(no celular)
+service.gui.PASSWORD=Senha
+service.gui.PASSWORD_CHANGE_FAILURE=A alteração de senha falhou
+service.gui.PASSWORD_CHANGE_SUCCESS=Senha alterada com sucesso
+service.gui.PASTE=&Colar
+service.gui.PERSONAL=Pessoal
+service.gui.PORT=Porta
+service.gui.POSTAL_CODE=Código postal
+service.gui.PREFERENCES=Preferências
+service.gui.PREFIX=Prefixo
+service.gui.PRESENCE=Presença
+service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Enter' para sugestões
service.gui.PRESS_FOR_CALL_INFO=Pressione para obter informações da chamada
+service.gui.PRESS_TO_OPEN_CRM=Clique para abrir aplicação de CRM
+service.gui.PREVIOUS=Anterior
+service.gui.PRINT=Im&primir
+service.gui.PROACTIVE_NOTIFICATION=está escrevendo uma mensagem
+service.gui.PROBLEMS_ENCOUNTERED=Problemas encontrados
+service.gui.PROTOCOL=Protocolo
+service.gui.PUT_OFF_HOLD=Cancelar espera
+service.gui.PUT_ON_HOLD=Colocar em espera
service.gui.QUIT=&Sair
+service.gui.READY=Pronto
+service.gui.RECENT_MESSAGES=Conversas recentes
+service.gui.REASON=Motivo
+service.gui.RECEIVED={0} recebido
+service.gui.RECONNECTION_LIMIT_EXCEEDED=Você está sendo conectado e desconectado do servidor muito rápido. A conta seguinte: Nome de usuário: {0}, Nome do servidor: {1} foi temporariamente banida e terá de esperar algum tempo antes de tentar conectar novamente.
+service.gui.RE_REQUEST_AUTHORIZATION=Pedir autorização novamente
+service.gui.REFERRED_STATUS=Mencionado
+service.gui.REJECT=&Rejeitar
+service.gui.REMEMBER_PASSWORD=Lembrar senha
+service.gui.REMOVE=&Remover
+service.gui.REMOVE_ACCOUNT=&Remover conta
+service.gui.REMOVE_ACCOUNT_MESSAGE=Tem certeza de que deseja remover esta conta?
+service.gui.REMOVE_CONTACT=&Remover contato
+service.gui.REMOVE_CONTACT_TEXT=<DIV>Tem certeza que pretende remover <B> {0} </B><BR>da sua lista de contatos?</DIV>
+service.gui.REMOVE_CONTACT_NOT_CONNECTED=Você precisa estar conectado para remover esse contato. Por favor acesse e tente novamente.
+service.gui.REMOVE_GROUP=&Remover grupo
+service.gui.REMOTELY_ON_HOLD_STATUS=Remotamente em espera
+service.gui.RENAME=&Renomear
+service.gui.RENAME_CONTACT=Re&nomear contato
+service.gui.RENAME_CONTACT_WIZARD=No campo abaixo você pode definir o nome que deseja usar para o contato.
+service.gui.RENAME_GROUP=Re&nomear grupo
+service.gui.RENAME_GROUP_INFO=No campo abaixo você pode definir o nome que deseja usar para o grupo.
+service.gui.RENAME_CLEAR_USER_DEFINED=Restaurar
+service.gui.RINGING_STATUS=Chamando
+service.gui.REQUEST=&Solicitar
+service.gui.REQUEST_AUTHORIZATION=Solicita&r autorização
+service.gui.REQUEST_AUTHORIZATION_MSG=Não foi possível adicionar {0} à sua lista de contatos. {0} terá de autorizar o seu pedido para o/a adicionar. Por favor informe seu pedido abaixo.
+service.gui.RETRY=Tentar novamente
+service.gui.REVOKE_OWNERSHIP=Revogar propriedade
+service.gui.REVOKE_ADMIN=Revogar privilégio de administração
+service.gui.REVOKE_MODERATOR=Revogar privilégio de moderador
+service.gui.REVOKE_MEMBERSHIP=Revogar participação
+service.gui.REVOKE_VOICE=Revogar voz
+service.gui.SAVE=&Salvar
+service.gui.SEARCH=Pe&squisar
+service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Clique no botão abaixo para mostrar todas as salas existentes no servidor selecionado. Depois escolha aquela que você deseja participar e clique no botão Entrar.
+service.gui.SEARCH_STRING_CONTACT_SOURCE=Contato pesquisado
service.gui.SECURITY=Segurança
+service.gui.SELECT_ACCOUNT_INFO=Qual conta deseja usar para se comunicar com este contato?
+service.gui.SELECT_COLOR=Selecionar cor
+service.gui.SELECT_GROUP=Selecionar grupo
+service.gui.SELECT_GROUP_INFO=Em qual grupo deseja incluir este contato? (Opcional)
+service.gui.SELECT_NO_GROUP=Sem grupo
+service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=A lista abaixo contém todas as contas que suportam o recurso de conversas com múltiplos usuários. Selecione aquela que vocês deseja utilizar para criar sua sala.
+service.gui.SELECT_VIDEO_CONFERENCE=Selecionar videoconferência
+service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Selecione sala da lista e pressione OK para adicioná-la.
+service.gui.SEND=&Enviar
+service.gui.SEND_FILE=Enviar &arquivo
service.gui.SEND_MESSAGE=&Enviar mensagem
+service.gui.SEND_PRIVATE_MESSAGE=Enviar mensagem privada
+service.gui.SEND_SMS=&Enviar SMS
+service.gui.SEND_SMS_DETAILS=Lembre-se que você tem de introduzir o número no formato internacional; iniciar com +55 para BR; por exemplo: +5521977770000
+service.gui.SEND_SMS_NOT_SUPPORTED=O protocolo que você selecionou não suporta mensagens SMS.
+service.gui.SMS=SMS
+service.gui.SEND_VIA=Enviar via
+service.gui.SENT=enviado
+service.gui.SERVER_CHAT_ROOMS=Salas do servidor
service.gui.SET_GLOBAL_STATUS=Definir estado global
+service.gui.SET_STATUS_MESSAGE=Definir mensagem de status
+service.gui.SET_SUBJECT=Definir assunto
service.gui.SETTINGS=&Opções
+service.gui.SHARE_DESKTOP=&Compartilhar a área de trabalho
+service.gui.SHARE_DESKTOP_WITH_CONTACT=Compartilhar área de trabalho com contato
+service.gui.SHARE_FULL_SCREEN=Compartilhar tela completa
+service.gui.SHARE_REGION=Compartilhar região
service.gui.SHOW=Mostrar
+service.gui.SHOW_CONTACT_LIST_TOOL_TIP=Clique aqui para fechar a visualização do histórico e mostrar a sua lista de contatos.
+service.gui.SHOW_MORE=exibir mais...
service.gui.SHOW_OFFLINE_CONTACTS=Mostrar contatos desconectados
+service.gui.SIGN_IN=Entrar
+service.gui.SMS_SUCCESSFULLY_SENT=Mensagem SMS enviada com sucesso!
+service.gui.SMS_SEND_CONNECTION_PROBLEM=Você tem que estar conectado antes de poder enviar mensagens SMS. Conecte-se primeiro ao ser provedor de SMS.
+service.gui.SPECIFY_REASON=No campo abaixo você pode definir o motivo desta operação.
+service.gui.SPECIFY_SERVER=Complete as informações do servidor da sua conta.
service.gui.SOUND_OFF=Desativar sons
service.gui.SOUND_ON=Ativar sons
+service.gui.START_SHARING=Iniciar compartilhamento
+service.gui.STATUS=Status
+service.gui.STATUS_CHANGED_CHAT_MESSAGE=tornou-se {0}
+service.gui.STATUS_CHANGE_GENERAL_ERROR=Falha na mudança de status da conta: Nome de usuário: {0}, Nome do servidor: {1}, devido a um erro geral.
+service.gui.STATUS_CHANGE_NETWORK_FAILURE=Falha na mudança de estado da conta: Nome de usuário: {0}, Nome do servidor: {1}, devido a um problema de rede.
+service.gui.STATUS_MESSAGE_INFO=Na linha abaixo pode indicar a nova mensagem que pretende usar.
+service.gui.STOP_SHARING=Interromper compartilhamento
+service.gui.STREET=Rua
+service.gui.SUBJECT=Assunto
+service.gui.SUMMARY=Resumo
+service.gui.TELEPHONY=Telefonia
service.gui.TOOLS=&Ferramentas
+service.gui.TRANSFER=Trans&ferência
+service.gui.TO=&Para:
+service.gui.TRANSFER_CALL_MSG=Selecione o nome do contato que você deseja transferir e depois clique em Transferir.
+service.gui.TRANSFER_CALL_TITLE=Transferir Chamada
+service.gui.TRANSFER_CALL_TO=Transferir para:
+service.gui.TRANSPARENCY_NOT_ENABLED=Transparência não é suportada por sua configuração atual.
+service.gui.TYPE_YOUR_REQUEST=Escreva o seu pedido aqui
+service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Não foi possível alterar a qualidade do vídeo para esta chamada.
+service.gui.USER_IDENTIFIER=Identificador de usuário:
+service.gui.USER_EXISTS_ERROR=Este usuário existe na rede selecionada. Escolha outro usuário ou outra rede.
+service.gui.USERNAME_NULL=Digite o seu nome de usuário e sua senha.
+service.gui.WEBPAGE=Abrir a página web
+service.gui.ACCOUNT_CREATION_FAILED=Não foi possível criar a sua conta devido ao erro: {0}
+service.gui.UNKNOWN=Usuário desconhecido
+service.gui.UNKNOWN_STATUS=Estado desconhecido
+service.gui.UNREGISTERED_MESSAGE=Não foi possível conectar à conta: Nome de usuário: {0}, Nome do servidor: {1}. Você está offline.
+service.gui.USE_PROVISIONING=Use provisionamento online
+service.gui.VALUE=Valor
+service.gui.VIDEO_CALL=Chamada de &vídeo
+service.gui.VIA=via
+service.gui.VIEW=&Visualizar
+service.gui.VIEW_HISTORY=Exibir &histórico
+service.gui.VIEW_SMILEYS=Exibir &smileys
service.gui.VIEW_TOOLBAR=Visualizar &barra de ferramentas
+service.gui.VIEW_SIMPLE_CHAT_THEME=Ver tema simples de janela de conversação
+service.gui.VOICEMAIL_NEW_URGENT_OLD_RECEIVED={0} nova(s) ({1} urgente(s)) e {2} antigas
+service.gui.VOICEMAIL_NEW_URGENT_RECEIVED={0} nova ({1} urgente) mensagens
+service.gui.VOICEMAIL_NEW_OLD_RECEIVED={0} novas e {1} mensagens antigas
+service.gui.VOICEMAIL_NEW_RECEIVED={0} mensagens novas
+service.gui.VOICEMAIL_OLD_RECEIVED={0} mensagens antigas
+service.gui.VOICEMAIL_NO_MESSAGES=Sem mensagens.
+service.gui.VOICEMAIL_TITLE=Mensagens de voz
+service.gui.VOICEMAIL_TOOLTIP=Mensagens de voz para:
+service.gui.VOICEMAIL_TIP=Clique no botão de chamada para ouvir suas mensagens.
+service.gui.VOICEMAIL_TIP_NO_ACCOUNT=Configure o URI para verificar o voicemail no assistente de conta
+service.gui.VOLUME_CONTROL_TOOL_TIP=Ajustar o volume
+service.gui.WAITING_AUTHORIZATION=Aguardando autorização
+service.gui.WARNING=Alerta
+service.gui.YES=Sim
+service.gui.NEW_GMAIL_HEADER=Você recebeu uma nova mensagem em sua {0} <a href="{1}">caixa de entrada</a>:<br/>
+service.gui.NEW_GMAIL_MANY_HEADER=Você recebeu {2} novas mensagens em sua {0} <a href="{1}">caixa de entrada</a>:<br/>
+service.gui.NEW_GMAIL_FOOTER=mais uma conversa não lida em sua <a href="{0}">caixa de entrada</a>.<br/>
+service.gui.NEW_GMAIL_MANY_FOOTER={1} mais conversas não lidas em sua <a href="{0}">caixa de entrada</a>.<br/>
+service.gui.ACTIVATE=Ativar
+service.gui.DEACTIVATE=Desativar
+service.gui.NEW=Novo
+service.gui.ENTER_FULL_SCREEN_TOOL_TIP=Mudar para tela cheia
+service.gui.EXIT_FULL_SCREEN_TOOL_TIP=Sair da tela cheia
+service.gui.HOLD_BUTTON_TOOL_TIP=Alternar espera
+service.gui.MUTE_BUTTON_TOOL_TIP=Alternar Mudo ou segure o botão para ajustar som do microfone
+service.gui.PARK=Em espera
+service.gui.PARKING_SLOT=Fila de espera
+service.gui.PARK_BUTTON_TOOL_TIP=Chamada em espera
+service.gui.RECORD_BUTTON_TOOL_TIP=Alternar Gravação
+service.gui.LOCAL_VIDEO_BUTTON_TOOL_TIP=Alternar Vídeo
service.gui.SHOW_LOCAL_VIDEO_BUTTON_TOOL_TIP=Mostrar/Esconder vídeo local
service.gui.SHOW_HIDE_PEERS_TOOL_TIP=Mostrar/Esconder lista de participantes da chamada
+service.gui.TRANSFER_BUTTON_TOOL_TIP=Transferir chamada
+service.gui.TRANSFER_TO=Transferir para...
service.gui.SECURITY_INFO=Informações de segurança
-service.gui.UPDATE=Atualizar
-
-
+service.gui.SECURITY_WARNING=Alerta de segurança
+service.gui.SECURITY_ERROR=Erro de segurança
+service.gui.SPEED=Velocidade:
+service.gui.SILENT_MEMBER=membro silencioso
+service.gui.NON_SECURE_CONNECTION=Não é possível estabelecer uma conexão segura para a conta {0}. Se você quer conectar através de um servidor não seguro, por favor marque "Permitir conexões não seguras" na configuração de sua conta
+service.gui.MOBILE_PHONE=Celular
+service.gui.VIDEO_PHONE=Vídeo
+service.gui.WORK_PHONE=Trabalho
+service.gui.PHONE=Telefone
+service.gui.PHONES=Telefones
+service.gui.EDIT_NOT_SUPPORTED=Edição desta conta não é suportada
+service.gui.SHOW_PREVIEW=(exibir visualização)
+service.gui.SHOW_PREVIEW_WARNING_DESCRIPTION=Pretende continuar com a visualização desta imagem?\n\nTenha em mente que ao ativar a visualização de Imagem/Vídeo pode comprometer o seu anonimato e expor a sua atividade na rede.
+service.gui.SHOW_PREVIEW_DIALOG_TITLE=Mostrar previsualização de Imagem/Video
+
+service.gui.ZID_NAME_SET=Nome do identificador ZRTP:
+service.gui.ZID_NAME_NOT_SET=O nome do identificador ZRTP não está definido.
+service.gui.ZID_NAME_BUTTON=Clique para definir o nome do identificador ZRTP.
+service.gui.ZID_NAME_DIALOG=Alterar nome do identificador ZRTP
+service.gui.ZID_NAME_UNEXPECTED=<html>As chaves ZRTP não coincidem.<br><b>Compare e verifique a string de autenticação entre os equipamentos envolvidos!</b><br>Altere as chaves ZRP e armazene-as somente se a string de autenticação coincidir.</html>
+
+service.gui.JANUARY=Jan
+service.gui.FEBRUARY=Fev
+service.gui.MARCH=Mar
+service.gui.APRIL=Abr
+service.gui.MAY=Mai
+service.gui.JUNE=Jun
+service.gui.JULY=Jul
+service.gui.AUGUST=Ago
+service.gui.SEPTEMBER=Set
+service.gui.OCTOBER=Out
+service.gui.NOVEMBER=Nov
+service.gui.DECEMBER=Dez
service.gui.callinfo.TECHNICAL_CALL_INFO=Informação técnica da chamada
service.gui.callinfo.CALL_INFORMATION=Informações da chamada
+service.gui.callinfo.CALL_IDENTITY=Identidade
+service.gui.callinfo.PEER_COUNT=Contador de participante
+service.gui.callinfo.IS_CONFERENCE_FOCUS=Foco na conferência
+service.gui.callinfo.CALL_TRANSPORT=Transporte da chamada de sinalização
+service.gui.callinfo.CALL_DURATION=Duração da chamada
+service.gui.callinfo.TLS_PROTOCOL=Protocolo TLS
+service.gui.callinfo.TLS_CIPHER_SUITE=Conjunto de cifras do TLS
+service.gui.callinfo.TLS_CERTIFICATE_CONTENT=O conteudo do certificado do servidor TLS é apresentado abaixo.
+service.gui.callinfo.VIEW_CERTIFICATE=Visualizar certificado
+service.gui.callinfo.CODEC=Codec / Frequencia
+service.gui.callinfo.NA=N.A.
+service.gui.callinfo.VIDEO_SIZE=Tamanho do vídeo
service.gui.callinfo.AUDIO_INFO=Informações do áudio
service.gui.callinfo.VIDEO_INFO=Informações do vídeo
-
+service.gui.callinfo.LOCAL_IP=IP / Porta Local
+service.gui.callinfo.REMOTE_IP=Porta / IP remoto
+service.gui.callinfo.BANDWITH=Largura de banda
+service.gui.callinfo.LOSS_RATE=Taxa de perda
+service.gui.callinfo.RTT=RTT
+service.gui.callinfo.JITTER=Jitter
+service.gui.callinfo.MEDIA_STREAM_TRANSPORT_PROTOCOL=Protocolo de transporte de streaming
+service.gui.callinfo.MEDIA_STREAM_RTP=RTP
+service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
+service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=Protocolo de troca de chaves
+service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=Tipo extendido de candidato ICE
+service.gui.callinfo.ICE_STATE=Estado de Processamento ICE
+
+#enum values from IceProcessingState
+service.gui.callinfo.ICE_STATE.WAITING=Reunir candidatos
+service.gui.callinfo.ICE_STATE.RUNNING=Verificação de conectividade
+service.gui.callinfo.ICE_STATE.COMPLETED=Concluído
+service.gui.callinfo.ICE_STATE.FAILED=Falhou
+
+service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=Computador local IP / Porta
+service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=Porta / IP reflexiva local
+service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=IP / Porta local retransmitida
+service.gui.callinfo.ICE_REMOTE_HOST_ADDRESS=IP / Porta do hospedeiro remoto
+service.gui.callinfo.ICE_REMOTE_REFLEXIVE_ADDRESS=IP / Porta reflexiva remota
+service.gui.callinfo.ICE_REMOTE_RELAYED_ADDRESS=IP / Porta remota retransmitida
+service.gui.callinfo.TOTAL_HARVESTING_TIME=Tempo total de captação
+service.gui.callinfo.HARVESTING_TIME=Tempo de captação
+service.gui.callinfo.HARVESTING_MS_FOR=ms (para
+service.gui.callinfo.HARVESTS=captações)
+service.gui.callinfo.DECODED_WITH_FEC=Pacotes decodificados com FEC
+service.gui.callinfo.DISCARDED_PERCENT=Pacotes atualmente sendo descartados
+service.gui.callinfo.DISCARDED_TOTAL=Número de pacotes descartados
+service.gui.callinfo.ADAPTIVE_JITTER_BUFFER=Buffer do jitter adaptativo
+service.gui.callinfo.JITTER_BUFFER_DELAY=Buffer de jitter
+
+service.gui.ALWAYS_TRUST=Sempre confiar neste certificado
+service.gui.CERT_DIALOG_TITLE=Verificar Certificado
+service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} não pode verificar a identidade do servidor durante a conexão a<br><b>{1}</b>.<br><br> O certificado não é confiável, o que significa que a identidade do servidor não pode ser verificada automaticamente.<br><br> Deseja conectar mesmo assim?<br> Para mais informações, clique em "Exibir Certificado".</html>
+service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0} não pode verificar a identidade do certificado do servidor.<br><br> O certificado não é confiável, o que significa que a identidade do servidor não pode<br> ser verificada automaticamente. Deseja continuar com a conexão?<br><br> Para mais informações clique em "Exibir Certificado".</html>
service.gui.CONTINUE_ANYWAY=Continuar assim mesmo
+service.gui.CERT_INFO_CHAIN=Cadeia de certificados:
+service.gui.CERT_INFO_ISSUED_TO=Emitido Por
+
+#service.gui.CERT_INFO_ are combined from Rdn names
+service.gui.CERT_INFO_CN=Nome comum (CN):
+service.gui.CERT_INFO_O=Organização:
+service.gui.CERT_INFO_C=Nome do País:
+service.gui.CERT_INFO_ST=Nome do Estado ou Província:
+service.gui.CERT_INFO_L=Nome da Localidade:
+service.gui.CERT_INFO_ISSUED_BY=Emitido Por
+service.gui.CERT_INFO_OU=Unidade Organizacional:
+service.gui.CERT_INFO_VALIDITY=Validade
+service.gui.CERT_INFO_ISSUED_ON=Data de emissão:
+service.gui.CERT_INFO_EXPIRES_ON=Expira Em:
+service.gui.CERT_INFO_FINGERPRINTS=Impressões digitais
service.gui.CERT_INFO_CERT_DETAILS=Informação do certificado
+service.gui.CERT_INFO_SER_NUM=Numero de Série:
+service.gui.CERT_INFO_VER=Versão:
+service.gui.CERT_INFO_SIGN_ALG=Algoritmo de assinatura:
service.gui.CERT_INFO_PUB_KEY_INFO=Informações da chave pública
-service.gui.CONTINUE=Continuar
+service.gui.CERT_INFO_ALG=Algoritmo:
+service.gui.CERT_INFO_PUB_KEY=Chave pública:
+service.gui.CERT_INFO_KEY_BITS_PRINT={0} bits
+service.gui.CERT_INFO_EXP=Expoente:
+service.gui.CERT_INFO_KEY_SIZE=Tamanho da chave:
+service.gui.CERT_INFO_SIGN=Assinatura:
+service.gui.SHOW_CERT=Mostrar Certificado
service.gui.HIDE_CERT=Ocultar certificado
service.gui.AUTO_ANSWER=Atendimento automático e transferência de chamadas
service.gui.AUTO_ANSWER_LABEL=Resposta automática
-
-service.gui.security.NO_VIDEO=Sem vídeo
+service.gui.AUTO_ANSWER_ALL_CALLS=Todas as chamadas
+service.gui.AUTO_ANSWER_ALERT_INFO_FIELDS=Somente chamadas que requeiram. (Aquelas contendo um campo "Informação-Alerta" definido para "Resposta Automática")
+service.gui.AUTO_ANSWER_CUSTOM_FIELDS=Chamadas com o seguinta campo e valor
+service.gui.AUTO_ANSWER_FIELD=Campo/Cabeçalho:
+service.gui.AUTO_ANSWER_VALUE=Valor:
+service.gui.AUTO_ANSWER_DESCR_VLUE=deixe vazio para qualquer
+service.gui.AUTO_ANSWER_FWD_CALLS=Encaminhar Chamadas
+service.gui.AUTO_ANSWER_FWD_CALLS_TO=Redirecionar todas as chamadas para o seguinte número ou URI:
+service.gui.AUTO_ANSWER_VIDEO=Vídeo
+service.gui.AUTO_ANSWER_VIDEO_CALLS_WITH_VIDEO=Responder chamadas de vídeo com vídeo
+service.gui.LOCAL_VIDEO_ERROR_TITLE=Erro no vídeo local
+service.gui.LOCAL_VIDEO_ERROR_MESSAGE=Não foi possível ativar/desativar o vídeo local.
+
+service.gui.security.SECURE_AUDIO=Ãudio seguro
+service.gui.security.AUDIO_NOT_SECURED=Ãudio inseguro
+service.gui.security.SECURE_VIDEO=Vídeo seguro
+service.gui.security.VIDEO_NOT_SECURED=Vídeo inseguro
service.gui.security.CALL_SECURED_TOOLTIP=Chamada segura. Para mais informações clique aqui.
+service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Clique aqui para comparar o seu código de segurança com o do outro participante.
# keep the following string short
-
+service.gui.security.COMPARE_WITH_PARTNER_SHORT=Comparar com o outro participante:
+service.gui.security.STRING_COMPARED=Código comparado!
+service.gui.security.SAS_INFO_TOOLTIP=<html>Para que tudo esteja seguro você<br/>precisa <b>comparar</b> verbalmente o pequeno <br/>código de autenticação exibido com o código<br/>do outro participante e clicar no botão confirmar quando o <br /> código for verificado.<br/><br/>Se você não confirmar, será solicitada a verificação<br/>na próxima vez que chamar este participante.</html>
+service.gui.security.SECURITY_ALERT=Tentanto uma chamada segura. Desconectará em
+
+service.gui.avatar.CHOOSE_ICON=Escolha uma imagem
+service.gui.avatar.REMOVE_ICON=Remover a imagem actual
+service.gui.avatar.CLEAR_RECENT=Limpar imagens recentes
+service.gui.avatar.RECENT_ICONS=Imagens recentes:
# service.gui.avatar.imagepicker
service.gui.avatar.imagepicker.CANCEL=Cancelar
+service.gui.avatar.imagepicker.CHOOSE_FILE=Escolher...
+service.gui.avatar.imagepicker.CLICK=Clique e Sorria
+service.gui.avatar.imagepicker.IMAGE_FILES=Arquivos de imagem
+service.gui.avatar.imagepicker.IMAGE_PICKER=Imagem
+service.gui.avatar.imagepicker.IMAGE_SIZE=Tamanho da imagem
+service.gui.avatar.imagepicker.RESET=Reiniciar
+service.gui.avatar.imagepicker.SET=Definir
+service.gui.avatar.imagepicker.TAKE_PHOTO=Tirar uma foto
+service.gui.security.encryption.required=Encriptação requerida!
+service.protocol.ICE_FAILED=Não foi possível estabelecer a conexão (ICE falhou e transmissão não encontrada)
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
+service.systray.MODE=Característica de exibição na bandeja do sistema
+service.systray.mode.NATIVE=Padrão
+service.systray.mode.DISABLED=Desabilitado
+service.systray.CLI_NOTE=Se sua escolha não funcionar, você pode iniciar {0} com o argumento "--notray". Isto força o modo para "Desabilitado" e mostra a interface gráfica ao usuário. Alterar a característica de exibição na bandeja do sistema requer reinicialização.
+impl.protocol.sip.XCAP_ERROR_TITLE=Erro no arquivo da lista de contatos SIP
+impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=O recurso não pode ser lido {0}. Para {1}
+impl.protocol.sip.XCAP_ERROR_UNAUTHORIZED=Usuário ou senha errados usando xcap. Para {0}.
# systray
+impl.systray.SET_STATUS=Definir estado
+impl.systray.FAILED_TO_OPEN_ADD_CONTACT_DIALOG=Falhou ao abrir janela "Adicionar Contato".
+impl.systray.POPUP_MESSAGE_HANDLER=Mensagens popup
+impl.swingnotification.POPUP_MESSAGE_HANDLER={0} popups
+impl.growlnotification.POPUP_MESSAGE_HANDLER=Notificações sonoras
+impl.galagonotification.POPUP_MESSAGE_HANDLER=Notificações do freedesktop.org no Ambiente de Trabalho
# New Account Dialog
+impl.gui.main.account.DEFAULT_PAGE_TITLE=Selecionar Rede
+impl.gui.main.account.DEFAULT_PAGE_BODY=Você pode usar a lista acima para selecionar a rede que deseja adicionar uma conta.
+impl.gui.main.account.DUMMY_PROTOCOL_NAME=selecione a rede
+impl.gui.main.account.DUMMY_PROTOCOL_DESCRIPTION=selecione a rede
# LDAP
+impl.ldap.CONFIG_FORM_TITLE=Configuração do LDAP
impl.ldap.GENERAL=Geral
+impl.ldap.FIELDS=Campos
+impl.ldap.QUERY=Consulta
+impl.ldap.QUERY_DEFAULT=Criar automaticamente
+impl.ldap.QUERY_CUSTOM=Consulta personalizada
+impl.ldap.QUERY_CUSTOM_HINT=Use {0} como um espaço reservado para o termo de busca.
+impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=Adicionar coringas automaticamente ao argumento de pesquisa
+impl.ldap.QUERY_PHOTO_INLINE=Trazer fotos junto com demais atributos
+impl.ldap.EDIT=editar
+impl.ldap.ENABLED=Habilitado
+impl.ldap.SERVER_NAME=Nome do servidor
+impl.ldap.SERVER_NAME_EXAMPLE=Meu servidor LDAP
+impl.ldap.SERVER_HOSTNAME=Nome da máquina
+impl.ldap.SERVER_EXIST=O servidor já existe, escolha um nome diferente
+impl.ldap.USE_SSL=Usar SSL
+impl.ldap.AUTH_NONE=Nenhum
+impl.ldap.AUTH_SIMPLE=Simples
+impl.ldap.SCOPE_SUB_TREE=Sub árvore
+impl.ldap.SCOPE_ONE=Um
+impl.ldap.SAVE=&Salvar
impl.ldap.CANCEL=Cancelar
+impl.ldap.SERVER_PORT=Porta
+impl.ldap.PASSWORD=Senha
+impl.ldap.MAILSUFFIX_FIELD_NAME=Campo(s) de sufixo de e-mail
+impl.ldap.WORKPHONE_FIELD_NAME=Campo(s) do telefone do trabalho
+impl.ldap.MOBILEPHONE_FIELD_NAME=Campo(s) do celular
+impl.ldap.HOMEPHONE_FIELD_NAME=Campo(s) do telefone de casa
+impl.ldap.MAIL_FIELD_EXAMPLE=e-mail
+impl.ldap.MAILSUFFIX_FIELD_EXAMPLE=@domain.org (não se esqueça de adicionar '@')
+impl.ldap.WORKPHONE_FIELD_EXAMPLE=telefoneEmpresa
+impl.ldap.MOBILEPHONE_FIELD_EXAMPLE=celularEmpresa
+impl.ldap.HOMEPHONE_FIELD_EXAMPLE=telefoneCasa
+impl.ldap.PHONE_PREFIX=Prefixo do telefone:
+
+# SIP Protocol
+
+#Jabber Protocol
# Address book plugin
+plugin.addrbook.OUTLOOK_IS_NOT_DEFAULT_MAIL_CLIENT_TITLE=Erro ao acessar seus contatos do Microsoft Outlook.
+plugin.addrbook.OUTLOOK_IS_NOT_DEFAULT_MAIL_CLIENT={0} não é possível acessar os contatos do Microsoft Outlook neste momento porque o Outlook não está definido como a aplicação padrão de e-mail.
+plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT=Definir o Outlook como cliente de e-mail padrão
# Google Contacts
+impl.googlecontacts.CONFIG_FORM_TITLE=Contatos do Google
+impl.googlecontacts.EDIT=editar
+impl.googlecontacts.ENABLED=Habilitado
+impl.googlecontacts.ACCOUNT_NAME=Nome da conta
+impl.googlecontacts.SAVE=&Salvar
impl.googlecontacts.CANCEL=Cancelar
+impl.googlecontacts.USERNAME=Nome da conta
+impl.googlecontacts.PASSWORD=Senha
+impl.googlecontacts.PREFIX=Prefixo do telefone:
# account info
plugin.accountinfo.TITLE=Informações da conta
+plugin.accountinfo.DISPLAY_NAME=Exibir nome
+plugin.accountinfo.FIRST_NAME=Primeiro nome:
+plugin.accountinfo.MIDDLE_NAME=Nome do meio:
+plugin.accountinfo.LAST_NAME=Último nome:
+plugin.accountinfo.NICKNAME=Apelido:
+plugin.accountinfo.URL=URL:
+plugin.accountinfo.AGE=Idade:
+plugin.accountinfo.BDAY=Data de nascimento:
+plugin.accountinfo.BDAY_FORMAT=MMM dd, yyyy
+plugin.accountinfo.GENDER=Sexo:
plugin.accountinfo.CITY=Cidade:
+plugin.accountinfo.POST=Código postal
+plugin.accountinfo.COUNTRY=País
+plugin.accountinfo.EMAIL=E-mail
+plugin.accountinfo.PHONE=Telefone
+plugin.accountinfo.MOBILE_PHONE=celularEmpresa
+plugin.accountinfo.ORGANIZATION=Nome da organização:
+plugin.accountinfo.JOB_TITLE=Função:
+plugin.accountinfo.ABOUT_ME=Sobre mim:
+plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
+plugin.accountinfo.GLOBAL_ICON=Usar icone global
+plugin.accountinfo.LOCAL_ICON=Usar este ícone:
# connection info
plugin.connectioninfo.TITLE=Informações da conexão
# contact info
+plugin.contactinfo.USER_PICTURES=Imagens do usuário
# aimaccregwizz
+plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Nome do usuário e senha
+plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Registrar nova conta
# branding
+plugin.branding.ABOUT_WINDOW_TITLE=Sobre {0}
+plugin.branding.LOGO_MESSAGE=VoIP de código aberto && Mensageiro Instantâneo
plugin.branding.ABOUT_MENU_ENTRY=&Sobre
-# Dict protocol
-plugin.dictaccregwizz.SERVER_INFO=Informações do servidor
-
-# facebookaccregwizz
# generalconfig
plugin.generalconfig.GROUP_CHAT_MESSAGES=Agrupar conversas em uma janela
plugin.generalconfig.LOG_HISTORY=Salvar histórico das conversas
+plugin.generalconfig.SHOW_HISTORY=Mostrar
plugin.generalconfig.HISTORY_SIZE=mensagens recentes em novas janelas de conversação
plugin.generalconfig.SEND_MESSAGES_WITH=Enviar mensagens utilizando:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=Trazer a janela de conversação para a frente
@@ -389,13 +879,17 @@ plugin.generalconfig.LEAVE_CHATROOM_ON_WINDOW_CLOSE=Deixar salas de conversaçã
plugin.generalconfig.SHOW_RECENT_MESSAGES=Mostrar conversas recentes (o histórico precisa estar habilitado)
plugin.generalconfig.REMOVE_SPECIAL_PHONE_SYMBOLS=Remover caracteres especiais antes de chamar números telefônicos
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS=Converter letras em número telefônico
-plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS_EXAMPLE=ex.: +1-800-CASA -> +1-800-123456
+plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS_EXAMPLE=Exemplo: 0800-MEUNUMERO-> 0800-638686376
# gibberish accregwizz
# icqaccregwizz
+plugin.icqaccregwizz.REGISTER_NEW_ACCOUNT=Registrar nova conta
# irc accregwizz
+plugin.ircaccregwizz.USERNAME=Apelido
+plugin.ircaccregwizz.HOST=Nome da máquina
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE={0} autenticação
# jabber accregwizz
plugin.jabberaccregwizz.NO_STUN_ADDRESS=Por favor insira um endereço de servidor STUN válido para poder continuar.
@@ -406,23 +900,24 @@ plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=Seu servidor XMPP nã
plugin.jabberaccregwizz.PASSWORD_NOT_STORED=A senha foi alterada no servidor, mas a configuração local não foi atualizada
plugin.jabberaccregwizz.ENCODINGS=Codificadores
plugin.jabberaccregwizz.AUDIO=Ãudio
-
-# mailbox
-
-# msn accregwizz
+plugin.jabberaccregwizz.VIDEO=Vídeo
+plugin.jabberaccregwizz.RESET=Reiniciar
# plugin manager
-plugin.pluginmanager.UPDATE=Atualizar
+plugin.pluginmanager.UNINSTALL=Desinstalar
+plugin.pluginmanager.NEW=Novo
# simple accregwizz
# sipaccregwizz
+plugin.sipaccregwizz.PROXY_PORT=Porta do servidor proxy
+plugin.sipaccregwizz.DISPLAY_NAME=Exibir nome
+plugin.sipaccregwizz.CLIST_TYPE=Tipo
+plugin.sipaccregwizz.XCAP_PASSWORD=Senha
+#used from SecurityPanel
# skin manager
-# ssh accregwizz
-plugin.sshaccregwizz.OPTIONAL=Opcional
-
# status update
plugin.autoaway.ENABLE_CHANGE_STATUS=Mudar o estado quando ausente
plugin.autoaway.AWAY_MINUTES=Minutos antes de mudar estado para ausente:
@@ -431,6 +926,7 @@ plugin.autoaway.AWAY_MINUTES=Minutos antes de mudar estado para ausente:
plugin.updatechecker.DIALOG_TITLE=Instalar atualizações
plugin.updatechecker.DIALOG_MESSAGE=<html>Uma nova versão do {0} está disponível.
plugin.updatechecker.BUTTON_DOWNLOAD=Transferir
+plugin.updatechecker.BUTTON_CLOSE=F&echar
plugin.updatechecker.UPDATE_MENU_ENTRY=Procurar por atualizações
plugin.updatechecker.DIALOG_NOUPDATE=Sua versão está atualizada.
plugin.updatechecker.DIALOG_MISSING_UPDATE=O instalador da atualização não foi encontrado.
@@ -438,33 +934,44 @@ plugin.updatechecker.DIALOG_MISSING_UPDATE=O instalador da atualização não fo
# usersearch
# whiteboard
-
-# yahoo accregwizz
-
-# zero accregwizz
+plugin.whiteboard.OPEN=Abrir
+plugin.whiteboard.COLOR=Cor
+plugin.whiteboard.DELETE=Excluir
# gtalk accregwizz
# iptel accregwizz
-# sip2sip accregwizz
-
# ippi accregwizz
# key binding chooser
+#in new ChatWindow() -> manipulated
+plugin.keybindings.CHAT_COPY=&Copiar
+plugin.keybindings.CHAT_CUT=&Recortar
+plugin.keybindings.CHAT_PASTE=&Colar
+plugin.keybindings.MAIN_RENAME=Re&nomear contato
+plugin.keybindings.globalchooser.SHORTCUT_NAME=Nome
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Conversação
# Notification Configuration Form
+plugin.notificationconfig.ENABLE_NOTIF=Habilitar
plugin.notificationconfig.DISPLAY_POPUP=Mostrar uma mensagem em uma janela flutuante
plugin.notificationconfig.POPUP_NOTIF_HANDLER=Tipo de notificação flutuante
plugin.notificationconfig.tableheader.SOUND=Tocar um som usando o dispositivo de notificação
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=Tocar um som usando o dispositivo de reprodução de áudio
+plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=Tocar um som usando o dispositivo de reprodução de áudio
+#NotificationsTable constants
+plugin.notificationconfig.event.IncomingCall=Recebendo chamada
+plugin.notificationconfig.event.IncomingFile=Recebendo chamada
plugin.notificationconfig.event.HangUp=Desligar
# ZRTP Securing
# ZRTP Configuration
+impl.media.security.zrtp.CONFIG=Configuração do LDAP
impl.media.security.zrtp.TITLE=Chamar
+impl.media.security.zrtp.PUB_KEYS=Chave pública:
impl.media.security.zrtp.DESCRIPTION=O {0} tentará garantir automaticamente a segurança de suas chamadas. Você receberá um notificação audiovisual quando uma chamada segura for estabelecida. O botão abaixo permite alterar de forma avançada como o {0} se comportará durante negociações ZRTP. Nenhuma alteração é necessária para poder fazer chamadas seguras. Você deverá somente alterar essas configurações se você possuir conhecimento de como ZRTP e encriptação em geral funcionam.
@@ -481,54 +988,199 @@ impl.media.configform.ECHOCANCEL=Habilitar cancelamento de eco
impl.media.configform.ENCODINGS=Codificadores
impl.media.configform.UP=&Subir
impl.media.configform.VIDEO=Mais configurações
+impl.media.configform.VIDEO_MORE_SETTINGS=Mais configurações
impl.media.configform.VIDEO_RESOLUTION=Resolução de vídeo
impl.neomedia.configform.AUDIO=Ãudio
+impl.neomedia.configform.VIDEO=Vídeo
+#in JNIEncoder
+impl.neomedia.configform.H264.preferredKeyFrameRequester.rtcp=RTP
# The callrecordingconfig plugin was never really committed into trunk and its
# ConfigurationForm was actually put in the neomedia bundle.
# Security configuration form title
plugin.securityconfig.TITLE=Segurança
+plugin.securityconfig.masterpassword.TITLE=Senha
+plugin.securityconfig.masterpassword.CURRENT_PASSWORD=Senha atual:
+plugin.securityconfig.masterpassword.ENTER_PASSWORD=Informe sua senha:
+plugin.securityconfig.masterpassword.REENTER_PASSWORD=Repita sua senha:
+plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Mudança de Senha Falhou
+plugin.securityconfig.masterpassword.MP_CHANGE_SUCCESS=Senha Alterada
+plugin.securityconfig.masterpassword.MP_CHANGE_SUCCESS_MSG=Senha Master alterada
+plugin.securityconfig.masterpassword.MP_REMOVE_SUCCESS_MSG=Senha Master alterada
+plugin.securityconfig.masterpassword.COL_TYPE=Tipo
+plugin.securityconfig.masterpassword.COL_NAME=Nome
+plugin.securityconfig.masterpassword.COL_PASSWORD=Senha
+plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=Desconhecido
+plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(não é possível decifrar)
+plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=Senhas armazenadas
plugin.securityconfig.masterpassword.HIDE_PASSWORDS_BUTTON=Ocultar senhas
# otr plugin
+plugin.otr.menu.TITLE=Chat seguro
+plugin.otr.menu.START_OTR=Iniciar conversa privada
+plugin.otr.menu.END_OTR=Encerrar conversa privada
+plugin.otr.menu.LOADING_OTR=Iniciar conversa privada
+plugin.otr.menu.TIMED_OUT=Iniciar conversa privada
+plugin.otr.menu.REFRESH_OTR=Iniciar conversa privada
plugin.otr.menu.WHATS_THIS=O que é isso
+plugin.otr.menu.CB_AUTO=Iniciar mensagens privadas automaticamente
+plugin.otr.menu.CB_AUTO_ALL=Iniciar mensagens privadas automaticamente
+plugin.otr.menu.CB_ENABLE=Habilitar mensagens privadas
+plugin.otr.menu.CB_REQUIRE=Exigir mensagens privadas
+plugin.otr.menu.CB_RESET=Reiniciar
plugin.otr.authbuddydialog.CANCEL=Cancelar
plugin.otr.authbuddydialog.HELP=Aj&uda
+plugin.otr.smpprogressdialog.AUTHENTICATION_SUCCESS=Autenticação bem sucedida!
+plugin.otr.smpprogressdialog.AUTHENTICATION_FAIL=Autenticação falhou!
plugin.otr.configform.MY_PRIVATE_KEYS=Minhas Chaves Privadas
+plugin.otr.configform.KNOWN_FINGERPRINTS=Impressões Digitais Conhecidas
+plugin.otr.configform.CB_AUTO=Iniciar mensagens privadas automaticamente
+plugin.otr.configform.CB_ENABLE=Habilitar mensagens privadas
+plugin.otr.configform.CB_REQUIRE=Exigir mensagens privadas
plugin.otr.configform.GENERATE=Gerar
+plugin.otr.configform.FINGERPRINT=Impressão Digital
+plugin.otr.configform.VERIFY_FINGERPRINT=Verificar Impressão Digital
plugin.otr.configform.COLUMN_NAME_CONTACT=Contato
+plugin.otr.configform.COLUMN_NAME_VERIFIED_STATUS=Verificada
+plugin.otr.configform.COLUMN_VALUE_VERIFIED_TRUE=Sim
+plugin.otr.configform.COLUMN_VALUE_VERIFIED_FALSE=Não
+plugin.otr.activator.sessionstared=Conversa privada com {0} iniciada.
+plugin.otr.activator.sessionlost=Conversa privada com {0} iniciada.
+plugin.otr.activator.smpaborted={0} interrompeu o processo de autenticação.
+plugin.otr.activator.smperror=Ocorreu um erro no processo de autenticação.
+plugin.otr.activator.unencryptedmsgreceived=A mensagem foi recebida não criptografada
+plugin.otr.activator.unreadablemsgreceived={0} enviou uma mensagem criptografada ilegível.
# global proxy plugin
+plugin.globalproxy.GLOBAL_PROXY_CONFIG=Proxy Global
+plugin.globalproxy.PROXY_TYPE=Tipo de Servidor Proxy
+plugin.globalproxy.PROXY_ADDRESS=Servidor Proxy
+plugin.globalproxy.PROXY_PORT=Porta do servidor proxy
+plugin.globalproxy.PROXY_USERNAME=Usuário do servidor proxy
+plugin.globalproxy.PROXY_PASSWORD=Senha do servidor proxy
#plugin.globalproxy.PROTOCOL_SUPPORT
+plugin.globalproxy.FWD_DNS_ADDR=Endereço do Proxy DNS
+plugin.globalproxy.FWD_DNS_PORT=Porta do DNS Proxy
# plugin reconnect
+plugin.reconnectplugin.NETWORK_DOWN=Conectividade de rede perdida
#plugin chat config
plugin.chatconfig.TITLE=Conversação
+plugin.chatconfig.replacement.ENABLE_SMILEY_STATUS=Habilitar substituição de smiley
+plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS=Habilitar
+plugin.chatconfig.replacement.DISABLE_REPLACEMENT=Desabilitar
+plugin.chatconfig.replacement.REPLACEMENT_SOURCES=Fontes:
+plugin.chatconfig.spellcheck.TITLE=Corretor Ortográfico
#provisioning plugin
+plugin.provisioning.PROVISIONING=Provisionamento
+plugin.provisioning.ENABLE_DISABLE=Habilitar provisionamento
+plugin.provisioning.AUTO=Descobrir automaticamente um URI de provisionamento
+plugin.provisioning.DHCP=DHCP
+plugin.provisioning.DNS=DNS
+plugin.provisioning.URI=URI
plugin.provisioning.RESTART_WARNING=Note que suas alterações só terão efeito na próxima vez em que você iniciar o {0}!
+plugin.provisioning.UUID=UUID
+plugin.provisioning.COPYTOCLIPBOARD=Copiar UUID para área de transferência
+plugin.provisioning.CLIPBOARD_FAILED=Falhou ao copiar UUID para área de transferência
+plugin.provisioning.FORGET_PASSWORD=Esquecer senha
# packet logging service
+plugin.loggingutils.PACKET_LOGGING_CONFIG=Log
+plugin.loggingutils.ENABLE_DISABLE=Habilitar log de pacotes
+plugin.loggingutils.PACKET_LOGGING_RTP=RTP
+plugin.loggingutils.PACKET_LOGGING_RTP_DESCRIPTION=(guarda 1 pacote de cada 5000)
+plugin.loggingutils.PACKET_LOGGING_ICE4J=ice4j.org
+plugin.loggingutils.PACKET_LOGGING_FILE_COUNT=Número de arquivos de log
+plugin.loggingutils.PACKET_LOGGING_FILE_SIZE=Tamanho máximo do arquivo (em KB)
+plugin.loggingutils.ARCHIVE_BUTTON=Arquivar Logs
plugin.loggingutils.UPLOAD_LOGS_BUTTON=Enviar relatórios
plugin.loggingutils.UPLOAD_BUTTON=Enviar
+plugin.loggingutils.ARCHIVE_FILECHOOSE_TITLE=Escolher arquivo
+plugin.loggingutils.ARCHIVE_UPREPORT_EMAIL=johnsmith@email.com
+plugin.loggingutils.ARCHIVE_MESSAGE_NOTOK=Erro archivando logs \n{0}
# dns config plugin
+plugin.dnsconfig.TITLE=DNS
+plugin.dnsconfig.DNSSEC=DNS Security (DNSSEC)
+plugin.dnsconfig.border.TITLE=Resolvedor backup
+plugin.dnsconfig.lblBackupResolver.text=Nome da máquina
+plugin.dnsconfig.lblBackupPort.text=Porta
+plugin.dnsconfig.lblRedemption.text=Voltar para resolvedor primário
+plugin.dnsconfig.dnssec.chkEnabled=Habilitar resolvedor DNSSEC
+plugin.dnsconfig.dnssec.lblDefault=Comportamento padrão
+plugin.dnsconfig.dnssec.chkAbsolute=Tratar todos os nomes de domínio como absolutos
+plugin.dnsconfig.dnssec.lblNameservers=Servidores de nome customizados
+plugin.dnsconfig.dnssec.DOMAIN_NAME=Domínio
+plugin.dnsconfig.dnssec.MODE=Comportamento
+plugin.dnsconfig.dnssec.ENABLE_FAILED=Mudança de estado falhou
+plugin.dnsconfig.dnssec.ENABLE_FAILED_MSG=Mudança de estado do DNSSEC falhou.
+net.java.sip.communicator.util.dns.SecureResolveMode.IgnoreDnssec=Ignorar
+net.java.sip.communicator.util.dns.SecureResolveMode.SecureOnly=Obrigatório
+net.java.sip.communicator.util.dns.SecureResolveMode.SecureOrUnsigned=Obrigatório para zonas assinadas
+util.dns.INSECURE_ANSWER_TITLE=Falha de DNSSEC
+util.dns.INSECURE_ANSWER_MESSAGE_NO_REASON=Resposta do DNS para {0} é insegura.
+util.dns.DNSSEC_ADVANCED_OPTIONS=Mostrar opções avançadas
+util.dns.DNSSEC_ADVANCED_REASON_UNSIGNED={0} pesquisa por {1} não foi assinada.
+net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.Accept=Aceitar mesmo assim
+net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.AlwaysAccept=Aceitar sempre
+net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.Deny=&Negar
+net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.AlwaysDeny=Negar sempre
#plugin spellcheck
+plugin.spellcheck.TITLE=Ortografia e Gramática
+plugin.spellcheck.MENU=Mostrar Ortografia e Gramática
+plugin.spellcheck.ENABLE_SPELL_CHECK=Habilitar corretor ortográfico
+plugin.spellcheck.dialog.FIND=Localizar Próxima
+plugin.spellcheck.dialog.REPLACE=Substituir
+plugin.spellcheck.dialog.ADD=Acrescentar Palavra
+plugin.spellcheck.DICT_ERROR_TITLE=Erro alterando dicionário
+plugin.spellcheck.DICT_ERROR=Não é possível alterar dicionário
+plugin.spellcheck.DICT_RETRIEVE_ERROR=Dicionário não pode ser obtido de
+plugin.spellcheck.UNINSTALL_DICTIONARY=Desinstalar
+plugin.spellcheck.DICT_ERROR_DELETE_TITLE=Erro desinstalando dicionário
+plugin.spellcheck.DICT_ERROR_DELETE=Não é possível desinstalar dicionário
+plugin.spellcheck.SPELLCHECK=Corretor ortográfico
#Certificate configuration plugin
+plugin.certconfig.TITLE=Configuração TLS
+plugin.certconfig.TRUSTSTORE_CONFIG=Fonte de certificados raiz confiáveis
+plugin.certconfig.JAVA_TRUSTSTORE=Java
+plugin.certconfig.WINDOWS_TRUSTSTORE=Windows
+plugin.certconfig.CERT_LIST_TITLE=Configurações de autenticação de cliente TLS
+plugin.certconfig.CERT_LIST_DESCRIPTION=<html><body>As configurações aqui gerenciadas podem ser escolhidas como certificados de cliente TLS nas configurações de conta (ex.: para logar com um certificado em seu provedor SIP em vez de usuário e senha).</body></html>
+plugin.certconfig.ALIAS=Nome do identificador no KeyStore
+plugin.certconfig.KEYSTORE_TYPE=Tipo
+plugin.certconfig.EDIT_ENTRY=Editar configuração do certificado do cliente TLS
plugin.certconfig.KEYSTORE=Arquivo
+plugin.certconfig.KEYSTORE_PASSWORD=Senha
+plugin.certconfig.INCOMPLETE=Por favor preencha todos os campos
+plugin.certconfig.SHOW_CERT_EXCEPTION=Não foi possível mostrar o certificado ({0}).
+plugin.certconfig.KEYSTORE_EXCEPTION=Não foi possível carregar o keystore ({0}).
+plugin.certconfig.ALIAS_LOAD_EXCEPTION=Não foi possível obter identificadores do keystore ({0}).
+plugin.certconfig.INVALID_KEYSTORE_TYPE=O tipo de KeyStore selecionado parece ser inválido ({0}).
+plugin.certconfig.BROWSE_KEYSTORE=Abrir KeyStore
+plugin.certconfig.REVOCATION_TITLE=Opções de revogação de certificado
# Phone number contact source plugin
+plugin.phonenumbercontactsource.DISPLAY_NAME=Números telefônicos
# properties editor
+plugin.propertieseditor.TITLE=Editor de propriedades
+plugin.propertieseditor.NEW_PROPERTY_TITLE=Adicionar nova propriedade
+plugin.propertieseditor.CHECK_BOX=Mostre este alerta na próxima vez
plugin.propertieseditor.DESCRIPTION=O botão abaixo permite alterar as propriedades de configuração do Jitsi. Alterar estas configurações avançadas pode comprometer a estabilidade, segurança e performance deste aplicativo. Você deve continuar apenas se tiver certeza do que está fazendo.
+plugin.propertieseditor.IM_AWARE=Estou ciente dos riscos
+plugin.propertieseditor.NEED_RESTART=Nota: algumas propriedades exigem reinício antes que as alterações façam efeito.
#Thunderbird address book plugin
+plugin.thunderbird.CONFIG_FORM_TITLE=Thunderbird
+plugin.thunderbird.ENABLED=Habilitado
+plugin.thunderbird.PHONE_PREFIX=Prefixo do telefone:
diff --git a/resources/languages/resources_ro.properties b/resources/languages/resources_ro.properties
index 872eb64..3b7168e 100644
--- a/resources/languages/resources_ro.properties
+++ b/resources/languages/resources_ro.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,26 +43,20 @@ service.gui.ACCOUNT_ME=Eu
service.gui.ACCOUNT_REGISTRATION_WIZARD=Asistent de înregistrare a contului
service.gui.ACCOUNTS=Conturi
service.gui.ADD=&Adaugă
-service.gui.ADD_ACCOUNT=Adaugă cont
service.gui.ADD_CONTACT=&Adaugă contact
service.gui.ADD_AUTHORIZED_CONTACT=Adaugă {0} în lista ta de contacte
service.gui.ADD_CONTACT_TO=&Adaugă contact la
service.gui.ADD_CONTACT_ERROR=Nu s-a putut adăuga contactul cu identificatorul: {0}
service.gui.ADD_CONTACT_ERROR_TITLE=Eroare la adăugarea contactului
service.gui.ADD_CONTACT_EXIST_ERROR=Contactul {0} deja există în lista dvs de contacte.
-service.gui.ADD_CONTACT_IDENTIFIER=În câmpul de mai jos introduceți identificatorul contactului pe care doriți să-l adăugați.
-service.gui.ADD_CONTACT_WIZARD=Asistent de adăugare a contactului
service.gui.ADD_GROUP_LOCAL_ERROR=A eșuat adăugarea grupului cu numele: {0}. Problema a intervenit în timpul unei operații locale IO.
service.gui.ADD_GROUP_EXIST_ERROR=Grupul {0} deja există în lista dvs de contacte. Vă rugăm să alegeți un alt nume.
service.gui.ADD_GROUP_NET_ERROR=A eșuat adăugarea grupului cu numele: {0}. Problema se datorează unei erori de rețea. Verificați conexiunea la rețea și reîncercați.
service.gui.ADD_GROUP_ERROR=Nu s-a putut adăuga grupul cu numele: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=Numele grupului trebuie să nu fie gol.
-service.gui.ADD_GROUP=Creează grup
-service.gui.ADD_SUBCONTACT=&Adaugă subcontact
service.gui.ADDRESS=Adresă
service.gui.ADMINISTRATOR=administrator
service.gui.ADVANCED=&Avansat
-service.gui.ALL=&Toate
service.gui.ALL_CONTACTS=&Toate contactele
service.gui.APPLY=&Aplică
service.gui.ARE_CALLING=sună...
@@ -60,7 +65,6 @@ service.gui.AT=la
service.gui.AUTHORIZE=&Autorizează
service.gui.AUTHORIZATION_ACCEPTED=contactul a acceptat cererea dvs de autorizare.
service.gui.AUTHENTICATION_FAILED=Autentificarea a eșuat pentru {0}. Parola introdusă nu este validă.
-service.gui.AUTHENTICATION_REQUESTED=Este necesară autentificare
service.gui.AUTHENTICATION_REQUESTED_SERVER=Serverul {0} solicită autentificarea dvs.
service.gui.AUTHENTICATION_REJECTED=contactul a refuzat cererea dvs de autorizare.
service.gui.AUTHENTICATION_WINDOW_TITLE=autentificarea {0}
@@ -103,13 +107,11 @@ service.gui.CHAT_ROOM_USER_KICKED=a fost exclus(ă) din {0}
service.gui.CHAT_ROOM_USER_QUIT=a părăsit {0}
service.gui.CHAT_ROOM_NAME=Numele conferinței
service.gui.ROOM_NAME=Conferință
-service.gui.AUTOJOIN=Intră automatic
service.gui.CHANGE_PASSWORD=Schimbă parola
service.gui.CHAT_ROOM_NAME_INFO=În câmpul de mai jos introduceți numele conferinței pe care doriți să o creați.
service.gui.CHAT_ROOM_NOT_EXIST=Conferința {0} nu a fost găsită pe serverul {1}. Verificați corectitudinea numelui introdus.
service.gui.CHAT_ROOM_NOT_CONNECTED=Este necesar să fiți conectat(ă) pentru a vă putea înscrie la conferință {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Trebuie să fiți conectat(ă) pentru a vă putea deconecta de la o conferință.
-service.gui.CHAT_ROOM_NOT_JOINED=Trebuie să fiți înscris(ă) la conferință pentru a avea posibilitatea de a efectua diverse operații în cadrul acesteia.
service.gui.CHAT_ROOM_OPTIONS=Setările conferinței
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Conferința {0} necesită să fiți înregistrat(ă) pentru a vă înscrie la ea.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Conferința {0} necesită parolă.
@@ -123,21 +125,17 @@ service.gui.CLEAR=Șterge
service.gui.CLOSE=ÃŽn&chide
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Ați primit un mesaj acum 2 secunde. Sunteți sigur(ă) ca vreți să terminați conversația dată?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=Are loc transfer de fișiere. Sunteți sigur(ă) că doriți să-l amânați?
-service.gui.CONFIRM=Confirmă
service.gui.CONNECTED_STATUS=Conectat
service.gui.CONNECTING=Se conectează...
service.gui.CONNECTING_STATUS=Conexiunea
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Se conectează...
service.gui.CONNECTION=Conexiunea
-service.gui.CONNECTION_FAILED_MSG=Eroare de conexiune pentru următorul cont: Nume utilizator: {0}, Nume server: {1}. Vă rugăm să verificați conexiunea la rețea sau să contactați administratorul rețelei dvs pentru mai multă informație.
service.gui.CONNECTION_EXPIRED_MSG=La momentan sunteți deconectat(ă) de la serverul {0}.
service.gui.CONTACT_NAME=ID sau număr
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Contactul {0} nu suportă telefonie.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Contactul {0} nu suportă discuții în grup.
service.gui.CONTACT_PAUSED_TYPING={0} s-a oprit din scrierea mesajului
service.gui.CONTACT_TYPING={0} scrie un mesaj
service.gui.CONTACT_INFO=&Informația de contact
-service.gui.CONTACTLIST=Listă de contacte
service.gui.CONTACTS=Contacte
service.gui.COPY=&Copiază
service.gui.COPY_LINK=Copiază &legătura
@@ -147,13 +145,10 @@ service.gui.CREATE_CHAT_ROOM=&Creează conferință...
service.gui.CREATE_CHAT_ROOM_ERROR=Nu s-a putut crea conferința cu numele {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=Asistent de creare a conferinței
service.gui.CREATE_CONFERENCE_CALL=&Creează un apel în grup...
-service.gui.CREATE_CONFERENCE_CHAT=&Creează o discuție în grup...
service.gui.CREATE_GROUP=&Creează grup...
service.gui.CREATE_GROUP_NAME=În câmpul de mai jos introduceți numele grupului pe care doriți să-l creați.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Lista dvs de contacte nu conține nici un grup. Pentru început creați un grup (Fișier/Creează grup).
service.gui.CONTACT_INFO_NOT_SUPPORTED=Acest contact nu suportă informații de contact pe web
service.gui.CUT=T&aie
-service.gui.DATE=Data
service.gui.DELETE=Șterge
service.gui.DENY=&Refuză
service.gui.DESKTOP_SHARING_WARNING=<b>Sunteți sigur că doriți să distribuiți public ecranul?</b> <br> Apăsând OK veți lăsa alți oameni să vă vadă ecranul.
@@ -163,7 +158,6 @@ service.gui.DISCONNECTED_STATUS=Deconectat
service.gui.DND_STATUS=A nu deranja
service.gui.DO_NOT_ASK_AGAIN=A nu întreba din nou
service.gui.DO_NOT_SHOW_AGAIN=A nu afișa mesajul din nou
-service.gui.DOWNLOAD_NOW=&Descarcă acum
service.gui.DURATION=durata
service.gui.EDIT=&Editare
service.gui.EDITED_AT=editat la {0}
@@ -179,7 +173,6 @@ service.gui.ERROR_RECEIVED_FROM=S-a recepționat o eroare de la
service.gui.ESTIMATED_TIME=Timpul aproximativ:
service.gui.EVENTS=Evenimente
service.gui.EXIT=Term&ină
-service.gui.EXTENDED_CRITERIA=Criteriu extins
service.gui.GENERAL=General
service.gui.GENERAL_ERROR=Eroare generală
service.gui.GROUP_NAME=Numele grupului
@@ -237,12 +230,12 @@ service.gui.HISTORY=&Istoria
service.gui.HISTORY_CONTACT=Istoria - {0}
service.gui.HOME=Acasă
service.gui.HOME_PAGE=Pagina de pornire
-service.gui.HOUR=Ora
service.gui.ICE=ICE
service.gui.IDENTIFIER=Identificatorul
service.gui.IGNORE=&Ignoră
service.gui.INSERT_SMILEY=Inserează smile
service.gui.INCOMING_CALL=Apelul de intrare recepționat de la: {0}
+service.gui.INCOMING_SCREEN_SHARE=Apelul de intrare recepționat de la: {0}
service.gui.INCOMING_CALL_STATUS=Apel primit
service.gui.INSTANT_MESSAGINGS=MI
service.gui.INITIATING_CALL_STATUS=Se inițiază apelul
@@ -258,7 +251,6 @@ service.gui.IS_CALLING=sună...
service.gui.IS_NOW={0} acuma e {1}
service.gui.JOIN=&ÃŽnscriere
service.gui.JOIN_AS=ÃŽ&nscriere ca
-service.gui.CLOSE_CHAT_ROOM_DIALOG=ÃŽ&nchide
service.gui.JOB_TITLE=Funcție
service.gui.JOIN_CHAT_ROOM=&Înscriere la conferință...
service.gui.JOIN_CHAT_ROOM_TITLE=Înscriere la conferință
@@ -269,7 +261,6 @@ service.gui.KICK_FAILED=Excluderea a eșuat
service.gui.KICK_FAILED_GENERAL_ERROR=A eșuat excluderea {0}. A intervenit o eroare generală la server.
service.gui.KICK_FAILED_NOT_ALLOWED=A eșuat excluderea {0}. Proprietarul sau administratorul conferinței nu poate fi exclus.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=A eșuat excluderea {0}. Nu dispuneți de suficiente privilegii pentru această operație.
-service.gui.LAST=Ultimul
service.gui.LAST_NAME=Prenume:
service.gui.LEAVE=&Părăsește
service.gui.LIMIT_REACHED_FOR_IP=Dvs aveți prea multe registrări curente de pe adresa IP locală și serverul {0} nu mai permite alte înregistrări.
@@ -288,7 +279,6 @@ service.gui.MESSAGE=Mesaj:
service.gui.MISSED_CALLS_TOOL_TIP=Apeluri pierdute de la:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= și {0} mai mult(e)
service.gui.MODERATOR=moderator
-service.gui.MORE=Vizualizați mai mult
service.gui.MORE_LABEL=Mută
service.gui.MOVE=Mută
service.gui.MOVE_SUBCONTACT=M&ută subcontactul
@@ -297,7 +287,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=Contactul selectat este același ca și \n co
service.gui.MOVE_SUBCONTACT_QUESTION=Sunteți sigur(ă) că doriți să mutați {0} în {1}?
service.gui.MOVE_TO_GROUP=&Mută în grup
service.gui.MOVE_CONTACT=Mută contactul
-service.gui.MOVE_CONTACT_ERROR=&Contactul nu poate fi mutat
service.gui.MSG_DELIVERY_FAILURE=Mesajul de mai sus nu a putut fi trimis
service.gui.MSG_DELIVERY_NOT_SUPPORTED=Protocolul pe care îl utilizaţi nu permite trimiterea mesajelor în mod deconectat. Puteţi încerca să accesaţi acest contact prin intermediul altui protocol sau aşteptaţi până când el/ea se va conecta.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=A intervenit o eroare internă. Cel mai posibil că aceasta este o dificultate neprevăzută. Vă rugăm să o raportaţi aici: http://www.sip-communicator.org/index.php/Development/BugsAndIssues.
@@ -308,7 +297,6 @@ service.gui.MSG_NOT_POSSIBLE=Discuții cu acest contact nu sunt posibile (nu est
service.gui.MSG_RECEIVED={0} a scris
service.gui.MSG_SEND_CONNECTION_PROBLEM=Trebuie să fiți conectat(ă) pentru a putea trimite mesaje.
service.gui.MULTIPLE_LOGINS=Sunteți autentificat(ă) de mai multe ori cu același cont. Următorul cont: Nume utilizator: {0}, Nume server: {1} este la moment deconectat.
-service.gui.MUTE=Mut
service.gui.NAME=Nume
service.gui.NETWORK=Rețea
service.gui.NETWORK_FAILURE=Eroare de rețea
@@ -317,6 +305,7 @@ service.gui.NEW_ACCOUNT=Adaugă un &cont nou
service.gui.NEW_MESSAGE=Mesaj nou
service.gui.NEW_NAME=Nume nou
service.gui.NEW_STATUS_MESSAGE=Mesaj nou de statut
+service.gui.NICKNAME=Porecla:
service.gui.NO=Nu
service.gui.NONE=Nimic
service.gui.NO_CAMERA_AVAILABLE=Nicio cameră video disponibilă
@@ -331,7 +320,6 @@ service.gui.NON_EXISTING_USER_ID=Serverul {0} nu recunoaște identificatorul uti
service.gui.SD_QUALITY=Calitate standard
service.gui.OFFLINE=Deconectat(ă)
service.gui.OK=&OK
-service.gui.OLDER_CALLS=Apeluri anterioare
service.gui.ONLINE=Conectat(ă)
service.gui.OPEN=Deschide
service.gui.OPEN_FILE_FROM_IMAGE=Apăsați dublu-click pentru a deschide fișierul.
@@ -339,8 +327,11 @@ service.gui.OPEN_FOLDER=Deschide mapa
service.gui.OPEN_IN_BROWSER=Deschide în &navigator
service.gui.OPTIONS=Setări
service.gui.OR=sau
-service.gui.OR_ENTER_PHONE_NUMBER=Sau introduceți număr de telefon aici...
service.gui.ORGANIZATION=Organizaţia:
+service.gui.chat.role.ADMINISTRATOR=administrator
+service.gui.chat.role.MODERATOR=moderator
+service.gui.chat.role.MEMBER=membru
+service.gui.chat.role.SILENT_MEMBER=membru tăcut
service.gui.OWNER=proprietarul conferinței
service.gui.PASSWORD=Parola
service.gui.PASSWORD_CHANGE_FAILURE=Schimbarea parolei a eÅŸuat
@@ -355,7 +346,6 @@ service.gui.PRESENCE=Prezența
service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Enter' pentru sugestii
service.gui.PRESS_FOR_CALL_INFO=Apasă pentru infoormații despre apel
service.gui.PREVIOUS=Anterior
-service.gui.PREVIOUS_TOOLTIP=Răsfoiește conversațiile anterioare
service.gui.PRINT=&Imprimă
service.gui.PROACTIVE_NOTIFICATION=scrie un mesaj
service.gui.PROBLEMS_ENCOUNTERED=Probleme întâmpinate
@@ -368,7 +358,6 @@ service.gui.REASON=Motiv
service.gui.RECONNECTION_LIMIT_EXCEEDED=Ați fost deconectat(ă) și reconectat(ă) la server prea rapid. Următorul cont : Nume utilizator: {0}, Nume server: {1} este blocat la moment și este nevoie să așteptați un pic înainte de a încerca să vă reconectați.
service.gui.RE_REQUEST_AUTHORIZATION=&Cerere de autorizare
service.gui.REJECT=&Respinge
-service.gui.REMIND_ME_LATER=Amintește-mi mai târziu
service.gui.REMEMBER_PASSWORD=Reține parola
service.gui.REMOVE=&Șterge
service.gui.REMOVE_ACCOUNT=&Șterge contul
@@ -391,26 +380,17 @@ service.gui.REVOKE_ADMIN=Recheamă statutul de administrator
service.gui.REVOKE_MODERATOR=Recheamă statutul de moderator
service.gui.REVOKE_MEMBERSHIP=Recheamă statutul de membru
service.gui.REVOKE_VOICE=Recheamă dreptul la voce
-service.gui.ROOT_GROUP=Grupul de bază
service.gui.SAVE=&Salvează
-service.gui.SAVE_AS_DEFAULT=Salvează ca implicit
service.gui.SEARCH=&Caută
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Apăsați butonul de mai jos pentru afișarea tuturor conferințelor existente pe serverul selectat. Alegeți apoi una la care doriți să vă înscrieți și apăsați butonul de înscriere.
service.gui.SECURITY=Securitatea
-service.gui.SELECT_ACCOUNT=Selectați contul
service.gui.SELECT_COLOR=Selectați culoarea
service.gui.SELECT_GROUP=Selectați grupul
-service.gui.SELECT_GROUP_WIZARD_MSG=Lista de mai jos conține toate grupurile din lista de contacte. Selectați-l pe acela în care doriți să adăugați noul contact.
service.gui.SELECT_NO_GROUP=Nici un grup
-service.gui.SELECT_GROUP_WIZARD=Specificați grupul
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=Lista de mai jos conține toate conturile ce permit participarea la conferințe. Selectați-l pe acela pe care doriți să-l utilizați la crearea propriei conferințe.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=Lista de mai jos conține toate conturile înregistrate. Selectați-l pe acela pe care doriți să-l utilizați în conversațiile cu noul contact.
-service.gui.SELECT_PROVIDERS_WIZARD=Selectați contul
service.gui.SEND=&Trimite
service.gui.SEND_FILE=Trimite &fișier
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Nu există informații despre acest contact.
service.gui.SEND_MESSAGE=&Trimite un mesaj
-service.gui.SEND_AS_SMS=Trimite ca SMS
service.gui.SEND_SMS=T&rimite SMS
service.gui.SEND_SMS_DETAILS=Nu uitați că dvs trebuie să introduceți numărul în formatul internațional, de ex. începând cu +44 pentru Marea Britanie, +447777000000
service.gui.SEND_SMS_NOT_SUPPORTED=Protocolul selectat nu suportă trimiterea de mesaje SMS.
@@ -439,7 +419,6 @@ service.gui.STATUS_MESSAGE_INFO=În câmpul de mai jos puteți specifica noul me
service.gui.STREET=Stradă
service.gui.SUBJECT=Subiectul
service.gui.SUMMARY=Sumarul
-service.gui.TODAY=Astăzi
service.gui.TOOLS=&Unelte
service.gui.TRANSFER=Trans&feră
service.gui.TO=&Spre:
@@ -448,7 +427,6 @@ service.gui.TRANSFER_CALL_TITLE=Transferați apelul
service.gui.TRANSFER_CALL_TO=Transferați la:
service.gui.TRANSPARENCY_NOT_ENABLED=Transparența nu este suportată de configurația dvs curentă.
service.gui.TYPE_YOUR_REQUEST=Introduceți aici cererea dvs
-service.gui.UNMUTE=Activează
service.gui.USER_IDENTIFIER=Identificatorul utilizatorului:
service.gui.USER_EXISTS_ERROR=Acest utilizator deja există în rețeaua selectată. Vă rugăm să alegeți alt(ă) utilizator sau rețea.
service.gui.ACCOUNT_CREATION_FAILED=Noi am eșuat să creăm contul dvs din cauza următoarei erori: {0}
@@ -457,7 +435,6 @@ service.gui.UNKNOWN_STATUS=Stare necunoscută
service.gui.UNREGISTERED_MESSAGE=A eșuat conexiunea la următorul cont: Nume utilizator: {0}, Nume Server: {1}. La momentan sunteți deconectat(ă).
service.gui.VIDEO_CALL=&Apel video
service.gui.VIA=via
-service.gui.VIA_SMS=Via SMS
service.gui.VIEW=&Vizualizare
service.gui.VIEW_HISTORY=Vizualizează &istoria
service.gui.VIEW_SMILEYS=Vizualizează &smilе-urile
@@ -471,9 +448,6 @@ service.gui.VOICEMAIL_TOOLTIP=Mesaje vocale pentru:
service.gui.VOLUME_CONTROL_TOOL_TIP=Ajustează volum
service.gui.WARNING=Avertisment
service.gui.YES=Da
-service.gui.YESTERDAY=Ieri
-service.gui.EXISTING_ACCOUNT_ERROR=Contul introdus de dvs este deja instalat.
-service.gui.NEW_MAIL=<b>Dvs aveți un mesaj electronic nou!</b><br/><b>De la:</b> {0} {1} <br/><b>Subiect:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=Dvs ați recepționat un nou mesaj electronic în <a href="{1}">cutia dvs {0}</a>:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=Dvs ați recepționat {2} mesaje electronice noi în <a href="{1}">cutia dvs {0}</a>:<br/>
service.gui.NEW_GMAIL_FOOTER=o discuție necitită în plus în cutia <a href="{0}">dvs</a>.<br/>
@@ -494,7 +468,6 @@ service.gui.SECURITY_WARNING=Avertisment de securitate
service.gui.SECURITY_ERROR=Eroare de securitate
service.gui.SPEED=Viteza:
service.gui.SILENT_MEMBER=membru tăcut
-service.gui.UPDATE=Actualizează
service.gui.MOBILE_PHONE=Mobil
service.gui.VIDEO_PHONE=Video
service.gui.WORK_PHONE=Serviciu
@@ -523,12 +496,16 @@ service.gui.callinfo.AUDIO_INFO=Info audio
service.gui.callinfo.MEDIA_STREAM_RTP=ZRTP
service.gui.callinfo.MEDIA_STREAM_SRTP=ZRTP
+#enum values from IceProcessingState
+
+
service.gui.ALWAYS_TRUST=Încredere permanentă acestui certificat
service.gui.CERT_DIALOG_TITLE=Verifică certificatul
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} nu putem verifica identitatea serverului când ne conectăm <br>la {1}:{2}.<br><br> Certificatul nu este de încredere, ceea ce înseamnă că identitatea serverului nu poate<br> fi automatic verificată. Doriţi să continuăm conectarea?<br><br> Pentru mai multă informaţie apăsaţi "Vizualizaţi certificatul".</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0} nu putem verifica identitatea serverului când ne conectăm <br>la {1}:{2}.<br><br> Certificatul nu este de încredere, ceea ce înseamnă că identitatea serverului nu poate<br> fi automatic verificată. Doriţi să continuăm conectarea?<br><br> Pentru mai multă informaţie apăsaţi "Vizualizaţi certificatul".</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} nu putem verifica identitatea serverului când ne conectăm <br>la {1}:{2}.<br><br> Certificatul nu este de încredere, ceea ce înseamnă că identitatea serverului nu poate<br> fi automatic verificată. Doriţi să continuăm conectarea?<br><br> Pentru mai multă informaţie apăsaţi "Vizualizaţi certificatul".</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} nu putem verifica identitatea serverului când ne conectăm <br>la {1}:{2}.<br><br> Certificatul nu este de încredere, ceea ce înseamnă că identitatea serverului nu poate<br> fi automatic verificată. Doriţi să continuăm conectarea?<br><br> Pentru mai multă informaţie apăsaţi "Vizualizaţi certificatul".</html>
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Nume general:
service.gui.CERT_INFO_O=Organizația:
service.gui.CERT_INFO_C=Denumirea țării:
@@ -537,24 +514,21 @@ service.gui.CERT_INFO_L=Denumirea localității:
service.gui.CERT_INFO_OU=Unitatea organizațională:
service.gui.CERT_INFO_ISSUED_ON=Eliberat pe:
service.gui.CERT_INFO_EXPIRES_ON=Expiră pe:
+service.gui.CERT_INFO_FINGERPRINTS=Amprenta
service.gui.CERT_INFO_SER_NUM=Numărul de serie:
service.gui.CERT_INFO_VER=Versiunea:
service.gui.CERT_INFO_SIGN_ALG=Algoritmul semnăturii:
service.gui.CERT_INFO_ALG=Algoritmul:
service.gui.CERT_INFO_PUB_KEY=Cheia publică:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} octeți: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} biți
service.gui.CERT_INFO_EXP=Exponentul:
service.gui.CERT_INFO_KEY_SIZE=Mărimea cheii:
service.gui.CERT_INFO_SIGN=Semnătura:
-service.gui.CONTINUE=Continuă
service.gui.SHOW_CERT=Vizualizează certificatul
service.gui.HIDE_CERT=Ascunde certificatul
service.gui.AUTO_ANSWER_VIDEO=Video
-service.gui.security.NO_VIDEO=Video HD
-service.gui.security.COMPARE_WITH_PARTNER=Comparați cu partenerul și apăsați lăcata pentru a confirma.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Comparaţi cu partenerul: {0}
@@ -568,18 +542,12 @@ service.gui.avatar.imagepicker.CLICK=Apasă și Zâmbește
service.gui.avatar.imagepicker.IMAGE_FILES=Fișierele imaginilor
service.gui.avatar.imagepicker.IMAGE_PICKER=Poză
service.gui.avatar.imagepicker.IMAGE_SIZE=Dimensiunile imaginii
-service.gui.avatar.imagepicker.INITIALIZING=Inițializare
service.gui.avatar.imagepicker.RESET=Resetează
service.gui.avatar.imagepicker.SET=Setează
service.gui.avatar.imagepicker.TAKE_PHOTO=Ia-o fotografie
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Eroarea webcamerei
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
# systray
@@ -598,9 +566,7 @@ impl.gui.main.account.DUMMY_PROTOCOL_DESCRIPTION=selectați rețea
# LDAP
impl.ldap.GENERAL=General
-impl.ldap.NEW=Nou
impl.ldap.EDIT=&Editare
-impl.ldap.REMOVE=Åžterge
impl.ldap.ENABLED=Activează
impl.ldap.SERVER_HOSTNAME=Nume gazdă:
impl.ldap.AUTH_NONE=Nimic
@@ -610,12 +576,14 @@ impl.ldap.SERVER_PORT=Portul
impl.ldap.PASSWORD=Parola
impl.ldap.MAIL_FIELD_EXAMPLE=Poşta electronică:
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
# Google Contacts
-impl.googlecontacts.NEW=Nou
impl.googlecontacts.EDIT=&Editare
-impl.googlecontacts.REMOVE=Åžterge
impl.googlecontacts.ENABLED=Activează
impl.googlecontacts.SAVE=&Salvează
impl.googlecontacts.CANCEL=Renunță
@@ -639,9 +607,6 @@ plugin.accountinfo.COUNTRY=Țară
plugin.accountinfo.EMAIL=Email:
plugin.accountinfo.PHONE=Numărul de telefon:
plugin.accountinfo.JOB_TITLE=Funcție
-plugin.accountinfo.USER_PICTURES=Imagini de utilizator
-plugin.accountinfo.CHANGE=Modifică
-plugin.accountinfo.ONLY_MESSAGE=Numai mesaje
# connection info
@@ -659,49 +624,12 @@ plugin.aimaccregwizz.USERNAME=Pseudonimul AIM:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Pseudonimul și parola
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Înregistrează un cont nou
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=În cazul în care nu aveți un cont AIM apăsați acest buton pentru a crea unul nou.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Rescrie setările standarde ale serverului
# branding
plugin.branding.ABOUT_WINDOW_TITLE=Despre {0}
plugin.branding.LOGO_MESSAGE=Open Source VoIP && Mesagerie Instantanee
-plugin.branding.LOADING=Încărcăm
plugin.branding.ABOUT_MENU_ENTRY=&Despre
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>{1} la moment curent se află în activă dezvoltare. Versiunea pe care o folosiți este una experimentală și POATE SĂ NU lucreze cum se așteaptă. Vă rugăm să vă referiți la {2} pentru mai multă informație.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2009 Copyright <b>sip-communicator.org</b>. Toate drepturile sunt rezervate. Vizitaţi <a href="http://sip-communicator.org">http://sip-communicator.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}><b>SIP Communicator</b> este distribuit sub termenii LGPL (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=Dicționare
-plugin.dictaccregwizz.ANY_DICTIONARY=Orice dicționar
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Orice dicționar din {0}
-plugin.dictaccregwizz.FIRST_MATCH=Prima coincidență
-plugin.dictaccregwizz.NO_MATCH=Nici o coincidență
-plugin.dictaccregwizz.MATCH_RESULT=Nici o definiție pentru "{0}" nu a fost găsită, posibil că aveți în vedere:\n
-plugin.dictaccregwizz.INVALID_DATABASE=Dicționarul curent "{0}" nu mai există pe serverul dat.
-plugin.dictaccregwizz.INVALID_STRATEGY=Strategia curentă nu este disponibilă pe server.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=Protocolul de serviciu Dict
-plugin.dictaccregwizz.HOST=Gazdă
-plugin.dictaccregwizz.SERVER_INFO=Informații despre server
-plugin.dictaccregwizz.STRATEGY_SELECTION=Selectarea strategiei
-plugin.dictaccregwizz.STRATEGY_LIST=Lista strategiilor:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Caută strategii
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=Strategia este folosită pentru a căuta cuvinte asemănătoare în caz dacă traducerea nu a fost găsită, mulțumesc diferitelor abordări. Spre exemplu, strategia Prefix va căuta cuvinte care încep asemenea cuvântului pe care îl dorim să traducem.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Informație despre contul Dict
-plugin.dictaccregwizz.FIRST_ACCOUNT=Acest asistent va crea pentru dvs primul vostru cont Dict pentru dict.org.\n\nDvs puteți adăuga un dicționar nou recurgând la Asistent de înregistrare a contului. Completați câmpul Gazdă cu dicționarul pe care l-ați dori să adăugați.
-plugin.dictaccregwizz.THREAD_CONNECT=Încercăm să ne conectăm la server
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=Încercare de conexiune a eșuat, acesta nu este server dict sau serverul este deconectat
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=Recepționăm strategiile
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Nici o strategie nu a fost găsită pe server
-plugin.dictaccregwizz.POPULATE_LIST=Completăm lista
-plugin.dictaccregwizz.CLOSING_CONNECTION=ÃŽnchidem conexiunea
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Pentru a folosi Facebook discuții dvs trebuie să creați un "Nume utilizator" <br>din pagina dvs "Setările contului" pe Facebook.</a><br><br>Notă: Când creați numele vostru de utilizator, dvs trebuie să vă deconectați de la web-pagină <br>și posibil să fie nevoie de timp anumit înainte ca dvs să aveți posibilitatea de a vă conecta cu numele vostru nou de utilizator!</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=Protocolul de discuții Facebook
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Nume utilizator:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Nume utilizator și Parola
+
# generalconfig
plugin.generalconfig.AUTO_START=Porneşte automat {0} când calculatorul restartează
@@ -711,9 +639,6 @@ plugin.generalconfig.SHOW_HISTORY=Vizualizează
plugin.generalconfig.HISTORY_SIZE=mesaje recente în discuțiile noi
plugin.generalconfig.SEND_MESSAGES_WITH=Trimite mesaje cu:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=Adu fereastra cu discuții în față
-plugin.generalconfig.ERROR_PERMISSION=Dvs nu aveți privilegii necesare pentru a elimina pornirea automatică
-plugin.generalconfig.TRANSPARENCY=Transparența
-plugin.generalconfig.ENABLE_TRANSPARENCY=Activează transparența
plugin.generalconfig.DEFAULT_LANGUAGE=Limbajul interfeței
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Modificările dvs vor acționa după următoare restartare.
plugin.generalconfig.SIP_CLIENT_PORT=Portul clientului SIP
@@ -741,6 +666,7 @@ plugin.icqaccregwizz.REGISTER_NEW_ACCOUNT=Înregistrează un cont nou
plugin.ircaccregwizz.PROTOCOL_NAME=IRC
plugin.ircaccregwizz.PROTOCOL_DESCRIPTION=Protocolul IRC.
plugin.ircaccregwizz.USERNAME_AND_PASSWORD=UIN și parola
+plugin.ircaccregwizz.USERNAME=Porecla:
plugin.ircaccregwizz.INFO_PASSWORD=Majoritatea serverelor IRC nu necesită parola.
plugin.ircaccregwizz.AUTO_NICK_CHANGE=Schimbă porecla automatic dacă este deja utilizată
plugin.ircaccregwizz.USE_DEFAULT_PORT=Folosește portul standard
@@ -751,7 +677,6 @@ plugin.ircaccregwizz.IRC_SERVER=Serverul
# jabber accregwizz
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=Protocolul SIP
plugin.jabberaccregwizz.PASSWORD_CONFIRM=Confirmați parola
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=Identificatorul și Parola
plugin.jabberaccregwizz.CSERVER=Serverul
plugin.jabberaccregwizz.SERVER=Serverul de conexiune
plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=Activează păstrarea în "activ"
@@ -765,10 +690,7 @@ plugin.jabberaccregwizz.SERVER_COLUMN=Serverul
plugin.jabberaccregwizz.COMMENT_COLUMN=Comentariul
plugin.jabberaccregwizz.RESOURCE=Resursa
plugin.jabberaccregwizz.PRIORITY=Prioritatea
-plugin.jabberaccregwizz.XMPP_ERROR=Eroarea XMPP
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Eroarea XMPP necunoscută. Verificați dacă numele serverului este corect.
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Rescrie setările standard a serverului
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Setările avansate
plugin.jabberaccregwizz.USE_ICE=Folosește ICE
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=Detectează serverele STUN/TURN automatic
plugin.jabberaccregwizz.SUPPORT_TURN=Suportă TURN
@@ -781,31 +703,14 @@ plugin.jabberaccregwizz.NO_STUN_USERNAME=Vă rugăm să introduceți o adresă v
plugin.jabberaccregwizz.STUN_ALREADY_EXIST=Serverul STUN specificat deja există.
plugin.jabberaccregwizz.JID_ADDRESS=Adresa IP
plugin.jabberaccregwizz.EXISTING_ACCOUNT=Cont SIP existent
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Confirmaţi parola
plugin.jabberaccregwizz.ENCODINGS=&Codificări:
plugin.jabberaccregwizz.AUDIO=Audio
plugin.jabberaccregwizz.VIDEO=Video
plugin.jabberaccregwizz.RESET=Resetează
-# mailbox
-plugin.mailbox.OUTGOING=Mesajul de trimis:
-plugin.mailbox.INCOMING=Mesajele de intrare:
-plugin.mailbox.WAIT_TIME=Întârziere până apelul este trimis la poșta vocală
-plugin.mailbox.MAX_MESSAGE_TIME=Durata maximă a mesajului de intrare
-plugin.mailbox.CONFIRM=Confirmă
-plugin.mailbox.DEFAULTS=Standarde
-plugin.mailbox.MAILBOX=Cutia poștală
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Protocol pentru conectare și discutare în serviciul MSN.
-plugin.msnaccregwizz.USERNAME=Poșta electronică:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=Identificatorul și Parola
-
# plugin manager
plugin.pluginmanager.INSTALL=Instalează
plugin.pluginmanager.UNINSTALL=Dezinstalează
-plugin.pluginmanager.UPDATE=Actualizează
plugin.pluginmanager.PLUGINS=Plug-in-urile
plugin.pluginmanager.URL=URL
plugin.pluginmanager.CHOOSE_FILE=Selectați fișier
@@ -829,7 +734,6 @@ plugin.sipaccregwizz.SERVER_PORT=Portul serverului
plugin.sipaccregwizz.PROXY=Proxy
plugin.sipaccregwizz.PROXY_PORT=Portul proxy
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Transportul preferat
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Setări avansate
plugin.sipaccregwizz.PROXY_OPTIONS=Opțiuni proxy
plugin.sipaccregwizz.PROXY_AUTO=Configurare automată proxy
plugin.sipaccregwizz.ENABLE_PRESENCE=Activează prezența (SIMPLE)
@@ -841,8 +745,6 @@ plugin.sipaccregwizz.KEEP_ALIVE=Păstrează "activ"
plugin.sipaccregwizz.KEEP_ALIVE_METHOD=Metoda de păstrare în "activ"
plugin.sipaccregwizz.KEEP_ALIVE_INTERVAL=Intervalul de păstrare în "activ"
plugin.sipaccregwizz.KEEP_ALIVE_INTERVAL_INFO=Între 1 și 3600 secunde
-plugin.sipaccregwizz.REGISTER=REGISTER
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Rescrie setările standarde a serverului
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Activează suportul apelurilor criptate
plugin.sipaccregwizz.AUTH_NAME=Nume de autorizare
plugin.sipaccregwizz.DISPLAY_NAME=Nume de afiÅŸare
@@ -853,6 +755,7 @@ plugin.sipaccregwizz.CLIST_TYPE=Tipul
plugin.sipaccregwizz.XCAP_USE_SIP_CREDENTIALS=Folosește acreditive SIP
plugin.sipaccregwizz.XCAP_USER=Utilizatorul
plugin.sipaccregwizz.XCAP_PASSWORD=Parola
+#used from SecurityPanel
# skin manager
plugin.skinmanager.SKINS=Skinuri
@@ -860,15 +763,6 @@ plugin.skinmanager.DEFAULT_SKIN=Skin principal
plugin.skinmanager.ADD_NEW_SKIN=Adaugă skin...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=Skinul principal al aplicației.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=Protocolul pentru conectare la calculatoare prin SSH.
-plugin.sshaccregwizz.USERNAME=Identificatorul contului:
-plugin.sshaccregwizz.IDENTITY_FILE=Fișierul de identitate:
-plugin.sshaccregwizz.KNOWN_HOSTS=Gazde cunoscute:
-plugin.sshaccregwizz.OPTIONAL=Opțional
-plugin.sshaccregwizz.ACCOUNT_DETAILS=Detaliile contului
-
# status update
plugin.autoaway.AUTO_STATUS=Absent automatic
plugin.autoaway.ENABLE_CHANGE_STATUS=Schimbă statutul în timpul absenței
@@ -913,21 +807,6 @@ plugin.whiteboard.DESELECT=Deselectează
plugin.whiteboard.DELETE=Șterge
plugin.whiteboard.PROPERTIES=Proprietăți
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Protocol pentru conectare şi discuţii pe serviciul Yahoo.
-plugin.yahooaccregwizz.USERNAME=Nume utilizator:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=Identificatorul și Parola
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=Protocolul de serviciu Zeroconf (Bonjour).
-plugin.zeroaccregwizz.FIRST_NAME=Nume:
-plugin.zeroaccregwizz.LAST_NAME=Prenume:
-plugin.zeroaccregwizz.EMAIL=Poșta electronică:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=Să țin minte contactele Bonjour?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=Identificatorul și Parola
-plugin.zeroaccregwizz.USERID=Identificatorul utilizatorului
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Protocolul Google Talk
plugin.googletalkaccregwizz.USERNAME=Nume utilizator Google Talk
@@ -940,25 +819,18 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, portalul IP telecomunicaÈ
plugin.iptelaccregwizz.USERNAME=Nume utilizator
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=Subscrie la iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIP și discuții
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Nume de utilizator
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Repetați parola
plugin.sip2sipaccregwizz.EMAIL=Poșta electronică
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=Pentru ajutor despre acest serviciu vizitați<br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>Poșta electronică se folosește pentru a trimite mesaje vocale, <br>notificări despre apeluri ratate și pentru a recupera parola pierdută</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>Pentru ajutor despre acest serviciu vizitați <a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=Cont sip2sip.info existent
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Creează un cont sip2sip.info gratis
-
-# ippi accregwizz
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=Pentru ajutor despre acest serviciu vizitați<br>http://ippi.fr
plugin.ippiaccregwizz.INFO_NOTE=<html>Pentru ajutor despre acest serviciu vizitaţi <a href=''>http://wiki.sip2sip.info</a></html>
plugin.ippiaccregwizz.EXISTING_ACCOUNT=Cont SIP existent
plugin.ippiaccregwizz.CREATE_ACCOUNT=Creează un cont SIP gratis
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Închide fereastra de discuții
plugin.keybindings.CHAT_COPY=Copiază
plugin.keybindings.CHAT_CUT=Taie
@@ -974,9 +846,11 @@ plugin.keybindings.OPEN_HISTORY=Vizualizează istoria
plugin.keybindings.OPEN_SMILIES=Vizualizează smile-urile
plugin.keybindings.globalchooser.SHORTCUT_NAME=Nume
plugin.keybindings.PLUGIN_NAME=Taste pentru acces rapid
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Discuţie
# Notification Configuration Form
+plugin.notificationconfig.ENABLE_NOTIF=Activează
plugin.notificationconfig.DESCRIPTION=Descriere
plugin.notificationconfig.TURN_ON_ALL=Activează toate
plugin.notificationconfig.TURN_OFF_ALL=Dezactivează toate
@@ -988,6 +862,7 @@ plugin.notificationconfig.EXEC_PROG=Îndeplinește o aplicație:
plugin.notificationconfig.DISPLAY_POPUP=Vizualizează un mesaj în pop-up fereastră
plugin.notificationconfig.POPUP_NOTIF_HANDLER=Tipul notificărilor pop-up:
plugin.notificationconfig.tableheader.EXECUTE=Îndeplineşte o aplicaţie:
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Apel primit
plugin.notificationconfig.event.IncomingFile=Apel primit
plugin.notificationconfig.event.IncomingMessage=Mesajele de intrare:
@@ -1040,6 +915,7 @@ impl.media.configform.VIDEO_RESET=RestabileÅŸte standarde
impl.neomedia.configform.AUDIO=Audio
impl.neomedia.configform.VIDEO=Video
+#in JNIEncoder
impl.neomedia.configform.H264.preferredKeyFrameRequester.rtcp=ZRTP
# The callrecordingconfig plugin was never really committed into trunk and its
@@ -1063,7 +939,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=Parola curentă:
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Introduceți noua parolă:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Reintroduceţi parola:
plugin.securityconfig.masterpassword.MP_TITLE=Parola principală
-plugin.securityconfig.masterpassword.MP_NOT_SET=(nu este setat)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=Dvs nu ați introdus Parola principală curentă corect. Vă rugăm să încercați din nou.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=Parola principală nu este corectă!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Schimbarea parolei a eșuat
@@ -1078,7 +953,6 @@ plugin.securityconfig.masterpassword.COL_NAME=Nume
plugin.securityconfig.masterpassword.COL_PASSWORD=Parola
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(necunoscut)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(nu pot decripta)
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=Åžterge
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=Șterge toate
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=Sunteți sigur(ă) că doriți să ștergeți toate parole?
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=Șterge toate parole
@@ -1137,7 +1011,6 @@ plugin.globalproxy.PROXY_PORT=Portul proxy
plugin.globalproxy.PROXY_USERNAME=Nume utilizator proxy
plugin.globalproxy.PROXY_PASSWORD=Parola proxy
plugin.globalproxy.DESCRIPTION={0} din acest moment va folosi setările proxy de mai jos pentru toate rețelele pe care dvs le conectați sau reconectați. \nSuportul proxy este la moment experimental și lucrează doar cu unele protocoale. Verificați tabela de mai jos pentru mai multe detalii:
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>JABBER</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
# plugin reconnect
@@ -1150,6 +1023,8 @@ plugin.reconnectplugin.NETWORK_DOWN=Conectivitatea la rețea este pierdută!
plugin.chatconfig.TITLE=Discuție
plugin.chatconfig.replacement.TITLE=Imagine/Video:
plugin.chatconfig.replacement.ENABLE_SMILEY_STATUS=Activează înlocuirea smile-urilor
+plugin.chatconfig.replacement.REPLACEMENT_TITLE=Activează înlocuirea Imagine/Video
+plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS=Activează
plugin.chatconfig.replacement.REPLACEMENT_SOURCES=Surse:
#provisioning plugin
@@ -1173,7 +1048,6 @@ net.java.sip.communicator.util.dns.SecureResolveMode.IgnoreDnssec=&Ignoră
net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.Deny=&Refuză
#plugin spellcheck
-plugin.spellcheck.EDIT_PERSONAL_DICT=&Editare
plugin.spellcheck.UNINSTALL_DICTIONARY=Dezinstalează
diff --git a/resources/languages/resources_ru.properties b/resources/languages/resources_ru.properties
index 0e67e5b..d58bc13 100644
--- a/resources/languages/resources_ru.properties
+++ b/resources/languages/resources_ru.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -29,10 +40,9 @@ service.gui.ABOUT=&О программе
service.gui.ACCEPT=&ПринÑÑ‚ÑŒ
service.gui.ACCOUNT=Ðккаунт
service.gui.ACCOUNT_ME=Я
-service.gui.ACCOUNT_REGISTRATION_WIZARD=МаÑтер региÑтрации учетных запиÑей
-service.gui.ACCOUNTS=Ðккаунты
+service.gui.ACCOUNT_REGISTRATION_WIZARD=МаÑтер региÑтрации учётных запиÑей
+service.gui.ACCOUNTS=Учётные запиÑи
service.gui.ADD=&Добавить
-service.gui.ADD_ACCOUNT=Добавить аккаунт
service.gui.ADD_CONTACT=&Добавить контакт
service.gui.ADD_AUTHORIZED_CONTACT=Добавить {0} в ваш ÑпиÑок контактов
service.gui.ADD_CONTACT_TO_CONTACTLIST=Добавить контакт в ваш ÑпиÑок контактов
@@ -42,20 +52,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Ошибка при добавлении кÐ
service.gui.ADD_CONTACT_EXIST_ERROR=Контакт {0} уже ÑущеÑтвует в ÑпиÑке контактов.
service.gui.ADD_CONTACT_NETWORK_ERROR=Сервер не ответил на Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð°: {0}.
service.gui.ADD_CONTACT_NOT_SUPPORTED=Ðе удалоÑÑŒ добавить контакт Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¾Ð¼: {0}. ÐžÐ¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð½Ðµ поддерживаетÑÑ.
-service.gui.ADD_CONTACT_IDENTIFIER=В поле ниже введите идентификатор контакта который вы желаете добавить.
-service.gui.ADD_CONTACT_WIZARD=МаÑтер Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð¾Ð²
service.gui.ADD_CONTACT_NOT_CONNECTED=Ð’Ñ‹ должны быть подключены Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы добавить контакт. ПожалуйÑта, выполните вход и попробуйте Ñнова.
-service.gui.ADD_GROUP_LOCAL_ERROR=Ðе удалоÑÑŒ добавить группу Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼: {0}. Сбой произошёл во Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¸ ввода-вывода.
+service.gui.ADD_GROUP_LOCAL_ERROR=Ðе удалоÑÑŒ добавить группу Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼: {0}. Произошёл Ñбой во Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¸ ввода-вывода.
service.gui.ADD_GROUP_EXIST_ERROR=Группа {0} уже ÑущеÑтвует в ÑпиÑке контактов. ПожалуйÑта, выберите другое имÑ.
service.gui.ADD_GROUP_NET_ERROR=Ðе удалоÑÑŒ добавить группу Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼: {0}. Сбой произошёл по причине отказа Ñети. ПожалуйÑта, проверьте ваше Ñетевое подключение и попробуйте Ñнова.
service.gui.ADD_GROUP_ERROR=Ðе удалоÑÑŒ добавить группу: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=Ð˜Ð¼Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ñ‹ не может быть пуÑтым.
-service.gui.ADD_GROUP=Создать группу
-service.gui.ADD_SUBCONTACT=&Добавить дополнительный контакт
service.gui.ADDRESS=ÐдреÑ
service.gui.ADMINISTRATOR=админиÑтратор
service.gui.ADVANCED=&РаÑширенные
-service.gui.ALL=&Ð’Ñе
service.gui.ALL_CONTACTS=&Ð’Ñе контакты
service.gui.ALTERNATE_ADDRESS=Ðльтернативный адреÑ
service.gui.APPLY=&Применить
@@ -64,8 +69,7 @@ service.gui.ARE_NOW=Ð’Ñ‹ ÑÐµÐ¹Ñ‡Ð°Ñ {0}
service.gui.AT=времÑ
service.gui.AUTHORIZE=&Ðвторизовать
service.gui.AUTHORIZATION_ACCEPTED={0} ÑобеÑедник принÑл Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° авторизацию.
-service.gui.AUTHENTICATION_FAILED=Проверка подлинноÑти Ð´Ð»Ñ {0} не удалаÑÑŒ. Введённый пароль неверен.
-service.gui.AUTHENTICATION_REQUESTED=Запрошена проверка подлинноÑти
+service.gui.AUTHENTICATION_FAILED=Проверка подлинноÑти Ð´Ð»Ñ {0} не удалаÑÑŒ. Введённый вами пароль неверен.
service.gui.AUTHENTICATION_REQUESTED_SERVER=Сервер {0} запроÑил проверку подлинноÑти.
service.gui.AUTHENTICATION_REJECTED={0} ÑобеÑедник отверг Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° авторизацию.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} авторизациÑ
@@ -92,7 +96,7 @@ service.gui.CALL_HISTORY_GROUP_NAME=ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð²Ñ‹Ð·Ð¾Ð²Ð¾Ð²
service.gui.CALL_VIA=Позвонить через:
service.gui.CALL_NAME_OR_NUMBER=Введите Ð¸Ð¼Ñ Ð¸Ð»Ð¸ номер
service.gui.CALL_NOT_SUPPORTING_PARTICIPANT=Этот звонок поддерживает только учаÑтников из Ñети {0} и вашего {1} аккаунта. {2} не Ñодержит адреÑов Ð´Ð»Ñ Ñтой Ñети или аккаунта.
-service.gui.CALL_WITH=Ðбонент
+service.gui.CALL_WITH=Вызов Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ
service.gui.CALL_NO_AUDIO_DEVICE=Ð’Ñ‹ не выбрали ни одного аудиоуÑтройÑтва.
service.gui.CALL_NO_AUDIO_CODEC=У Ð²Ð°Ñ Ð½Ðµ уÑтановлены аудиокодеки.
service.gui.CALL_NO_DEVICE_CODECS_Q=Хотите продолжить вызов?
@@ -107,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=Ð’ поле ниже вы можете ввеÑ
service.gui.CHANGE_NICKNAME_ERROR=Ðе удалоÑÑŒ изменить ник
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Такое Ð¸Ð¼Ñ ÑƒÐ¶Ðµ ÑущеÑтвует
service.gui.CHANGE_VIDEO_QUALITY=Изменить качеÑтво передаваемого видео
-service.gui.CHAT_CONFERENCE_LABEL=КонференциÑ
service.gui.CHAT_CONFERENCE_ITEM_LABEL={0} конференциÑ
service.gui.CHAT_ROOM_ALREADY_JOINED=ÐšÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ñ {0} уже подключена.
service.gui.CHAT_ROOM_CONFIGURATION=ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ ÐºÐ¾Ð¼Ð½Ð°Ñ‚Ñ‹ {0}
@@ -115,27 +118,28 @@ service.gui.CHAT_ROOM_CONFIGURATION_FAILED=Ðе удалоÑÑŒ открыть н
service.gui.CHAT_ROOM_CONFIGURATION_FORBIDDEN=Ðе удалоÑÑŒ отобразить конфигурацию комнаты {0}. Только владелец комнаты может увидеть или изменить конфигурацию.
service.gui.CHAT_ROOM_CONFIGURATION_SUBMIT_FAILED=Произошла ошибка во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ð¸ конференции {0}.
service.gui.CHAT_ROOM_CONFIGURATION_MEMBERS_EDIT_TITLE=Редактировать ÑпиÑок учаÑтников
+service.gui.CHAT_ROOM_CONFIGURATION_MEMBERS_EDIT_DESCRIPTION=СпиÑок Ñправа Ñодержит пользователей, имеющих членÑтво в Ñтой комнате. Когда чат-комната 'Только Ð´Ð»Ñ ÑƒÑ‡Ð°Ñтников', в комнате будут лишь те, кто допущен к подключению.
service.gui.CHAT_ROOM_USER_JOINED=подключилÑÑ Ðº {0}
service.gui.CHAT_ROOM_USER_LEFT=покинул {0}
service.gui.CHAT_ROOM_USER_KICKED=был иÑключён из {0}
service.gui.CHAT_ROOM_USER_QUIT=вышел из {0}
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Удалить выбранную комнату из ÑпиÑка Ñохранённых
+service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=Отправка ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿Ñ€ÐµÑ‰ÐµÐ½Ð° (Ð³Ð¾Ð»Ð¾Ñ Ð¾Ñ‚Ð¾Ð·Ð²Ð°Ð½)
service.gui.CHAT_ROOM_NAME=Ð˜Ð¼Ñ ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ð¸
service.gui.CLEAR_CUSTOM_MESSAGES=ОчиÑтка пользовательÑких Ñообщений
service.gui.ROOM_NAME=КонференциÑ
-service.gui.AUTOJOIN=ÐвтоматичеÑкий вход
service.gui.CHANGE_PASSWORD=Сменить пароль
service.gui.CHAT_ROOM_NAME_INFO=Ð’ поле ниже введите Ð¸Ð¼Ñ ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ð¸, которую хотите Ñоздать.
service.gui.CHAT_ROOM_NOT_EXIST=ÐšÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ñ {0} не была найдена на Ñервере {1}. ПожалуйÑта, проверьте правильноÑÑ‚ÑŒ введённого имени.
service.gui.CHAT_ROOM_NOT_CONNECTED=Ð’Ñ‹ должны быть зарегиÑтрированы, чтобы иметь возможноÑÑ‚ÑŒ приÑоединитьÑÑ Ðº конференции {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Ð’Ñ‹ должны быть подключены чтобы иметь возможноÑÑ‚ÑŒ выйти из конференции.
-service.gui.CHAT_ROOM_NOT_JOINED=Ð’Ñ‹ должны войти в конференцию, чтобы иметь возможноÑÑ‚ÑŒ Ñовершать какие-либо операции Ñ Ð½ÐµÐ¹.
service.gui.CHAT_ROOM_OPTIONS=ÐаÑтройки конференции
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=ÐšÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ñ {0} требует региÑтрации Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ð°.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=ÐšÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ñ {0} запроÑила пароль.
service.gui.CHAT_ROOMS=Конференции
service.gui.CHAT_ROOM=Комната
service.gui.CHAT_ROOM_SUBJECT_CHANGED={0} изменил тему на {1}
+service.gui.CHAT_ROOM_ALTERNATE_ADDRESS=Ð’Ñ‹ можете продолжать разговор в Ñледующей чат-комнате: {0}
+service.gui.CHAT_NICKNAME_CHANGE={0} теперь извеÑтен как {1}
service.gui.CHOOSE_CONTACT=Выберите контакт
service.gui.CHOOSE_NUMBER=Выберите номер
service.gui.CHOOSE_ACCOUNT=ПожалуйÑта, выберите один из указанных контактов.
@@ -144,7 +148,7 @@ service.gui.COUNTRY=Страна
service.gui.SHOW_MORE_TOOLTIP=Ðажмите Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð¾Ñтей
service.gui.CLEAR=ОчиÑтить
service.gui.CLOSE=За&крыть
-service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Ð’Ñ‹ получили новое Ñообщение меньше, чем 2 Ñекунды назад. Ð’Ñ‹ уверены, что желаете закрыть Ñтот чат?
+service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Ð’Ñ‹ получили новое Ñообщение менее, чем 2 Ñекунды назад. Ð’Ñ‹ уверены, что желаете закрыть Ñтот чат?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=У Ð²Ð°Ñ Ð¸Ð¼ÐµÑŽÑ‚ÑÑ Ð°ÐºÑ‚Ð¸Ð²Ð½Ñ‹Ðµ передачи файлов. Ð’Ñ‹ уверенны, что желаете прервать их?
service.gui.CONFIRM=Подтвердить
service.gui.CONNECTED_STATUS=Подключен
@@ -152,16 +156,15 @@ service.gui.CONNECTING=Подключение...
service.gui.CONNECTING_STATUS=Подключение
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Подключение*
service.gui.CONNECTION=Соединение
-service.gui.CONNECTION_FAILED_MSG=Ðе удалоÑÑŒ Ñоединение Ð´Ð»Ñ Ñледующего аккаунта: Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ: {0}, Ð˜Ð¼Ñ Ñервера: {1}. ПожалуйÑта проверьте ваше Ñетевое подключение или ÑвÑжитеÑÑŒ Ñ Ð²Ð°ÑˆÐ¸Ð¼ Ñетевым админиÑтратором Ð´Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации.
service.gui.CONNECTION_EXPIRED_MSG=Ð’ данный момент вы отключены от Ñервера {0}.
service.gui.CONTACT_NAME=ID или номер
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Выбранный контакт {0} не поддерживает голоÑовую ÑвÑзь.
+service.gui.CONTACT_NAME_PROMPT=jane.doe@example.com
+service.gui.CONTACT_NAME_INFO=Добавить Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ Ð¼Ð³Ð½Ð¾Ð²ÐµÐ½Ð½Ñ‹Ñ… Ñообщений (например: jane.doe@example.com) или номер IP-телефонии
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Выбранный контакт {0} не поддерживает чат в конференции.
service.gui.CONTACT_PAUSED_TYPING={0} переÑтал печатать Ñообщение
service.gui.CONTACT_TYPING={0} печатает Ñообщение
-service.gui.CONTACT_TYPING_SEND_FAILED=ÑобеÑедник {0} не увидит процеÑÑ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑообщениÑ
+service.gui.CONTACT_TYPING_SEND_FAILED=ой-ой... мы не Ñмогли Ñообщить {0} , что вы печатаете
service.gui.CONTACT_INFO=&ÐšÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ
-service.gui.CONTACTLIST=СпиÑок контактов
service.gui.CONTACTS=Контакты
service.gui.COPY=&Копировать
service.gui.COPY_LINK=Копировать &ÑÑылку
@@ -171,27 +174,26 @@ service.gui.CREATE_CHAT_ROOM=&Создать конференцию...
service.gui.CREATE_CHAT_ROOM_ERROR=Ðе удалоÑÑŒ Ñоздать конференцию {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=МаÑтер ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ð¹
service.gui.CREATE_CONFERENCE_CALL=&Создать многопользовательÑкий звонок...
-service.gui.CREATE_CONFERENCE_CHAT=&Создать многопользовательÑкий чат...
service.gui.CREATE_GROUP=&Создать группу...
service.gui.CREATE_GROUP_NAME=Ð’ поле ниже введите Ð¸Ð¼Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ñ‹, которую вы хотите Ñоздать.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Ваш ÑпиÑок контактов не Ñодержит ни одной группы. ПожалуйÑта, Ñначала Ñоздайте группу (Файл/Создать группу).
service.gui.CREATE_VIDEO_BRIDGE=Создать &видео-моÑÑ‚...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Создать &видеомоÑÑ‚
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Создать/ПриÑоединитьÑÑ Ðº видео конференции
service.gui.CREATE_VIDEO_CONFERENCE=Создать новую видео конференцию Ð´Ð»Ñ Ñтой комнаты
service.gui.CONTACT_INFO_NOT_SUPPORTED=Данный контакт не поддерживает Ñетевую контактную информацию
service.gui.CUT=В&ырезать
-service.gui.DATE=Дата
service.gui.DELETE=Удалить
service.gui.DENY=&Отклонить
service.gui.DESKTOP_SHARING_WARNING=<b>Ð’Ñ‹ уверены, что хотите предоÑтавить доÑтуп к вашему Ñкрану?</b> <br> Ðажатие OK позволит абонентам, учаÑтвующим в разговоре, видеть Ñодержимое вашего Ñкрана.
+service.gui.DESKTOP_SHARING_DIALOG_INDICATE=Ð’Ñ‹ показыаете Ñвой Ñкран
service.gui.DIALPAD=Ðомеронабиратель
service.gui.DISPLAY_NAME=Отображаемое имÑ
+service.gui.DISPLAY_NAME_PROMPT=Jane Doe
+service.gui.DISPLAY_NAME_INFO=Добавить Ð¸Ð¼Ñ Ð´Ð»Ñ Ñтого контакта. ЕÑли оÑтавить пуÑтым, будет иÑпользован Ð°Ð´Ñ€ÐµÑ IM или номер VoIP. (ÐеобÑзательно)
service.gui.DISCONNECTED_STATUS=Отключено
service.gui.DND_STATUS=Ðе беÑпокоить
service.gui.DO_NOT_ASK_AGAIN=Ðе Ñпрашивать Ñнова
service.gui.DO_NOT_SHOW_AGAIN=Ðе показывать Ñто Ñообщение Ñнова
-service.gui.DOWNLOAD_NOW=&Загрузить ÑейчаÑ
service.gui.DRAG_FOR_SHARING=ПеремеÑтите Ñюда Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¾ÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±Ñ‰ÐµÐ³Ð¾ доÑтупа...
service.gui.DURATION=длительноÑÑ‚ÑŒ
service.gui.DESTROY_CHATROOM=Удалить комнату
@@ -208,10 +210,10 @@ service.gui.ENTER_PHONE_NUMBER=Введите номер телефона
service.gui.ENTER_NAME_OR_NUMBER=Введите Ð¸Ð¼Ñ Ð¸Ð»Ð¸ номер
service.gui.ERROR=Ошибка
service.gui.ERROR_WAS=Ошибка была: {0}
+service.gui.ERROR_RECEIVED_FROM=От {0} получено Ñообщение об ошибке
service.gui.ESTIMATED_TIME=Приблизительное времÑ:
service.gui.EVENTS=СобытиÑ
service.gui.EXIT=В&ыйти
-service.gui.EXTENDED_CRITERIA=РаÑширенный критерий
service.gui.GENERAL=Общие
service.gui.GENERAL_ERROR=ÐžÐ±Ñ‰Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°
service.gui.GROUP_NAME=Ð˜Ð¼Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ñ‹
@@ -253,7 +255,6 @@ service.gui.FONT_ITALIC=КурÑив
service.gui.FONT_SIZE=Размер
service.gui.FONT_STYLE=Стиль
service.gui.FONT_UNDERLINE=Подчеркивание
-service.gui.FROM={0} из {1}
service.gui.GRANT_OWNERSHIP=Добавить к владельцам...
service.gui.GRANT_ADMIN=Добавить к админиÑтраторам...
service.gui.GRANT_MODERATOR=Добавить к модераторам
@@ -269,61 +270,62 @@ service.gui.HIDE_MAIN_WINDOW=<DIV>Ðажатие креÑтика в углу о
service.gui.HISTORY=&ИÑториÑ
service.gui.HISTORY_CONTACT=ИÑÑ‚Ð¾Ñ€Ð¸Ñ - {0}
service.gui.HISTORY_TOGGLE_PER_CONTACT=Выключить иÑторию Ð´Ð»Ñ Ñтого контакта
-service.gui.HISTORY_TOGGLE_PER_CHATROOM=Выключить иÑторию Ð´Ð»Ñ Ñтого контакта
-service.gui.HISTORY_ERASE_PER_CONTACT=Стереть вÑÑŽ иÑторию контакта
-service.gui.HISTORY_ERASE_PER_CHATROOM=Стереть вÑÑŽ иÑторию комнаты
+service.gui.HISTORY_TOGGLE_PER_CHATROOM=Выключить иÑторию Ð´Ð»Ñ Ñтой комнаты
+service.gui.HISTORY_TOGGLE_ALL=Выключить иÑторию Ð´Ð»Ñ Ð²Ñех беÑед и контактов
+service.gui.HISTORY_ERASE_PER_CONTACT=Стереть вÑÑŽ иÑторию Ð´Ð»Ñ Ñтого контакта
+service.gui.HISTORY_ERASE_PER_CHATROOM=Стереть вÑÑŽ иÑторию Ñтой комнаты
service.gui.HISTORY_ERASE_ALL=Стереть вÑÑŽ иÑторию в {0}
service.gui.HISTORY_REMOVE_PER_CONTACT_WARNING=ДейÑтвительно окончательно уничтожить вÑе локально Ñохраненные ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ {0}?
service.gui.HISTORY_REMOVE_ALL_WARNING=ДейÑтвительно окончательно уничтожить вÑе локально Ñохраненные ÑообщениÑ?
service.gui.HISTORY_REMOVE_ERROR=Ошибка ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¾ Ñохраненных Ñообщений.
-service.gui.HOME=Домой
+service.gui.HOME=Ðа главную
service.gui.HOME_PAGE=ДомашнÑÑ Ñтраница
-service.gui.HOUR=ВремÑ
service.gui.ICE=ICE
service.gui.IDENTIFIER=Идентификатор
service.gui.IGNORE=&Игнорировать
service.gui.INSERT_SMILEY=Ð’Ñтавить Ñмайлик
service.gui.INCOMING_CALL=ВходÑщий звонок от: {0}
+service.gui.INCOMING_SCREEN_SHARE=ВходÑщее предложение показать Ñкран от: {0}
service.gui.INCOMING_CALL_STATUS=ВходÑщий звонок
+service.gui.INCOMING_SCREEN_SHARE_STATUS=ВходÑщее предложение показать Ñкран
service.gui.INSTANT_MESSAGINGS=IMs
service.gui.IM=IM
service.gui.INITIATING_CALL_STATUS=ОÑущеÑтвление вызова
service.gui.INVITATION=ТекÑÑ‚ приглашениÑ
service.gui.INVITATION_RECEIVED=Приглашение принÑто
-service.gui.INVITATION_RECEIVED_MSG={0} приглаÑил Ð’Ð°Ñ Ð² конференцию {1}. Ð’Ñ‹ можете принÑÑ‚ÑŒ, отклонить или игнорировать приглашение.
-service.gui.INVITATION_REJECTED={0} отклонил Ваше приглашение в конференцию. Причина: {1}.
+service.gui.INVITATION_RECEIVED_MSG={0} приглаÑил Ð²Ð°Ñ Ð² конференцию {1}. Ð’Ñ‹ можете принÑÑ‚ÑŒ, отклонить или игнорировать приглашение.
+service.gui.INVITATION_REJECTED={0} отклонил ваше приглашение в конференцию. Причина: {1}.
service.gui.INVITE=&ПриглаÑить
-service.gui.INVITE_CONTACT_MSG=Выберите имена контактов, которые хотите добавить к Ñтому обÑуждению и нажмите ПриглаÑить.
+service.gui.INVITE_CONTACT_MSG=Выберите имена контактов, которые вы хотите добавить к Ñтой конференции и нажмите ПриглаÑить.
service.gui.INVITE_CONTACT_TO_CHAT=ПриглаÑить контакты в чат
service.gui.INVITE_CONTACT_TO_CALL=ПриглаÑить контакты к звонку
service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=ПриглаÑить контакты в видеомоÑÑ‚
service.gui.INVITE_REASON=Причина приглашениÑ
service.gui.IS_CALLING={0} звонит...
service.gui.IS_NOW={0} теперь {1}
-service.gui.JITSI_WARNING=SIP Communicator был переименован в Jitsi.<br/>ЕÑли Ð’Ñ‹ хотите иÑпользовать новую верÑию программы, пожалуйÑта загружайте Jitsi.<br/><br/>ПриноÑим Ñвои Ð¸Ð·Ð²Ð¸Ð½ÐµÐ½Ð¸Ñ Ð·Ð° возможные причиненные неудобÑтва.<br/><br/>Команда разработчиков Jitsi
-service.gui.JITSI_WARNING_TITLE=SIP Communicator теперь Ñтал Jitsi
service.gui.JOIN=&Войти
service.gui.JOIN_AS=В&ойти как
-service.gui.CLOSE_CHAT_ROOM_DIALOG=З&акрыть
+service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=ПодключитьÑÑ Ðº ÑущеÑтвующей видеоконференции
+service.gui.JOIN_VIDEO=ПодключитьÑÑ Ðº видео
service.gui.JOB_TITLE=ДолжноÑÑ‚ÑŒ
service.gui.JOIN_CHAT_ROOM=&Войти в конференцию...
service.gui.JOIN_CHAT_ROOM_TITLE=Войти в конференцию
service.gui.JOIN_CHAT_ROOM_NAME=ПожалуйÑта, введите Ð¸Ð¼Ñ ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ð¸, в которую хотите войти.
service.gui.JOIN_CHAT_ROOM_WIZARD=МаÑтер приÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ðº конференции
service.gui.JOIN_AUTOMATICALLY=ПриÑоединÑÑ‚ÑŒÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки
+service.gui.DONT_JOIN_AUTOMATICALLY=Ðе подключатьÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки
service.gui.KICK=&Выгнать
service.gui.KICK_FAILED=Ðе удалоÑÑŒ выгнать
service.gui.KICK_FAILED_GENERAL_ERROR=Ðе удалоÑÑŒ выгнать {0}. Произошла Ð¾Ð±Ñ‰Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° Ñервера.
service.gui.KICK_FAILED_NOT_ALLOWED=Ðе удалоÑÑŒ выгнать {0}. Владелец и админиÑтратор конференции не может быть выгнан.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Ðе удалоÑÑŒ выгнать {0}. У Ð²Ð°Ñ Ð½ÐµÑ‚ на Ñто прав.
-service.gui.LAST=ПоÑледний
service.gui.LAST_NAME=ФамилиÑ
service.gui.LEAVE=&Покинуть
-service.gui.LIMIT_REACHED_FOR_IP=У Ð²Ð°Ñ Ñлишком много региÑтраций Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ IP адреÑа и Ñервер {0} не позволÑет больше региÑтраций.
-service.gui.LIST=ПоÑледний
+service.gui.LIMIT_REACHED_FOR_IP=У Ð²Ð°Ñ Ñлишком много региÑтраций Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ IP адреÑа. Сервер {0} не позволÑет больше региÑтраций.
+service.gui.LIST=СпиÑок
service.gui.LOADING_ROOMS=Загружаю конференции...
service.gui.LOADING=Загрузка...
-service.gui.LOCALLY_ON_HOLD_STATUS=В ожидании
+service.gui.LOCALLY_ON_HOLD_STATUS=УдерживаетÑÑ Ð½Ð° линии
service.gui.LOGIN_NETWORK_ERROR=Ðе удаётÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ аккаунт: Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ: {0}, Ð˜Ð¼Ñ Ñервера: {1}, в ÑвÑзи Ñо Ñбоем Ñети. ПожалуйÑта, проверьте ваше Ñетевое подключение.
service.gui.LOGIN_GENERAL_ERROR=Произошла ошибка во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð°ÐºÐºÐ°ÑƒÐ½Ñ‚Ð°: Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ: {0}, Ð˜Ð¼Ñ Ñервера: {1}:{2}.
service.gui.LOGIN_INTERNAL_ERROR=Произошла ошибка во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð°ÐºÐºÐ°ÑƒÐ½Ñ‚Ð°: Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ: {0}, Ð˜Ð¼Ñ Ñервера: {1}. Скорее вÑего Ñто внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° приложениÑ. ПожалуйÑта, Ñообщите о проблеме в наш ÑпиÑок раÑÑылки (dev@jitsi.java.net).
@@ -336,7 +338,6 @@ service.gui.MESSAGE=Сообщение
service.gui.MISSED_CALLS_TOOL_TIP=Пропущенные вызовы от:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= и {0} больше
service.gui.MODERATOR=модератор
-service.gui.MORE=ПоÑмотреть больше
service.gui.MORE_LABEL=Еще
service.gui.MOVE=ПеремеÑтить
service.gui.MOVE_SUBCONTACT=П&еремеÑтить контакт
@@ -345,12 +346,12 @@ service.gui.MOVE_SUBCONTACT_FAILED=Контакт, который вы выбрÐ
service.gui.MOVE_SUBCONTACT_QUESTION=Ð’Ñ‹ уверенны, что желаете перемеÑтить {0} в {1}?
service.gui.MOVE_TO_GROUP=&ПеремеÑтить в группу
service.gui.MOVE_CONTACT=ПеремеÑтить контакт
-service.gui.MOVE_CONTACT_ERROR=&Контакт не может быть перемещён
service.gui.MSG_DELIVERY_FAILURE=Сообщение выше не может быть доÑтавлено
service.gui.MSG_DELIVERY_NOT_SUPPORTED=ИÑпользуемый вами протокол не поддерживает offline-ÑообщениÑ. Ð’Ñ‹ можете попробовать ÑвÑзатьÑÑ Ñ {0} через другой протокол или подождать пока он/она не подключатÑÑ Ðº Ñети.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Произошла внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° приложениÑ. Возможно Ñто баг. ПожалуйÑта, Ñообщите о ней Ñюда: https://jitsi.org/Development/BugsAndIssues.
service.gui.MSG_DELIVERY_ERROR=Ðе удалоÑÑŒ доÑтавить Ñообщение.
service.gui.MSG_DELIVERY_UNKNOWN_ERROR=Произошла неизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° во Ð²Ñ€ÐµÐ¼Ñ Ð´Ð¾Ñтавки вашего ÑообщениÑ.
+service.gui.MSG_DELIVERY_UNSUPPORTED_OPERATION=ÐÐµÐ¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÐ¼Ð°Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ.
service.gui.MSG_NOT_DELIVERED=Произошла ÑÐµÑ‚ÐµÐ²Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°. ПожалуйÑта, проверьте вашу Ñетевую конфигурацию и попробуйте Ñнова.
service.gui.MSG_NOT_POSSIBLE=Обмен ÑообщениÑми невозможен Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ контакта (не поддерживаетÑÑ Ð¿Ñ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»Ð¾Ð¼)
service.gui.MSG_RECEIVED={0} напиÑал
@@ -358,8 +359,7 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=Ð’Ñ‹ должны быть подклюÑ
service.gui.MULTIPLE_LOGINS=Ð’Ñ‹ подключены больше одного раза к тому же аккаунту. Следующий аккаунт: Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ: {0}, Ð˜Ð¼Ñ Ñервера: {1} в данный момент отключён.
service.gui.MY_CHAT_ROOMS=Добавить комнату
service.gui.MY_CHAT_ROOMS_TITLE=Добавить комнату
-service.gui.MUTE=Отключить звук
-service.gui.MUTUALLY_ON_HOLD_STATUS=В ожидании
+service.gui.MUTUALLY_ON_HOLD_STATUS=СовмеÑтное удержание
service.gui.NAME=ИмÑ
service.gui.NETWORK=Сеть
service.gui.NETWORK_FAILURE=Сбой Ñети
@@ -369,19 +369,20 @@ service.gui.NEW_MESSAGE=Ðовое Ñообщение
service.gui.NEW_NAME=Ðовое имÑ
service.gui.NEW_STATUS_MESSAGE=Ðовый ÑÑ‚Ð°Ñ‚ÑƒÑ ÑообщениÑ
service.gui.NEW_STATUS_MESSAGE_SAVE=Сохранить ÑобÑтвенное Ñообщение
+service.gui.NICKNAME=ПÑевдоним
service.gui.NO=Ðет
service.gui.NONE=Ðет
-service.gui.NO_CAMERA_AVAILABLE=Камера не подключена
+service.gui.NO_CAMERA_AVAILABLE=Камера не обнаружена
service.gui.NO_DESKTOP_SHARING_FOR_PROTOCOL=ДемонÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‡ÐµÐ³Ð¾ Ñтола не поддерживаетÑÑ Ð´Ð°Ð½Ð½Ñ‹Ð¼ протоколом
service.gui.NO_VIDEO_ENCODINGS=Видеокодеки не определены в конфигурации
service.gui.NO_VIDEO_FOR_PROTOCOL=Передача видео не поддерживаетÑÑ Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ протокола
service.gui.NO_AVAILABLE_ROOMS=СпиÑок комнат Ð´Ð»Ñ Ñтого Ñервера в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð½Ðµ доÑтупен.
service.gui.NO_CONTACTS_FOUND=СоответÑтвующие контакты не найдены. Ðажмите Ctrl+Enter, чтобы позвонить {0} или иÑпользуйте кнопки ниже.
-service.gui.NO_CONTACTS_FOUND_SHORT=СоответÑтвующие контакты не найдены.
+service.gui.NO_CONTACTS_FOUND_SHORT=ПодходÑщих контактов не найдено.
service.gui.NO_MESSAGE=Ðет Ñообщений
service.gui.NO_GROUP_CHAT_ACCOUNT_AVAILABLE=Ðе обнаружены аккаунты Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¾Ð¹ многопользовательÑкого чата. ПоÑетите jitsi.org Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð±Ð¾Ð»ÐµÐµ подробной информации о том какие протоколы поддерживает многопользовательÑкий чат.
service.gui.NO_ONLINE_CONFERENCING_ACCOUNT=Ðккаунт не поддерживает конференции. Проверьте https://jitsi.org Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸ о протоколах Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¾Ð¹ конференций.
-service.gui.NO_ONLINE_TELEPHONY_ACCOUNT=По крайней мере один SIP Ðккаунт необходим Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы Ñделать звонок. Войдите в один из ваших SIP аккаунтов и повторите попытку.
+service.gui.NO_ONLINE_TELEPHONY_ACCOUNT=По крайней мере один SIP аккаунт необходим Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы Ñделать звонок. Войдите в один из ваших SIP аккаунтов и повторите попытку.
service.gui.NOT_AUTHORIZED=Ðе авторизован
service.gui.NON_EMPTY_CHAT_WINDOW_CLOSE=Ð’ Ñтом чате еÑÑ‚ÑŒ не отправленное Ñообщение. Ð’Ñ‹ уверены, что хотите закрыть Ñтот чат?
service.gui.NON_EXISTING_USER_ID=Ðа Ñервере {0} нет такого пользователÑ.
@@ -389,7 +390,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=Ðе в ÑпиÑке контакто
service.gui.SD_QUALITY=Стандартное качеÑтво
service.gui.OFFLINE=Ðе в Ñети
service.gui.OK=&OK
-service.gui.OLDER_CALLS=Старые звонки
service.gui.ONLINE=Ð’ Ñети
service.gui.OPEN=Открыть
service.gui.OPEN_FILE_FROM_IMAGE=Дважды щелкните, чтобы открыть файл.
@@ -397,11 +397,19 @@ service.gui.OPEN_FOLDER=Открыть папку
service.gui.OPEN_IN_BROWSER=Открыть в &браузере
service.gui.OPTIONS=Опции
service.gui.OPEN_AUTOMATICALLY=Открыть комнату автоматичеÑки в Ñлучае
+service.gui.OPEN_ON_ACTIVITY=Открыть активноÑÑ‚ÑŒ
+service.gui.OPEN_ON_MESSAGE=Открыть только по Ñообщению
service.gui.OPEN_ON_IMPORTANT_MESSAGE=Открывать только Ð´Ð»Ñ Ð²Ð°Ð¶Ð½Ñ‹Ñ… Ñообщений
service.gui.OR=или
-service.gui.OR_ENTER_PHONE_NUMBER=Или введите номер телефона здеÑÑŒ...
service.gui.ORGANIZATION=ОрганизациÑ
service.gui.OTHER=Другое
+service.gui.chat.role.OWNER=Владелец
+service.gui.chat.role.ADMINISTRATOR=ÐдминиÑтратор
+service.gui.chat.role.MODERATOR=Модератор
+service.gui.chat.role.MEMBER=УчаÑтник
+service.gui.chat.role.GUEST=ГоÑÑ‚ÑŒ
+service.gui.chat.role.SILENT_MEMBER=Безмолвный учаÑтник
+service.gui.chat.role.OUTCAST=Запрещено подключатьÑÑ
service.gui.OWNER=владелец комнаты
service.gui.ON_MOBILE_TOOLTIP=(на мобильный)
service.gui.PASSWORD=Пароль
@@ -416,8 +424,8 @@ service.gui.PREFIX=ПрефикÑ
service.gui.PRESENCE=ПриÑутÑтвие
service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Enter' Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ð¹
service.gui.PRESS_FOR_CALL_INFO=Ðажмите Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸ о звонке
+service.gui.PRESS_TO_OPEN_CRM=Ðажмите Ð´Ð»Ñ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ CRM
service.gui.PREVIOUS=Предыдущий
-service.gui.PREVIOUS_TOOLTIP=Обзор Ñтарых разговоров
service.gui.PRINT=&Печать
service.gui.PROACTIVE_NOTIFICATION=пишет Ñообщение
service.gui.PROBLEMS_ENCOUNTERED=Ð’ÑтречающиеÑÑ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ñ‹
@@ -428,11 +436,11 @@ service.gui.QUIT=&Выйти
service.gui.READY=Готово
service.gui.RECENT_MESSAGES=ПоÑледние разговоры
service.gui.REASON=Причина
+service.gui.RECEIVED={0} получено
service.gui.RECONNECTION_LIMIT_EXCEEDED=Ð’Ñ‹ были отключены и подключены к Ñерверу Ñлишком быÑтро. Следующий аккаунт: Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ: {0}, Сервер: {1} временно заблокирован и придетÑÑ Ð½ÐµÐ¼Ð½Ð¾Ð³Ð¾ подождать, прежде чем пробовать войти Ñнова.
service.gui.RE_REQUEST_AUTHORIZATION=Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð¾Ð¹ авторизации
service.gui.REFERRED_STATUS=Переведен
service.gui.REJECT=&Отклонить
-service.gui.REMIND_ME_LATER=Ðапомнить мне позже
service.gui.REMEMBER_PASSWORD=Запомнить пароль
service.gui.REMOVE=&Удалить
service.gui.REMOVE_ACCOUNT=&Удалить аккаунт
@@ -447,7 +455,8 @@ service.gui.RENAME_CONTACT=Переименовать &контакт
service.gui.RENAME_CONTACT_WIZARD=Ð’ поле ниже можно указать имÑ, которое вы хотели бы иÑпользовать Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ контакта.
service.gui.RENAME_GROUP=Переименовать &группу
service.gui.RENAME_GROUP_INFO=Ð’ поле ниже можно указать название, которое хотите иÑпользовать Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ группы.
-service.gui.RINGING_STATUS=Вызываю
+service.gui.RENAME_CLEAR_USER_DEFINED=ВоÑÑтановить
+service.gui.RINGING_STATUS=Звонит
service.gui.REQUEST=&ЗапроÑ
service.gui.REQUEST_AUTHORIZATION=&Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ð¸
service.gui.REQUEST_AUTHORIZATION_MSG=Ðе удаетÑÑ Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ {0} в ÑпиÑок контактов. {0} должен разрешить Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° добавление. ПожалуйÑта, введите Ваш Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð¸Ð¶Ðµ.
@@ -457,27 +466,23 @@ service.gui.REVOKE_ADMIN=ИÑключить из админиÑтраторов
service.gui.REVOKE_MODERATOR=ИÑключить из модераторов
service.gui.REVOKE_MEMBERSHIP=Ðннулировать членÑтво
service.gui.REVOKE_VOICE=ИÑключить из голоÑованиÑ
-service.gui.ROOT_GROUP=ÐšÐ¾Ñ€Ð½ÐµÐ²Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð°
service.gui.SAVE=&Сохранить
-service.gui.SAVE_AS_DEFAULT=Сохранить по умолчанию
service.gui.SEARCH=&ПоиÑк
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Ðажмите кнопку ниже, чтобы показать вÑе чаты, ÑущеÑтвующие на выбранном Ñервере. Затем выберите тот, в который хотите приÑоединитьÑÑ Ð¸ нажмите на кнопку ÑоединениÑ.
service.gui.SEARCH_STRING_CONTACT_SOURCE=ПоиÑк контактов
service.gui.SECURITY=БезопаÑноÑÑ‚ÑŒ
service.gui.SELECT_ACCOUNT=Выбрать аккаунт
+service.gui.SELECT_ACCOUNT_INFO=Какую учётную запиÑÑŒ вы хотите иÑпользовать Ð´Ð»Ñ ÑвÑзи Ñ Ñтим контактом?
service.gui.SELECT_COLOR=Выбрать цвет
service.gui.SELECT_GROUP=Выбрать группу
-service.gui.SELECT_GROUP_WIZARD_MSG=ПредÑтавленный ниже ÑпиÑок Ñодержит вÑе группы в ÑпиÑке контактов. Выберите одну, которую хотите добавить новый контакт.
+service.gui.SELECT_GROUP_INFO=Под какой группой вы хотите отобразить Ñтот контакт? (ÐеобÑзательно)
service.gui.SELECT_NO_GROUP=Без группы
-service.gui.SELECT_GROUP_WIZARD=Укажите группу
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=ПредÑтавленный ниже ÑпиÑок Ñодержит вÑе учетные запиÑи, которые поддерживают многопользовательÑкий чат. Выберите тот, который хотите иÑпользовать Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ð¸.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=Приведенный ниже перечень Ñодержит вÑе зарегиÑтрированные учетные запиÑи. Выберите ту, которую хотите иÑпользовать Ð´Ð»Ñ Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñ Ð½Ð¾Ð²Ñ‹Ð¼ контактом.
-service.gui.SELECT_PROVIDERS_WIZARD=Выберите аккаунт
+service.gui.SELECT_VIDEO_CONFERENCE=Выбрать видеоконференцию
+service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Выберите чат-комнату из ÑпиÑка и нажмите OK чтобы добавить ее
service.gui.SEND=&Отправить
service.gui.SEND_FILE=Отправить &файл
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± Ñтом контакте отÑутÑтвует.
service.gui.SEND_MESSAGE=&Отправить Ñообщение
-service.gui.SEND_AS_SMS=Отправить как SMS
service.gui.SEND_PRIVATE_MESSAGE=Отправить личное Ñообщение
service.gui.SEND_SMS=Отправить SMS
service.gui.SEND_SMS_DETAILS=Помните, что вам нужно ввеÑти номер телефона в международном формате, например, Ð½Ð°Ñ‡Ð¸Ð½Ð°Ñ Ñ +7 Ð´Ð»Ñ Ð Ð¾ÑÑии, +78001112233
@@ -485,13 +490,13 @@ service.gui.SEND_SMS_NOT_SUPPORTED=Выбранный протокол не по
service.gui.SMS=СМС
service.gui.SEND_VIA=Отправить по
service.gui.SENT=поÑланный
-service.gui.SERVER_CHAT_ROOMS=Сервер комнаты
+service.gui.SERVER_CHAT_ROOMS=Серверные чат комнаты
service.gui.SET_GLOBAL_STATUS=УÑтановить глобальный ÑтатуÑ
service.gui.SET_STATUS_MESSAGE=УÑтановить ÑÑ‚Ð°Ñ‚ÑƒÑ ÑообщениÑ
service.gui.SET_SUBJECT=Задать тему
service.gui.SETTINGS=&Опции
-service.gui.SHARE_DESKTOP=&Открыть рабочий Ñтол
-service.gui.SHARE_DESKTOP_WITH_CONTACT=Открыть рабочий Ñтол контакту
+service.gui.SHARE_DESKTOP=&ПредоÑтавить доÑтуп к рабочему Ñтолу
+service.gui.SHARE_DESKTOP_WITH_CONTACT=ПредоÑтавить контакту доÑтуп к рабочему Ñтолу
service.gui.SHARE_FULL_SCREEN=Открыть рабочий Ñтол в полноÑкранном режиме
service.gui.SHARE_REGION=Открыть чаÑÑ‚ÑŒ
service.gui.SHOW=Показать
@@ -516,21 +521,19 @@ service.gui.STREET=Улица
service.gui.SUBJECT=Тема
service.gui.SUMMARY=Сводка
service.gui.TELEPHONY=ТелефониÑ
-service.gui.TODAY=СегоднÑ
service.gui.TOOLS=&ИнÑтрументы
service.gui.TRANSFER=Передача
service.gui.TO=&Кому:
service.gui.TRANSFER_CALL_MSG=Выберите контакт, который хотите передать, и нажмите Передача.
-service.gui.TRANSFER_CALL_TITLE=ПеревеÑти звонок
+service.gui.TRANSFER_CALL_TITLE=Передача вызова
service.gui.TRANSFER_CALL_TO=Перевод на:
-service.gui.TRANSPARENCY_NOT_ENABLED=ПрозрачноÑÑ‚ÑŒ не поддерживаетÑÑ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ¹ конфигурацией.
+service.gui.TRANSPARENCY_NOT_ENABLED=ПрозрачноÑÑ‚ÑŒ не поддерживаетÑÑ Ð²Ð°ÑˆÐµÐ¹ текущей конфигурацией.
service.gui.TYPE_YOUR_REQUEST=Введите Ñвой Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð·Ð´ÐµÑÑŒ
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Ðе удалоÑÑŒ изменить качеÑтво видео Ð´Ð»Ñ Ñтого вызова.
-service.gui.UNMUTE=Включить звук
service.gui.USER_IDENTIFIER=Идентификатор пользователÑ:
service.gui.USER_EXISTS_ERROR=Этот пользователь уже ÑущеÑтвует в выбранной Ñети. ПожалуйÑта, выберите другого Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ Ñеть.
service.gui.USERNAME_NULL=ПожалуйÑта, заполните Ñвое Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸ пароль.
-service.gui.WEBPAGE=Открыть веб Ñтраницу
+service.gui.WEBPAGE=Открыть веб-Ñтраницу
service.gui.ACCOUNT_CREATION_FAILED=Мы не Ñмогли Ñоздать учетную запиÑÑŒ из-за Ñледующей ошибки: {0}
service.gui.UNKNOWN=ÐеизвеÑтный пользователь
service.gui.UNKNOWN_STATUS=ÐеизвеÑтное ÑоÑтоÑние
@@ -539,13 +542,12 @@ service.gui.USE_PROVISIONING=ИÑпользовать автонаÑтройку
service.gui.VALUE=Значение
service.gui.VIDEO_CALL=&Видеовызов
service.gui.VIA=через
-service.gui.VIA_SMS=Через SMS
service.gui.VIEW=&Показать
service.gui.VIEW_HISTORY=Показать &иÑторию
service.gui.VIEW_SMILEYS=Показать &Ñмайлы
service.gui.VIEW_TOOLBAR=Показать &тулбар
service.gui.VIEW_SIMPLE_CHAT_THEME=ПроÑтой вид чата
-service.gui.VOICEMAIL_NEW_URGENT_OLD_RECEIVED={0} новых ({1} важных) и {2} Ñтарых Ñообщений
+service.gui.VOICEMAIL_NEW_URGENT_OLD_RECEIVED={0} новых ({1} Ñрочных) и {2} Ñтарых Ñообщений
service.gui.VOICEMAIL_NEW_URGENT_RECEIVED={0} новых ({1} Ñрочных) Ñообщений
service.gui.VOICEMAIL_NEW_OLD_RECEIVED={0} новых и {1} Ñтарых Ñообщений
service.gui.VOICEMAIL_NEW_RECEIVED={0} новых Ñообщений
@@ -553,15 +555,12 @@ service.gui.VOICEMAIL_OLD_RECEIVED={0} Ñтарых Ñообщений
service.gui.VOICEMAIL_NO_MESSAGES=Ðет Ñообщений.
service.gui.VOICEMAIL_TITLE=ГолоÑовые ÑообщениÑ
service.gui.VOICEMAIL_TOOLTIP=ГолоÑовые ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð´Ð»Ñ:
-service.gui.VOICEMAIL_TIP=Ðажмите кнопку вызова Ð´Ð»Ñ Ð¿Ñ€Ð¾ÑÐ»ÑƒÑˆÐ¸Ð²Ð°Ð½Ð¸Ñ Ñообщений.
+service.gui.VOICEMAIL_TIP=Ðажмите кнопку вызова, чтобы проÑлушать ваши ÑообщениÑ.
service.gui.VOICEMAIL_TIP_NO_ACCOUNT=ПожалуйÑта, наÑтройте URI Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ голоÑовой почты в учетной запиÑи
service.gui.VOLUME_CONTROL_TOOL_TIP=Регулировка громкоÑти
service.gui.WAITING_AUTHORIZATION=Ожидание авторизации
service.gui.WARNING=Предупреждение
service.gui.YES=Да
-service.gui.YESTERDAY=Вчера
-service.gui.EXISTING_ACCOUNT_ERROR=Введенный аккаунт уже уÑтановлен.
-service.gui.NEW_MAIL=<b>У Ð’Ð°Ñ Ð¾Ð´Ð½Ð¾ новое пиÑьмо!</b><br/><b>От:</b> {0} {1} <br/><b>Тема:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=Ð’Ñ‹ получили новое пиÑьмо во {0} <a href="{1}">входÑщие</a>:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=Ð’Ñ‹ получили {2} новых пиÑьма во {0} <a href="{1}">входÑщие</a>:<br/>
service.gui.NEW_GMAIL_FOOTER=еще один непрочитанный разговор во<a href="{0}">входÑщих</a>.<br/>
@@ -569,13 +568,17 @@ service.gui.NEW_GMAIL_MANY_FOOTER={1} еще непрочитанный разг
service.gui.ACTIVATE=Ðктивировать
service.gui.DEACTIVATE=Деактивировать
service.gui.NEW=Ðовый
-service.gui.ENTER_FULL_SCREEN_TOOL_TIP=Развернуть на веÑÑŒ Ñкран
+service.gui.ENTER_FULL_SCREEN_TOOL_TIP=Войти в полноÑкранный режим
service.gui.EXIT_FULL_SCREEN_TOOL_TIP=Выйти из полноÑкранного режима
service.gui.HOLD_BUTTON_TOOL_TIP=Удержание разговора
service.gui.MUTE_BUTTON_TOOL_TIP=Выключить микрофон или удерживайте кнопку Ð´Ð»Ñ Ð½Ð°Ñтройки громкоÑти микрофона
+service.gui.PARK=Удержание
+service.gui.PARKING_SLOT=МеÑто Ð´Ð»Ñ ÑƒÐ´ÐµÑ€Ð¶Ð°Ð½Ð¸Ñ:
+service.gui.PARK_BUTTON_TOOL_TIP=ПоÑтавить звонок на удержание
service.gui.RECORD_BUTTON_TOOL_TIP=ЗапиÑÑŒ разговора
service.gui.LOCAL_VIDEO_BUTTON_TOOL_TIP=Включить видеоÑвÑзь
service.gui.SHOW_LOCAL_VIDEO_BUTTON_TOOL_TIP=Показать/Ñкрыть Ñвое видео
+service.gui.SHOW_HIDE_PEERS_TOOL_TIP=Показать/Ñкрыть ÑпиÑок учаÑтников конференции
service.gui.TRANSFER_BUTTON_TOOL_TIP=ПереадреÑовать вызов
service.gui.TRANSFER_TO=ПереадреÑовать на...
service.gui.SECURITY_INFO=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ безопаÑноÑти
@@ -584,14 +587,15 @@ service.gui.SECURITY_ERROR=Ошибка безопаÑноÑти
service.gui.SPEED=СкороÑÑ‚ÑŒ:
service.gui.SILENT_MEMBER=молчаливый учаÑтник
service.gui.NON_SECURE_CONNECTION=БезопаÑное Ñоединение не может быть уÑтановлено Ð´Ð»Ñ {0}. ЕÑли Ð’Ñ‹ хотите иÑпользовать незащищенное подключение, пожалуйÑта, уÑтановите флажок "Разрешить незащищенные ÑоединениÑ" в конфигурации учетной запиÑи
-service.gui.UPDATE=Обновить
service.gui.MOBILE_PHONE=Мобильный
service.gui.VIDEO_PHONE=Видеовызовы
service.gui.WORK_PHONE=Рабочий
service.gui.PHONE=Телефон
service.gui.PHONES=Телефон
service.gui.EDIT_NOT_SUPPORTED=Редактирование Ñтой учетной запиÑи не поддерживаетÑÑ
-service.gui.SHOW_PREVIEW=(показать превью)
+service.gui.SHOW_PREVIEW=(предварительный проÑмотр)
+service.gui.SHOW_PREVIEW_WARNING_DESCRIPTION=Ð’Ñ‹ хотите отобразить Ñто изображение ?\n\nИмейте в виду, что предпроÑмотр изображений/видео можеть нарушить Вашу анонимноÑÑ‚ÑŒ и раÑкрыть Вашу активноÑÑ‚ÑŒ в Ñети.
+service.gui.SHOW_PREVIEW_DIALOG_TITLE=Показать предпроÑмотр изображениÑ/видео
service.gui.ZID_NAME_SET=Ð˜Ð¼Ñ ZRTP идентификатора:
service.gui.ZID_NAME_NOT_SET=Ðе задано Ð¸Ð¼Ñ ZRTP идентификатора.
@@ -617,10 +621,11 @@ service.gui.callinfo.CALL_INFORMATION=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ вызове
service.gui.callinfo.CALL_IDENTITY=Ð£Ñ‡ÐµÑ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ
service.gui.callinfo.PEER_COUNT=КоличеÑтво учаÑтников
service.gui.callinfo.IS_CONFERENCE_FOCUS=КонференциÑ
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Шифрование включено
service.gui.callinfo.CALL_TRANSPORT=ТранÑпорт Ñигнализации
service.gui.callinfo.CALL_DURATION=ДлительноÑÑ‚ÑŒ вызова
service.gui.callinfo.TLS_PROTOCOL=Протокол TLS
+service.gui.callinfo.TLS_CIPHER_SUITE=набор шифров TLS
+service.gui.callinfo.TLS_CERTIFICATE_CONTENT=Содержимое Ñертификата TLS Ñервера показано ниже.
service.gui.callinfo.VIEW_CERTIFICATE=ПроÑмотр Ñертификата
service.gui.callinfo.CODEC=Кодек / ЧаÑтота
service.gui.callinfo.NA=N.A.
@@ -629,7 +634,7 @@ service.gui.callinfo.AUDIO_INFO=Ðудио поток
service.gui.callinfo.VIDEO_INFO=Видео поток
service.gui.callinfo.LOCAL_IP=Локальный IP / Порт
service.gui.callinfo.REMOTE_IP=Удаленный IP / Порт
-service.gui.callinfo.BANDWITH=ПолоÑа пропуÑканиÑ
+service.gui.callinfo.BANDWITH=ПропуÑÐºÐ½Ð°Ñ ÑпоÑобноÑÑ‚ÑŒ
service.gui.callinfo.LOSS_RATE=ÐŸÐ¾Ñ‚ÐµÑ€Ñ Ð¿Ð°ÐºÐµÑ‚Ð¾Ð²
service.gui.callinfo.RTT=RTT
service.gui.callinfo.JITTER=Джиттер
@@ -639,10 +644,14 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=Протокол обмена ключами
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=ICE кандидат раÑширенного типа
service.gui.callinfo.ICE_STATE=СоÑтоÑние ICE
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=Получение кандидатов
service.gui.callinfo.ICE_STATE.RUNNING=Проверка подключениÑ
service.gui.callinfo.ICE_STATE.COMPLETED=Завершено
service.gui.callinfo.ICE_STATE.FAILED=Ошибка
+service.gui.callinfo.ICE_STATE.TERMINATED=Завершённый
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=Локальный IP / Порт
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=Локальный входÑщий IP / Порт
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=Локальный иÑходÑщий IP / Порт
@@ -655,35 +664,42 @@ service.gui.callinfo.HARVESTING_MS_FOR=Ð¼Ñ (длÑ
service.gui.callinfo.HARVESTS=результатов)
service.gui.callinfo.DECODED_WITH_FEC=Пакетов декодированных Ñ FEC
service.gui.callinfo.DISCARDED_PERCENT=Отброшенных пакетов
-service.gui.callinfo.DISCARDED_TOTAL=Ð’Ñего отброшенных пакетов
+service.gui.callinfo.DISCARDED_TOTAL=КоличеÑтво отброшенных пакетов
+service.gui.callinfo.ADAPTIVE_JITTER_BUFFER=Ðдаптивный буфер Ñинхронизации
+service.gui.callinfo.JITTER_BUFFER_DELAY=Буфер Ñинхронизации
service.gui.ALWAYS_TRUST=Ð’Ñегда доверÑÑ‚ÑŒ Ñтому Ñертификату
service.gui.CERT_DIALOG_TITLE=Проверить Ñертификат
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} не может проверить подлинноÑÑ‚ÑŒ Ñервера при подключении к<br><b>{1}</b>.<br><br>Сертификат не ÑвлÑетÑÑ Ð´Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ñ‹Ð¼, Ñто означает, что Ñервер не может быть автоматичеÑки проверен.<br><br>Ð’Ñ‹ хотите продолжить подключение?<br> Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации, нажмите кнопку "Показать Ñертификат".</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0} не может проверить подлинноÑÑ‚ÑŒ Ñертификата Ñервера.<br><br>Сертификат не ÑвлÑетÑÑ Ð´Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ñ‹Ð¼. Это означает, что Ñервер не<br> может быть автоматичеÑки проверен.Ð’Ñ‹ хотите продолжить подключение?<br><br> Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации, нажмите кнопку "Показать Ñертификат".</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} не может проверить подлинноÑÑ‚ÑŒ клиента.<br><br> Сертификат не ÑвлÑетÑÑ Ð´Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ñ‹Ð¼, Ñто означает, что клиент не<br> может быть автоматичеÑки проверен. Ð’Ñ‹ хотите принÑÑ‚ÑŒ подключение?<br><br> Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации, нажмите кнопку "Показать Ñертификат".</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} не может проверить подлинноÑÑ‚ÑŒ клиента {1}.<br><br> Сертификат не ÑвлÑетÑÑ Ð´Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ñ‹Ð¼, Ñто означает, что клиент не<br> может быть автоматичеÑки проверен. Ð’Ñ‹ хотите продолжить подключение?<br><br> Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации, нажмите кнопку "Показать Ñертификат".</html>
service.gui.CONTINUE_ANYWAY=Ð’Ñе равно продолжить
+service.gui.CERT_INFO_CHAIN=Цепочка Ñертификатов:
+service.gui.CERT_INFO_ISSUED_TO=Выпущен длÑ
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Ð˜Ð¼Ñ Ñертификата:
service.gui.CERT_INFO_O=ОрганизациÑ:
service.gui.CERT_INFO_C=Страна:
service.gui.CERT_INFO_ST=Штат или облаÑÑ‚ÑŒ:
service.gui.CERT_INFO_L=ÐаÑеленный пункт:
+service.gui.CERT_INFO_ISSUED_BY=Выдан
service.gui.CERT_INFO_OU=Подразделение:
+service.gui.CERT_INFO_VALIDITY=Срок дейÑтвиÑ
service.gui.CERT_INFO_ISSUED_ON=ДейÑтвителен Ñ:
service.gui.CERT_INFO_EXPIRES_ON=ДейÑтвителен по:
-service.gui.CERT_INFO_FINGERPRINTS=Ключ
+service.gui.CERT_INFO_FINGERPRINTS=Отпечатки
+service.gui.CERT_INFO_CERT_DETAILS=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ Ñертификате
service.gui.CERT_INFO_SER_NUM=Серийный номер:
service.gui.CERT_INFO_VER=ВерÑиÑ:
service.gui.CERT_INFO_SIGN_ALG=Ðлгоритм подпиÑи:
+service.gui.CERT_INFO_PUB_KEY_INFO=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± открытом ключе
service.gui.CERT_INFO_ALG=Ðлгоритм:
service.gui.CERT_INFO_PUB_KEY=Открытый ключ:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} байт: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} бит
service.gui.CERT_INFO_EXP=ЭкÑпонента:
service.gui.CERT_INFO_KEY_SIZE=Размер ключа:
service.gui.CERT_INFO_SIGN=ПодпиÑÑŒ:
-service.gui.CONTINUE=Продолжить
service.gui.SHOW_CERT=Показать Ñертификат
service.gui.HIDE_CERT=Скрыть Ñертификат
@@ -699,26 +715,26 @@ service.gui.AUTO_ANSWER_FWD_CALLS=ПереадреÑÐ°Ñ†Ð¸Ñ Ð·Ð²Ð¾Ð½ÐºÐ¾Ð²
service.gui.AUTO_ANSWER_FWD_CALLS_TO=ПереадреÑовывать вÑе звонки на номер или URI:
service.gui.AUTO_ANSWER_VIDEO=Видеовызовы
service.gui.AUTO_ANSWER_VIDEO_CALLS_WITH_VIDEO=Отвечать на видеозвонки Ñ Ð²Ð¸Ð´ÐµÐ¾
+service.gui.LOCAL_VIDEO_ERROR_TITLE=Ошибка Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ñ‹Ð¼ видео
+service.gui.LOCAL_VIDEO_ERROR_MESSAGE=Ðевозможно включить/выключить локальное видео.
service.gui.security.SECURE_AUDIO=Ðудиопоток защищен
service.gui.security.AUDIO_NOT_SECURED=Ðудиопоток не защищен
service.gui.security.SECURE_VIDEO=Видеопоток защищен
service.gui.security.VIDEO_NOT_SECURED=Видеопоток не защищен
-service.gui.security.NO_VIDEO=Ðет видео
-service.gui.security.CIPHER=Шифр: {0}
service.gui.security.CALL_SECURED_TOOLTIP=Разговор защищен. Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸ нажмите Ñюда.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Разговор не защищен.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Ðажмите здеÑÑŒ, чтобы Ñверить ключ Ñ ÑобеÑедником.
-service.gui.security.COMPARE_WITH_PARTNER=Сверьте ключ Ñ ÑобеÑедником и нажмите замочек Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Сверьте ключ Ñ ÑобеÑедником:
service.gui.security.STRING_COMPARED=Ключ подтвержден!
+service.gui.security.SAS_INFO_TOOLTIP=<html>Чтобы полноÑтью быть защищённым, Вам<br/>Ñледует голоÑом <b>Ñверить</b>короткую<br/>Ñтроку аутентификации, указанную здеÑÑŒ,<br/>Ñ Ð¿Ð°Ñ€Ñ‚Ð½ÐµÑ€Ð¾Ð¼ и нажать кнопку подтверждениÑ, когда <br/>Ñтрока будет проверена.<br/><br/>ЕÑли Ð’Ñ‹ очиÑтите подтверждение, Вам потребуетÑÑ Ð·Ð°Ð½Ð¾Ð²Ð¾ проверÑÑ‚ÑŒ ÑобеÑедника<br/>при Ñледующем звонке Ñтому партнеру.</html>
service.gui.security.SECURITY_ALERT=Ð˜Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð·Ð°Ñ‰Ð¸Ñ‚Ñ‹ вызова. Отключение через
-service.gui.avatar.CHOOSE_ICON=Выбрать аватар
+service.gui.avatar.CHOOSE_ICON=Выбрать картинку
service.gui.avatar.REMOVE_ICON=Удалить текущий аватар
service.gui.avatar.CLEAR_RECENT=ОчиÑтить ÑпиÑок
-service.gui.avatar.RECENT_ICONS=Ðватары:
+service.gui.avatar.RECENT_ICONS=Ðедавние картинки:
# service.gui.avatar.imagepicker
service.gui.avatar.imagepicker.CANCEL=Отмена
service.gui.avatar.imagepicker.CHOOSE_FILE=Обзор ...
@@ -726,19 +742,20 @@ service.gui.avatar.imagepicker.CLICK=Сделать Ñнимок
service.gui.avatar.imagepicker.IMAGE_FILES=Файлы изображений
service.gui.avatar.imagepicker.IMAGE_PICKER=Изображение
service.gui.avatar.imagepicker.IMAGE_SIZE=Размер изображениÑ
-service.gui.avatar.imagepicker.INITIALIZING=ИнициализациÑ
service.gui.avatar.imagepicker.RESET=СброÑ
service.gui.avatar.imagepicker.SET=Задать
service.gui.avatar.imagepicker.TAKE_PHOTO=Сделать Ñнимок
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Ошибка вебкамеры
service.gui.security.encryption.required=ТребуетÑÑ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ!
+service.protocol.ICE_FAILED=Ðевозможно уÑтановить подключение (Ñбой ICE, не найдено транÑлÑции)
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
+service.systray.MODE=Ð ÐµÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð»Ð¾Ñ‚ÐºÐ°
+service.systray.mode.NATIVE=ИÑходный
+service.systray.mode.DISABLED=Деактивирован
+service.systray.mode.APPINDICATOR=Индикатор Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ (Unity, KDE, неÑÑно Ñ Gnome 3; может упаÑÑ‚ÑŒ на Debian)
+service.systray.mode.APPINDICATOR_STATIC=СтатичеÑкий индикатор Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ (нет меню ÑоÑтоÑÐ½Ð¸Ñ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð¾Ð¹ запиÑи)
+service.systray.CLI_NOTE=ЕÑли ваш выбор не работает, вы можете выполнить {0} Ñ Ð¾Ð¿Ñ†Ð¸ÐµÐ¹ "--notray". Это принудительно переведёт ÑÑ‚Ð°Ñ‚ÑƒÑ Ð² положение "Деактивирован" и покажет графичеÑкий интерфейÑ. Изменение ÑоÑтоÑÐ½Ð¸Ñ Ð»Ð¾Ñ‚ÐºÐ° требует перезапуÑка.
impl.protocol.sip.XCAP_ERROR_TITLE=Ошибка в адреÑной книге SIP
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=РеÑÑƒÑ€Ñ Ð½Ðµ может быть прочитан {0}. Ð”Ð»Ñ {1}
@@ -764,9 +781,11 @@ impl.ldap.GENERAL=Общие
impl.ldap.FIELDS=ПолÑ
impl.ldap.QUERY=ЗапроÑ
impl.ldap.QUERY_DEFAULT=Создать автоматичеÑки
-impl.ldap.NEW=Ðовый
+impl.ldap.QUERY_CUSTOM=Индивидуальный запроÑ
+impl.ldap.QUERY_CUSTOM_HINT=ИÑпользуйте {0} в качеÑтве шаблона Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка термина.
+impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=ÐвтоматичеÑки добавить метаÑимволы в текÑÑ‚ запроÑа
+impl.ldap.QUERY_PHOTO_INLINE=Получать фото вмеÑте Ñ Ð¾Ñтальными атрибутами
impl.ldap.EDIT=изменить
-impl.ldap.REMOVE=Удалить
impl.ldap.ENABLED=Ðктивен
impl.ldap.SERVER_NAME=Краткое имÑ
impl.ldap.SERVER_NAME_EXAMPLE=ÐдреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° LDAP
@@ -799,21 +818,27 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=homePhone
impl.ldap.PHONE_PREFIX=Телефонный префикÑ
impl.ldap.PHONE_PREFIX_EXAMPLE=Ðапример: +7
+# SIP Protocol
+impl.protocol.sip.INVALID_ADDRESS=''{0}'' не ÑвлÑетÑÑ Ð´ÐµÐ¹Ñтвительным SIP адреÑом.
+
+#Jabber Protocol
+impl.protocol.jabber.INVALID_ADDRESS=''{0}'' не ÑвлÑетÑÑ Ð´ÐµÐ¹Ñтвительным XMPP JID.
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=ÐдреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð°
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=Включить поиÑк в адреÑной книге MacOSX
plugin.addrbook.ENABLE_MICROSOFT_OUTLOOK=Включить поиÑк контактов в Microsoft Outlook
plugin.addrbook.DESCRIPTION=ЕÑли включено, будет производитьÑÑ Ð¿Ð¾Ð¸Ñк в ÑиÑтемной адреÑной книге и вÑе ÑоответÑтвующие контакты из адреÑной книги поÑвÑÑ‚ÑÑ Ð² вашем ÑпиÑке контактов.
-plugin.addrbook.DEFAULT_IM_APP=Сделать Jitsi клиентом Ð´Ð»Ñ Ð¼Ð³Ð½Ð¾Ð²ÐµÐ½Ð½Ð¾Ð³Ð¾ обмена ÑообщениÑми по умолчанию (Ð˜Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ð¸Ñ Ñ Outlook)
+plugin.addrbook.DEFAULT_IM_APP=Сделать Jitsi клиентом Ð´Ð»Ñ Ð¾Ð±Ð¼ÐµÐ½Ð° мгновенными ÑообщениÑми по умолчанию (Ð˜Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ð¸Ñ Ñ Outlook)
plugin.addrbook.PREFIX=Телефонный префикÑ
plugin.addrbook.PREFIX_EXAMPLE=Ðапример: +7
+plugin.addrbook.OUTLOOK_IS_NOT_DEFAULT_MAIL_CLIENT_TITLE=Ошибка доÑтупа к контактам Microsoft Outlook
+plugin.addrbook.OUTLOOK_IS_NOT_DEFAULT_MAIL_CLIENT={0} не может в данный момент получить доÑтуп к контактам Microsoft Outlook, так как Outlook не ÑвлÑетÑÑ Ð¿Ð¾Ñ‡Ñ‚Ð¾Ð²Ð¾Ð¹ программой по умолчанию.
plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT=Сделать Outlook почтовым клиентом по умолчанию
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Контакты Google
-impl.googlecontacts.NEW=Ðовый
impl.googlecontacts.EDIT=изменить
-impl.googlecontacts.REMOVE=Удалить
impl.googlecontacts.ENABLED=Ðктивен
impl.googlecontacts.ACCOUNT_NAME=Ðккаунт
impl.googlecontacts.SAVE=Сохранить
@@ -822,6 +847,10 @@ impl.googlecontacts.USERNAME=Ð˜Ð¼Ñ Ð°ÐºÐºÐ°ÑƒÐ½Ñ‚Ð°
impl.googlecontacts.PASSWORD=Пароль
impl.googlecontacts.PREFIX=Телефонный префикÑ
impl.googlecontacts.WRONG_CREDENTIALS=Ðеверные данные Ð´Ð»Ñ Ð°ÐºÐºÐ°ÑƒÐ½Ñ‚Ð° Google {0}
+impl.googlecontacts.OAUTH_DIALOG_TITLE=ÐÐ²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñ‡ÐµÑ€ÐµÐ· Google Контакты
+impl.googlecontacts.INSTRUCTIONS=<html><p><b>Ðажмите на ÑÑылку ниже, чтобы утвердить плагину Google Контакты доÑтуп к учётной запиÑи.</b><br><br> Ðажав на ÑÑылку, в вашем обозревателе откроетÑÑ Ð²ÐµÐ±-Ñтраница. Войдите в требуемую учётную запиÑÑŒ и подтвердите доÑтуп. ПоÑле утверждениÑ, Google покажет вам код. Скопируйте Ñтот код в текÑтовое поле ниже и нажмите 'Сохранить' </p><p>Это Ð¾Ð´Ð½Ð¾Ñ€Ð°Ð·Ð¾Ð²Ð°Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ. Токен авторизации будет Ñохранён Ð´Ð»Ñ Ð¿Ð¾Ñледующего иÑпользованиÑ.</p></html>
+impl.googlecontacts.CODE=Код:
+impl.googlecontacts.HYPERLINK_TEXT=Ðажмите здеÑÑŒ, чтобы одобрить доÑтуп к {0}
# account info
plugin.accountinfo.TITLE=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± аккаунте
@@ -836,26 +865,27 @@ plugin.accountinfo.NICKNAME=Ðик:
plugin.accountinfo.URL=URL:
plugin.accountinfo.AGE=ВозраÑÑ‚:
plugin.accountinfo.BDAY=Дата рождениÑ:
+plugin.accountinfo.BDAY_FORMAT=МММ дд, гггг
plugin.accountinfo.GENDER=Пол:
plugin.accountinfo.STREET=ÐдреÑ:
plugin.accountinfo.CITY=Город:
plugin.accountinfo.REGION=ОблаÑÑ‚ÑŒ:
plugin.accountinfo.POST=Почтовый индекÑ:
-plugin.accountinfo.COUNTRY=Страна
+plugin.accountinfo.COUNTRY=Страна:
plugin.accountinfo.EMAIL=Электронный Ñщик:
+plugin.accountinfo.WORK_EMAIL=Рабочий E-mail:
plugin.accountinfo.PHONE=Телефон:
+plugin.accountinfo.WORK_PHONE=Рабочий телефон:
plugin.accountinfo.MOBILE_PHONE=Мобильный телефон:
plugin.accountinfo.ORGANIZATION=ОрганизациÑ:
plugin.accountinfo.JOB_TITLE=ДолжноÑÑ‚ÑŒ:
plugin.accountinfo.ABOUT_ME=Обо мне:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
-plugin.accountinfo.USER_PICTURES=Фотографии пользователÑ
plugin.accountinfo.GLOBAL_ICON=ИÑпользовать общий значок
plugin.accountinfo.LOCAL_ICON=ИÑпользовать Ñледующий значок:
-plugin.accountinfo.CHANGE=Изменить
-plugin.accountinfo.ONLY_MESSAGE=Только ÑообщениÑ
# connection info
+plugin.connectioninfo.TITLE=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ Ñоединении
# contact info
plugin.contactinfo.TITLE=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ контакте
@@ -863,7 +893,7 @@ plugin.contactinfo.CONTACT_SUMMARY_DESCRIPTION=Ð¡ÑƒÐ¼Ð¼Ð°Ñ€Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°
plugin.contactinfo.CONTACT_EXTENDED_DESCRIPTION=РаÑширенный контактные данные
plugin.contactinfo.NOT_SPECIFIED=[Ðе указано]
plugin.contactinfo.USER_PICTURES=Ð¤Ð¾Ñ‚Ð¾Ð³Ñ€Ð°Ñ„Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ
-plugin.contactinfo.USER_STATUS_MESSAGE=СтатуÑ
+plugin.contactinfo.USER_STATUS_MESSAGE=Сообщение о ÑоÑтоÑнии
# aimaccregwizz
plugin.aimaccregwizz.PROTOCOL_NAME=AIM
@@ -872,62 +902,24 @@ plugin.aimaccregwizz.USERNAME=AIM ИмÑ:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Идентификатор Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸ пароль
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð¹ учетной запиÑи
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Ð’ Ñлучае, еÑли вы не имеете учетной запиÑи AIM, нажмите на Ñту кнопку, чтобы Ñоздать новую.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Переопределить параметры Ñервера по умолчанию
# branding
plugin.branding.ABOUT_WINDOW_TITLE=О Ð½Ð°Ñ {0}
plugin.branding.LOGO_MESSAGE=Open Source VoIP && Обмен мгновенными ÑообщениÑми
-plugin.branding.LOADING=Загрузка
plugin.branding.ABOUT_MENU_ENTRY=&О программе
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>{1} в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð² Ñтадии активной разработки. ВерÑиÑ, Ð·Ð°Ð¿ÑƒÑ‰ÐµÐ½Ð½Ð°Ñ Ð²Ð°Ð¼Ð¸, ÑкÑÐ¿ÐµÑ€Ð¸Ð¼ÐµÐ½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð¸ может работать ÐЕ ТÐК как вы ожидаете. ПожалуйÑта, обратитеÑÑŒ к {2} Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 Copyright <b>jitsi.org</b>. Ð’Ñе права защищены. ПоÑетите <a href="https://jitsi.org">https://jitsi.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}><b>Jitsi</b> раÑпроÑтранÑетÑÑ Ð¿Ð¾ лицензии LGPL (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=Словари
-plugin.dictaccregwizz.ANY_DICTIONARY=Любой Ñловарь
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Любой Ñловарь от {0}
-plugin.dictaccregwizz.FIRST_MATCH=Первое Ñовпадение
-plugin.dictaccregwizz.NO_MATCH=Ðет Ñовпадений
-plugin.dictaccregwizz.MATCH_RESULT=Определений Ð´Ð»Ñ "{0}" не найдено, может быть, вы имеете в виду:\n
-plugin.dictaccregwizz.INVALID_DATABASE=Текущего ÑÐ»Ð¾Ð²Ð°Ñ€Ñ "{0}" не ÑущеÑтвует на Ñервере.
-plugin.dictaccregwizz.INVALID_STRATEGY=ÐынешнÑÑ ÑÑ‚Ñ€Ð°Ñ‚ÐµÐ³Ð¸Ñ Ð¾Ñ‚ÑутÑтвует на Ñервере.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=DICT протокол
-plugin.dictaccregwizz.HOST=ХоÑÑ‚
-plugin.dictaccregwizz.SERVER_INFO=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ Ñервере
-plugin.dictaccregwizz.STRATEGY_SELECTION=Выбор метода
-plugin.dictaccregwizz.STRATEGY_LIST=СпиÑок методов:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=ПоиÑк методов
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=ИÑпользовать метод Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка похожих Ñлов, еÑли перевод не был найден, Ð±Ð»Ð°Ð³Ð¾Ð´Ð°Ñ€Ñ Ñ€Ð°Ð·Ð½Ñ‹Ð¼ методам. Ðапример, номера Ñтратегии будет иÑкать Ñлова, которые начинаютÑÑ, как Ñлово, которое вы бы перевеÑти.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± учетной запиÑи
-plugin.dictaccregwizz.FIRST_ACCOUNT=Этот маÑтер поможет Ñоздать ваш первый аккаунт на Ñайте dict.org.\n\nÐ’Ñ‹ можете добавить новый Ñловарь Ð¿Ñ€Ð¾Ð¹Ð´Ñ Ñ€ÐµÐ³Ð¸Ñтрацию учетной запиÑи в маÑтере. Заполните Ð¿Ð¾Ð»Ñ ÑÐ»Ð¾Ð²Ð°Ñ€Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ð¹ вы хотели бы добавить.
-plugin.dictaccregwizz.THREAD_CONNECT=Попытка Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº Ñерверу
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=Попытка Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð½Ðµ удалаÑÑŒ, Ñто не Ñервер Ñловарей или Ñервер недоÑтупен
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=Получение метода
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Метод не найден на Ñервере
-plugin.dictaccregwizz.POPULATE_LIST=Заполнение ÑпиÑка
-plugin.dictaccregwizz.CLOSING_CONNECTION=Закрытие ÑоединениÑ
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы иÑпользовать Facebook чат необходимо Ñоздать "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" <br>в "ÐаÑтройках аккаунта " на Facebook.</a><br><br>Примечание: При Ñоздании имени Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½ÐµÐ¾Ð±Ñ…Ð¾Ð´Ð¸Ð¼Ð¾ выйти из Ñтраницы <br>и может потребоватьÑÑ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ðµ времÑ, прежде чем вы Ñможете войти Ñ Ð²Ð°ÑˆÐ¸Ð¼ новым именем пользователÑ!</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=Протокол чата Facebook
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸ пароль
+plugin.branding.COPYRIGHT_LICENSE=<DIV><font size=3 color={0}>ÐвторÑкие права 2003-{1} <a href="{2}"><b>{3}</b></a>, Ð’Ñе права защищены.</font><br><br>{4} раÑпроÑтранÑетÑÑ Ð½Ð° уÑловиÑÑ… <a href="{5}">{6}</a>.</DIV>
+
+plugin.busylampfield.PICKUP=ПоднÑÑ‚ÑŒ трубку
# generalconfig
plugin.generalconfig.AUTO_START=ÐвтоматичеÑкий запуÑк {0} при загрузке компьютера
-plugin.generalconfig.CHATALERTS_ON_MESSAGE=ИÑпользовать панель задач / облаÑÑ‚ÑŒ уведомлений Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ñщих звонков и Ñообщений
+plugin.generalconfig.CHATALERTS_ON_MESSAGE=ИÑпользовать панель задач / облаÑÑ‚ÑŒ уведомлений Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ñщих звонков и беÑед
plugin.generalconfig.GROUP_CHAT_MESSAGES=Группировать текÑтовые чаты в одном окне
plugin.generalconfig.LOG_HISTORY=ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ñ‡Ð°Ñ‚Ð°
plugin.generalconfig.SHOW_HISTORY=Показывать
plugin.generalconfig.HISTORY_SIZE=поÑледних Ñообщений в новом чате
plugin.generalconfig.SEND_MESSAGES_WITH=ОтправлÑÑ‚ÑŒ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ нажатии:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=ПереноÑить окно чата поверх вÑех окон при входÑщем Ñообщении
-plugin.generalconfig.ERROR_PERMISSION=У Ð²Ð°Ñ Ð½ÐµÑ‚ доÑтаточных привилегий Ð´Ð»Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð¿ÑƒÑка
-plugin.generalconfig.TRANSPARENCY=ПрозрачноÑÑ‚ÑŒ
-plugin.generalconfig.ENABLE_TRANSPARENCY=Включить прозрачноÑÑ‚ÑŒ
plugin.generalconfig.DEFAULT_LANGUAGE=Язык интерфейÑа
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð²ÑтупÑÑ‚ в Ñилу при Ñледующем запуÑке Jitsi.
plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0}% переведено
@@ -938,19 +930,27 @@ plugin.generalconfig.ERROR_PORT_NUMBER=Ðеверный номер порта
plugin.generalconfig.CHECK_FOR_UPDATES=ПроверÑÑ‚ÑŒ наличие обновлений при запуÑке
plugin.generalconfig.STARTUP_CONFIG=ЗапуÑк
plugin.generalconfig.LEAVE_CHATROOM_ON_WINDOW_CLOSE=Сообщить о выходе из чата при закрытии окна
+plugin.generalconfig.SHOW_RECENT_MESSAGES=Показать недавние беÑеды (завиÑит от иÑтории разговоров)
plugin.generalconfig.REMOVE_SPECIAL_PHONE_SYMBOLS=Удалить Ñпециальные Ñимволы из телефонного номера, прежде чем Ñделать вызов
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS=Преобразовывать буквы в цифры телефонного номера
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS_EXAMPLE=напр. +1-800-MYPHONE преобразуетÑÑ Ð² +1-800-694663
plugin.generalconfig.SIP_CALL_CONFIG=SIP
+plugin.generalconfig.XMPP_CONFIG=XMPP
+plugin.generalconfig.XMPP_USE_ALL_RESOURCES=ИÑпользовать вÑе реÑурÑÑ‹ при обнаружении возможноÑтей контакта
plugin.generalconfig.OPUS_CONFIG=Кодек Opus
+plugin.generalconfig.OPUS_AUDIO_BANDWIDTH=ЧаÑтота выборки:
+plugin.generalconfig.OPUS_BITRATE=СреднÑÑ ÑкороÑÑ‚ÑŒ кодировщика (кбит/Ñ)
plugin.generalconfig.OPUS_USE_DTX=ИÑпользовать DTX:
plugin.generalconfig.OPUS_USE_FEC=ИÑпользовать Inband FEC:
+plugin.generalconfig.OPUS_COMPLEXITY=СложноÑÑ‚ÑŒ кодировщика:
+plugin.generalconfig.OPUS_MIN_EXPECTED_PACKET_LOSS=Минимальные ожидаемые потери пакетов(%):
plugin.generalconfig.SILK_CONFIG=Silk
plugin.generalconfig.SILK_USE_FEC=ИÑпользовать Inband FEC:
plugin.generalconfig.SILK_ALWAYS_ASSUME_PACKET_LOSS=Ð’Ñегда учитывать потери пакетов:
plugin.generalconfig.SILK_SAT=Порог голоÑовой активноÑти (0-1):
plugin.generalconfig.SILK_ADVERTISE_FEC=ОбъÑвлÑÑ‚ÑŒ поддержку FEC в SDP:
plugin.generalconfig.RESTORE=ВоÑÑтановить Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию
+plugin.generalconfig.MINIMIZE_NOT_HIDE=Минимизировать оÑновное окно вмеÑто Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ð¸Ð»Ð¸ ÑворачиваниÑ
# gibberish accregwizz
plugin.gibberishaccregwizz.PROTOCOL_NAME=Gibberish
@@ -969,12 +969,24 @@ plugin.icqaccregwizz.REGISTER_NEW_ACCOUNT=РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð¹ уч
plugin.ircaccregwizz.PROTOCOL_NAME=IRC
plugin.ircaccregwizz.PROTOCOL_DESCRIPTION=Протокол IRC.
plugin.ircaccregwizz.USERNAME_AND_PASSWORD=UIN и пароль
+plugin.ircaccregwizz.USERNAME=ПÑевдоним
+plugin.ircaccregwizz.EXAMPLE_USERNAME=Пример: IRC-пользователь
plugin.ircaccregwizz.INFO_PASSWORD=БольшинÑтво IRC Ñерверов не требуют паролÑ.
plugin.ircaccregwizz.AUTO_NICK_CHANGE=ÐвтоматичеÑки менÑÑ‚ÑŒ ник, когда он уже иÑпользуетÑÑ
plugin.ircaccregwizz.USE_DEFAULT_PORT=ИÑпользовать порт по умолчанию
plugin.ircaccregwizz.PASSWORD_NOT_REQUIRED=Мой ник не требует идентификации
plugin.ircaccregwizz.HOST=ХоÑÑ‚:
plugin.ircaccregwizz.IRC_SERVER=Сервер
+plugin.ircaccregwizz.EXAMPLE_SERVER=Пример: chat.freenode.net
+plugin.ircaccregwizz.USE_SECURE_CONNECTION=ИÑпользовать безопаÑное подключение
+plugin.ircaccregwizz.ENABLE_CONTACT_PRESENCE=Включить приÑутÑтвие контакта
+plugin.ircaccregwizz.ENABLE_CHAT_ROOM_PRESENCE=Включить приÑутÑтвие чат комнаты
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE=SASL аутентификациÑ
+plugin.ircaccregwizz.ENABLE_SASL_AUTHENTICATION=Включить SASL аутентификацию
+plugin.ircaccregwizz.SASL_USERNAME=Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ
+plugin.ircaccregwizz.SASL_AUTHZ_ROLE=ДолжноÑÑ‚ÑŒ
+plugin.ircaccregwizz.SASL_IRC_PASSWORD_USED=ВышеупомÑнутый IRC пароль иÑпользуетÑÑ Ð´Ð»Ñ SASL аутентификации
+plugin.ircaccregwizz.RESOLVE_DNS_THROUGH_PROXY=Ð’Ñегда разрешать DNS имена через прокÑи
# jabber accregwizz
plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
@@ -997,17 +1009,14 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Комментарий
plugin.jabberaccregwizz.RESOURCE=РеÑурÑ
plugin.jabberaccregwizz.AUTORESOURCE=ÐвтоматичеÑкое Ñоздание реÑурÑа
plugin.jabberaccregwizz.PRIORITY=Приоритет
-plugin.jabberaccregwizz.XMPP_ERROR=Ошибка XMPP
-plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° XMPP ({0)}. УбедитеÑÑŒ, что Ð¸Ð¼Ñ Ñервера, ÑвлÑетÑÑ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼.
+plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° XMPP ({0)}. УбедитеÑÑŒ, что Ð¸Ð¼Ñ Ñервера ÑвлÑетÑÑ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Пароли не Ñовпадают.
plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Переопределить параметры Ñервера по умолчанию
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Дополнительные параметры
plugin.jabberaccregwizz.USE_ICE=ИÑпользовать ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=ИÑпользовать Google Jingle/ICE (ÑкÑÐ¿ÐµÑ€Ð¸Ð¼ÐµÐ½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=ÐвтоматичеÑки обнаруживать STUN/TURN Ñервера
plugin.jabberaccregwizz.SUPPORT_TURN=Поддерживать TURN
plugin.jabberaccregwizz.TURN_USERNAME=Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ TURN
-plugin.jabberaccregwizz.IP_ADDRESS=IP ÐдреÑ
+plugin.jabberaccregwizz.IP_ADDRESS=IP-ÐдреÑ
plugin.jabberaccregwizz.ADD_STUN_SERVER=Добавить STUN-Ñервер
plugin.jabberaccregwizz.EDIT_STUN_SERVER=Редактировать STUN-Ñервер
plugin.jabberaccregwizz.ADDITIONAL_STUN_SERVERS=Дополнительные STUN-Ñервера
@@ -1027,19 +1036,17 @@ plugin.jabberaccregwizz.EXISTING_ACCOUNT=СущеÑтвующий аккаунт
plugin.jabberaccregwizz.DOMAIN_BYPASS_CAPS=Домен, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð³Ð¾ будут иÑпользоватьÑÑ GTalk-вызовы
plugin.jabberaccregwizz.TELEPHONY_DOMAIN=Домен Ð´Ð»Ñ Ñ‚ÐµÐ»ÐµÑ„Ð¾Ð½Ð¸Ð¸
plugin.jabberaccregwizz.ALLOW_NON_SECURE=Разрешить небезопаÑные подключениÑ
+plugin.jabberaccregwizz.DISABLE_CARBON=Отключить мультиклиентный обмен ÑообщениÑми
plugin.jabberaccregwizz.DTMF_AUTO=ÐвтоматичеÑки выбирать между RTP и Inband
plugin.jabberaccregwizz.SERVER_OPTIONS=Параметры Ñервера
plugin.jabberaccregwizz.CHANGE_PASSWORD=Изменить пароль
-plugin.jabberaccregwizz.NEW_PASSWORD=Ðовый пароль
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Повторите пароль
plugin.jabberaccregwizz.PORT_FIELD_INVALID=ПожалуйÑта, необходимо указать верный порт Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶ÐµÐ½Ð¸Ñ.
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=Ð”Ð»Ñ Ñмены Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð½ÐµÐ¾Ð±Ñ…Ð¾Ð´Ð¸Ð¼Ð¾ выполнить вход на Ñервер.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=Пароль пуÑтой.
plugin.jabberaccregwizz.TLS_REQUIRED=Соединение не иÑпользует TLS, пароль не будет изменен.
plugin.jabberaccregwizz.PASSWORD_CHANGED=Пароль уÑпешно изменен
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=Ваш XMPP Ñервер не поддерживает изменение паролÑ.
plugin.jabberaccregwizz.PASSWORD_NOT_STORED=Пароль был изменен на Ñервере, но локальные наÑтройки обновлены не были
-plugin.jabberaccregwizz.ENTER_NEW_PASSWORD=ПожалуйÑта, введите Ваш новый пароль в оба полÑ:
+plugin.jabberaccregwizz.ENTER_NEW_PASSWORD=ПожалуйÑта, введите ваш новый пароль в оба полÑ:
plugin.jabberaccregwizz.OVERRIDE_ENCODINGS=Переопределить глобальные наÑтройки кодеков
plugin.jabberaccregwizz.ENCODINGS=Кодеки
plugin.jabberaccregwizz.AUDIO=Ðудио
@@ -1048,21 +1055,6 @@ plugin.jabberaccregwizz.RESET=СброÑ
plugin.jabberaccregwizz.RESET_DESCRIPTION=Ð¡Ð±Ñ€Ð¾Ñ Ð½Ð° глобальные наÑтройки
plugin.jabberaccregwizz.DISABLE_JINGLE=Отключить Jingle (аудио и видеозвонки через XMPP).
-# mailbox
-plugin.mailbox.OUTGOING=ИÑходÑщее Ñообщение:
-plugin.mailbox.INCOMING=ВходÑщие Ñообщение:
-plugin.mailbox.WAIT_TIME=Звонок переводитьÑÑ Ð½Ð° автоответчик
-plugin.mailbox.MAX_MESSAGE_TIME=МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚ÑŒ входÑщих Ñообщений
-plugin.mailbox.CONFIRM=Подтвердить
-plugin.mailbox.DEFAULTS=По умолчанию
-plugin.mailbox.MAILBOX=Почтовый Ñщик
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Протокол Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸ чата на MSN Ñлужбе.
-plugin.msnaccregwizz.USERNAME=Электронный Ñщик:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=ID и пароль
-
# plugin manager
plugin.pluginmanager.INSTALL=УÑтановить
plugin.pluginmanager.UNINSTALL=Удалить
@@ -1091,9 +1083,9 @@ plugin.sipaccregwizz.SERVER_PORT=Порт Ñервера
plugin.sipaccregwizz.PROXY=ПрокÑи
plugin.sipaccregwizz.PROXY_PORT=Порт прокÑи
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Предпочтительный вид транÑпорта
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Дополнительные параметры
plugin.sipaccregwizz.PROXY_OPTIONS=ÐаÑтройки прокÑи-Ñервера
plugin.sipaccregwizz.PROXY_AUTO=ÐвтоматичеÑÐºÐ°Ñ Ð½Ð°Ñтройка прокÑи-Ñервера
+plugin.sipaccregwizz.PROXY_FORCE_BYPASS=Обход проверки безопаÑноÑти прокÑи Ð´Ð»Ñ Ñценариев HA (иÑпользовать только при необходимоÑти)
plugin.sipaccregwizz.ENABLE_PRESENCE=Включить приÑутÑтвие (SIMPLE)
plugin.sipaccregwizz.FORCE_P2P_PRESENCE=Принудительно включить режим приÑутÑÑ‚Ð²Ð¸Ñ peer-to-peer
plugin.sipaccregwizz.OFFLINE_CONTACT_POLLING_PERIOD=Период опроÑа контактов не в Ñети (в Ñек.)
@@ -1103,14 +1095,14 @@ plugin.sipaccregwizz.KEEP_ALIVE=Поддерживать активным
plugin.sipaccregwizz.KEEP_ALIVE_METHOD=Метод поддержки
plugin.sipaccregwizz.KEEP_ALIVE_INTERVAL=Интервал переподключениÑ
plugin.sipaccregwizz.KEEP_ALIVE_INTERVAL_INFO=От 1 до 3600 Ñекунд
+plugin.sipaccregwizz.DTMF_MINIMAL_TONE_DURATION=ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚ÑŒ RTP DTMF тона (мÑ)
+plugin.sipaccregwizz.DTMF_MINIMAL_TONE_DURATION_INFO=ДлительноÑÑ‚ÑŒ RTP DTMF по умолчанию 70 мÑ
plugin.sipaccregwizz.DTMF=DTMF
plugin.sipaccregwizz.DTMF_METHOD=Метод DTMF
plugin.sipaccregwizz.DTMF_AUTO=ÐвтоматичеÑки выбирать между RTP и Inband (нет SIP INFO)
plugin.sipaccregwizz.DTMF_RTP=RTP (RFC2833 / RFC4733)
plugin.sipaccregwizz.DTMF_SIP_INFO=SIP INFO
plugin.sipaccregwizz.DTMF_INBAND=Inband
-plugin.sipaccregwizz.REGISTER=REGISTER
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Переопределить параметры Ñервера по умолчанию
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Включить поддержку ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð·Ð²Ð¾Ð½ÐºÐ¾Ð²
plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=Сообщать о поддержке ZRTP в протоколе Ñигнализации
plugin.sipaccregwizz.AUTH_NAME=Ð˜Ð¼Ñ Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ð¸
@@ -1131,10 +1123,10 @@ plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=URI Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ ГП
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Пароли не Ñовпадают.
plugin.sipaccregwizz.NO_CERTIFICATE=<none> (иÑпользовать обычную проверку подлинноÑти)
plugin.sipaccregwizz.SAVP_OPTION=ИÑпользование RTP/SAVP
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=Выключено (иÑпользовать только RTP/AVP)
plugin.sipaccregwizz.SAVP_OPTION_1=ОбÑзательно (предлагать и принимать только RTP/SAVP)
plugin.sipaccregwizz.SAVP_OPTION_2=Опционально (Ñначала предлагать RTP/SAVP, затем RTP/AVP)
-plugin.sipaccregwizz.ENABLE_SDES_ATTRIBUTE=Включить S-деÑкриптор (также извеÑтный как SDES или SRTP)
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=Выберите протоколы ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ их приоритет (Ñверху протокол Ñ Ð½Ð°Ð¸Ð±Ð¾Ð»ÑŒÑˆÐ¸Ð¼ приоритетом):
plugin.sipaccregwizz.CIPHER_SUITES=ДоÑтупные наборы шифров:
plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>{0} будет пытатьÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки защитить вÑе Ваши звонки Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ ZRTP. Ð’Ñ‹ будете уведомлены об Ñтом каждый раз, оÑущеÑтвлÑÑ Ð²Ñ‹Ð·Ð¾Ð². Ð’Ñ‹ можете изменÑÑ‚ÑŒ дополнительные наÑтройки только в том Ñлучае, еÑли хорошо понимаете, что делаете.</div></html>
@@ -1144,23 +1136,14 @@ plugin.sipaccregwizz.SDES_OPTION=ÐžÐ¿Ñ†Ð¸Ñ SDES
# skin manager
plugin.skinmanager.SKINS=Скины
-plugin.skinmanager.DEFAULT_SKIN=Скин по умолчанию
-plugin.skinmanager.ADD_NEW_SKIN=Добавить новый Ñкин...
-plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=Скин Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию.
-
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=Протокол Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº удаленным компьютерам через SSH.
-plugin.sshaccregwizz.USERNAME=ID учетной запиÑи:
-plugin.sshaccregwizz.IDENTITY_FILE=Личный файл:
-plugin.sshaccregwizz.KNOWN_HOSTS=ИзвеÑтные хоÑÑ‚Ñ‹:
-plugin.sshaccregwizz.OPTIONAL=ÐеобÑзательный
-plugin.sshaccregwizz.ACCOUNT_DETAILS=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± учетной запиÑи
+plugin.skinmanager.DEFAULT_SKIN=Оболочка по умолчанию
+plugin.skinmanager.ADD_NEW_SKIN=Добавить новую оболочку...
+plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=Оболочка Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию.
# status update
plugin.autoaway.AUTO_STATUS=Ðвто отÑуÑтвие
plugin.autoaway.ENABLE_CHANGE_STATUS=Изменить ÑтатуÑ, когда отошел
-plugin.autoaway.AWAY_MINUTES=Минут до Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð² ''Ðет на меÑте'':
+plugin.autoaway.AWAY_MINUTES=Минут до Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð² режим ''Ðет на меÑте'':
# updatechecker
plugin.updatechecker.DIALOG_TITLE=УÑтановить обновлениÑ
@@ -1170,6 +1153,7 @@ plugin.updatechecker.BUTTON_DOWNLOAD=Скачать
plugin.updatechecker.BUTTON_CLOSE=Закрыть
plugin.updatechecker.BUTTON_INSTALL=УÑтановить
plugin.updatechecker.UPDATE_MENU_ENTRY=Проверить обновлениÑ
+plugin.updatechecker.DIALOG_WARN={0} необходимо выйти перед тем, как он Ñможет уÑтановить обновлениÑ. Любые беÑеды или звонки будут временно отключены. Следует ли {0} продолжить уÑтановку обновлений?
plugin.updatechecker.DIALOG_NOUPDATE=Ваша верÑÐ¸Ñ ÑвлÑетÑÑ Ð°ÐºÑ‚ÑƒÐ°Ð»ÑŒÐ½Ð¾Ð¹.
plugin.updatechecker.DIALOG_NOUPDATE_TITLE=Ðет новой верÑии
plugin.updatechecker.DIALOG_MISSING_UPDATE=Обновление уÑтановщика не удалоÑÑŒ.
@@ -1203,22 +1187,6 @@ plugin.whiteboard.DESELECT=Отменить
plugin.whiteboard.DELETE=Удалить
plugin.whiteboard.PROPERTIES=СвойÑтва
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Протокол Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸ Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð½Ð° Yahoo! Service.
-plugin.yahooaccregwizz.USERNAME=Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=ID и пароль
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=Zeroconf (Bonjour) протокол.
-plugin.zeroaccregwizz.FIRST_NAME=ИмÑ:
-plugin.zeroaccregwizz.LAST_NAME=ФамилиÑ:
-plugin.zeroaccregwizz.EMAIL=Электронный Ñщик:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=Запомнить Bonjour контакты?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=ID и пароль
-plugin.zeroaccregwizz.USERID=ПользовательÑкий ID
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Протокол Google Talk
@@ -1232,19 +1200,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, портал IP ТелеÐ
plugin.iptelaccregwizz.USERNAME=Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=ПодпиÑатьÑÑ Ð½Ð° iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIP и чат
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Введите пароль еще раз
plugin.sip2sipaccregwizz.EMAIL=ÐÐ´Ñ€ÐµÑ Ñлектронной почты
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки об уÑлуге поÑетите<br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>ÐÐ´Ñ€ÐµÑ Ñлектронной почты иÑпользуетÑÑ Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ голоÑовых Ñообщений, <br>уведомлений о пропущенных звонках, а также воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ ÑƒÑ‚ÐµÑ€Ñнного паролÑ</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки об уÑлуге поÑетите<a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=СущеÑтвующий sip2sip.info аккаунт
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Создать беÑплатный аккаунт sip2sip.info
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP && Мгновенные ÑообщениÑ
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки об уÑлуге поÑетите<br>http://ippi.fr
@@ -1253,6 +1213,8 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=СущеÑтвующие ippi аккауÐ
plugin.ippiaccregwizz.CREATE_ACCOUNT=Создать беÑплатную учетную запиÑÑŒ ippi
# key binding chooser
+plugin.keybindings.WAITING=Ðажмите Ñрлык...
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Закрыть окно чата
plugin.keybindings.CHAT_COPY=Копировать
plugin.keybindings.CHAT_CUT=Вырезать
@@ -1275,10 +1237,10 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=ДейÑтвие
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=Сочетание клавиш
plugin.keybindings.globalchooser.SHORTCUT_SECOND=Дополнительно
plugin.keybindings.globalchooser.PRESS_BTN=Ðажмите Ð´Ð»Ñ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÑÐ¾Ñ‡ÐµÑ‚Ð°Ð½Ð¸Ñ ÐºÐ»Ð°Ð²Ð¸Ñˆ
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=Ожидание
-plugin.keybindings.globalchooser.PUSH_TO_TALK=Push to talk
+plugin.keybindings.globalchooser.PUSH_TO_TALK=Ðажмите, чтобы говорить
plugin.keybindings.globalchooser.ENABLE_SPECIAL=Включить обнаружение Ñпециальных клавиш
plugin.keybindings.PLUGIN_NAME=Ð¡Ð¾Ñ‡ÐµÑ‚Ð°Ð½Ð¸Ñ ÐºÐ»Ð°Ð²Ð¸Ñˆ
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Чат
plugin.keybindings.MAIN=ОÑновные
plugin.keybindings.GLOBAL=Глобальные
@@ -1306,6 +1268,7 @@ plugin.notificationconfig.tableheader.SOUND=СиÑтемный звуковой
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=Звуковой Ñигнал через динамики
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=Звуковой Ñигнал через динамик ПК
plugin.notificationconfig.tableheader.DESCRIPTION=ОпиÑание ÑобытиÑ
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=ВходÑщий звонок
plugin.notificationconfig.event.SecurityMessage=Сообщение безопаÑноÑти
plugin.notificationconfig.event.IncomingFile=Получен файл
@@ -1376,11 +1339,13 @@ impl.media.configform.AUDIO=&Ðудио ÑиÑтема:
impl.media.configform.AUDIO_IN=Микрофон:
impl.media.configform.AUDIO_NOTIFY=&УведомлениÑ:
impl.media.configform.AUDIO_OUT=Динамики:
+impl.media.configform.AUTOMATICGAINCONTROL=ÐвтоматичеÑÐºÐ°Ñ Ñ€ÐµÐ³ÑƒÐ»Ð¸Ñ€Ð¾Ð²ÐºÐ° уÑилениÑ
impl.media.configform.DENOISE=Включить Ð¿Ð¾Ð´Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÑˆÑƒÐ¼Ð°
impl.media.configform.DEVICES=УÑтройÑтва
impl.media.configform.DOWN=&Вниз
impl.media.configform.ECHOCANCEL=Включить подавление Ñха
impl.media.configform.ENCODINGS=Кодеки
+impl.media.configform.NO_AVAILABLE_AUDIO_DEVICE=Ðет доÑтупного звукового уÑтройÑтва. ПожалуйÑта, подключите его.
impl.media.configform.NO_DEVICE=<Ðет уÑтройÑтва>
impl.media.configform.NO_PREVIEW=Предварительный проÑмотр
impl.media.configform.UP=&Вверх
@@ -1388,25 +1353,32 @@ impl.media.configform.VIDEO=&Выбрать веб-камеру:
impl.media.configform.VIDEO_MORE_SETTINGS=Дополнительно
impl.media.configform.VIDEO_RESOLUTION=Разрешение видео
impl.media.configform.VIDEO_FRAME_RATE=КоличеÑтво кадров (в Ñек.)
+impl.media.configform.VIDEO_PACKETS_POLICY=ÐŸÐ¾Ñ€Ð¾Ð³Ð¾Ð²Ð°Ñ ÑкороÑÑ‚ÑŒ RTP (кБайт/Ñ)
+impl.media.configform.VIDEO_BITRATE=СкороÑÑ‚ÑŒ передачи данных видео (килобит/Ñ)
impl.media.configform.VIDEO_RESET=Ð¡Ð±Ñ€Ð¾Ñ Ð½Ð°Ñтроек
-impl.media.configform.AUDIO_DEVICE_SELECTED_AUDIO_IN=Выбрано новое уÑтройÑтво Ð´Ð»Ñ Ð²Ð²Ð¾Ð´Ð° звука:
-impl.media.configform.AUDIO_DEVICE_SELECTED_AUDIO_OUT=Выбрано новое уÑтройÑтво Ð´Ð»Ñ Ð²Ñ‹Ð²Ð¾Ð´Ð° звука:
-impl.media.configform.AUDIO_DEVICE_SELECTED_AUDIO_NOTIFICATIONS=Выбрано новое уÑтройÑтво Ð´Ð»Ñ Ð¾Ð¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ð¹:
-impl.media.configform.VIDEO_DEVICE_SELECTED=Выбрано новое уÑтройÑтво Ð´Ð»Ñ Ð²Ð¸Ð´ÐµÐ¾:
+impl.media.configform.AUDIO_DEVICE_CONNECTED=Подключенное уÑтройÑтво:
+impl.media.configform.AUDIO_DEVICE_DISCONNECTED=Отключенное уÑтройÑтво:
+impl.media.configform.AUDIO_DEVICE_SELECTED_AUDIO_IN=Ðовое выбранное уÑтройÑтво Ð´Ð»Ñ Ð²Ð²Ð¾Ð´Ð° звука:
+impl.media.configform.AUDIO_DEVICE_SELECTED_AUDIO_OUT=Ðовое выбранное уÑтройÑтво Ð´Ð»Ñ Ð²Ñ‹Ð²Ð¾Ð´Ð° звука:
+impl.media.configform.AUDIO_DEVICE_SELECTED_AUDIO_NOTIFICATIONS=Ðовое выбранное уÑтройÑтво Ð´Ð»Ñ Ð¾Ð¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ð¹:
+impl.media.configform.VIDEO_DEVICE_SELECTED=Ðовое выбранное уÑтройÑтво Ð´Ð»Ñ Ð²Ð¸Ð´ÐµÐ¾:
impl.media.configform.AUDIO_DEVICE_CONFIG_MANAGMENT_CLICK=Ðажмите Ð´Ð»Ñ Ð½Ð°Ñтройки уÑтройÑтв
impl.neomedia.configform.AUDIO=Ðудио
impl.neomedia.configform.VIDEO=Видео
impl.neomedia.configform.H264=H.264
+impl.neomedia.configform.H264.defaultIntraRefresh=ПериодичеÑкое обновление интра-данных
impl.neomedia.configform.H264.defaultProfile=Профиль Ð´Ð»Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ:
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=Базовый
impl.neomedia.configform.H264.defaultProfile.high=Ð’Ñ‹Ñокое
impl.neomedia.configform.H264.defaultProfile.main=ОÑновной
+impl.neomedia.configform.H264.keyint=МакÑимальный интервал между ключевыми кадрами
impl.neomedia.configform.H264.preferredKeyFrameRequester=Метод запроÑа ключевых кадров:
impl.neomedia.configform.H264.preferredKeyFrameRequester.rtcp=RTCP
impl.neomedia.configform.H264.preferredKeyFrameRequester.signaling=СигнализациÑ
-impl.neomedia.configform.H264.preset=ПредуÑтановки кодеков
+impl.neomedia.configform.H264.preset=ПредуÑтановка шифратора
# The callrecordingconfig plugin was never really committed into trunk and its
# ConfigurationForm was actually put in the neomedia bundle.
@@ -1422,15 +1394,14 @@ plugin.callrecordingconfig.CALL_SAVED_TO={0}
plugin.securityconfig.TITLE=БезопаÑноÑÑ‚ÑŒ
plugin.securityconfig.masterpassword.TITLE=Пароли
plugin.securityconfig.masterpassword.CHANGE_MASTER_PASSWORD=Изменить МаÑтер-пароль...
-plugin.securityconfig.masterpassword.USE_MASTER_PASSWORD=ИÑпользовать МаÑтер-пароль
+plugin.securityconfig.masterpassword.USE_MASTER_PASSWORD=ИÑпользовать маÑтер-пароль
plugin.securityconfig.masterpassword.SAVED_PASSWORDS=Сохраненные пароли...
plugin.securityconfig.masterpassword.INFO_TEXT=МаÑтер-пароль иÑпользуетÑÑ Ð´Ð»Ñ Ð·Ð°Ñ‰Ð¸Ñ‚Ñ‹ Ñохраненных паролей к учетным запиÑÑм. ПожалуйÑта, убедитеÑÑŒ, что вы запомнили его.
plugin.securityconfig.masterpassword.CURRENT_PASSWORD=Текущий пароль:
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Введите новый пароль:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Введите пароль повторно:
plugin.securityconfig.masterpassword.MP_TITLE=МаÑтер-пароль
-plugin.securityconfig.masterpassword.MP_NOT_SET=(не уÑтановлено)
-plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=Ð’Ñ‹ ввели неправильный текущий МаÑтер-пароль. ПожалуйÑта, попробуйте еще раз.
+plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=Ð’Ñ‹ ввели неправильный текущий маÑтер-пароль. ПожалуйÑта, попробуйте еще раз.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=МаÑтер-пароль неправильный!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Изменение Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð½Ðµ удалоÑÑŒ
plugin.securityconfig.masterpassword.MP_CHANGE_SUCCESS=Пароль уÑпешно изменен
@@ -1455,11 +1426,14 @@ plugin.securityconfig.masterpassword.PASSWORD_QUALITY_METER=СложноÑÑ‚ÑŒ Ð
plugin.securityconfig.masterpassword.MP_INPUT=ПожалуйÑта введите ваш маÑтер-пароль:\n\n
# otr plugin
-plugin.otr.menu.TITLE=Шифрование
+plugin.otr.menu.TITLE=БезопаÑÐ½Ð°Ñ Ð±ÐµÑеда
plugin.otr.menu.START_OTR=Ðачать приватный разговор
plugin.otr.menu.END_OTR=Закончить приватный разговор
+plugin.otr.menu.FINISHED=Ваш приÑтель закончил личную беÑеду. Вам Ñледует Ñделать то же Ñамое
+plugin.otr.menu.VERIFIED=Ваша Ð»Ð¸Ñ‡Ð½Ð°Ñ Ð±ÐµÑеда ÑвлÑетÑÑ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ð¾Ð¹
+plugin.otr.menu.UNVERIFIED=Ваша Ð»Ð¸Ñ‡Ð½Ð°Ñ Ð±ÐµÑеда не ÑвлÑетÑÑ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ð¾Ð¹. ПожалуйÑта, удоÑтоверьтеÑÑŒ в подлинноÑти вашего приÑтелÑ
plugin.otr.menu.LOADING_OTR=Ðачать приватный разговор...
-plugin.otr.menu.TIMED_OUT=Ðачать приватный разговор
+plugin.otr.menu.TIMED_OUT=Ðачало личной беÑеды проÑрочено (Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ‹ÑˆÐ»Ð¾).
plugin.otr.menu.REFRESH_OTR=Обновить приватный разговор
plugin.otr.menu.AUTHENTICATE_BUDDY=Проверка ÑобеÑедника
plugin.otr.menu.WHATS_THIS=О технологии
@@ -1469,13 +1443,23 @@ plugin.otr.menu.CB_ENABLE=Включить шифрование Ñообщени
plugin.otr.menu.CB_REQUIRE=Требовать шифрование Ñообщений
plugin.otr.menu.CB_RESET=СброÑ
plugin.otr.menu.OTR_TOOLTIP=Шифрование перепиÑки OTR
-plugin.otr.authbuddydialog.AUTHENTICATION_METHOD=Как бы вы хотели проходить авторизацию?
+plugin.otr.authbuddydialog.HELP_URI=https://jitsi.org/GSOC2009/OTR
+plugin.otr.authbuddydialog.AUTHENTICATION_INFO=УдоÑтоверение в подлинноÑти ÑобеÑедника гарантирует, что человек, Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ð¼ вы говорите, ÑвлÑетÑÑ Ñ‚ÐµÐ¼, за кого он ÑÐµÐ±Ñ Ð²Ñ‹Ð´Ð°ÐµÑ‚.
+plugin.otr.authbuddydialog.AUTHENTICATION_METHOD=Как бы вы хотели пройти авторизацию?
plugin.otr.authbuddydialog.AUTHENTICATION_METHOD_QUESTION=Ð’Ð¾Ð¿Ñ€Ð¾Ñ Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ð¸
+plugin.otr.authbuddydialog.AUTHENTICATION_METHOD_SECRET=ÐÐ²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð¾Ð¼ Ñекретных данных
plugin.otr.authbuddydialog.AUTHENTICATION_METHOD_FINGERPRINT=ÐÐ²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ð¾ отпечатку
+plugin.otr.authbuddydialog.AUTHENTICATION_FINGERPRINT=Чтобы проверить отпечаток, ÑвÑжитеÑÑŒ Ñо Ñвоим приÑтелем через другой подтверждённый канал, такой как телефон или ÑÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ Ð¿Ð¾Ñ‡Ñ‚Ð° Ñ CPG-подпиÑью. Каждому из Ð²Ð°Ñ Ñледует Ñообщить ваш отпечаток друг другу. ЕÑли вÑÑ‘ Ñовпадает, вы должны пометить Ñледующий диалог как *дейÑтвительно* проверенный Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ отпечатка.
plugin.otr.authbuddydialog.LOCAL_FINGERPRINT=Ваш ключ, {0}: {1}
plugin.otr.authbuddydialog.REMOTE_FINGERPRINT=Ключ ÑобеÑедника {0}: {1}
-plugin.otr.authbuddydialog.QUESTION_INIT=Введите Ñвой вопроÑ:
+plugin.otr.authbuddydialog.AUTH_BY_QUESTION_INFO_INIT=Чтобы проверить подлинноÑÑ‚ÑŒ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ вопроÑа, вам необходимо ÑоÑтавить вопроÑ, ответ на который извеÑтен только вам и вашему приÑтелю. Вашему ÑобеÑеднику зададут Ñтот Ð²Ð¾Ð¿Ñ€Ð¾Ñ Ð¸ еÑли ответы не будут Ñовпадать, тогда, возможно, вы разговариваете Ñ Ñамозванцем.
+plugin.otr.authbuddydialog.AUTH_BY_SECRET_INFO_INIT=Ð”Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ подлинноÑти Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Ñекретных данных вам Ñледует подобрать данные, которые извеÑтны только вам и вашему приÑтелю. Затем вашего приÑÑ‚ÐµÐ»Ñ Ñ‚Ð¾Ð¶Ðµ попроÑÑÑ‚ подобрать данные и еÑли они не будут Ñовпадать, тогда, возможно, вы беÑедуете Ñ Ñамозванцем.
+plugin.otr.authbuddydialog.AUTH_BY_SECRET_INFO_RESPOND=Ваш приÑтель пытаетÑÑ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ð¸Ñ‚ÑŒ, разговаривает ли он Ñ Ð²Ð°Ð¼Ð¸ или Ñ Ñамозванцем. Он задал вам вопроÑ. ЕÑли вы хотите пройти проверку подлинноÑти, пожалуйÑта, введите ответ ниже.
+plugin.otr.authbuddydialog.SHARED_SECRET=Введите ваш общий Ñекрет:
+plugin.otr.authbuddydialog.QUESTION_RESPOND=Ваш приÑтель задаёт вам вопроÑ:
+plugin.otr.authbuddydialog.QUESTION_INIT=Введите ваш Ð²Ð¾Ð¿Ñ€Ð¾Ñ Ð·Ð´ÐµÑÑŒ:
plugin.otr.authbuddydialog.ANSWER=Введите Ñвой ответ (Ñ ÑƒÑ‡ÐµÑ‚Ð¾Ð¼ региÑтра):
+plugin.otr.authbuddydialog.AUTHENTICATION_FROM=Проверка подлинноÑти от {0}.
plugin.otr.authbuddydialog.CANCEL=Отмена
plugin.otr.authbuddydialog.HELP=Помощь
plugin.otr.authbuddydialog.TITLE=Проверка ÑобеÑедника
@@ -1484,6 +1468,7 @@ plugin.otr.authbuddydialog.I_HAVE=ЕÑÑ‚ÑŒ
plugin.otr.authbuddydialog.I_HAVE_NOT=Я не
plugin.otr.authbuddydialog.VERIFY_ACTION=подтверждаю, что Ñто дейÑтвительно правильный ключ Ð´Ð»Ñ {0}.
plugin.otr.authbuddydialog.FINGERPRINT_CHECK=ПожалуйÑта, введите уникальный код, полученный от {0}.
+plugin.otr.smpprogressdialog.TITLE=ПроцеÑÑ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ подлинноÑти
plugin.otr.smpprogressdialog.AUTHENTICATION_SUCCESS=Проверка прошла уÑпешно!
plugin.otr.smpprogressdialog.AUTHENTICATION_FAIL=Сбой проверки подлинноÑти!
plugin.otr.configform.MY_PRIVATE_KEYS=СобÑтвенные ключи
@@ -1496,7 +1481,7 @@ plugin.otr.configform.GENERATE=Создать
plugin.otr.configform.REGENERATE=Обновить
plugin.otr.configform.FINGERPRINT=Ключ
plugin.otr.configform.VERIFY_FINGERPRINT=Подтвердить ключ
-plugin.otr.configform.FORGET_FINGERPRINT=Отклонить ключ
+plugin.otr.configform.FORGET_FINGERPRINT=Забыть отпечаток
plugin.otr.configform.COLUMN_NAME_CONTACT=Контакт
plugin.otr.configform.COLUMN_NAME_VERIFIED_STATUS=Проверен
plugin.otr.configform.COLUMN_VALUE_VERIFIED_TRUE=Да
@@ -1504,22 +1489,35 @@ plugin.otr.configform.COLUMN_VALUE_VERIFIED_FALSE=Ðет
plugin.otr.activator.unverifiedsessionwarning={0} ÑвÑзываетÑÑ Ñ Ð’Ð°Ð¼Ð¸ Ñ Ð½ÐµÐ´Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ð¾Ð³Ð¾ компьютера. Ð’Ñ‹ должны <A href="jitsi://{1}/{2}?{3}">проверить подлинноÑÑ‚ÑŒ ÑобеÑедника {0}</a>.
plugin.otr.activator.unverifiedsessionstared=<b>Ðепроверенный</b> приватный разговор Ñ {0} началÑÑ.
plugin.otr.activator.sessionstared=Приватный разговор Ñ {0} началÑÑ.
-plugin.otr.activator.sessionfinished={0} закончил приватный разговор Ñ Ð’Ð°Ð¼Ð¸. Ð’Ñ‹ должны Ñделать то же Ñамое.
+plugin.otr.activator.sessionfinished={0} закончил приватный разговор Ñ Ð²Ð°Ð¼Ð¸. Ð’Ñ‹ должны Ñделать то же Ñамое.
plugin.otr.activator.sessionlost=Приватный разговор Ñ {0} закончен.
-plugin.otr.activator.unreadablemsgreceived={0} отправил нечитаемое шифрованное Ñообщение.
+plugin.otr.activator.historyon={0} запиÑывает Ñту беÑеду на ваше уÑтройÑтво. Ð’Ñ‹ можете <A href="jitsi://{1}/{2}">отключить иÑторию разговора здеÑÑŒ</a>.
+plugin.otr.activator.historyoff={0} ÐЕ запиÑывает Ñту беÑеду. Ð’Ñ‹ можете <A href="jitsi://{1}/{2}">активировать иÑторию разговора здеÑÑŒ</a>.
+plugin.otr.activator.sessionfinishederror=Ваше Ñообщение [{0}] не было отправлено. ПожалуйÑта, закончите вашу личную беÑеду Ñ {1}.
+plugin.otr.activator.smpaborted={0} прервал процеÑÑ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ подлинноÑти.
+plugin.otr.activator.smperror=Ð’ процеÑÑе проверки подлинноÑти произошла ошибка.
+plugin.otr.activator.unencryptedmsgreceived=Сообщение было получено в незашифрованном виде.
+plugin.otr.activator.unreadablemsgreceived={0} отправил вам неразборчивое зашифрованное Ñообщение.
+plugin.otr.activator.requireencryption=Ваше Ñообщение [{0}] не было отправлено. ТребуетÑÑ ÐºÐ¾Ð½Ñ„Ð¸Ð´ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ñ‹Ð¹ обмен ÑообщениÑми.
+plugin.otr.activator.unreadablemsgreply=Ð’Ñ‹ отправили {0} неразборчивое зашифрованное Ñообщение. ПожалуйÑта, закончите вашу личную беÑеду Ñ {1} или обновите её.
+plugin.otr.activator.fallbackmessage=<span style="font-weight: bold;">{0} пытаетÑÑ Ð½Ð°Ñ‡Ð°Ñ‚ÑŒ Ñ Ð²Ð°Ð¼Ð¸ зашифрованную <a href="http://en.wikipedia.org/wiki/Off-the-Record_Messaging"> беÑеду в формате Off-The-Record</a>. Однако, ваше программное обеÑпечение не поддерживает Off-The-Record. Ð”Ð»Ñ Ð±Ð¾Ð»ÑŒÑˆÐµÐ¹ информации Ñмотрите <a href="http://en.wikipedia.org/wiki/Off-the-Record_Messaging">http://en.wikipedia.org/wiki/Off-the-Record_Messaging</a></span>
+plugin.otr.activator.multipleinstancesdetected=Ваш приÑтель {0} вошёл в ÑиÑтему много раз и ОТР уÑтановила неÑколько ÑеанÑов. Ð’Ñ‹ можете выбрать иÑходÑщий ÑÐµÐ°Ð½Ñ Ð¸Ð· меню ниже.
+plugin.otr.activator.msgfromanotherinstance={0} отправил вам Ñообщение, которое было предназначено Ð´Ð»Ñ Ð´Ñ€ÑƒÐ³Ð¾Ð¹ ÑеÑÑии. ЕÑли вы вошли в ÑиÑтему неÑколько раз, Ð´Ñ€ÑƒÐ³Ð°Ñ ÑеÑÑиÑ, возможно, получила Ñто Ñообщение.
# global proxy plugin
-plugin.globalproxy.GLOBAL_PROXY_CONFIG=ПрокÑи-Ñервер
+plugin.globalproxy.GLOBAL_PROXY_CONFIG=Глобальный прокÑи-Ñервер
plugin.globalproxy.PROXY_TYPE=Тип прокÑи-Ñервера
plugin.globalproxy.PROXY_ADDRESS=ПрокÑи-Ñервер
plugin.globalproxy.PROXY_PORT=Порт
plugin.globalproxy.PROXY_USERNAME=Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ
plugin.globalproxy.PROXY_PASSWORD=Пароль
plugin.globalproxy.DESCRIPTION={0} будет иÑпользовать перечиÑленные параметры прокÑи-Ñервера Ð´Ð»Ñ Ð²Ñех Ñетей при Ñледующем подключении. \nПоддержка прокÑи в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ ÑкÑÐ¿ÐµÑ€Ð¸Ð¼ÐµÐ½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð¸ работает только Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ð¼Ð¸ протоколами. Смотрите таблицу ниже Ð´Ð»Ñ Ð±Ð¾Ð»ÐµÐµ подробной информации:
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>XMPP</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
+plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ </td><td> HTTP </td><td> HTTP+ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ </td></tr><tr><td>XMPP (Джаббер)</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
-plugin.globalproxy.FWD_DNS_ADDR=ÐÐ´Ñ€ÐµÑ Ñервера DNS Proxy
-plugin.globalproxy.FWD_DNS_PORT=Порт Ñервера DNS Proxy
+plugin.globalproxy.FWD_DNS=Также прокÑифицировать DNS
+plugin.globalproxy.FWD_DNS_NOTE=Полезно Ñ Ð¢Ð¾Ñ€. Помогает избежать утечки DNS, направлÑÑ Ð²ÐµÑÑŒ DNS трафик через Тор прокÑи. ТребуетÑÑ Ð¿ÐµÑ€ÐµÐ·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ°.
+plugin.globalproxy.FWD_DNS_ADDR=ÐÐ´Ñ€ÐµÑ Ñервера DNS ПрокÑи
+plugin.globalproxy.FWD_DNS_PORT=Порт Ñервера DNS ПрокÑи
# plugin reconnect
plugin.reconnectplugin.CONNECTION_FAILED_MSG=Ðе удалоÑÑŒ Ñоединение Ð´Ð»Ñ Ñледующего аккаунта:\nÐ˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ: {0}, Ð˜Ð¼Ñ Ñервера: {1}.\nПожалуйÑта, проверьте ваше Ñетевое подключение или ÑвÑжитеÑÑŒ Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтратором.
@@ -1531,30 +1529,32 @@ plugin.reconnectplugin.NETWORK_DOWN=Подключение к Ñети прерÐ
plugin.chatconfig.TITLE=Чат
plugin.chatconfig.replacement.TITLE=Фото/Видео:
plugin.chatconfig.replacement.ENABLE_SMILEY_STATUS=Включить поддержку Ñмайликов
-plugin.chatconfig.replacement.REPLACEMENT_TITLE=Включить предпроÑмотр Ð´Ð»Ñ Ñ„Ð¾Ñ‚Ð¾ и видео
+plugin.chatconfig.replacement.REPLACEMENT_TITLE=Замещение ИзображениÑ/Видео
plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS=Включить
+plugin.chatconfig.replacement.ENABLE_REPLACEMENT_PROPOSAL=Отключено (показать ÑÑылку Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð²Ð°Ñ€Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð³Ð¾ проÑмотра)
+plugin.chatconfig.replacement.DISABLE_REPLACEMENT=Отключить
+plugin.chatconfig.replacement.CONFIGURE_REPLACEMENT=Изменить наÑтройки Ð·Ð°Ð¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ/Видео
plugin.chatconfig.replacement.REPLACEMENT_SOURCES=ИÑточники:
plugin.chatconfig.spellcheck.TITLE=Проверка правопиÑаниÑ
#provisioning plugin
-plugin.provisioning.PROVISIONING=ÐвтонаÑтройка
-plugin.provisioning.ENABLE_DISABLE=ÐвтоматичеÑкое обнаружение адреÑа автонаÑтройки
+plugin.provisioning.PROVISIONING=Резервирование
+plugin.provisioning.ENABLE_DISABLE=Включить резервирование
plugin.provisioning.AUTO=ÐвтоматичеÑкое обнаружение адреÑа автонаÑтройки
plugin.provisioning.DHCP=DHCP
plugin.provisioning.DNS=DNS
-plugin.provisioning.BONJOUR=Bonjour
+plugin.provisioning.BONJOUR=ПриветÑвие
plugin.provisioning.MANUAL=Вручную задать Ð°Ð´Ñ€ÐµÑ URI автонаÑтройки
plugin.provisioning.URI=URI
plugin.provisioning.RESTART_WARNING=Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð²ÑтупÑÑ‚ в Ñилу только при Ñледующем запуÑке {0}!
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=Скопировать UUID в буфер
plugin.provisioning.CLIPBOARD_FAILED=Ошибка при копировании UUID в буфер
-plugin.provisioning.EXIT_ON_FAIL=Закрывать Jitsi, еÑли автонаÑтройка не удалаÑÑŒ
plugin.provisioning.CREDENTIALS=Ð£Ñ‡ÐµÑ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð½Ð°Ñтройки
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=Ð’Ñ‹ дейÑтвительно хотите ÑброÑить пароль Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð½Ð°Ñтройки?
plugin.provisioning.PROV_FAILED=ÐвтонаÑтройка не удалаÑÑŒ
plugin.provisioning.PROV_FAILED_MSG=<html>ÐвтонаÑтройка не удалаÑÑŒ. {0}! <br>ПожалуйÑта, попробуйте позже или ÑвÑжитеÑÑŒ Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтратором.</html>
-plugin.provisioning.FORGET_PASSWORD=Ð¡Ð±Ñ€Ð¾Ñ Ñохраненных паролей
+plugin.provisioning.FORGET_PASSWORD=Забыть пароль
# packet logging service
plugin.loggingutils.PACKET_LOGGING_CONFIG=Протоколирование
@@ -1564,7 +1564,7 @@ plugin.loggingutils.PACKET_LOGGING_RTP_DESCRIPTION=(запиÑывает 1 из
plugin.loggingutils.PACKET_LOGGING_ICE4J=ice4j.org
plugin.loggingutils.PACKET_LOGGING_DESCRIPTION=<html>ЗапиÑывать отладочные ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð»Ð¸Ñ‡Ð½Ñ‹Ñ… протоколов в папку журналов <br>в формате pcap (tcpdump/wireshark).</html>
plugin.loggingutils.PACKET_LOGGING_FILE_COUNT=КоличеÑтво файлов журнала
-plugin.loggingutils.PACKET_LOGGING_FILE_SIZE=МакÑимальный размер файла (в Кб)
+plugin.loggingutils.PACKET_LOGGING_FILE_SIZE=МакÑимальный размер файла (в КБ)
plugin.loggingutils.ARCHIVE_BUTTON=Ðрхивировать журналы
plugin.loggingutils.UPLOAD_LOGS_BUTTON=Загрузить журналы
plugin.loggingutils.UPLOAD_BUTTON=Загрузить
@@ -1582,9 +1582,9 @@ plugin.dnsconfig.chkBackupDnsEnabled.text=ЗадейÑтвовать дополÐ
plugin.dnsconfig.lblBackupResolver.text=Ð˜Ð¼Ñ DNS-Ñервера
plugin.dnsconfig.lblBackupResolverFallbackIP.text=IP-Ð°Ð´Ñ€ÐµÑ DNS-Ñервера
plugin.dnsconfig.lblBackupPort.text=Порт
-plugin.dnsconfig.lblRedemption.text=Возврат на первичный DNS
+plugin.dnsconfig.lblRedemption.text=ВернутьÑÑ Ðº первичному ДÐС
plugin.dnsconfig.lblRedemption.description=<html>ЧиÑло откликов первичного DNS-Ñервера перед тем, как задейÑтвовать его опÑÑ‚ÑŒ вмеÑто резервного</html>
-plugin.dnsconfig.lblPatience.text=ИÑпользовать дополнительный DNS поÑле
+plugin.dnsconfig.lblPatience.text=ЗапуÑкать дополнительный ДÐС поÑле
plugin.dnsconfig.lblPatience.description=<html>КоличеÑтво миллиÑекунд Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð¾Ñ‚Ð²ÐµÑ‚Ð° от первичного DNS, прежде чем иÑпользовать резервный</html>
plugin.dnsconfig.dnssec.chkEnabled=ЗадейÑтвовать DNSSEC
plugin.dnsconfig.dnssec.lblDefault=Режим по умолчанию
@@ -1616,8 +1616,6 @@ util.dns.DNSSEC_WARNING=<html><div width="600">{0} попыталÑÑ Ð¿Ð¾Ð´ÐºÐ»
#plugin spellcheck
plugin.spellcheck.TITLE=ÐžÑ€Ñ„Ð¾Ð³Ñ€Ð°Ñ„Ð¸Ñ Ð¸ Грамматика
plugin.spellcheck.MENU=Открыть Ñловарь
-plugin.spellcheck.LANG=Язык
-plugin.spellcheck.EDIT_PERSONAL_DICT=Правка
plugin.spellcheck.ENABLE_SPELL_CHECK=Проверка правопиÑаниÑ
plugin.spellcheck.dialog.FIND=Ðайти далее
plugin.spellcheck.dialog.REPLACE=Заменить
@@ -1652,15 +1650,20 @@ plugin.certconfig.FILE_TYPE_DESCRIPTION=Хранилище ÑертификатÐ
plugin.certconfig.ALIAS_LOAD_EXCEPTION=Ðе удаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡Ð¸Ñ‚ÑŒ пÑевдонимы из хранилища ключей ({0}).
plugin.certconfig.INVALID_KEYSTORE_TYPE=Выбранный тип хранилища ключей неверен ({0}).
plugin.certconfig.BROWSE_KEYSTORE=Открыть хранилище ключей
+plugin.certconfig.REVOCATION_TITLE=ÐаÑтройки отзыва Ñертификатов
+plugin.certconfig.REVOCATION_CHECK_ENABLED=Проверка СОС (СпиÑка Отозванных Сертификатов) включена
+plugin.certconfig.REVOCATION_OCSP_ENABLED=Проверка ÑтатуÑа Ñертификата на предмет отозванноÑти включена
# Phone number contact source plugin
plugin.phonenumbercontactsource.DISPLAY_NAME=Телефонные номера
# properties editor
plugin.propertieseditor.TITLE=Редактор ÑвойÑтв
-plugin.propertieseditor.NEW_PROPERTY_TITLE=Добавить ÑвойÑтво
+plugin.propertieseditor.NEW_PROPERTY_TITLE=Добавить новое ÑвойÑтво
plugin.propertieseditor.CHECK_BOX=Показать Ñто предупреждение в Ñледующий раз
-plugin.propertieseditor.IM_AWARE=Я оÑознаю риÑк
+plugin.propertieseditor.DESCRIPTION=Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ ÐºÐ½Ð¾Ð¿ÐºÐ° позволÑет изменÑÑ‚ÑŒ ÑвойÑтва конфигурации Jitsi. Изменение Ñтих продвинутых наÑтроек может пагубно влиÑÑ‚ÑŒ на ÑтабильноÑÑ‚ÑŒ, безопаÑноÑÑ‚ÑŒ и производительноÑÑ‚ÑŒ данного приложениÑ. Вам Ñледует продолжить только еÑли вы уверены в том, что вы делаете.
+plugin.propertieseditor.IM_AWARE=Я отдаю Ñебе отчет о риÑках
+plugin.propertieseditor.NEED_RESTART=Ðа заметку: некоторые ÑвойÑтва могут потребовать перезапуÑка перед тем, как новые наÑтройки вÑтупÑÑ‚ в Ñилу.
#Thunderbird address book plugin
plugin.thunderbird.CONFIG_FORM_TITLE=Thunderbird
diff --git a/resources/languages/resources_si.properties b/resources/languages/resources_si.properties
index 909a419..be6326f 100644
--- a/resources/languages/resources_si.properties
+++ b/resources/languages/resources_si.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,24 +43,18 @@ service.gui.ACCOUNT_ME=මම
service.gui.ACCOUNT_REGISTRATION_WIZARD=ගිණුම ලියà·à¶´à¶¯à·’ංචි කිරීමේ සහකරු
service.gui.ACCOUNTS=ගිණුම්
service.gui.ADD=එකතු කරන්න (&A)
-service.gui.ADD_ACCOUNT=ගිණුමක් එකතු කරන්න
service.gui.ADD_CONTACT=සබà·à¶³à·”මක් එකතු කරන්න (&A)
service.gui.ADD_CONTACT_TO=සබà·à¶³à·”මක් එකතු කරන්න (&A) -
service.gui.ADD_CONTACT_ERROR={0} යන සබà·à¶³à·”ම එකතු කිරීම අසà·à¶»à·Šà¶®à¶š විය
service.gui.ADD_CONTACT_ERROR_TITLE=සබà·à¶³à·”ම එකතු කිරීම අසà·à¶»à·Šà¶®à¶š විය
service.gui.ADD_CONTACT_EXIST_ERROR={0} යන සබà·à¶³à·”ම දà·à¶±à¶§à¶¸à¶­à·Š ඔබේ ලà·à¶ºà·’ස්තුවේ අන්තර්ගතයි.
-service.gui.ADD_CONTACT_IDENTIFIER=පහත තීරුවේ ඔබ එකතු කිරීමට යන සබà·à¶³à·”මේ හඳුන්වනය ඇතුලත් කරන්න.
-service.gui.ADD_CONTACT_WIZARD=සබà·à¶³à·”ම් එකතු කිරීමේ සහකරු
service.gui.ADD_GROUP_LOCAL_ERROR={0} යන නම සහිත සමූහය එකතු කිරීම අසà·à¶»à·Šà¶®à¶š විය. මෙම පද්ධතියේ IO operation එකක් අතරතුර දà·à·à¶ºà¶šà·Š ඇතිවිය.
service.gui.ADD_GROUP_EXIST_ERROR={0} යන සමූහය දà·à¶±à¶§à¶¸à¶­à·Š ඔබේ ලà·à¶ºà·’ස්තුවේ අන්තර්ගතයි. කරුණà·à¶šà¶» වෙනත් නමක් ඇතුලත් කරන්න.
service.gui.ADD_GROUP_NET_ERROR=ජà·à¶½ දà·à·à¶ºà¶šà·Š හේතුවෙන් {0} යන නම සහිත සමූහය එකතු කිරීම අසà·à¶»à·Šà¶®à¶š විය. කරුණà·à¶šà¶» ඔබගේ ජà·à¶½ සම්බන්ධතà·à·€ පරීක්ෂà·à¶šà¶» නà·à·€à¶­ උත්සà·à·„ කරන්න.
service.gui.ADD_GROUP_ERROR={0} යන නම සහිත සමූහය එකතු කිරීම අසà·à¶»à·Šà¶®à¶š විය.
service.gui.ADD_GROUP_EMPTY_NAME=සමූහ නà·à¶¸à¶º හිස් විය නොහà·à¶š.
-service.gui.ADD_GROUP=සමූහයක් à·ƒà·à¶¯à¶±à·Šà¶±
-service.gui.ADD_SUBCONTACT=උප-සබà·à¶³à·”මක් එකතු කරන්න (&A)
service.gui.ADMINISTRATOR=administrator
service.gui.ADVANCED=à·€à·à¶©à·’මනත් (&A)
-service.gui.ALL=සියල්ල (&A)
service.gui.ALL_CONTACTS=සියලු සබà·à¶³à·”ම් (&A)
service.gui.APPLY=ක්â€à¶»à·’යà·à¶­à·Šà¶¸à¶š කරන්න (&A)
service.gui.ARE_CALLING=අමතමින්...
@@ -57,7 +62,6 @@ service.gui.ARE_NOW=ඔබ දà·à¶±à·Š {0}
service.gui.AT=වේලà·à·€:
service.gui.AUTHORIZATION_ACCEPTED=මෙම සබà·à¶³à·”ම ඔබේ ඉල්ලීම අනුමත කර ඇත.
service.gui.AUTHENTICATION_FAILED=අවසර නොලà·à¶¶à·š. ඔබ ඇතුලත් කල රහස් පදය à·€à·à¶»à¶¯à·’යි.
-service.gui.AUTHENTICATION_REQUESTED=සත්â€à¶ºà¶­à· සහතික කිරීමක් ඉල්ලුම් කර ඇත.
service.gui.AUTHENTICATION_REQUESTED_SERVER={0} server එක ඔබේ අනන්â€à¶ºà¶­à·à·€ සහතික කිරීමට ඉල්ලුම් කර ඇත.
service.gui.AUTHENTICATION_REJECTED=මෙම සබà·à¶³à·”ම ඔබේ ඉල්ලීම ප්â€à¶»à¶­à·’ක්ෂේප කර ඇත.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} සත්â€à¶ºà¶­à· සහතික කිරීම
@@ -97,12 +101,10 @@ service.gui.CHAT_ROOM_USER_KICKED={0}න් එලවන ලදි
service.gui.CHAT_ROOM_USER_QUIT={0} සමු ගත්තà·
service.gui.CHAT_ROOM_NAME=සංවà·à¶¯à¶ºà·š නම
service.gui.ROOM_NAME=සංවà·à¶¯ මණ්ඩපය
-service.gui.AUTOJOIN=ස්වයංක්â€à¶»à·“ය සම්බන්ධවීම
service.gui.CHAT_ROOM_NAME_INFO=පහත තීරුවේ ඔබ සෑදීමට යන සංවà·à¶¯ මණ්ඩපය සඳහ෠නම ඇතුලත් කරන්න.
service.gui.CHAT_ROOM_NOT_EXIST={0} කුටිය {1} server එකේ සොයà·à¶œà¶­ නොහà·à¶š. කරුණà·à¶šà¶» ඔබ ඇතුලත් කළ නම නිවà·à¶»à¶¯à·’දà·à¶ºà·’ තහවුරු කරගන්න.
service.gui.CHAT_ROOM_NOT_CONNECTED={0} සංවà·à¶¯à¶ºà¶§ සම්බන්ධ වීම සඳහ෠ඔබ ප්â€à¶»à·€à·šà·à·€à·“ (log-in) තිබිය යුතුය.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=සංවà·à¶¯à¶ºà¶šà·’න් ඉවත්වීම සඳහ෠ඔබ ප්â€à¶»à·€à·šà·à·€à·“ (log-in) තිබිය යුතුය.
-service.gui.CHAT_ROOM_NOT_JOINED=à·€à·à¶©à·’දුර ක්â€à¶»à·’යà·à¶šà·à¶»à¶šà¶¸à·Šà·€à¶½à¶§ ප්â€à¶»à¶®à¶¸à¶ºà·™à¶±à·Š සංවà·à¶¯à¶ºà¶§ සම්බන්ධවී සිටිය යුතුය.
service.gui.CHAT_ROOM_OPTIONS=සංවà·à¶¯ මණ්ඩප à·ƒà·à¶šà·ƒà·”ම්
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED={0} සංවà·à¶¯à¶ºà¶§ සම්බන්ධ වීම සඳහ෠ලියà·à¶´à¶¯à·’ංචි පà·à¶»à¶¸à¶ºà¶šà·Š අවà·à·Šâ€à¶ºà·€à·š.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD={0} සංවà·à¶¯ මණ්ඩපය රහස්පදයක් ඉල්ල෠සිටියි.
@@ -112,14 +114,11 @@ service.gui.CHAT_ROOM_SUBJECT_CHANGED={0}à·„à·’ මà·à¶­à·˜à¶šà·à·€ {1} ලෙ
service.gui.CLOSE=වහන්න (&o)
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=ඔබâ€à¶§ අවසà·à¶±à·€à¶»à¶§ පණිවිඩය ලà·à¶¶à·”ණේ මෙයට තත්පර දෙකකටත් අඩු කà·à¶½à¶ºà¶šà·Š ඉහතදීය. ඔබට à·ƒà·à¶¶à·€à·’න්ම ඉවත්වීමට අවà·à·Šâ€à¶ºà¶¯?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=දà·à¶±à¶§à¶¸à¶­à·Š ඔබේ ගොනු හුවමà·à¶»à·” වෙමින් පවතී. ඒව෠අහà·à·ƒà·’ කිරීම තහවුරු කරන්න.
-service.gui.CONFIRM=තහවුරු කරන්න
service.gui.CONNECTING=සම්බන්ධ වෙමින්...
service.gui.CONNECTING_STATUS=සබà·à¶³à·”ම
service.gui.CONNECTING_EARLY_MEDIA_STATUS=සම්බන්ධ වෙමින්...
service.gui.CONNECTION=සබà·à¶³à·”ම
-service.gui.CONNECTION_FAILED_MSG=පහත ගිණුම සමග සම්බන්ධවීම අසà·à¶»à·Šà¶®à¶š විය.පරිà·à·“ලක නà·à¶¸à¶º: {0}, Server නà·à¶¸à¶º: {1}. කරුණà·à¶šà¶» ඔබගේ ජà·à¶½ සබà·à¶³à·”ම පරීක්ෂ෠කරන්න. නà·à¶­à·„ොත් à·€à·à¶©à·’ විස්තර ජà·à¶½ administratorගෙන් ලබ෠ගන්න.
service.gui.CONNECTION_EXPIRED_MSG={0} server එක සමග ඔබ දà·à¶±â€à¶§ සම්බන්ධවී නොමà·à¶­.
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=තà·à¶»à¶± ලද {0} සබà·à¶³à·”ම දුරකථන සහà·à¶º නොදක්වයි.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=තà·à¶»à¶± ලද {0} සබà·à¶³à·”ම සම්මන්ත්â€à¶»à¶« සඳහ෠සහà·à¶º නොදක්වයි.
service.gui.CONTACT_PAUSED_TYPING={0} පණිවිඩය ඇතුලත් කිරීම නà·à·€à·à¶­à·Šà·€à·–à·€à·
service.gui.CONTACT_TYPING={0} පණිවිඩයක් ඇතුලත් කරමින් සිටියි
@@ -132,13 +131,10 @@ service.gui.CREATE_CHAT_ROOM=සංවà·à¶¯ මණ්ඩපක් à·ƒà·à¶¯à¶±à
service.gui.CREATE_CHAT_ROOM_ERROR={0} සංවà·à¶¯ මණ්ඩපක් සෑදීම අසà·à¶»à·Šà¶®à¶š විය.
service.gui.CREATE_CHAT_ROOM_WIZARD=සංවà·à¶¯ මණ්ඩප සෑදීමේ සහකරු
service.gui.CREATE_CONFERENCE_CALL=සම්මන්ත්â€à¶»à¶« ඇමතුමක් ගන්න... (&C)
-service.gui.CREATE_CONFERENCE_CHAT=සම්මන්ත්â€à¶»à¶«à¶ºà¶šà·Š ආරම්භ කරන්න... (&C)
service.gui.CREATE_GROUP=සමූහයක් à·ƒà·à¶¯à¶±à·Šà¶±... (&C)
service.gui.CREATE_GROUP_NAME=පහත තීරුවේ ඔබ සෑදීමට යන සමූහය සඳහ෠නම ඇතුලත් කරන්න.
-service.gui.CREATE_FIRST_GROUP_WIZARD=ඔබේ සබඳත෠ලà·à¶ºà·’ස්තුවේ කිසිඳු සමූහයක් අඩංගු නොවේ. කරුණà·à¶šà¶» ප්â€à¶»à¶®à¶¸à¶ºà·™à¶±à·Š සමූයක් à·ƒà·à¶¯à¶±à·Šà¶± (ගොනු මෙනුවෙන්).
service.gui.CONTACT_INFO_NOT_SUPPORTED=මෙම සබà·à¶³à·”ම ජà·à¶½ සබඳත෠තොරතුරු සඳහ෠සහà·à¶º නොදක්වයි
service.gui.CUT=කපන්න (&U)
-service.gui.DATE=දිනය
service.gui.DELETE=මකන්න
service.gui.DESKTOP_SHARING_WARNING=<b>තිරය පෙන්වීට අවà·à·Šâ€à¶ºà¶¶à·€ තහවුරු කරන්න</b> <br> 'හරි' එබීමෙන් පසු ඔබගේ පරිගණක තිරය මෙම ඇමතුමට සම්බන්ධව ඇති අයට දිස්වනු ඇත.
service.gui.DIALPAD=ඇමතුම් පà·à¶±à¶½à¶º
@@ -159,7 +155,6 @@ service.gui.ERROR_WAS=දà·à·‚ය: {0}
service.gui.ESTIMATED_TIME=ඇස්තමේන්තුගත කà·à¶½à¶º:
service.gui.EVENTS=සිදුවීම්
service.gui.EXIT=පිටවෙන්න (&X)
-service.gui.EXTENDED_CRITERIA=à·€à·à¶©à·’දුර නිර්ණà·à¶ºà¶š
service.gui.GENERAL=à·ƒà·à¶¸à·à¶±à·Šâ€à¶º
service.gui.GENERAL_ERROR=à·ƒà·à¶¸à·à¶±à·Šâ€à¶º දà·à·‚යක්
service.gui.GROUP_NAME=සමූහ නà·à¶¸à¶º
@@ -213,7 +208,6 @@ service.gui.HIDE_OFFLINE_CONTACTS=ජà·à¶½à¶ºà¶§ සම්බන්ධනොව
service.gui.HIDE_MAIN_WINDOW=<DIV>කතිර ලකුණ එබීමෙන් මෙය ඉවත් නොවේ, කවුලුව සඟවයි. ඔබට ඉවත්වීමට අවà·à·Šâ€à¶º නම් ගොනු/පිටවෙන්න තà·à¶»à¶±à·Šà¶±</DIV>
service.gui.HISTORY=අතීතය (&H)
service.gui.HISTORY_CONTACT=අතීතය - {0}
-service.gui.HOUR=පà·à¶º
service.gui.IDENTIFIER=හඳුන්වනය
service.gui.IGNORE=නොසලක෠හරින්න (&I)
service.gui.INSERT_SMILEY=සිනà·-මුහුණක් යොදන්න
@@ -230,7 +224,6 @@ service.gui.IS_CALLING=අමතයි...
service.gui.IS_NOW={0} දà·à¶±à·Š {1} නම්වේ
service.gui.JOIN=එකතුවෙන්න (&J)
service.gui.JOIN_AS=...ලෙස එකතුවෙන්න (&O)
-service.gui.CLOSE_CHAT_ROOM_DIALOG=වසන්න (&L)
service.gui.JOIN_CHAT_ROOM=සංවà·à¶¯ මණ්ඩපයට එකතුවෙන්න... (&J)
service.gui.JOIN_CHAT_ROOM_TITLE=සංවà·à¶¯ මණ්ඩපයට එකතුවෙන්න...
service.gui.JOIN_CHAT_ROOM_NAME=කරුණà·à¶šà¶» ඔබ සම්බන්ධවීමට කà·à¶¸à¶­à·’ සංවà·à¶¯ මණ්ඩපයේ නම ඇතුලත් කරන්න.
@@ -240,7 +233,6 @@ service.gui.KICK_FAILED=ඉවත් කිරීම අසà·à¶»à·Šà¶®à¶š à·€à·
service.gui.KICK_FAILED_GENERAL_ERROR={0} ඉවත් කිරීම අසà·à¶»à·Šà¶®à¶š විය. පොදු server දà·à·à¶ºà¶šà·Š ඇතිවිය.
service.gui.KICK_FAILED_NOT_ALLOWED={0} ඉවත් කිරීම අසà·à¶»à·Šà¶®à¶š විය. මෙම කුටියේ අයිතිකරු ඉවත් කල නොහà·à¶šà·’විය.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS={0} ඉවත් කිරීම අසà·à¶»à·Šà¶®à¶š විය. ඔබට ඒ සඳහ෠වරප්â€à¶»à·ƒà·à¶¯ නොමà·à¶­.
-service.gui.LAST=අවසà·à¶±
service.gui.LAST_NAME=අවසà·à¶± නම:
service.gui.LEAVE=පිටවෙන්න (&L)
service.gui.LIMIT_REACHED_FOR_IP=ඔබට දà·à¶±à¶§à¶¸à¶­à·Š මෙම IP ලිපිනයෙන් ලියà·à¶´à¶¯à·’ංචිවීම් විà·à·à¶½ ප්â€à¶»à¶¸à·à¶«à¶ºà¶šà·Š ඇත. server {0} තවත් ලියà·à¶´à¶¯à·’ංචිවීම් සඳහ෠ඉඩ ලබ෠නොදෙයි.
@@ -255,7 +247,6 @@ service.gui.MEMBER=à·ƒà·à¶¸à·à¶¢à·’කයà·
service.gui.MESSAGE=පණිවිඩය:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= සහ තවත් {0}ක්
service.gui.MODERATOR=සභà·à¶´à¶­à·’
-service.gui.MORE=à·€à·à¶©à·’මනත් විස්තර
service.gui.MORE_LABEL=තà·à¶±à·Šà¶¸à·à¶»à·” කරන්න
service.gui.MOVE=තà·à¶±à·Šà¶¸à·à¶»à·” කරන්න
service.gui.MOVE_SUBCONTACT=සබà·à¶³à·”ම මà·à¶»à·” කරන්න (&O)
@@ -264,7 +255,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=ඔබ තේරූ සබà·à¶³à·”ම මු
service.gui.MOVE_SUBCONTACT_QUESTION=ඔබට {0}, {1}†වෙත මà·à¶»à·”කිරීමට අවà·à·Šâ€à¶ºà¶¶à·€ තහවුරු කරන්න.
service.gui.MOVE_TO_GROUP=සමූහයට මà·à¶»à·” කරන්න. (&M)
service.gui.MOVE_CONTACT=සබà·à¶³à·”ම මà·à¶»à·” කරන්න
-service.gui.MOVE_CONTACT_ERROR=සබà·à¶³à·”ම මà·à¶»à·” කිරීමට නොහà·à¶š (&C)
service.gui.MSG_DELIVERY_FAILURE=ඉහත පණිවිඩය බà·à¶»à¶¯à·“මට නොහà·à¶šà·’විය
service.gui.MSG_DELIVERY_NOT_SUPPORTED=ඔබ පà·à·€à·’ච්චි කරන ප්â€à¶»à·œà¶§à·à¶šà·à¶½à¶º ජà·à¶½à¶ºà¶§ සම්බන්ධනොවී පණිවිඩ යà·à·€à·“මට සහà·à¶º නොදක්වයි. මෙම සබà·à¶³à·”ම සමග වෙනත් ප්â€à¶»à·œà¶§à·à¶šà·à¶½à¶ºà¶šà·’න් සම්බන්ධවීමට උත්සà·à·„ කරන්න. නà·à¶­à·„ොත් ඔහු/ඇය ජà·à¶½à¶ºà¶§ සම්බන්ධවනතුරු රà·à¶³à·“ සිටින්න.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=අභ්â€à¶ºà¶±à·Šà¶­à¶» දà·à·à¶ºà¶šà·Š ඇතිවිය. බොහà·à¶¯à·”රට මෘදුකà·à¶‚ගයේ දොà·à¶ºà¶šà·Š වියහà·à¶š. කරුණà·à¶šà¶» මෙතà·à¶±à¶§ à·€à·à¶»à·Šà¶­à· කරන්න: http://www.sip-communicator.org/index.php/Development/BugsAndIssues.
@@ -275,7 +265,6 @@ service.gui.MSG_NOT_POSSIBLE=මෙම සබà·à¶³à·”මට පණිවිඩ
service.gui.MSG_RECEIVED={0} ගෙන්
service.gui.MSG_SEND_CONNECTION_PROBLEM=පණිවිඩ යà·à·€à·“මට ඔබ ජà·à¶½à¶ºà¶§ සම්බන්ධවී සිටිය යුතුය.
service.gui.MULTIPLE_LOGINS=ඔබ එකම ගිණුමෙන් එක් වරකට වඩ෠ප්â€à¶»à·€à·šà·à·€à·“ ඇත. {0} පරිà·à·“ලක නà·à¶¸à¶º සහ {1} server නà·à¶¸à¶º සහිත ගිණුම දà·à¶±à¶§ විසන්ධිවී ඇත.
-service.gui.MUTE=නිà·à·Šà·à¶¶à·Šà¶¯
service.gui.NAME=නම
service.gui.NETWORK=ජà·à¶½à¶º
service.gui.NETWORK_FAILURE=ජà·à¶½ දà·à·à¶ºà¶šà·Š
@@ -294,7 +283,6 @@ service.gui.NON_EMPTY_CHAT_WINDOW_CLOSE=ඔබ නොයà·à·€à·– පණිවà·
service.gui.NON_EXISTING_USER_ID={0} server එක මෙම පරිà·à·“ලක නà·à¶¸à¶º හඳුන෠නොගනී.
service.gui.OFFLINE=විසන්ධිව
service.gui.OK=හරි (&O)
-service.gui.OLDER_CALLS=පසුගිය ඇමතුම්
service.gui.ONLINE=සම්බන්ධව
service.gui.OPEN=විවෘත කරන්න
service.gui.OPEN_FILE_FROM_IMAGE=ගොනුව විවෘත කිරීම සඳහ෠double click කරන්න.
@@ -302,7 +290,6 @@ service.gui.OPEN_FOLDER=බහà·à¶½à·”ම විවෘත කරන්න
service.gui.OPEN_IN_BROWSER=අන්තර්ජà·à¶½ ගවේà·à¶šà¶ºà·š විවෘත කරන්න (&B)
service.gui.OPTIONS=තේරීම්
service.gui.OR=à·„à·
-service.gui.OR_ENTER_PHONE_NUMBER=හ෠මෙතà·à¶± දුකතන අංකය ඇතුලත් කරන්න...
service.gui.ORGANIZATION=සංවිධà·à¶±à¶º:
service.gui.OWNER=කුටියේ අයිතිකරු
service.gui.PASSWORD=රහස්පදය
@@ -313,7 +300,6 @@ service.gui.PORT=තොටුපළ
service.gui.PRESENCE=පà·à·€à·à¶­à·Šà¶¸
service.gui.PRESS_ENTER_FOR_SUGGESTIONS=යà·à¶¢à¶±à· සඳහà·: 'Enter'
service.gui.PREVIOUS=පසුගිය
-service.gui.PREVIOUS_TOOLTIP=පසුගිය සංවà·à¶¯ පිරික්සන්න
service.gui.PRINT=මුද්â€à¶»à¶«à¶º (&P)
service.gui.PROACTIVE_NOTIFICATION=පණිවිඩයක් සටහන් කරමින්...
service.gui.PROTOCOL=ප්â€à¶»à·œà¶§à·à¶šà·à¶½à¶º
@@ -346,25 +332,17 @@ service.gui.REVOKE_ADMIN=admin අවලංගුකරන්න
service.gui.REVOKE_MODERATOR=moderator අවලංගුකරන්න
service.gui.REVOKE_MEMBERSHIP=à·ƒà·à¶¸à·à¶¢à·’කත්වය අවලංගුකරන්න
service.gui.REVOKE_VOICE=කටහඬ අහà·à·ƒà·’කරන්න
-service.gui.ROOT_GROUP=ප්â€à¶»à¶°à·à¶± සමූහය
service.gui.SAVE=සුරකින්න (&S)
service.gui.SEARCH=සොයන්න (&S)
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=තà·à¶»à·à¶œà¶­à·Š server එකෙහි ඇති සියලු සංවà·à¶¯ මණ්ඩප පෙන්වීමට පහත බොත්තම ඔබ෠ඔබ සම්බන්ධවීමට කà·à¶¸à¶­à·’ මණ්ඩපට තà·à¶»à¶±à·Šà¶±.
service.gui.SECURITY=ආරක්ෂà·à·€
-service.gui.SELECT_ACCOUNT=ගිණුම තà·à¶»à¶±à·Šà¶±
service.gui.SELECT_COLOR=පà·à¶§ තà·à¶»à¶±à·Šà¶±
service.gui.SELECT_GROUP=සමූහය තà·à¶»à¶±à·Šà¶±
-service.gui.SELECT_GROUP_WIZARD_MSG=පහත ලà·à¶ºà·’ස්තුවේ ඔබේ සබඳත෠ලà·à¶ºà·’ස්තුවේ ඇති සියලු සමූහයන් අන්තර්ගතවේ. නව සබà·à¶³à·”ම එකතුවිය යුතු සමූහය තà·à¶»à¶±à·Šà¶±.
service.gui.SELECT_NO_GROUP=සමූහයක් නොමà·à¶­
-service.gui.SELECT_GROUP_WIZARD=සමූහය සඳහන් කරන්න
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=පහත ලà·à¶ºà·’ස්තුවේ බහු පරිà·à·“ලක සංවà·à¶¯ සඳහ෠සහය දක්වන සියලු ගිණම් අන්තර්ගතවේ. ඔබේ සංවà·à¶¯ මණ්ඩපය සෑදීම සඳහ෠යොදà·à¶œà·à¶±à·“මට අවà·à·Šâ€à¶º ගිණුම තà·à¶»à¶±à·Šà¶±.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=පහත ලà·à¶ºà·’ස්තුවේ ඔබ ලියà·à¶´à¶¯à·’ංචිවූ සියලු ගිණම් අන්තර්ගතවේ. නව සබà·à¶³à·”ම සමග අදහස් හුවමà·à¶»à·” කිරීමට අවà·à·Šâ€à¶º ගිණුම තà·à¶»à¶±à·Šà¶±.
-service.gui.SELECT_PROVIDERS_WIZARD=ගිණුම තà·à¶»à¶±à·Šà¶±.
service.gui.SEND=යවන්න (&S)
service.gui.SEND_FILE=ගොනුව යවන්න (&F)
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=මෙම සබà·à¶³à·”ම සඳහ෠තොරතුරු කිසිවක් නොමà·à¶­.
service.gui.SEND_MESSAGE=පණිවිඩයක් යවන්න (&S)
-service.gui.SEND_AS_SMS=කෙටි පණිවිඩයක් ලෙස යවන්න
service.gui.SEND_SMS=කෙටි පණිවිඩය යවන්න (&E)
service.gui.SEND_SMS_DETAILS=මෙය ජà·à¶­à·Šâ€à¶ºà¶±à·Šà¶­à¶» අංකයක් ලෙස ඇතුලත්කළ යුතු බව මතක තබà·à¶œà¶±à·Šà¶±.උදà·- à·à·Šâ€à¶»à·“ ලංකà·à·€à·š අංකයක් +94 ලෙස ආරම්භ කරන්න, +941110000000
service.gui.SEND_SMS_NOT_SUPPORTED=ඔබ තà·à¶»à¶± ලද ගිණුම කෙටි පණිවිඩ සඳහ෠සහà·à¶º නොදක්වයි.
@@ -391,7 +369,6 @@ service.gui.STATUS_CHANGE_NETWORK_FAILURE=ජà·à¶½ දà·à·à¶ºà¶šà·Š හේත
service.gui.STATUS_MESSAGE_INFO=ඔබට පහත තීරුවේ නව පණිවිඩය ඇතුලත් කළ à·„à·à¶š.
service.gui.SUBJECT=මà·à¶­à·˜à¶šà·à·€
service.gui.SUMMARY=à·ƒà·à¶»à·à¶‚à·à¶º
-service.gui.TODAY=අද
service.gui.TOOLS=මෙවලම්
service.gui.TRANSFER=පවරන්න (&F)
service.gui.TO=වෙත: (&T)
@@ -400,7 +377,6 @@ service.gui.TRANSFER_CALL_TITLE=ඇමතුම පවරන්න
service.gui.TRANSFER_CALL_TO=වෙත පවරන්න:
service.gui.TRANSPARENCY_NOT_ENABLED=ඔබේ වර්තමà·à¶± à·ƒà·à¶šà·ƒà·”ම් පà·à¶»à¶¯à·˜à·à·Šâ€à¶ºà¶­à·à·€ සඳහ෠සහà·à¶º නොදක්වයි.
service.gui.TYPE_YOUR_REQUEST=මෙතà·à¶± ඔබේ ඉල්ලීම ඇතුලත් කරන්න.
-service.gui.UNMUTE=නිà·à·Šà·à¶¶à·Šà¶¯à¶­à·à·€ අහà·à·ƒà·’ කරන්න
service.gui.USER_IDENTIFIER=පරිà·à·“ලක හඳුන්වනය:
service.gui.USER_EXISTS_ERROR=තේරූ ජà·à¶½à¶ºà·š දà·à¶±à¶§à¶¸à¶­à·Š මෙම පරිà·à·’ලකය෠පවතී. කරුණà·à¶šà¶» වෙනත් පරිà·à·’ලකයෙක් හ෠ජà·à¶½à¶ºà¶šà·Š තà·à¶»à¶±à·Šà¶±.
service.gui.ACCOUNT_CREATION_FAILED=මෙම දà·à·à¶º හේතුවෙන් ඔබේ ගිණුම සෑදීම අසà·à¶»à·Šà¶®à¶š විය: {0}
@@ -414,9 +390,6 @@ service.gui.VIEW_TOOLBAR=මෙවලම් තීරුව පෙන්වනà·
service.gui.VOICEMAIL_NO_MESSAGES=පණිවිඩයක් නොමà·à¶­
service.gui.WARNING=අවවà·à¶¯à¶ºà¶ºà·’
service.gui.YES=ඔව්
-service.gui.YESTERDAY=ඊයේ
-service.gui.EXISTING_ACCOUNT_ERROR=ඔබ ඇතුලත්කළ ගිණුම දà·à¶±à¶§à¶¸à¶­à·Š ස්ථà·à¶´à¶±à¶º කර ඇත.
-service.gui.NEW_MAIL=<b>ඔබට නව ලිපියක් තිබේ!</b><br/><b>එවන්නà·:</b> {0} {1} <br/><b>මà·à¶­à·˜à¶šà·â€à·€:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=ඔබේ {0} <a href="{1}">inbox</a> එකට නව ලිපියක් ලà·à¶¶à·“ ඇත:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=ඔබේ {0} <a href="{1}">inbox</a> එකට නව ලිපි {2}ක් ලà·à¶¶à·“ ඇත:<br/>
service.gui.NEW_GMAIL_FOOTER=ඔබේ <a href="{0}">inbox</a> එකේ නොකියවූ තවත් එක් සංවà·à¶¯à¶ºà¶šà·Š තිබේ. <br/>
@@ -436,7 +409,6 @@ service.gui.SECURITY_WARNING=ආරක්ෂක අවවà·à¶¯à¶º
service.gui.SECURITY_ERROR=ආරක්ෂණ දà·à·à¶º
service.gui.SPEED=වේගය:
service.gui.SILENT_MEMBER=à·ƒà·à¶¸à·à¶¢à·’කය෠නිà·à·Šà·à¶¶à·Šà¶¯ කරන්න
-service.gui.UPDATE=යà·à·€à¶­à·Šà¶šà·à¶½à·“න
service.gui.VIDEO_PHONE=දෘà·à·Šâ€à¶º
service.gui.PHONE=දුරකතනය:
service.gui.PHONES=දුරකතනය:
@@ -459,12 +431,16 @@ service.gui.callinfo.VIEW_CERTIFICATE=සහතිකය පෙන්වන්à¶
service.gui.callinfo.MEDIA_STREAM_RTP=ZRTP
service.gui.callinfo.MEDIA_STREAM_SRTP=ZRTP
+#enum values from IceProcessingState
+
+
service.gui.ALWAYS_TRUST=මෙම සහතිකය සෑමවිටම විà·à·Šà·€à·à·ƒ කරන්න
service.gui.CERT_DIALOG_TITLE=සහතිකය තහවුරු කරන්න
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{1}:{2} වෙත සම්බන්ධවීමේදී server එකෙහි අනන්â€à¶ºà¶­à·à·€ {0}ට තහවුරු කරගත නොහà·à¶š. <br><br> සහතිකය විà·à·Šà·€à·à·ƒ කළ නොහà·à¶šà·’ බà·à·€à·’න් server එකෙහි අනන්â€à¶ºà¶­à·à·€ ස්වයංක්â€à¶»à·“යව තහවුරු කරගත නොහà·à¶š. ඔබට මෙම සම්බන්ධවීම පවත්වà·à¶œà·™à¶± යà·à¶¸à¶§ අවà·à·Šâ€à¶ºà¶¯? <br><br> à·€à·à¶©à·’දුර තොරතුරු සඳහ෠"සහතිකය පෙන්වන්න" යන්න ඔබන්න.</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{1}:{2} වෙත සම්බන්ධවීමේදී server එකෙහි අනන්â€à¶ºà¶­à·à·€ {0}ට තහවුරු කරගත නොහà·à¶š. <br><br> සහතිකය විà·à·Šà·€à·à·ƒ කළ නොහà·à¶šà·’ බà·à·€à·’න් server එකෙහි අනන්â€à¶ºà¶­à·à·€ ස්වයංක්â€à¶»à·“යව තහවුරු කරගත නොහà·à¶š. ඔබට මෙම සම්බන්ධවීම පවත්වà·à¶œà·™à¶± යà·à¶¸à¶§ අවà·à·Šâ€à¶ºà¶¯? <br><br> à·€à·à¶©à·’දුර තොරතුරු සඳහ෠"සහතිකය පෙන්වන්න" යන්න ඔබන්න.</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{1}:{2} වෙත සම්බන්ධවීමේදී server එකෙහි අනන්â€à¶ºà¶­à·à·€ {0}ට තහවුරු කරගත නොහà·à¶š. <br><br> සහතිකය විà·à·Šà·€à·à·ƒ කළ නොහà·à¶šà·’ බà·à·€à·’න් server එකෙහි අනන්â€à¶ºà¶­à·à·€ ස්වයංක්â€à¶»à·“යව තහවුරු කරගත නොහà·à¶š. ඔබට මෙම සම්බන්ධවීම පවත්වà·à¶œà·™à¶± යà·à¶¸à¶§ අවà·à·Šâ€à¶ºà¶¯? <br><br> à·€à·à¶©à·’දුර තොරතුරු සඳහ෠"සහතිකය පෙන්වන්න" යන්න ඔබන්න.</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{1}:{2} වෙත සම්බන්ධවීමේදී server එකෙහි අනන්â€à¶ºà¶­à·à·€ {0}ට තහවුරු කරගත නොහà·à¶š. <br><br> සහතිකය විà·à·Šà·€à·à·ƒ කළ නොහà·à¶šà·’ බà·à·€à·’න් server එකෙහි අනන්â€à¶ºà¶­à·à·€ ස්වයංක්â€à¶»à·“යව තහවුරු කරගත නොහà·à¶š. ඔබට මෙම සම්බන්ධවීම පවත්වà·à¶œà·™à¶± යà·à¶¸à¶§ අවà·à·Šâ€à¶ºà¶¯? <br><br> à·€à·à¶©à·’දුර තොරතුරු සඳහ෠"සහතිකය පෙන්වන්න" යන්න ඔබන්න.</html>
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=පොදු නà·à¶¸à¶º:
service.gui.CERT_INFO_O=සංවිධà·à¶±à¶º:
service.gui.CERT_INFO_C=රට:
@@ -478,18 +454,15 @@ service.gui.CERT_INFO_VER=සංස්කරණය:
service.gui.CERT_INFO_SIGN_ALG=මුද්â€à¶»à· ඇල්ගොරිතමය:
service.gui.CERT_INFO_ALG=ඇල්ගොරිතමය:
service.gui.CERT_INFO_PUB_KEY=පොදු යතුර:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} බයිට්: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} බිට්
service.gui.CERT_INFO_EXP=ප්â€à¶»à¶šà·à·à¶šà¶ºà·:
service.gui.CERT_INFO_KEY_SIZE=යතුරේ ප්â€à¶»à¶¸à·à¶«à¶º:
service.gui.CERT_INFO_SIGN=මුද්â€à¶»à·à·€:
-service.gui.CONTINUE=පවත්වà·à¶œà¶±à·Šà¶±
service.gui.SHOW_CERT=සහතිකය පෙන්වන්න
service.gui.HIDE_CERT=සහතිකය සඟවන්න
service.gui.AUTO_ANSWER_VIDEO=දෘà·à·Šâ€à¶º
-service.gui.security.COMPARE_WITH_PARTNER=සහකරු සමග සසඳà·à¶¶à¶½à· තහවුරුකිරීම සඳහ෠ඉබියතුර ඔබන්න.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT={0} සහකරු සමග සසඳන්න
@@ -503,18 +476,12 @@ service.gui.avatar.imagepicker.CLICK=ඔබ෠සිනà·à·ƒà·™à¶±à·Šà¶±
service.gui.avatar.imagepicker.IMAGE_FILES=පිළිබිඹු ගොනු
service.gui.avatar.imagepicker.IMAGE_PICKER=රූපය
service.gui.avatar.imagepicker.IMAGE_SIZE=පිළිබිඹුවේ ප්â€à¶»à¶¸à·à¶«à¶º
-service.gui.avatar.imagepicker.INITIALIZING=අරඹමින්
service.gui.avatar.imagepicker.RESET=නà·à·€à¶­ පිහිටුවන්න
service.gui.avatar.imagepicker.SET=තà·à¶»à¶±à·Šà¶±
service.gui.avatar.imagepicker.TAKE_PHOTO=ඡà·à¶ºà·à¶»à·–පයක් ගන්න
-service.gui.avatar.imagepicker.WEBCAM_ERROR=වෙබ්කà·à¶¸à¶»à·à·€à·š දà·à·à¶ºà¶šà·Š
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
# systray
@@ -533,9 +500,7 @@ impl.gui.main.account.DUMMY_PROTOCOL_DESCRIPTION=ජà·à¶½à¶º තà·à¶»à¶±à·Šà¶±
# LDAP
impl.ldap.GENERAL=à·ƒà·à¶¸à·à¶±à·Šâ€à¶º
-impl.ldap.NEW=නව
impl.ldap.EDIT=à·ƒà·à¶šà·ƒà·”ම් (E)
-impl.ldap.REMOVE=ඉවත්කරන්න
impl.ldap.ENABLED=සක්â€à¶»à·“ය කරන්න
impl.ldap.SERVER_HOSTNAME=සත්කà·à¶»à¶š නම:
impl.ldap.SAVE=සුරකින්න (&S)
@@ -544,12 +509,14 @@ impl.ldap.SERVER_PORT=තොටුපළ
impl.ldap.PASSWORD=රහස්පදය
impl.ldap.MAIL_FIELD_EXAMPLE=විද්â€à¶ºà·”ත් තà·à¶´à·à¶½à·Š ලිපිනය:
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
# Google Contacts
-impl.googlecontacts.NEW=නව
impl.googlecontacts.EDIT=à·ƒà·à¶šà·ƒà·”ම් (E)
-impl.googlecontacts.REMOVE=ඉවත්කරන්න
impl.googlecontacts.ENABLED=සක්â€à¶»à·“ය කරන්න
impl.googlecontacts.SAVE=සුරකින්න (&S)
impl.googlecontacts.CANCEL=එප෠(&C)
@@ -569,9 +536,6 @@ plugin.accountinfo.BDAY=උපන් දිනය:
plugin.accountinfo.GENDER=â€à·ƒà·Šà¶­à·Šâ€à¶»à·“/පුරුෂ භà·à·€à¶º:
plugin.accountinfo.EMAIL=විද්â€à¶ºà·”ත් තà·à¶´à·‘ල:
plugin.accountinfo.PHONE=දුරකතනය:
-plugin.accountinfo.USER_PICTURES=පරිà·à·“ලක රූප
-plugin.accountinfo.CHANGE=වෙනස් කරන්න
-plugin.accountinfo.ONLY_MESSAGE=පණිවිඩ පමණක්
# connection info
@@ -589,49 +553,12 @@ plugin.aimaccregwizz.USERNAME=AIM තිරනà·à¶¸à¶º:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=තිරනà·à¶¸à¶º සහ රහස්පදය
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=නව ගිණුමක් ලියà·à¶´à¶¯à·’ංචි කරන්න
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=ඔබට AIM ගිණුමක් නොමà·à¶­à·’නම්, අලුතෙන් ආරම්භ කිරීමට මෙම බොත්තම ඔබන්න.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=server එකෙහි සම්මත à·ƒà·à¶šà·ƒà·”ම් වෙනස් කරන්න
# branding
plugin.branding.ABOUT_WINDOW_TITLE={0} ගà·à¶±
plugin.branding.LOGO_MESSAGE=විවෘත කේත VoIP සහ ක්ෂණික පණිවිඩ
-plugin.branding.LOADING=ප්â€à¶»à·€à·šà· වෙම්න්
plugin.branding.ABOUT_MENU_ENTRY=පිළිබඳව (&A)
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>The {1},දà·à¶±à¶§ සක්â€à¶»à·“ය ගොඩනà·à¶œà·”ම් අදියරේ ඇත. ඔබ පà·à·€à·’ච්චි කරන සංස්කරණය පරීක්ෂණ මට්ටමේ ඇති බà·à·€à·’න් බලà·à¶´à·œà¶»à·œà¶­à·Šà¶­à·”වන ආකà·à¶»à¶ºà¶§ ක්â€à¶»à·’ය෠නොකිරීමට පිළිවන. කරුණà·à¶šà¶» à·€à·à¶©à·’විස්තර සඳහ෠{2} බලන්න.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2009 ප්â€à¶»à¶šà·à·à¶± හිමිකම <b>sip-communicator.org</b>. සියලු හිමිකම් ඇවිරිණි. <a href="http://sip-communicator.org">http://sip-communicator.org</a> වෙත යන්න.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}><b>SIP Communicator</b>, LGPLà·„à·’ අඩංගු වගන්ති යටතේ බෙදà·à·„à·à¶»à·š.(<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=à·à¶¶à·Šà¶¯à¶šà·à·‚
-plugin.dictaccregwizz.ANY_DICTIONARY=ඕනෑම à·à¶¶à·Šà¶¯à¶šà·à·‚යක්
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM={0} සිට ඕනෑම à·à¶¶à·Šà¶¯à¶šà·à·‚යක්
-plugin.dictaccregwizz.FIRST_MATCH=ප්â€à¶»à¶®à¶¸ ගà·à·…පුම
-plugin.dictaccregwizz.NO_MATCH=ගà·à·…පීම් නොමà·à¶­
-plugin.dictaccregwizz.MATCH_RESULT="{0}" සඳහ෠අර්ථ දà·à¶šà·Šà·€à·“ම් කිසිවක් සොයà·à¶œà¶­ නොහà·à¶š. සමහරවිට ඔබ අදහස් කරන්නේ මෙය විය à·„à·à¶š:\n
-plugin.dictaccregwizz.INVALID_DATABASE=මෙම "{0}" à·à¶¶à·Šà¶¯à¶šà·à·‚ය තවදුරටත් server එකෙහි නොපවතී.
-plugin.dictaccregwizz.INVALID_STRATEGY=මෙම මූලà·à¶´à·à¶º server එකෙහි අඩංගු නොවේ.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION='Dict' සේව෠ප්â€à¶»à·œà¶§à·à¶šà·à¶½à¶º
-plugin.dictaccregwizz.HOST=ධà·à¶»à¶šà¶ºà·
-plugin.dictaccregwizz.SERVER_INFO=server තොරතුරු
-plugin.dictaccregwizz.STRATEGY_SELECTION=මූලà·à¶´à· තේරීම
-plugin.dictaccregwizz.STRATEGY_LIST=මූලà·à¶´à·à¶ºà¶±à·Š ලà·à¶ºà·’ස්තුව
-plugin.dictaccregwizz.SEARCH_STRATEGIES=මූලà·à¶´à·à¶ºà¶±à·Š සොයන්න
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=මූලà·à¶´à·à¶º වන්නේ, පරිවර්තනයක් සොය෠නොගතහොත් සමà·à¶± වචන සෙවීමයි. උදà·à·„රණයක් ලෙස, උපසර්ග මූලà·à¶´à·à¶ºà¶ºà·™à¶±à·Š ඔබ පරිවර්තනය කිරීමට යන වචනයෙන් පටන්ගන්න෠වචන සොයà·à¶¯à·™à¶ºà·’.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE='Dict' ගිණුම් තොරතුරු
-plugin.dictaccregwizz.FIRST_ACCOUNT=මෙමගින්, dict.org à·„à·’ ඔබේ ප්â€à¶»à¶®à¶¸ Dict ගිණුම සෑදීමට සහà·à¶ºà·€à¶±à·” ඇත.\n\nනව ගිණුමක් එකතු කිරීමට "ගිණුම් ලියà·à¶´à¶¯à·’ංචිකිරීමේ සහකරු" වෙත ගොස් "සත්කà·à¶»à¶šà¶ºà·" තීරුවෙහි ඔබේ à·à¶¶à·Šà¶¯à¶šà·à·‚ය ඇතුලත් කරන්න.
-plugin.dictaccregwizz.THREAD_CONNECT=server එකට සම්බන්ධවීමට උත්සà·à·„ කරමින්...
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=සම්බන්ධවීමට නොහà·à¶šà·’විය. මෙය dic server එකක් නොවේ, එසේ නොමà·à¶­à·’නම් server එක ක්â€à¶»à·’යà·à¶šà·à¶»à·“à·€ නොපවතී
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=ලබà·à¶œà¶±à·Šà¶±à· මූලà·à¶´à·à¶ºà¶ºà¶±à·Š
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=මෙම server එකෙහි මූලà·à¶´à·à¶ºà¶šà·Š හමු නොවුණි
-plugin.dictaccregwizz.POPULATE_LIST=ලà·à¶ºà·’ස්තුව සකසමින්
-plugin.dictaccregwizz.CLOSING_CONNECTION=සම්බන්ධතà·à·€à¶º වසමින්
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">ෆේස්බුක් කතà·à¶¶à·„ සඳහ෠ඔබ පරිà·à·“ලක නà·à¶¸à¶ºà¶šà·Š සෑදිය යුතුවේ:<br>ෆේස්බුක් à·„à·’ "Account Settings" පිටුවෙන්.</a><br><br>සටහන: පරිà·à·“ලක නà·à¶¸à¶º සෑදූ පසු වෙබ් අඩවියෙන් ඉවත්වන්න<br>නව පරිà·à·“ලක නà·à¶¸à¶ºà·™à¶±à·Š ඇතුලුවීම සඳහ෠ටික වේලà·à·€à¶šà·Š ගතවිය à·„à·à¶šà·’ය!</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=ෆේස්බුක් කතà·à¶¶à·„ ප්â€à¶»à·œà¶§à·à¶šà·à¶½à¶º
-plugin.facebookaccregwizz.PROTOCOL_NAME=ෆේස්බුක් (facebook)
-plugin.facebookaccregwizz.USERNAME=පරිà·à·“ලක නà·à¶¸à¶º:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=පරිà·à·“ලක නà·à¶¸à¶º සහ රහස්පදය
+
# generalconfig
plugin.generalconfig.AUTO_START=පරිගණකය නà·à·€à¶­ ක්â€à¶»à·’යà·à¶­à·Šà¶¸à¶š කරනවිට {0} ස්වයංක්â€à¶»à·“යව ආරම්භ කරන්න
@@ -641,9 +568,6 @@ plugin.generalconfig.SHOW_HISTORY=පෙන්වන්න
plugin.generalconfig.HISTORY_SIZE=නව කතà·à¶¶à·„කදී මෑතකදී හුවමà·à¶»à·”වූ පණිවිඩ
plugin.generalconfig.SEND_MESSAGES_WITH=මෙමගින් යවන්න:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=කතà·à¶¶à·„ කවුලුව ඉදිරියට ගෙනෙන්න
-plugin.generalconfig.ERROR_PERMISSION=ස්වංක්â€à¶»à·“ය ආරම්භකිරීම ඉවත්කිරීම සඳහ෠ඔබට ප්â€à¶»à¶¸à·à¶«à·€à¶­à·Š අයිතීන් නොමà·à¶­
-plugin.generalconfig.TRANSPARENCY=පà·à¶»à¶¯à·˜à·à·Šâ€à¶ºà¶­à·à·€à¶º
-plugin.generalconfig.ENABLE_TRANSPARENCY=පà·à¶»à¶¯à·˜à·à·Šâ€à¶ºà¶­à·à·€à¶º සක්â€à¶»à·“ය කරන්න
plugin.generalconfig.DEFAULT_LANGUAGE=අතුරුමුහුණත් භà·à·‚à·à·€
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=ඔබ සිදුකල වෙනස්කම් ඊළඟ ප්â€à¶»à¶­à·’පිහිටුමේදී ක්â€à¶»à·’යà·à·€à¶§ නà·à¶‚වෙනු ඇත
plugin.generalconfig.SIP_CLIENT_PORT=SIP සේවà·à¶œà·Šâ€à¶»à·à·„ක දොරටුව
@@ -681,7 +605,6 @@ plugin.ircaccregwizz.IRC_SERVER=Server
# jabber accregwizz
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=SIP ප්â€à¶»à·œà¶§à·à¶šà·à¶½à¶º
plugin.jabberaccregwizz.PASSWORD_CONFIRM=රහස්පදය තහවුරු කරන්න
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=අනන්â€à¶ºà¶­à·à·€ සහ රහස්පදය
plugin.jabberaccregwizz.CSERVER=Server
plugin.jabberaccregwizz.SERVER=Server එකට සම්බන්ධවන්න
plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=ක්â€à¶»à·’යà·à¶­à·Šà¶¸à¶šà·€ තබà·à¶œà·à¶±à·“ම සක්â€à¶»à·“ය කරන්න
@@ -695,10 +618,7 @@ plugin.jabberaccregwizz.SERVER_COLUMN=Server
plugin.jabberaccregwizz.COMMENT_COLUMN=සටහන
plugin.jabberaccregwizz.RESOURCE=සම්පත
plugin.jabberaccregwizz.PRIORITY=ප්â€à¶»à¶¸à·”ඛතà·à·€
-plugin.jabberaccregwizz.XMPP_ERROR=XMPP දà·à·à¶ºà¶šà·Š
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=හඳුනà·à¶±à·œà¶œà¶­à·Š XMPP දà·à·à¶ºà¶šà·Š. server නà·à¶¸à¶º නිවà·à¶»à¶¯à·’දà·à¶ºà·’ පරීක්ෂ෠කරන්න.
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=server එකෙහි සම්මත à·ƒà·à¶šà·ƒà·”ම් අභිබව෠යන්න
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=à·€à·à¶©à·’දුර à·ƒà·à¶šà·ƒà·”ම්
plugin.jabberaccregwizz.USE_ICE=ICE පà·à·€à·’ච්චි කරන්න
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=STUN/TURN servers ස්වයංක්â€à¶»à·“යව හඳුනà·à¶œà¶±à·Šà¶±
plugin.jabberaccregwizz.SUPPORT_TURN=TURN සහà·à¶º
@@ -711,31 +631,14 @@ plugin.jabberaccregwizz.NO_STUN_USERNAME=ඉදිරියට යෑම සඳà
plugin.jabberaccregwizz.STUN_ALREADY_EXIST=ඔබ සඳහන් කළ STUN server එක දà·à¶±à¶§à¶¸à¶­à·Š පවතී.
plugin.jabberaccregwizz.JID_ADDRESS=IP ලිපිනය
plugin.jabberaccregwizz.EXISTING_ACCOUNT=දà·à¶±à¶§à¶¸à¶­à·Š පවතින SIP ගිණුමක්
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=රහස්පදය තහවුරු කරන්න
plugin.jabberaccregwizz.ENCODINGS=කේතකයන් (&E):
plugin.jabberaccregwizz.AUDIO=à·à·Šâ€à¶»à·€à·Šâ€à¶º
plugin.jabberaccregwizz.VIDEO=දෘà·à·Šâ€à¶º
plugin.jabberaccregwizz.RESET=නà·à·€à¶­ පිහිටුවන්න
-# mailbox
-plugin.mailbox.OUTGOING=යà·à·€à·™à¶± පණිවිඩය:
-plugin.mailbox.INCOMING=ලà·à¶¶à·™à¶± පණිවිඩ:
-plugin.mailbox.WAIT_TIME=ඇමතුම voicemail වෙත යà·à·€à·“මට රà·à¶³à·“ සිටිය යුතු කà·à¶½à¶º
-plugin.mailbox.MAX_MESSAGE_TIME=උපරිම පණිවිඩ කà·à¶½à¶º
-plugin.mailbox.CONFIRM=තහවුරු කරන්න
-plugin.mailbox.DEFAULTS=සම්මත à·ƒà·à¶šà·ƒà·”ම්
-plugin.mailbox.MAILBOX=තà·à¶´à·à¶½à·Š පෙට්ටිය
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=එම්.එස්.එන්. (MSN)
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=MSN සේව෠සඳහ෠සම්බන්ධවීමට සහ එමගින් කතà·à¶¶à·„ කිරීමට අදà·à¶½ ප්â€à¶»à·œà¶§à·à¶šà·à¶½à¶º.
-plugin.msnaccregwizz.USERNAME=විද්â€à¶ºà·”ත් තà·à¶´à·à¶½à·Š ලිපිනය:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=පරිà·à·“ලක නà·à¶¸à¶º සහ රහස්පදය
-
# plugin manager
plugin.pluginmanager.INSTALL=ස්ථà·à¶´à¶±à¶º කරන්න
plugin.pluginmanager.UNINSTALL=අස්ථà·à¶´à¶±à¶º කරන්න
-plugin.pluginmanager.UPDATE=යà·à·€à¶­à·Šà¶šà·à¶½à·“න
plugin.pluginmanager.PLUGINS=ප්ලග්-ඉන්
plugin.pluginmanager.URL=Url
plugin.pluginmanager.CHOOSE_FILE=ගොනුව තà·à¶»à¶±à·Šà¶±
@@ -759,7 +662,6 @@ plugin.sipaccregwizz.SERVER_PORT=Server දොරටුව
plugin.sipaccregwizz.PROXY=ප්â€à¶»à·œà¶šà·Šà·ƒà·’
plugin.sipaccregwizz.PROXY_PORT=ප්â€à¶»à·œà¶šà·Šà·ƒà·’ දොරටුව
plugin.sipaccregwizz.PREFERRED_TRANSPORT=ප්â€à¶»à·€à·à·„න ආකà·à¶»à¶º
-plugin.sipaccregwizz.ADVANCED_OPTIONS=à·€à·à¶©à·’දුර à·ƒà·à¶šà·ƒà·”ම්
plugin.sipaccregwizz.PROXY_OPTIONS=ප්â€à¶»à·œà¶šà·Šà·ƒà·’ à·ƒà·à¶šà·ƒà·”ම්
plugin.sipaccregwizz.PROXY_AUTO=ප්â€à¶»à·œà¶šà·Šà·ƒà·’ ස්වයංක්â€à¶»à·“යව සකසන්න
plugin.sipaccregwizz.ENABLE_PRESENCE=පà·à·€à·à¶­à·Šà¶¸ සක්â€à¶»à·“ය කරන්න (සරල)
@@ -771,8 +673,6 @@ plugin.sipaccregwizz.KEEP_ALIVE=සජීවීව තබà·à¶œà·à¶±à·“ම
plugin.sipaccregwizz.KEEP_ALIVE_METHOD=සජීවීව තබà·à¶œà·à¶±à·“මේ ක්â€à¶»à¶¸à¶º
plugin.sipaccregwizz.KEEP_ALIVE_INTERVAL=සජීවී පරà·à·ƒà¶º
plugin.sipaccregwizz.KEEP_ALIVE_INTERVAL_INFO=තත්පර 1 සහ 3600 අතර
-plugin.sipaccregwizz.REGISTER=ලියà·à¶´à¶¯à·’ංචිය
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=server එකෙහි සම්මත à·ƒà·à¶šà·ƒà·”ම් අබිභව෠යන්න
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=ඇමතුම් කේතනය කිරීමේ සහà·à¶º
plugin.sipaccregwizz.AUTH_NAME=බලයලත් නà·à¶¸à¶º
plugin.sipaccregwizz.DISPLAY_NAME=පෙන්වන නම
@@ -783,6 +683,7 @@ plugin.sipaccregwizz.CLIST_TYPE=ගිණුම් වර්ගය
plugin.sipaccregwizz.XCAP_USE_SIP_CREDENTIALS=SIP ගිණුම් දත්ත යොදà·à¶œà¶±à·Šà¶±
plugin.sipaccregwizz.XCAP_USER=පරිà·à·“ලක
plugin.sipaccregwizz.XCAP_PASSWORD=රහස්පදය
+#used from SecurityPanel
# skin manager
plugin.skinmanager.SKINS=තේමà·à·€
@@ -790,15 +691,6 @@ plugin.skinmanager.DEFAULT_SKIN=සම්මත තේමà·à·€
plugin.skinmanager.ADD_NEW_SKIN=නව තේමà·à·€à¶šà·Š එකතු කරන්න...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=යෙදුමේ සම්මත තේමà·à·€.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=SSH හරහ෠දුරස්ථ පරිගණය සම්බන්ධ කිරීම සඳහà·à·€à·– ප්â€à¶»à·œà¶§à·à¶šà·à¶½à¶ºà¶šà·’.
-plugin.sshaccregwizz.USERNAME=ගිණුම් අනන්â€à¶ºà¶­à·à·€:
-plugin.sshaccregwizz.IDENTITY_FILE=අනන්â€à¶ºà¶­à· ගොනුව:
-plugin.sshaccregwizz.KNOWN_HOSTS=දන්න෠සත්කà·à¶»à¶šà¶ºà¶±à·Š:
-plugin.sshaccregwizz.OPTIONAL=අතිරේක
-plugin.sshaccregwizz.ACCOUNT_DETAILS=ගිණුම් විස්තර
-
# status update
plugin.autoaway.AUTO_STATUS=ස්වයංක්â€à¶»à·“ය බà·à·„à·à¶»à·€à·“ම
plugin.autoaway.ENABLE_CHANGE_STATUS=බà·à·„à·à¶»à·€ සිටිනවිට තත්වය වෙනස්කරන්න
@@ -843,21 +735,6 @@ plugin.whiteboard.DESELECT=නොතà·à¶»à¶±à·Šà¶±
plugin.whiteboard.DELETE=මකන්න
plugin.whiteboard.PROPERTIES=තොරතුරු
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=යà·à·„à·– සේවà·à·€à¶±à·Š අතර සම්බන්ධ වීමට සහ කතà·à¶¶à·„ කිරීමට අදà·à·… ප්â€à¶»à·œà¶§à·à¶šà·à¶½à¶º.
-plugin.yahooaccregwizz.USERNAME=පරිà·à·“ලක නà·à¶¸à¶º:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=අනන්â€à¶ºà¶­à·à·€ සහ රහස්පදය
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=සීරà·-කන්ෆ් (Zeroconf)
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=සීරà·-කන්ෆ් (Zeroconf-Bonjour) සේව෠ප්â€à¶»à·œà¶§à·à¶šà·à¶½à¶º.
-plugin.zeroaccregwizz.FIRST_NAME=මුල් නම:
-plugin.zeroaccregwizz.LAST_NAME=අවසà·à¶± නම:
-plugin.zeroaccregwizz.EMAIL=විද්â€à¶ºà·”ත් තà·à¶´à·‘ල:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=Bonjour සබඳත෠මතක තබ෠ගන්න
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=අනන්â€à¶ºà¶­à·à·€ සහ රහස්පදය
-plugin.zeroaccregwizz.USERID=පරිà·à·“ලක නà·à¶¸à¶º
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=ගූගල් කත෠ප්â€à¶»à·œà¶§à·à¶šà·à¶½à¶º
plugin.googletalkaccregwizz.USERNAME=පරිà·à·“ලක නà·à¶¸à¶º
@@ -870,25 +747,18 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org සන්නිවේදà¶
plugin.iptelaccregwizz.USERNAME=පරිà·à·“ලක නà·à¶¸à¶º
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=iptel.org à·„à·’ ලියà·à¶´à¶¯à·’ංචි වන්න
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=සිප්2සිප් (sip2sip.info)
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=අන්තර්ජà·à¶½ ඇමතුම් සහ කතà·à¶¶à·„
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=පරිà·à·“ලක නà·à¶¸à¶º
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=රහස්පදය නà·à·€à¶­ ඇතුලත් කරන්න
plugin.sip2sipaccregwizz.EMAIL=විද්â€à¶ºà·”ත් තà·à¶´à·‘ල
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=සේව෠සහà·à¶º සඳහ෠<br>http://wiki.sip2sip.info වෙත යන්න
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>මගහà·à¶»à·”ණු ඇමතුම්, පටිගතකළ පණිවිඩ යà·à·€à·“මට සහ අස්ථà·à¶± ගතවූ රහස්පදය <br>ආපසු ලබà·à¶œà·à¶±à·“මට විද්â€à¶ºà·”ත් තà·à¶´à·à¶½à·Š ලිපිනය යොදà·à¶œà·à¶±à·š</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>සේව෠සහà·à¶º සඳහ෠<a href=''>http://wiki.sip2sip.info</a> වෙත යන්න</html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=දà·à¶±à¶§ පවතින සිප්2සිප් ගිණුමක්
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=නව සිප්2සිප් ගිණුමක් à·ƒà·à¶¯à¶±à·Šà¶±
-
-# ippi accregwizz
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=සේව෠සහà·à¶º සඳහ෠<br>http://wiki.sip2sip.info වෙත යන්න
plugin.ippiaccregwizz.INFO_NOTE=<html>සේව෠සහà·à¶º සඳහ෠<a href=''>http://wiki.sip2sip.info</a> වෙත යන්න</html>
plugin.ippiaccregwizz.EXISTING_ACCOUNT=දà·à¶±à¶§à¶¸à¶­à·Š පවතින SIP ගිණුමක්
plugin.ippiaccregwizz.CREATE_ACCOUNT=SIP ගිණුමක් à·ƒà·à¶¯à¶±à·Šà¶±
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=කතà·à¶¶à·„ කවුලුව à·€à·à·ƒà·“ම
plugin.keybindings.CHAT_COPY=පිටපත් කිරීම
plugin.keybindings.CHAT_CUT=කà·à¶´à·“ම
@@ -904,6 +774,7 @@ plugin.keybindings.OPEN_HISTORY=අතීතය විවෘත කිරීම
plugin.keybindings.OPEN_SMILIES=සිනà·-මුහුණු
plugin.keybindings.globalchooser.SHORTCUT_NAME=නම
plugin.keybindings.PLUGIN_NAME=යතුරුපුවරු කෙටි මං
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=කතà·à¶¶à·„
# Notification Configuration Form
@@ -918,6 +789,7 @@ plugin.notificationconfig.EXEC_PROG=à·€à·à¶©à·ƒà¶§à·„න ක්â€à¶»à·’යà·à
plugin.notificationconfig.DISPLAY_POPUP=මතුවන කවුලුවක පණිවිඩය පෙන්වන්න
plugin.notificationconfig.POPUP_NOTIF_HANDLER=නිවේදන වර්ගය:
plugin.notificationconfig.tableheader.EXECUTE=à·€à·à¶©à·ƒà¶§à·„න ක්â€à¶»à·’යà·à¶­à·Šà¶¸à¶š කරන්න:
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingMessage=ලà·à¶¶à·™à¶± පණිවිඩ:
plugin.notificationconfig.event.HangUp=විසන්ධි කරන්න
@@ -968,6 +840,7 @@ impl.media.configform.VIDEO_RESET=සම්මත à·ƒà·à¶šà·ƒà·”ම් ප්â€
impl.neomedia.configform.AUDIO=à·à·Šâ€à¶»à·€à·Šâ€à¶º
impl.neomedia.configform.VIDEO=දෘà·à·Šâ€à¶º
+#in JNIEncoder
impl.neomedia.configform.H264.preferredKeyFrameRequester.rtcp=ZRTP
# The callrecordingconfig plugin was never really committed into trunk and its
@@ -991,7 +864,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=පවත්න෠රහà
plugin.securityconfig.masterpassword.ENTER_PASSWORD=නව රහස්පදය :
plugin.securityconfig.masterpassword.REENTER_PASSWORD=නà·à·€à¶­ ඇතුලත් කරන්න:
plugin.securityconfig.masterpassword.MP_TITLE=ප්â€à¶»à¶°à·à¶± රහස්පදය
-plugin.securityconfig.masterpassword.MP_NOT_SET=(සකස෠නොමà·à¶­)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=පවතින රහස්පදය ඔබ ඇතුලත් කර නොමà·à¶­. නà·à·€à¶­ උත්සà·à·„ කරන්න.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=ප්â€à¶»à¶°à·à¶± රහස්පදය à·€à·à¶»à¶¯à·’යි!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=රහස්පදය වෙනස්කිරීම අසà·à¶»à·Šà¶®à¶š විය
@@ -1006,7 +878,6 @@ plugin.securityconfig.masterpassword.COL_NAME=නම
plugin.securityconfig.masterpassword.COL_PASSWORD=රහස්පදය
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(නොදනී)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(විකේතනය කළ නොහà·à¶š)
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=ඉවත්කරන්න
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=සියල්ල ඉවත්කරන්න
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=සියලු රහස්පද ඉවත්කිරීමට අවà·à·Šâ€à¶ºà¶¶à·€ තහවුරු කරන්න
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=සියලු රහස්පද ඉවත්කිරීම
@@ -1065,7 +936,6 @@ plugin.globalproxy.PROXY_PORT=ප්â€à¶»à·œà¶šà·Šà·ƒà·’ දොරටුව
plugin.globalproxy.PROXY_USERNAME=ප්â€à¶»à·œà¶šà·Šà·ƒà·’ පරිà·à·“ලක නà·à¶¸à¶º
plugin.globalproxy.PROXY_PASSWORD=ප්â€à¶»à·œà¶šà·Šà·ƒà·’ රහස්පදය
plugin.globalproxy.DESCRIPTION=මෙතà·à¶±à·Š පටන් ඔබ ඕනෑම ජà·à¶½à¶ºà¶šà¶§ සම්බන්ධවීමේදී මෙම ප්â€à¶»à·œà¶šà·Šà·ƒà·’ à·ƒà·à¶šà·ƒà·”ම් භà·à·€à·’ත෠කෙâ€à¶»à·™à¶±à·” ඇත. \nප්â€à¶»à·œà¶šà·Šà·ƒà·’ සහà·à¶º දà·à¶±à¶§ පරීක්ෂණ මට්ටමේ පවතින අතර එය ක්â€à¶»à·’යà·à¶­à·Šà¶¸à¶š වන්නේ සමහර ප්â€à¶»à·œà¶§à·à¶šà·à¶½ සමග පමණි. à·€à·à¶©à·’ විස්තර සඳහ෠පහත වගුව බලන්න.
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>යà·à·„à·–!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>එම්.එස්.එන්.</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>ජà·à¶¶'</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
# plugin reconnect
@@ -1100,7 +970,6 @@ plugin.dnsconfig.lblBackupPort.text=තොටුපළ
net.java.sip.communicator.util.dns.SecureResolveMode.IgnoreDnssec=නොසලක෠හරින්න (&I)
#plugin spellcheck
-plugin.spellcheck.EDIT_PERSONAL_DICT=à·ƒà·à¶šà·ƒà·”ම් (E)
plugin.spellcheck.UNINSTALL_DICTIONARY=අස්ථà·à¶´à¶±à¶º කරන්න
diff --git a/resources/languages/resources_sk.properties b/resources/languages/resources_sk.properties
index 70ccefb..72e4f3c 100644
--- a/resources/languages/resources_sk.properties
+++ b/resources/languages/resources_sk.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Ja
service.gui.ACCOUNT_REGISTRATION_WIZARD=Sprievodca registráciou úÄtu
service.gui.ACCOUNTS=ÚÄty
service.gui.ADD=&Pridať
-service.gui.ADD_ACCOUNT=PridaÅ¥ úÄet
service.gui.ADD_CONTACT=&Pridať kontakt
service.gui.ADD_AUTHORIZED_CONTACT=Pridať {0} do zoznamu kontaktov
service.gui.ADD_CONTACT_TO_CONTACTLIST=Pridať kontakt do zoznamu kontaktov
@@ -42,20 +52,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Chyba pri pridávaní kontaktu
service.gui.ADD_CONTACT_EXIST_ERROR=Kontakt {0} už existuje vo vašom zozname kontaktov.
service.gui.ADD_CONTACT_NETWORK_ERROR=Server neodpovedal na požiadávku pridania kontaktu: {0}
service.gui.ADD_CONTACT_NOT_SUPPORTED=Nepodarilo sa pridať kontakt s ID: {0}. Nepodporovaná operácia.
-service.gui.ADD_CONTACT_IDENTIFIER=Do pola nižšie zadajte identifikátor kontaktu, ktorý chcete pridať.
-service.gui.ADD_CONTACT_WIZARD=Sprievodca pridaním kontaktu
service.gui.ADD_CONTACT_NOT_CONNECTED=Na pridanie kontaktu musíte byť pripojený. Prosím prihláste sa na zvolenú službu a skúste znova.
service.gui.ADD_GROUP_LOCAL_ERROR=Nepodarilo sa pridaÅ¥ skupinu: {0}. Problém nastal poÄas lokálnej vstup/výstup operácie.
service.gui.ADD_GROUP_EXIST_ERROR=Skupina {0} už existuje vo vašom zozname kontaktov. Zvoľte iný názov.
service.gui.ADD_GROUP_NET_ERROR=Nepodarilo sa pridať skupinu: {0}. Problém nastal kvôli chybe v sieti. Prosím skontrolujte sieťové pripojenie a skúste znova.
service.gui.ADD_GROUP_ERROR=Nepodarilo sa pridať skupinu: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=Názov skupiny musí byť zadaný.
-service.gui.ADD_GROUP=Vytvoriť skupinu
-service.gui.ADD_SUBCONTACT=&Pridať subkontakt
service.gui.ADDRESS=Adresa
service.gui.ADMINISTRATOR=administrátor
service.gui.ADVANCED=&PokroÄilé
-service.gui.ALL=&VÅ¡etko
service.gui.ALL_CONTACTS=&VÅ¡etky kontakty
service.gui.ALTERNATE_ADDRESS=Alternatívna adresa
service.gui.APPLY=&Použiť
@@ -65,7 +70,6 @@ service.gui.AT=o
service.gui.AUTHORIZE=&Autorizovať
service.gui.AUTHORIZATION_ACCEPTED=kontakt prijal vašu žiadosť o autorizáciu.
service.gui.AUTHENTICATION_FAILED=Nepodarilo sa prihlásiť pre {0}. Zadali ste nesprávne heslo.
-service.gui.AUTHENTICATION_REQUESTED=Požadované prihlásenie
service.gui.AUTHENTICATION_REQUESTED_SERVER=Server {0} vyžaduje prihlásenie.
service.gui.AUTHENTICATION_REJECTED=kontakt zamietol vašu žiadosť o autorizáciu.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} prihlásenie
@@ -107,26 +111,24 @@ service.gui.CHANGE_NICKNAME_LABEL=Do políÄka nižšie zadajte novú prezívku.
service.gui.CHANGE_NICKNAME_ERROR=Chyba pri zmene prezývky
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Prezývka už existuje
service.gui.CHANGE_VIDEO_QUALITY=Zmeniť kvalitu vzdialeného videa
-service.gui.CHAT_CONFERENCE_LABEL=Konferencia
service.gui.CHAT_ROOM_ALREADY_JOINED=K miestnosti {0} ste už pripojený.
service.gui.CHAT_ROOM_CONFIGURATION=Nastavenia miestnosti {0}
service.gui.CHAT_ROOM_CONFIGURATION_FAILED=Nepodarilo sa získať formulár nastavenia miestnosti {0}.
+service.gui.CHAT_ROOM_CONFIGURATION_FORBIDDEN=Nebolo možné získaÅ¥ konfiguraÄný formulár pre {0} chat miestnosÅ¥. Iba majitelia chat miestnosti môžu vidieÅ¥ a zmeniÅ¥ konfiguraÄný formulár.
service.gui.CHAT_ROOM_CONFIGURATION_SUBMIT_FAILED=Chyba pri odosielaní formuláru nastavenia miestnosti {0}.
+service.gui.CHAT_ROOM_CONFIGURATION_MEMBERS_EDIT_TITLE=Uprav Älenský zoznam
service.gui.CHAT_ROOM_USER_JOINED=sa pripojil(a) {0}
service.gui.CHAT_ROOM_USER_LEFT=opustil(a) {0}
service.gui.CHAT_ROOM_USER_KICKED=bol(a) vykopnutý z {0}
service.gui.CHAT_ROOM_USER_QUIT=sa odpojil(a) {0}
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Vymaže vybranú miestnosť zo zoznamu uložených miestností.
service.gui.CHAT_ROOM_NAME=Názov miestnosti
service.gui.CLEAR_CUSTOM_MESSAGES=Vymazať vlastné správy
service.gui.ROOM_NAME=Miestnosť
-service.gui.AUTOJOIN=Automaticky pripojiť
service.gui.CHANGE_PASSWORD=Zmeniť heslo
service.gui.CHAT_ROOM_NAME_INFO=Do poľa nižšie zadajte názov miestnosti, ktorú chcete vytvoriť.
service.gui.CHAT_ROOM_NOT_EXIST=Miestnosť {0} nebola nájdená na serveri {1}. Prosím skontrolujte názov miestnosti.
service.gui.CHAT_ROOM_NOT_CONNECTED=Musíte byť prihlásený aby ste sa mohli pripojiť k miestnosti {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Musíte byť prihlásený aby ste mohli opustiť miestnosť.
-service.gui.CHAT_ROOM_NOT_JOINED=Musíte byÅ¥ pripojený k miestnosti aby ste s ňou mohli vykonávaÅ¥ ÄalÅ¡ie operácie.
service.gui.CHAT_ROOM_OPTIONS=Možnosti miestnosti
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Na pripojenie k miestnosti {0} je potrebná registrácia.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Miestnosť {0} vyžaduje heslo.
@@ -140,21 +142,17 @@ service.gui.CLEAR=Vymazať
service.gui.CLOSE=&Zavrieť
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Pred menej než dvoma sekundami ste prijali novú správu. Naozaj chcete zavrieť tento chat?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=Prebieha prenos súborov. Chcete ich zrušiť?
-service.gui.CONFIRM=Potvrdiť
service.gui.CONNECTED_STATUS=Pripojený
service.gui.CONNECTING=Pripája sa...
service.gui.CONNECTING_STATUS=Pripája sa
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Pripája sa*
service.gui.CONNECTION=Pripojenie
-service.gui.CONNECTION_FAILED_MSG=Pripojenie k serveru zlyhalo: Užívateľské meno: {0}, Názov serveru: {1}. Skontrolujte, prosím, svoje nastavenia alebo sa obráťte na správcu siete pre ÄalÅ¡ie informácie.
service.gui.CONNECTION_EXPIRED_MSG=Momentálne ste odpojení od serveru {0}.
service.gui.CONTACT_NAME=ID alebo Äíslo
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Zvolený {0} kontakt nepodporuje telefonovanie.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Zvolený {0} kontakt nepodporuje konferenÄný chat.
service.gui.CONTACT_PAUSED_TYPING={0} prestal(a) písať...
service.gui.CONTACT_TYPING={0} píše správu...
service.gui.CONTACT_INFO=&Informácie o kontakte
-service.gui.CONTACTLIST=Zoznam kontaktov
service.gui.CONTACTS=Kontakty
service.gui.COPY=&Kopírovať
service.gui.COPY_LINK=Kopírovať &odkaz
@@ -163,13 +161,10 @@ service.gui.CREATE_CHAT_ROOM=&Vytvoriť miestnosť...
service.gui.CREATE_CHAT_ROOM_ERROR=Nepodarilo sa vytvoriť miestnosť {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=Sprievodca vytváraním miestnosti
service.gui.CREATE_CONFERENCE_CALL=&VytvoriÅ¥ konferenÄný hovor...
-service.gui.CREATE_CONFERENCE_CHAT=&VytvoriÅ¥ konferenÄný chat...
service.gui.CREATE_GROUP=&Vytvoriť skupinu...
service.gui.CREATE_GROUP_NAME=Do poľa nižšie zadajte názov skupiny, ktorú chcete vytvoriť.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Váš zoznam kontaktov neobsahuje žiadnu skupinu. Prosím vytvorte najprv skupinu (Súbor/Vytvoriť skupinu).
service.gui.CONTACT_INFO_NOT_SUPPORTED=Tento kontakt nepodporuje informácie z webu
service.gui.CUT=&Vystrihnúť
-service.gui.DATE=Dátum
service.gui.DELETE=Vymazať
service.gui.DENY=&Zamietnuť
service.gui.DESKTOP_SHARING_WARNING=<b>Naozaj chcete zdielaÅ¥ obrazovku?</b> <br> StlaÄením OK umožníte vÅ¡etkým úÄastníkom hovoru vidieÅ¥ vaÅ¡u obrazovku.
@@ -179,7 +174,6 @@ service.gui.DISCONNECTED_STATUS=Odpojený
service.gui.DND_STATUS=Nerušiť
service.gui.DO_NOT_ASK_AGAIN=Nepýtať sa znovu
service.gui.DO_NOT_SHOW_AGAIN=Túto správu už nezobrazovať
-service.gui.DOWNLOAD_NOW=&Stiahnúť teraz
service.gui.DRAG_FOR_SHARING=Potiahnite sem to Äo chcete zdielaÅ¥...
service.gui.DURATION=trvanie
service.gui.EDIT=&Upraviť
@@ -196,7 +190,6 @@ service.gui.ERROR_WAS=Chyba bola: {0}
service.gui.ESTIMATED_TIME=Predpokladaný Äas:
service.gui.EVENTS=Udalosti
service.gui.EXIT=&UkonÄiÅ¥
-service.gui.EXTENDED_CRITERIA=Rozšírené hľadanie
service.gui.GENERAL=Všeobecný
service.gui.GENERAL_ERROR=Všeobecná chyba
service.gui.GROUP_NAME=Názov skupiny
@@ -252,7 +245,6 @@ service.gui.HIDE_MAIN_WINDOW=<DIV>Kliknutím na tlaÄidlo X nevypne aplikáciu,
service.gui.HISTORY=&História
service.gui.HISTORY_CONTACT=História - {0}
service.gui.HOME=Domov
-service.gui.HOUR=Hodina
service.gui.IDENTIFIER=Identifikátor
service.gui.IGNORE=Ignorovať
service.gui.INSERT_SMILEY=Vložiť smajlík
@@ -271,9 +263,6 @@ service.gui.INVITE_CONTACT_TO_CALL=Pozvať kontakty na hovor
service.gui.INVITE_REASON=Dôvod pozvania
service.gui.IS_CALLING=volá...
service.gui.IS_NOW={0} je teraz {1}
-service.gui.JITSI_WARNING=SIP Communicator bol nedávno premenovaný na Jitsi.<br/>Ak chcete aby vaša verzia ostala aktuálna, stiahnite si Jitsi teraz.<br/><br/>Ospravedlňujeme sa za všetky nepríjemnosti, ktoré vám to mohlo spôsobiť.<br/><br/>Jitsi Dev Team
-service.gui.JITSI_WARNING_TITLE=SIP Communicator sa premenoval na Jitsi
-service.gui.CLOSE_CHAT_ROOM_DIALOG=&Zatvoriť
service.gui.JOIN_CHAT_ROOM_TITLE=Pripojiť sa do miestnosti
service.gui.JOIN_CHAT_ROOM_NAME=Zadajte prosím názov miestnosti, do ktorej sa chcete pripojiť.
service.gui.JOIN_CHAT_ROOM_WIZARD=Sprievodca pripojením k miestnosti
@@ -293,7 +282,7 @@ service.gui.NAME=Meno
service.gui.NEW_ACCOUNT=PridaÅ¥ nový úÄet
service.gui.NO=Nie
service.gui.OPEN=Otvoriť
-service.gui.OPTIONS=Voliteľné
+service.gui.OPTIONS=Nastavenia
service.gui.chat.role.ADMINISTRATOR=administrátor
service.gui.PASSWORD=Heslo
service.gui.PASSWORD_CHANGE_FAILURE=Zmena hesla bola neúspešná
@@ -306,7 +295,7 @@ service.gui.RENAME_CONTACT=Premenovať kontakt
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Kliknite na tlaÄidlo na zobrazenie vÅ¡etkých chat miestností vo vybranom servery. Následne vyberte tú, do ktorej sa chcete zapojiÅ¥ a stlaÄte tlaÄidlo pripojiÅ¥.
service.gui.SECURITY=BezpeÄnosÅ¥
service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Vyberte chat miestnosÅ¥ z listu a stlaÄte ok pre jej pridanie.
-service.gui.SETTINGS=Voliteľné
+service.gui.SETTINGS=&Nastavenia
service.gui.SHOW=Zobraz
service.gui.SHOW_CONTACT_LIST_TOOL_TIP=Kliknite tu pre vypnutie historie a zobrazenie vášho kontaktu zoznamov.
service.gui.SHOW_MORE=ukázať viac...
@@ -317,7 +306,6 @@ service.gui.YES=Ãno
service.gui.NEW=Nový
service.gui.SHOW_LOCAL_VIDEO_BUTTON_TOOL_TIP=Zobraziť/skryť lokálne video
service.gui.SHOW_HIDE_PEERS_TOOL_TIP=ZobraziÅ¥/skryÅ¥ úÄastníkov rozhovoru
-service.gui.UPDATE=Aktualizovať
service.gui.VIDEO_PHONE=Video
@@ -325,13 +313,16 @@ service.gui.VIDEO_PHONE=Video
service.gui.callinfo.MEDIA_STREAM_RTP=RTP
service.gui.callinfo.MEDIA_STREAM_SRTP=RTP
+#enum values from IceProcessingState
+
+
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_PUB_KEY=Verejný klúÄ:
service.gui.AUTO_ANSWER_LABEL=Automatická odpoveÄ
service.gui.AUTO_ANSWER_VIDEO=Video
-service.gui.security.NO_VIDEO=HD video
-service.gui.security.COMPARE_WITH_PARTNER=Porovnajte údaje s partnerom a kliknite na "zámok" pre potvrdenie.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Porovnajte s partnerom: {0}
@@ -340,9 +331,6 @@ service.gui.avatar.imagepicker.CANCEL=Zrušiť
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
# systray
@@ -352,21 +340,21 @@ service.gui.avatar.imagepicker.CANCEL=Zrušiť
# LDAP
impl.ldap.CONFIG_FORM_TITLE=ICE nastavenie
impl.ldap.GENERAL=Všeobecný
-impl.ldap.NEW=Nový
impl.ldap.EDIT=upraviť
-impl.ldap.REMOVE=Odstrániť
impl.ldap.ENABLED=Povoliť
impl.ldap.CANCEL=Zrušiť
impl.ldap.SERVER_PORT=Port
impl.ldap.PASSWORD=Heslo
impl.ldap.MAIL_FIELD_EXAMPLE=E-mail:
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
# Google Contacts
-impl.googlecontacts.NEW=Nový
impl.googlecontacts.EDIT=upraviť
-impl.googlecontacts.REMOVE=Odstrániť
impl.googlecontacts.ENABLED=Povoliť
impl.googlecontacts.CANCEL=Zrušiť
impl.googlecontacts.PASSWORD=Heslo
@@ -391,19 +379,16 @@ plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=V prípade že nemáte AIM úÄet
# branding
plugin.branding.ABOUT_MENU_ENTRY=&O programe
-# Dict protocol
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Informácie o RSS úÄte
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.USERNAME=Užívateľské meno:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Používateľské meno a heslo
# generalconfig
plugin.generalconfig.AUTO_START=Zapnúť automaticky {0} pri štarte alebo reštarte
plugin.generalconfig.GROUP_CHAT_MESSAGES=Správy skupinových konverzácií v jednom okne
plugin.generalconfig.LOG_HISTORY=Ukladaj históriu konverzácií
plugin.generalconfig.HISTORY_SIZE=posledných správ v nových konverzáciách
+plugin.generalconfig.BRING_WINDOW_TO_FRONT=Preniesť okno s konverzáciou do popredia
plugin.generalconfig.CHECK_FOR_UPDATES=Skontrolovať aktualizácie pri štarte
+plugin.generalconfig.LEAVE_CHATROOM_ON_WINDOW_CLOSE=Opusť chat miestnosti po zatvorení okna
+plugin.generalconfig.SHOW_RECENT_MESSAGES=Zobraz posledné konverzácie (závisí na histórii konverzácií)
plugin.generalconfig.SIP_CALL_CONFIG=SIP
plugin.generalconfig.RESTORE=Obnoviť štandardné
@@ -417,32 +402,16 @@ plugin.ircaccregwizz.USERNAME_AND_PASSWORD=ID a heslo
# jabber accregwizz
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=SIP protokol
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=ID a heslo
plugin.jabberaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=VytvoriÅ¥ voľný SIP úÄet
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Vaše heslá sa nezhodujú.
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=PokroÄilé nastavenia
plugin.jabberaccregwizz.EXISTING_ACCOUNT=Existujúci SIP úÄet
plugin.jabberaccregwizz.ALLOW_NON_SECURE=PovoliÅ¥ nezabezpeÄené spojenia
plugin.jabberaccregwizz.AUDIO=Zvuk
plugin.jabberaccregwizz.VIDEO=Video
-# mailbox
-plugin.mailbox.OUTGOING=Odchádzajúca správa:
-plugin.mailbox.INCOMING=Prichádzajúce správy:
-plugin.mailbox.CONFIRM=Potvrdiť
-plugin.mailbox.DEFAULTS=Východzie
-plugin.mailbox.MAILBOX=Poštová schránka
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Protokol pre pripojenie k službe MSN.
-plugin.msnaccregwizz.USERNAME=E-mail:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=ID a heslo
-
# plugin manager
plugin.pluginmanager.INSTALL=Inštalovať
plugin.pluginmanager.UNINSTALL=Odinštalovať
-plugin.pluginmanager.UPDATE=Aktualizovať
plugin.pluginmanager.URL=Url
plugin.pluginmanager.CHOOSE_FILE=Vybrať súbor
plugin.pluginmanager.SYSTEM=Systém
@@ -459,7 +428,6 @@ plugin.sipaccregwizz.PROTOCOL_NAME=SIP
plugin.sipaccregwizz.PROTOCOL_DESCRIPTION=SIP protokol
plugin.sipaccregwizz.USERNAME_AND_PASSWORD=Používateľské meno a heslo
plugin.sipaccregwizz.PROXY_PORT=Proxy port
-plugin.sipaccregwizz.ADVANCED_OPTIONS=PokroÄilé nastavenia
plugin.sipaccregwizz.PROXY_OPTIONS=Nastavenia proxy
plugin.sipaccregwizz.PROXY_AUTO=Nastaviť proxy automaticky
plugin.sipaccregwizz.PRESENCE_OPTIONS=Nastavenia Prítomnosti
@@ -468,7 +436,6 @@ plugin.sipaccregwizz.KEEP_ALIVE_METHOD=Metóda pre udržiavanie spojenia
plugin.sipaccregwizz.KEEP_ALIVE_INTERVAL=Interval udržiavania spojenia
plugin.sipaccregwizz.KEEP_ALIVE_INTERVAL_INFO=Medzi 1 a 3600 sekundami
plugin.sipaccregwizz.DTMF_METHOD=Metóda DTMF
-plugin.sipaccregwizz.REGISTER=REGISTER
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Povoliť podporu pre šifrovanie hovorov
plugin.sipaccregwizz.AUTH_NAME=Meno pre autorizáciu
plugin.sipaccregwizz.DISPLAY_NAME=Zobraziť meno
@@ -479,6 +446,7 @@ plugin.sipaccregwizz.CLIST_TYPE=Typ
plugin.sipaccregwizz.XCAP_USER=Používateľ
plugin.sipaccregwizz.XCAP_PASSWORD=Heslo
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Vaše heslá sa nezhodujú.
+#used from SecurityPanel
# skin manager
plugin.skinmanager.SKINS=Vzhľady
@@ -486,10 +454,6 @@ plugin.skinmanager.DEFAULT_SKIN=Štandardný vzhľad
plugin.skinmanager.ADD_NEW_SKIN=Pridať nový vzhľad...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=Predvolený vzhľad aplikácie.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.OPTIONAL=Voliteľné
-
# status update
plugin.autoaway.ENABLE_CHANGE_STATUS=ZmeniÅ¥ status keÄ som preÄ
@@ -528,18 +492,6 @@ plugin.whiteboard.GRID=Mriežka
plugin.whiteboard.DELETE=Vymazať
plugin.whiteboard.PROPERTIES=Vlastnosti
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Protokol pre pripojenie k službe MSN.
-plugin.yahooaccregwizz.USERNAME=Užívateľské meno:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=ID a heslo
-
-# zero accregwizz
-plugin.zeroaccregwizz.FIRST_NAME=Krstné meno:
-plugin.zeroaccregwizz.LAST_NAME=Priezvisko:
-plugin.zeroaccregwizz.EMAIL=E-mail:
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=ID a heslo
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Google Talk protokol
@@ -550,16 +502,14 @@ plugin.googletalkaccregwizz.NEW_ACCOUNT_TITLE=Google Talk registrácia nového Ã
# iptel accregwizz
plugin.iptelaccregwizz.USERNAME=Užívatelské meno
-# sip2sip accregwizz
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Užívatelské meno
plugin.sip2sipaccregwizz.EMAIL=E-mailová adresa
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=VytvoriÅ¥ voľný SIP úÄet
-
-# ippi accregwizz
plugin.ippiaccregwizz.EXISTING_ACCOUNT=Existujúci SIP úÄet
plugin.ippiaccregwizz.CREATE_ACCOUNT=VytvoriÅ¥ voľný SIP úÄet
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Zavrieť okno chatu
plugin.keybindings.CHAT_COPY=Kopírovať
plugin.keybindings.CHAT_CUT=Vystrihnúť
@@ -576,6 +526,7 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=Meno
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=Primárna klávesová skratka
plugin.keybindings.globalchooser.SHORTCUT_SECOND=Sekundárna klávesová skratka
plugin.keybindings.globalchooser.PRESS_BTN=StlaÄte kláves pre nastavenie skratky
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Chat
plugin.keybindings.MAIN=Hlavný
@@ -594,6 +545,7 @@ plugin.notificationconfig.BROWSE_PROGRAM=Vybrať program
plugin.notificationconfig.tableheader.ENABLE=Povoliť alebo zakázať túto funkciu
plugin.notificationconfig.tableheader.EXECUTE=Spustiť program
plugin.notificationconfig.tableheader.DESCRIPTION=Opis udalosti
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Prichádzajúci hovor
plugin.notificationconfig.event.SecurityMessage=BezpeÄnostná správa
plugin.notificationconfig.event.IncomingFile=Prichádzajúci súbor
@@ -642,6 +594,7 @@ impl.media.configform.VIDEO_RESET=Obnoviť východzie nastavenia
impl.neomedia.configform.AUDIO=Zvuk
impl.neomedia.configform.VIDEO=Video
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.main=Hlavný
impl.neomedia.configform.H264.preferredKeyFrameRequester.rtcp=RTP
@@ -662,7 +615,6 @@ plugin.securityconfig.masterpassword.SAVED_PASSWORDS=Uložené heslá...
plugin.securityconfig.masterpassword.CURRENT_PASSWORD=SúÄastné heslo:
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Zadajte nové heslo:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Znovu zadajte nové heslo:
-plugin.securityconfig.masterpassword.MP_NOT_SET=(nenastavené)
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Zmena hesla bola neúspešná
plugin.securityconfig.masterpassword.MP_CHANGE_SUCCESS=Zmena hesla bola úspešná
plugin.securityconfig.masterpassword.MP_REMOVE_FAILURE=Odstránenie hesla bolo neúspešné
@@ -673,7 +625,6 @@ plugin.securityconfig.masterpassword.COL_PASSWORD=Heslo
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(neznámy)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(nie je možné dešifrovať)
plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=Uložené heslá
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=Odstrániť
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=Odstrániť všetky
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=Ste si istý, že chcete odstrániť všetky heslá?
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=Zmazať všetky heslá
@@ -721,7 +672,6 @@ plugin.globalproxy.PROXY_PORT=Port proxy
plugin.globalproxy.PROXY_USERNAME=Používateľské meno pre proxy
plugin.globalproxy.PROXY_PASSWORD=Heslo pre proxy
plugin.globalproxy.DESCRIPTION={0} bude používaÅ¥ nastavenia serveru proxy uvedenné vyÅ¡Å¡ie pre vÅ¡etky siete ku ktorým sa od teraz pripojíte. \nPodpora proxy je momentálne experimentálna a funguje iba s niektorými protokolmi. Pre detaily viÄ tabuľku dole:
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>JABBER</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
# plugin reconnect
@@ -768,8 +718,6 @@ net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult
#plugin spellcheck
plugin.spellcheck.TITLE=Pravopis a gramatika
plugin.spellcheck.MENU=Ukáž pravopis a gramatiku
-plugin.spellcheck.LANG=Jazyk
-plugin.spellcheck.EDIT_PERSONAL_DICT=Upraviť
plugin.spellcheck.ENABLE_SPELL_CHECK=Zapnúť kontrolu pravopisu
plugin.spellcheck.dialog.FIND=NájsÅ¥ ÄalÅ¡ie
plugin.spellcheck.dialog.REPLACE=Nahradiť
diff --git a/resources/languages/resources_sl.properties b/resources/languages/resources_sl.properties
index b19335e..5f9f079 100644
--- a/resources/languages/resources_sl.properties
+++ b/resources/languages/resources_sl.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -31,17 +42,254 @@ service.gui.ACCOUNT=RaÄun
service.gui.ACCOUNT_ME=Jaz
service.gui.ACCOUNT_REGISTRATION_WIZARD=ÄŒarovnik za ustvarjanje raÄunov
service.gui.ACCOUNTS=RaÄuni
-service.gui.ADD_ACCOUNT=Dodaj raÄun
+service.gui.ADD=&Dodaj
+service.gui.ADD_CONTACT=&Dodaj stik
service.gui.ADD_AUTHORIZED_CONTACT=Dodaj osebo {0} na seznam stikov
+service.gui.ADD_CONTACT_TO_CONTACTLIST=Dodaj stik na seznam stikov
service.gui.ADD_CONTACT_TO=&Dodaj stik v
+service.gui.ADD_CONTACT_ERROR=Stika {0} ni bilo mogoÄe dodati.
service.gui.ADD_CONTACT_ERROR_TITLE=Napaka stika
+service.gui.ADD_CONTACT_EXIST_ERROR=Stik {0} na seznamu stikov že obstaja.
+service.gui.ADD_CONTACT_NETWORK_ERROR=Strežnik se ne odziva na zahtevo dodajanja stika {0}.
+service.gui.ADD_CONTACT_NOT_SUPPORTED=Dodajanje stika {0} je spodletelo. Dejanje ni podprto.
+service.gui.ADD_CONTACT_NOT_CONNECTED=Za dodajanje stikov morate biti povezani. Prosimo, vpišite se z izbranim ponudnikom in poskusite znova.
+service.gui.ADD_GROUP_LOCAL_ERROR=Ni bilo mogoÄe dodati skupine: {0}. Problem se je pojavil med lokalno V/I operacijo.
+service.gui.ADD_GROUP_EXIST_ERROR=Skupina {0} na seznamu stikov že obstaja. Prosimo, izberite drugo ime.
+service.gui.ADD_GROUP_NET_ERROR=Ni bilo mogoÄe dodati skupine: {0}. Problem se je pojavil zaradi omrežne napake. Prosimo, preverite svojo omrežno povezavo in poskusite znova.
+service.gui.ADD_GROUP_ERROR=Ni bilo mogoÄe dodati skupine: {0}.
+service.gui.ADD_GROUP_EMPTY_NAME=Ime skupine ne more biti prazno.
+service.gui.ADDRESS=Naslov
service.gui.ADMINISTRATOR=Skrbnik
service.gui.ADVANCED=N&apredno
+service.gui.ALL_CONTACTS=&Vsi stiki
+service.gui.ALTERNATE_ADDRESS=Pomožni naslov
+service.gui.APPLY=&Uporabi
service.gui.ARE_CALLING={0} kliÄe...
-
-
-
-
+service.gui.ARE_NOW=Sedaj ste {0}
+service.gui.AT=pri
+service.gui.AUTHORIZE=&Pooblasti
+service.gui.AUTHORIZATION_ACCEPTED={0} je sprejel vašo prošnjo za pooblastitev.
+service.gui.AUTHENTICATION_FAILED=Overitev za {0} ni uspela. Geslo, ki ste ga vpisali, ni veljavno.
+service.gui.AUTHENTICATION_REQUESTED_SERVER=Strežnik {0} je zahteval vašo overitev.
+service.gui.AUTHENTICATION_REJECTED={0} je zavrnil vašo prošnjo za overitev.
+service.gui.AUTHENTICATION_WINDOW_TITLE={0} overitev
+service.gui.AUTHORIZATION_REQUESTED=Zahtevana overitev
+service.gui.AUTHORIZATION_REQUESTED_INFO=Stik {0} zahteva vašo overitev.
+service.gui.AUTHORIZATION_RESPONSE=Odgovor overitve
+service.gui.AWAY_STATUS=Odsoten
+service.gui.EXTENDED_AWAY_STATUS=Odsoten - daljše
+service.gui.BAN=IzobÄenje ni uspelo
+service.gui.BANNED=izobÄen
+service.gui.BAN_FAILED=IzobÄenje ni uspelo
+service.gui.BAN_FAILED_GENERAL_ERROR=IzobÄenje ni uspelo {0}. PriÅ¡lo je do sploÅ¡ne napake.
+service.gui.BAN_FAILED_NOT_ALLOWED=IzobÄenje ni uspelo {0}. Ni mogoÄe izobÄiti lastnika ali moderatorja klepetalnice.
+service.gui.BAN_FAILED_NOT_ENOUGH_PERMISSIONS=IzobÄenje ni uspelo {0}. Nimate te pravice.
+service.gui.BRB_MESSAGE=Trenutno me ni, a se bom vrnil kasneje.
+service.gui.BROWSE=Brskaj
+service.gui.BUSY_MESSAGE=Oprostite, trenutno sem zaposlen.
+service.gui.BUSY_STATUS=Zaposlen
+service.gui.CALL=PokliÄi
+service.gui.CALL_CONTACT=PokliÄi stik
+service.gui.CALL_FAILED=Klic ni uspel
+service.gui.CALL_HISTORY_TOOL_TIP=Klikni tukaj za prikaz zgodovine klicev
+service.gui.CALL_HISTORY_GROUP_NAME=Zgodovina klicev
+service.gui.CALL_VIA=PokliÄi skozi
+service.gui.CALL_NAME_OR_NUMBER=PokliÄi stik ali Å¡tevilko
+service.gui.CALL_NOT_SUPPORTING_PARTICIPANT=Ta klic podpira samo udeležence omrežja {0} in vaÅ¡ega raÄuna {1}. {2} ne vsebuje naslova za to omrežje ali raÄun.
+service.gui.CALL_WITH=PokliÄi z/s
+service.gui.CALL_NO_AUDIO_DEVICE=Nastavili niste nobene zvoÄne naprave.
+service.gui.CALL_NO_AUDIO_CODEC=Noben zvoÄni kodek ni omogoÄen.
+service.gui.CALL_NO_DEVICE_CODECS_Q=Želite nadaljevati s klicem?
+service.gui.CANCEL=&PrekliÄi
+service.gui.CHAT=Klepet
+service.gui.CHANGE_FONT=Spremeni pisavo
+service.gui.CHANGE_ROOM_SUBJECT=Spremeni zadevo klepetalnice ...
+service.gui.CHANGE_ROOM_SUBJECT_LABEL=V spodnje polje lahko vpišete novo zadevo klepetalnice
+service.gui.CHANGE_NICK=Spremeni vzdevek
+service.gui.CHANGE_NICKNAME=Spremeni vzdevek...
+service.gui.CHANGE_NICKNAME_LABEL=Spodaj lahko vnesete nov vzdevek.
+service.gui.CHANGE_NICKNAME_ERROR=Napaka pri spreminjanju vzdevka
+service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Vzdevek že obstaja
+service.gui.CHANGE_VIDEO_QUALITY=Spremeni kvaliteto oddaljenega videa
+service.gui.CHAT_CONFERENCE_ITEM_LABEL=konferenca od {0}
+service.gui.CHAT_ROOM_ALREADY_JOINED=Klepetalnica {0} je že pridružena.
+service.gui.CHAT_ROOM_CONFIGURATION=nastavitve za klepetalnico {0}
+service.gui.CHAT_ROOM_CONFIGURATION_FAILED=Ni bilo mogoÄe pridobiti obrazca za nastavitve klepetalnice {0}.
+service.gui.CHAT_ROOM_CONFIGURATION_FORBIDDEN=Ni bilo mogoÄe pridobiti obrazca za nastavitve klepetalnice {0}. Samo lastniki klepetalnic lahko vidijo in spreminjajo nastavitveni obrazec.
+service.gui.CHAT_ROOM_CONFIGURATION_SUBMIT_FAILED=Prišlo je do napake pri pošiljanju nastavitvenega obrazca za klepetalnico {0}.
+service.gui.CHAT_ROOM_CONFIGURATION_MEMBERS_EDIT_TITLE=Uredi spisek Älanov
+service.gui.CHAT_ROOM_CONFIGURATION_MEMBERS_EDIT_DESCRIPTION=ÄŒlani so uporabniki izpisani v spisku na desni. Ko je klepetalnica "Samo za Älane" se samo ti uporabniki lahko pridružijo.
+service.gui.CHAT_ROOM_USER_JOINED=se je pridružil {0}
+service.gui.CHAT_ROOM_USER_LEFT=je odšel {0}
+service.gui.CHAT_ROOM_USER_KICKED=ga je izobÄil {0}
+service.gui.CHAT_ROOM_USER_QUIT=je konÄal {0}
+service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=PoÅ¡iljanje sporoÄila je prepovedano (preklican glas)
+service.gui.CHAT_ROOM_NAME=Ime klepetalnice
+service.gui.CLEAR_CUSTOM_MESSAGES=PoÄisti sporoÄila po meti
+service.gui.ROOM_NAME=Klepetelnica
+service.gui.CHANGE_PASSWORD=Spremeni geslo
+service.gui.CHAT_ROOM_NAME_INFO=V spodnje polje vpišite ime klepetalnice, ki jo želite ustvariti.
+service.gui.CHAT_ROOM_NOT_EXIST=Klepetalnice {0} ni najti na strežniku {1}. Preverite, prosim, da ste ime napisali pravilno.
+service.gui.CHAT_ROOM_NOT_CONNECTED=Če se želite pridružiti klepetalnici {0} morate biti prijavljeni.
+service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Da zapustite klepetalnico morate biti prijavljeni.
+service.gui.CHAT_ROOM_OPTIONS=Možnosti kelpetalnice
+service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Klepetalnica {0} zahteva registracijo za pridružitev.
+service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Klepetalnica {0} zahteva geslo.
+service.gui.CHAT_ROOMS=Klepetalnice
+service.gui.CHAT_ROOM=Klepetelnica
+service.gui.CHAT_ROOM_SUBJECT_CHANGED={0} je spremenil zadevo v {1}
+service.gui.CHAT_ROOM_ALTERNATE_ADDRESS=Pogovor lahko nadaljujete v klepetalnici: {0}
+service.gui.CHAT_NICKNAME_CHANGE={0} je zdaj znan kot {1}
+service.gui.CHOOSE_CONTACT=Izberite stik
+service.gui.CHOOSE_NUMBER=Izberite Å¡tevilko
+service.gui.CHOOSE_ACCOUNT=Izberite prosim enega izmed raÄunov na seznamu
+service.gui.CITY=Mesto
+service.gui.COUNTRY=Država
+service.gui.SHOW_MORE_TOOLTIP=Kliknite za veÄ rezultatov
+service.gui.CLEAR=PoÄisti
+service.gui.CLOSE=&Zapri
+service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Pred manj kot 2 sekundama ste prejeli novo sporoÄilo. Ali res želite zapreti ta pogovor?
+service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=Nekateri prenosi datotek so še aktivni. Ali jih res želite prekiniti?
+service.gui.CONNECTED_STATUS=Povezan
+service.gui.CONNECTING=Povezovanje ...
+service.gui.CONNECTING_STATUS=Povezovanje
+service.gui.CONNECTING_EARLY_MEDIA_STATUS=Povezovanje*
+service.gui.CONNECTION=Povezava
+service.gui.CONTACT_NAME=ID ali Å tevilka
+service.gui.CONTACTS=Stiki
+service.gui.COPY=&Kopiraj
+service.gui.COPY_LINK=Kopiraj &povezavo
+service.gui.CREATE=&Ustvari
+servoce.gui.CREATE_CALL_FAILED=Klic ni uspel.
+service.gui.CREATE_CHAT_ROOM=Ustvari &klepetalnico ...
+service.gui.CREATE_CHAT_ROOM_ERROR=Ustvarjanje klepetalnice {0} ni uspelo.
+service.gui.CREATE_CHAT_ROOM_WIZARD=ÄŒarovnik za ustvarjanje klepetalnice
+service.gui.CREATE_CONFERENCE_CALL=&Ustvari konferenÄni klic ...
+service.gui.CREATE_GROUP=&Ustvari skupino ...
+service.gui.CREATE_VIDEO_BRIDGE=Ustvari most &video ...
+service.gui.CREATE_VIDEO_BRIDGE_MENU=Ustvari most &video
+service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Ustvari / Pridruži se videokonferenci
+service.gui.CREATE_VIDEO_CONFERENCE=Ustvari novo videokonferenco za to klepetalnico
+service.gui.CUT=&Izreži
+service.gui.DELETE=Izbriši
+service.gui.DENY=&Zavrni
+service.gui.DESKTOP_SHARING_WARNING=<b>Ali res želite dati svoje namizje v skupno uporabo?</b> <br> Če kliknete na DA bodo sogovorniki videli vaš zaslon.
+service.gui.DESKTOP_SHARING_DIALOG_INDICATE=Zaslon ste dali v skupno rabo
+service.gui.DIALPAD=Å tevilÄnica
+service.gui.DISPLAY_NAME=Ime za prikaz
+service.gui.DISCONNECTED_STATUS=Ni povezave
+service.gui.DND_STATUS=Ne moti
+service.gui.DO_NOT_ASK_AGAIN=Ne sprašuj spet
+service.gui.DO_NOT_SHOW_AGAIN=Tega sporoÄila ne prikaži veÄ
+service.gui.DRAG_FOR_SHARING=Sem povlecite kar želite dati v skupno rabo ...
+service.gui.DURATION=trajanje
+service.gui.DESTROY_CHATROOM=Zbriši klepetalnico
+service.gui.END_CONFERENCE=ZakljuÄi konferenco
+service.gui.ENTER_PHONE_NUMBER=Vpišite telefonsko številko
+service.gui.ENTER_NAME_OR_NUMBER=Vpišite ime ali številko
+service.gui.ERROR=Napaka
+service.gui.ERROR_RECEIVED_FROM=Napaka od {0}
+service.gui.ESTIMATED_TIME=Predvideni Äas:
+service.gui.EVENTS=Dogodki
+service.gui.EXIT=&Izhod
+service.gui.GENERAL=Splošno
+service.gui.GENERAL_ERROR=Splošna napaka
+service.gui.GROUP_NAME=Ime skupine
+service.gui.FAILED_STATUS=Klic ni uspel
+service.gui.FAILED_TO_JOIN_CHAT_ROOM=Ni se mogoÄe pridružiti klepetalnici: {0}.
+service.gui.FAX=Faks
+service.gui.FFC_STATUS=Na razpolago za klepet
+service.gui.FILE=&Datoteka
+service.gui.FILE_TOO_BIG=Velikost datoteke je veÄja od najveÄje dovoljene velikosti za protokol: {0}.
+service.gui.FILE_SEND_REFUSED={0} je zavrnil to datoteko.
+service.gui.FILE_TRANSFER_REFUSED=Zavrnjen prenos datoteke.
+service.gui.FILE_TRANSFER_NOT_SUPPORTED=Izbrani stik ne podpira prenosa datoteke.
+service.gui.FILE_TRANSFER_PREPARING=Priprava prenosa datoteke za uporabnika {0}. Prosim poÄakajte ...
+service.gui.FILE_TRANSFER_REQUEST_RECIEVED={0} deli datoteko z vami.
+service.gui.FILE_DOES_NOT_EXIST=Izbrane datoteke ni mogoÄe najti. Lahko je bila premaknjena ali izbrisana.
+service.gui.FILE_OPEN_FAILED=Datoteke ni mogoÄe odpreti. Lahko je bila premaknjena ali izbrisana.
+service.gui.FONT=Pisava
+service.gui.FONT_BOLD=Krepko
+service.gui.FONT_COLOR=Barva
+service.gui.FONT_ITALIC=LežeÄe
+service.gui.FONT_SIZE=Velikost
+service.gui.FONT_STYLE=Slog
+service.gui.FONT_UNDERLINE=PodÄrtano
+service.gui.HANG_UP=Odloži
+service.gui.HD_QUALITY=HD video
+service.gui.HELP=&PomoÄ
+service.gui.HIDE=Skrij
+service.gui.ICE=ICE
+service.gui.IDENTIFIER=DoloÄilnik
+service.gui.IS_CALLING={0} kliÄe ...
+service.gui.LAST_NAME=Priimek
+service.gui.LIST=Spisek
+service.gui.MEMBER=Älan
+service.gui.MESSAGE=SporoÄilo
+service.gui.MORE_LABEL=VeÄ
+service.gui.MOVE=Premakni
+service.gui.MOVE_SUBCONTACT=&Premakni stik
+service.gui.MOVE_CONTACT=Premakni stik
+service.gui.NAME=Ime
+service.gui.NEW_MESSAGE=Novo sporoÄilo
+service.gui.NEW_NAME=Novo ime
+service.gui.NEW_STATUS_MESSAGE=Nov status
+service.gui.NEW_STATUS_MESSAGE_SAVE=Shrani kot prilagojeno sporoÄilo
+service.gui.NICKNAME=Vzdevek
+service.gui.NO_CAMERA_AVAILABLE=Nobene kamere na razpolago
+service.gui.NO_DESKTOP_SHARING_FOR_PROTOCOL=V tem protokolu ni podpore za souporabo namizja
+service.gui.NO_VIDEO_FOR_PROTOCOL=V tem protokolu ni podpore za video
+service.gui.OR=ali
+service.gui.chat.role.OWNER=Lastnik
+service.gui.chat.role.ADMINISTRATOR=Skrbnik
+service.gui.chat.role.MODERATOR=Moderator
+service.gui.chat.role.MEMBER=ÄŒlan
+service.gui.chat.role.GUEST=Gost
+service.gui.chat.role.SILENT_MEMBER=Tihi Älan
+service.gui.chat.role.OUTCAST=IzobÄen
+service.gui.OWNER=lastnik klepetalnice
+service.gui.PASSWORD=Geslo
+service.gui.PASSWORD_CHANGE_FAILURE=Napak pri spremembi gesla
+service.gui.PASSWORD_CHANGE_SUCCESS=Geslo uspešno spremenjeno
+service.gui.PERSONAL=Osebno
+service.gui.PORT=Vrata
+service.gui.POSTAL_CODE=Poštna številka
+service.gui.PREFERENCES=Možnosti
+service.gui.PREFIX=Predpona
+service.gui.PRESENCE=Prisotnost
+service.gui.PREVIOUS=Prejšnji
+service.gui.PROACTIVE_NOTIFICATION=piÅ¡e sporoÄilo
+service.gui.PROTOCOL=Protokol
+service.gui.REASON=Razlog
+service.gui.REMEMBER_PASSWORD=Zapomni si geslo
+service.gui.RETRY=Ponovno poskusi
+service.gui.SAVE=&Shrani
+service.gui.SEARCH=&IÅ¡Äi
+service.gui.SELECT_COLOR=Izberi barvo
+service.gui.SELECT_GROUP=Izberi skupino
+service.gui.SELECT_NO_GROUP=Brez skupine
+service.gui.SEND_PRIVATE_MESSAGE=PoÅ¡lji zasebno sporoÄilo
+service.gui.SEND_SMS=P&ošlji SMS
+service.gui.SMS=SMS
+service.gui.SMS_SUCCESSFULLY_SENT=SporoÄilo SMS je bilo uspeÅ¡no poslano!
+service.gui.SOUND_OFF=Izklopi zvok
+service.gui.SOUND_ON=Vklopi zvok
+service.gui.STATUS=Stanje
+service.gui.STATUS_CHANGED_CHAT_MESSAGE=je postal {0}
+service.gui.STREET=Ulica
+service.gui.SUBJECT=Zadeva
+service.gui.SUMMARY=Povzetek
+service.gui.TELEPHONY=Telefonija
+service.gui.TOOLS=&Orodje
+
+
+
+
+#enum values from IceProcessingState
+
+
+
+#service.gui.CERT_INFO_ are combined from Rdn names
# keep the following string short
@@ -50,9 +298,6 @@ service.gui.ARE_CALLING={0} kliÄe...
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
# systray
@@ -61,6 +306,10 @@ service.gui.ARE_CALLING={0} kliÄe...
# LDAP
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
# Google Contacts
@@ -74,10 +323,8 @@ service.gui.ARE_CALLING={0} kliÄe...
# aimaccregwizz
# branding
+plugin.branding.ABOUT_MENU_ENTRY=O programu
-# Dict protocol
-
-# facebookaccregwizz
# generalconfig
@@ -89,20 +336,15 @@ service.gui.ARE_CALLING={0} kliÄe...
# jabber accregwizz
-# mailbox
-
-# msn accregwizz
-
# plugin manager
# simple accregwizz
# sipaccregwizz
+#used from SecurityPanel
# skin manager
-# ssh accregwizz
-
# status update
# updatechecker
@@ -111,21 +353,18 @@ service.gui.ARE_CALLING={0} kliÄe...
# whiteboard
-# yahoo accregwizz
-
-# zero accregwizz
-
# gtalk accregwizz
# iptel accregwizz
-# sip2sip accregwizz
-
# ippi accregwizz
# key binding chooser
+#in new ChatWindow() -> manipulated
+#Enum KeybindingSet.Category
# Notification Configuration Form
+#NotificationsTable constants
# ZRTP Securing
@@ -137,36 +376,233 @@ service.gui.ARE_CALLING={0} kliÄe...
+#in JNIEncoder
# The callrecordingconfig plugin was never really committed into trunk and its
# ConfigurationForm was actually put in the neomedia bundle.
# Security configuration form title
+plugin.securityconfig.masterpassword.COL_PASSWORD=Geslo
+plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(neznano)
+plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(ni mogoÄe odÅ¡ifrirati)
+plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=Shrani gesla
+plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=Odstrani vse
+plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=Ali res želite odstraniti vsa gesla?
+plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=Odstrani vsa gesla
+plugin.securityconfig.masterpassword.SHOW_PASSWORDS_BUTTON=Pokaži gesla
+plugin.securityconfig.masterpassword.HIDE_PASSWORDS_BUTTON=Skrij gesla
+plugin.securityconfig.masterpassword.PASSWORD_QUALITY_METER=Merilec kakovosti gesla
+plugin.securityconfig.masterpassword.MP_INPUT=Vpišite svoje glavno geslo:\n\n
# otr plugin
+plugin.otr.menu.TITLE=Varni klepet
+plugin.otr.menu.START_OTR=ZaÄni zasebni pogovor
+plugin.otr.menu.END_OTR=Prekini zasebni pogovor
+plugin.otr.menu.FINISHED=Vaš sogovornik je prekinil zasebni pogovor. Vi bi morali storiti isto
+plugin.otr.menu.VERIFIED=Vaš zasebni pogovor je preverjen
+plugin.otr.menu.UNVERIFIED=Vaš zasebni pogovor ni preverjen. Prosim overite svojega sogovornika
+plugin.otr.menu.LOADING_OTR=ZaÄenjam zasebni pogovor ...
+plugin.otr.menu.TIMED_OUT=ÄŒas za zaÄetek zasebnega pogovora je pretekel.
+plugin.otr.menu.REFRESH_OTR=Osveži zasebni pogovor
+plugin.otr.menu.AUTHENTICATE_BUDDY=Overi sogovornika
+plugin.otr.menu.WHATS_THIS=Kaj je to
+plugin.otr.menu.CB_AUTO=Samodejno zaÄni zasebni pogovor z {0}
+plugin.otr.menu.CB_AUTO_ALL=Samodejno zaÄni zasebni pogovor z vsemi
+plugin.otr.menu.CB_ENABLE=OmogoÄi zasebna sporoÄila
+plugin.otr.menu.CB_REQUIRE=Zahtevaj zasebna sporoÄila
+plugin.otr.menu.CB_RESET=Ponasatvi
+plugin.otr.menu.OTR_TOOLTIP=Å ifriraj pogovore z OTR
+plugin.otr.authbuddydialog.HELP_URI=https://jitsi.org/GSOC2009/OTR
+plugin.otr.authbuddydialog.AUTHENTICATION_INFO=Overjanje sogovornika pomaga pri zagotavljanju, da je oseba res ta kdor trdi, da je.
+plugin.otr.authbuddydialog.AUTHENTICATION_METHOD=Kako se želite overiti?
+plugin.otr.authbuddydialog.AUTHENTICATION_METHOD_QUESTION=Overjanje z vprašanjem
+plugin.otr.authbuddydialog.AUTHENTICATION_METHOD_SECRET=Overjanje s skupnim geslom
+plugin.otr.authbuddydialog.AUTHENTICATION_METHOD_FINGERPRINT=Overjanje s prstnim odtisom
+plugin.otr.authbuddydialog.AUTHENTICATION_FINGERPRINT=Za preverjanje prstnega odtisa navežite stik s sogovornikom preko drugega overjenega kanal, kot je telefon ali e-poÅ¡ta s podpisom GPG. Vsak mora sporoÄiti svoj prstni odtis drugemu. V primeru, da se vse sklada, oznaÄite , da *ste* preverili prstni odtis v naslednjem pogovornem oknu.
+plugin.otr.authbuddydialog.LOCAL_FINGERPRINT=Prstni odtis za vas {0}: {1}
+plugin.otr.authbuddydialog.REMOTE_FINGERPRINT=Domnevni prstni odtis za {0}: {1}
+plugin.otr.authbuddydialog.AUTH_BY_QUESTION_INFO_INIT=Za overjanje z vpraÅ¡anjem morate izbrati vpraÅ¡anje katerega odgovor je znan samo vam in sogovorniku. Sogovorniku bo postavljeno vpraÅ¡anje in Äe se odgovora ne skladata je možno, da se pogovarjate z goljufom.
+plugin.otr.authbuddydialog.AUTH_BY_SECRET_INFO_INIT=Za overjanje s skupnim geslom morate izbrati nekaj, kar je znano samo vam in sogovorniku. Sogovornik bo moral tudi izbrati geslo, ki je znano vam in Äe se skrivnosti ne skladata je možno, da se pogovarjate z goljufom.
+plugin.otr.authbuddydialog.AUTH_BY_SECRET_INFO_RESPOND=Vaš sogovornik želi preveriti, ali se res pogovarja z vami ali z goljufom. Sogovornik vam je postavil vprašanje. V primeru, da se želite overiti vpišite odgovor v spodnje polje.
+plugin.otr.authbuddydialog.SHARED_SECRET=Vpišite svoje skupno geslo:
+plugin.otr.authbuddydialog.QUESTION_RESPOND=Vaš sogovornik vas sprašuje:
+plugin.otr.authbuddydialog.QUESTION_INIT=Vpišite svoje vprašanje:
+plugin.otr.authbuddydialog.ANSWER=VpiÅ¡ite svoj odgovor (razlikovanje velikosti Ärk):
+plugin.otr.authbuddydialog.AUTHENTICATION_FROM=Overjeno z {0}.
+plugin.otr.authbuddydialog.CANCEL=PrekliÄi
+plugin.otr.authbuddydialog.HELP=PomoÄ
+plugin.otr.authbuddydialog.TITLE=Overi sogovornika
+plugin.otr.authbuddydialog.AUTHENTICATE_BUDDY=Overi sogovornika
+plugin.otr.authbuddydialog.I_HAVE=Sem
+plugin.otr.authbuddydialog.I_HAVE_NOT=Nisem
+plugin.otr.authbuddydialog.VERIFY_ACTION=preveril, da je to res pravi prstni odtis za {0}.
+plugin.otr.authbuddydialog.FINGERPRINT_CHECK=Vpišite prstni odtis, ki ste ga dobili od {0}.
+plugin.otr.smpprogressdialog.TITLE=Napredovanje overitve
+plugin.otr.smpprogressdialog.AUTHENTICATION_SUCCESS=Overitev je uspela!
+plugin.otr.smpprogressdialog.AUTHENTICATION_FAIL=Overitev ni uspela!
+plugin.otr.configform.MY_PRIVATE_KEYS=Moji zasebni kljuÄi
+plugin.otr.configform.KNOWN_FINGERPRINTS=Znani prstni odtisi
+plugin.otr.configform.CB_AUTO=Samodejno zaÄni zasebno sporoÄanje
+plugin.otr.configform.CB_ENABLE=OmogoÄi zasebno sporoÄanje
+plugin.otr.configform.CB_REQUIRE=Zahtevaj zasebno sporoÄanje
+plugin.otr.configform.NO_KEY_PRESENT=Nobenega kljuÄa ni
+plugin.otr.configform.GENERATE=Ustvari
+plugin.otr.configform.REGENERATE=Ponovo ustvari
+plugin.otr.configform.FINGERPRINT=Prstni odtis
+plugin.otr.configform.VERIFY_FINGERPRINT=Preveri prstni odtis
+plugin.otr.configform.FORGET_FINGERPRINT=Pozabi prstni odtis
+plugin.otr.configform.COLUMN_NAME_CONTACT=Naveži stik
+plugin.otr.configform.COLUMN_NAME_VERIFIED_STATUS=Preverjenoi
+plugin.otr.configform.COLUMN_VALUE_VERIFIED_TRUE=Da
+plugin.otr.configform.COLUMN_VALUE_VERIFIED_FALSE=Ne
+plugin.otr.activator.unverifiedsessionwarning={0} navezuje stik z vami iz neznanega raÄunalnika. Primerno bi bilo, da <A href="jitsi://{1}/{2}?{3}">overite {0}</a>.
+plugin.otr.activator.unverifiedsessionstared=ZaÄel se je <b>nepreverjen</b> zasebni pogovor z uporabnikom {0}.
+plugin.otr.activator.sessionstared=ZaÄel se je zasebni pogovor z uporabnikom {0}.
+plugin.otr.activator.sessionfinished={0} je prekinil zasebni pogovor z vami; vi bi morali storiti isto.
+plugin.otr.activator.sessionlost=Zasebni pogovor z {0} se je prekinil.
+plugin.otr.activator.historyon={0} snema vajin pogovor na vaÅ¡i napravi. Tukaj lahko <A href="jitsi://{1}/{2}">izkljuÄite zgodovino klepeta</a>.
+plugin.otr.activator.historyoff={0} NE snema vajinega pogovora. Tukaj lahko <A href="jitsi://{1}/{2}">vkljuÄite zgodovino klepeta</a>.
+plugin.otr.activator.sessionfinishederror=VaÅ¡e sporoÄilo [{0}] ni bilo poslano. Prosim prekinite vaÅ¡ zasebni pogovor z {1}.
+plugin.otr.activator.smpaborted={0} je preklical postopek overitve.
+plugin.otr.activator.smperror=Pri postopku overtive je prišlo do napake.
+plugin.otr.activator.unencryptedmsgreceived=To sporoÄilo je bilo sprejeto neÅ¡ifrirano,
+plugin.otr.activator.unreadablemsgreceived={0} vam je poslal Å¡ifrirano sporoÄilo, ki ga ni bilo mogoÄe prebrati.
+plugin.otr.activator.requireencryption=VaÅ¡e sporoÄilo [{0}] ni bilo poslano. Zahtevano je zasebno sporoÄanje.
+plugin.otr.activator.unreadablemsgreply=Poslali ste {0} neberljivo Å¡ifrirano sporoÄilo. Prosim prekinite zasebni pogovor z uporabnikom {1}, da osvežite pogovor.
+plugin.otr.activator.fallbackmessage=<span style="font-weight: bold;">{0} skuÅ¡a zaÄeti Å¡ifriran <a href="http://en.wikipedia.org/wiki/Off-the-Record_Messaging">pogovor Off-The-Record</a> z vami. A vaÅ¡a programska oprema ne podpira sporoÄanja Off-The-Record. Za veÄ informacij preberite <a href="http://en.wikipedia.org/wiki/Off-the-Record_Messaging">http://en.wikipedia.org/wiki/Off-the-Record_Messaging</a></span>
+plugin.otr.activator.multipleinstancesdetected=VaÅ¡ sogovornik {0} je prijavljen veÄkrat in OTR je vzpostavil veÄ sej. Iz spodnjega menija lahko izberete izhodno sejo.
+plugin.otr.activator.msgfromanotherinstance={0} vam je poslal sporoÄilo miÅ¡ljeno za drugo sejo. V primeru, da ste prijavljeni veÄkrat, bi lahko to sporÄilo priÅ¡lo v drugo sejo.
# global proxy plugin
+plugin.globalproxy.GLOBAL_PROXY_CONFIG=Splošni posredniški strežnik
+plugin.globalproxy.PROXY_TYPE=Vrsta posredniškega strežnika
+plugin.globalproxy.PROXY_ADDRESS=Posredniški strežnik
+plugin.globalproxy.PROXY_PORT=Vrata posredniškega strežnika
+plugin.globalproxy.PROXY_USERNAME=Uporabniško ime posredniškega strežnika
+plugin.globalproxy.PROXY_PASSWORD=Geslo posredniškega strežnika
#plugin.globalproxy.PROTOCOL_SUPPORT
+plugin.globalproxy.FWD_DNS=Uporabi posrednika za DNS
+plugin.globalproxy.FWD_DNS_ADDR=Naslov posrednika za DNS
+plugin.globalproxy.FWD_DNS_PORT=Vrata posredniška za DNS
# plugin reconnect
+plugin.reconnectplugin.NETWORK_DOWN=Prekinjena omrežna povezava!
#plugin chat config
+plugin.chatconfig.TITLE=Klepet
+plugin.chatconfig.replacement.TITLE=Slika/Video:
+plugin.chatconfig.replacement.ENABLE_SMILEY_STATUS=OmogoÄi zamejavo smeÅ¡kov
+plugin.chatconfig.replacement.REPLACEMENT_TITLE=Zamenjava slike/videa
+plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS=OmogoÄi
+plugin.chatconfig.replacement.ENABLE_REPLACEMENT_PROPOSAL=OnemogoÄi (pokaži povezavo za predogled)
+plugin.chatconfig.replacement.DISABLE_REPLACEMENT=OnemogoÄi
+plugin.chatconfig.replacement.CONFIGURE_REPLACEMENT=Spremeni nastavitve za zamenjavo slike/videa
+plugin.chatconfig.replacement.REPLACEMENT_SOURCES=Viri:
+plugin.chatconfig.spellcheck.TITLE=ÄŒrkovanje
#provisioning plugin
+plugin.provisioning.PROVISIONING=Oskrbovanje
+plugin.provisioning.ENABLE_DISABLE=OmogoÄi oskrbovanje
+plugin.provisioning.AUTO=Samodejno odkrij URI za oskrbovanje
+plugin.provisioning.DHCP=DHCP
+plugin.provisioning.DNS=DNS
+plugin.provisioning.BONJOUR=Bonjour
+plugin.provisioning.MANUAL=RoÄno vnesi URI za oskrbovanje
+plugin.provisioning.URI=URI
+plugin.provisioning.RESTART_WARNING=UpoÅ¡tevajte, da bodo vaÅ¡e spremembe zaÄele veljati Å¡ele pri naslednjem zagonu {0}!
+plugin.provisioning.UUID=UUID
+plugin.provisioning.COPYTOCLIPBOARD=Kopiraj UUID v odložiÅ¡Äe
+plugin.provisioning.CLIPBOARD_FAILED=Ni bilo mogoÄe kopirati UUID v odložiÅ¡Äe
+plugin.provisioning.CREDENTIALS=Zadnji shranjeni podatki oskrbovanja
+plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=Ali res želite odstraniti geslo za oskrbovanje?
+plugin.provisioning.PROV_FAILED=Oskrbovanje ni uspelo
+plugin.provisioning.PROV_FAILED_MSG=<html>Oskrbovanje ni uspelo. {0}! <br>Prosim poskusite kasneje ali pokliÄite svojega administratorja</html>
+plugin.provisioning.FORGET_PASSWORD=Pozabi geslo
# packet logging service
+plugin.loggingutils.PACKET_LOGGING_CONFIG=Dnevniški zapis
+plugin.loggingutils.ENABLE_DISABLE=OmogoÄi dnevniÅ¡ko zapisovnaje paketov
+plugin.loggingutils.PACKET_LOGGING_RTP=RTP
+plugin.loggingutils.PACKET_LOGGING_RTP_DESCRIPTION=(shrani 1 paket na 5000)
+plugin.loggingutils.PACKET_LOGGING_ICE4J=ice4j.org
+plugin.loggingutils.PACKET_LOGGING_DESCRIPTION=<html>Zapisuje razhroÅ¡Äevalne pakete raznih protokolov v <br>mapo dnevniÅ¡kega zapisa formatu pcap (tcpdump/wireshark).</html>
+plugin.loggingutils.PACKET_LOGGING_FILE_COUNT=Število dnevniških datotek
+plugin.loggingutils.PACKET_LOGGING_FILE_SIZE=NajveÄja velikost datoteke (v KB)
+plugin.loggingutils.ARCHIVE_BUTTON=Arhiviraj dnevniški zapis
+plugin.loggingutils.UPLOAD_LOGS_BUTTON=Pošlji dnevniški zapis
+plugin.loggingutils.UPLOAD_BUTTON=Pošlji
+plugin.loggingutils.ARCHIVE_FILECHOOSE_TITLE=Izberite datoteko
+plugin.loggingutils.ARCHIVE_UPREPORT_EMAIL=marijanovak@example.com
+plugin.loggingutils.ARCHIVE_MESSAGE_OK=Arhviranje dnevniških zapisov je uspelo \n{0}
+plugin.loggingutils.ARCHIVE_MESSAGE_NOTOK=Napaka pri arhviranju dnevniških zapisov \n{0}
# dns config plugin
+plugin.dnsconfig.TITLE=DNS
+plugin.dnsconfig.DNSSEC=Varni DNS (DNSSEC)
+plugin.dnsconfig.PARALLEL_DNS=Vzporedni DNS
+plugin.dnsconfig.border.TITLE=Rezervni razreševalnik
+plugin.dnsconfig.chkBackupDnsEnabled.text=OmogoÄi paralelno razreÅ¡evanje DNS
+plugin.dnsconfig.lblBackupResolver.text=Ime gostitelja
+plugin.dnsconfig.lblBackupResolverFallbackIP.text=Nadomestni IP
+plugin.dnsconfig.lblBackupPort.text=Vrata
+plugin.dnsconfig.lblRedemption.text=Nazaj k glavnemu razreševalniku
+plugin.dnsconfig.lblRedemption.description=<html>Å¡tevilo odzivov, ki jih mora nuditi glavni razreÅ¡evelnaik, da ponovo izkljuÄimo rezervnega</html>
+plugin.dnsconfig.lblPatience.text=Zaženi rezervni razreševalnik po
+plugin.dnsconfig.lblPatience.description=<html>Å¡tevilo ms, ko Äakamo na odziv glavnega DNS preden preidemo na rezervni razreÅ¡evalnik</html>
+plugin.dnsconfig.dnssec.chkEnabled=OmogoÄi razreÅ¡evalnik DNSSEC
+plugin.dnsconfig.dnssec.lblDefault=Privzeto obnašanje
+plugin.dnsconfig.dnssec.DOMAIN_NAME=Domena
+plugin.dnsconfig.dnssec.MODE=Obnašanje
+net.java.sip.communicator.util.dns.SecureResolveMode.IgnoreDnssec=Prezri
+net.java.sip.communicator.util.dns.SecureResolveMode.SecureOnly=Zahtevano
+util.dns.DNSSEC_ADVANCED_OPTIONS=Pokaži napredne možnosti
+net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.Accept=Sprejmi v vsakem priemeru
+net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.AlwaysAccept=Vedno sprejmi
+net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.Deny=Ne sprejmi
+net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.AlwaysDeny=Nikoli ne sprejmi
#plugin spellcheck
+plugin.spellcheck.TITLE=ÄŒrkovanje in slovnica
+plugin.spellcheck.MENU=Pokaži Ärkovanje in slovnico
+plugin.spellcheck.ENABLE_SPELL_CHECK=OmogoÄi Ärkovanje
+plugin.spellcheck.dialog.FIND=Najdi naslednje
+plugin.spellcheck.dialog.REPLACE=Zamenjaj
+plugin.spellcheck.dialog.ADD=Dodaj besedo
+plugin.spellcheck.DICT_ERROR_TITLE=Napaka pri spremembi slovarja
+plugin.spellcheck.DICT_ERROR=Ni mogoÄe spremeniti slovarja
+plugin.spellcheck.DICT_PROCESS_ERROR=Jezikovna oznaka ni poznana
+plugin.spellcheck.UNINSTALL_DICTIONARY=Odstrani
+plugin.spellcheck.DICT_ERROR_DELETE_TITLE=Napaka pri odstranjevanju slovarja
+plugin.spellcheck.DICT_ERROR_DELETE=Slovarja ni mogoÄe odstraniti
+plugin.spellcheck.SPELLCHECK=ÄŒrkovanje
#Certificate configuration plugin
+plugin.certconfig.JAVA_TRUSTSTORE=Java
+plugin.certconfig.WINDOWS_TRUSTSTORE=Windows
+plugin.certconfig.ALIAS=Vzdevek v shrambi kljuÄev
+plugin.certconfig.KEYSTORE_TYPE=Vrsta
+plugin.certconfig.KEYSTORE=Datoteka
+plugin.certconfig.KEYSTORE_PASSWORD=Geslo
+plugin.certconfig.ALIAS_LOAD_EXCEPTION=Zvdevka ni bilo mogoÄe pridobiti iz shrambe kljuÄev ({0}).
+plugin.certconfig.INVALID_KEYSTORE_TYPE=Izbrana vrsta shrambe kljuÄev ni veljavna ({0}).
+plugin.certconfig.BROWSE_KEYSTORE=Odpri shrambo kljuÄev
+plugin.certconfig.REVOCATION_TITLE=Možnosti preklica potrdil
+plugin.certconfig.REVOCATION_CHECK_ENABLED=Preverjanje CRL (Seznam preklicanih potrdil) omogoÄeno
+plugin.certconfig.REVOCATION_OCSP_ENABLED=Preverjanje OCSP (Spletni protokol stanja potrdil) omogoÄeno
# Phone number contact source plugin
+plugin.phonenumbercontactsource.DISPLAY_NAME=Telefonske Å¡tevilke
# properties editor
+plugin.propertieseditor.TITLE=Urejevalnik lastnosti
+plugin.propertieseditor.NEW_PROPERTY_TITLE=Dodaj lastnost
+plugin.propertieseditor.CHECK_BOX=PrihodnjiÄ Å¡e pokaži to opozorilo
+plugin.propertieseditor.IM_AWARE=Razumem tveganje
#Thunderbird address book plugin
+plugin.thunderbird.CONFIG_FORM_TITLE=Thunderbird
+plugin.thunderbird.ENABLED=OmogoÄen
+plugin.thunderbird.PHONE_PREFIX=Predklicna:
diff --git a/resources/languages/resources_sq.properties b/resources/languages/resources_sq.properties
index 51ca64d..b1bdff8 100644
--- a/resources/languages/resources_sq.properties
+++ b/resources/languages/resources_sq.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,30 +43,23 @@ service.gui.ACCOUNT_ME=Unë
service.gui.ACCOUNT_REGISTRATION_WIZARD=Rexhistrimi i llogarisë
service.gui.ACCOUNTS=Llogaritë
service.gui.ADD=&Shto
-service.gui.ADD_ACCOUNT=Shto llogari
service.gui.ADD_CONTACT=&Shto kontakt
service.gui.ADD_CONTACT_TO=&Shto kontakt
service.gui.ADD_CONTACT_ERROR=Dështoj në shtimin e kontaktit me id: {0}
service.gui.ADD_CONTACT_ERROR_TITLE=Gabim gjatë shtimit të kontaktit
service.gui.ADD_CONTACT_EXIST_ERROR=Kontakti {0} ekziston në listën tuaj të kontakteve
-service.gui.ADD_CONTACT_IDENTIFIER=Futni në fushën e mëposhtme informacionet e kontaktit të cilin ju dëshironi të shtoni.
-service.gui.ADD_CONTACT_WIZARD=Ndihmesa për shtimin e kontaktit
service.gui.ADD_GROUP_LOCAL_ERROR=Dështoj për të shtuar grupin me emrin: {0}. Problemi ka ndodhur gjatë një l/O (disku i plotë? Mungesa e të drejtave?).
service.gui.ADD_GROUP_EXIST_ERROR=Grupi {0} ekziston në listën tuaj të kontaktit. Ju lutem zgjidhni një tjetër emër.
service.gui.ADD_GROUP_NET_ERROR=Dështoj për të shtuar grupin me emrin: {0}. Problemi ka ndodhur për shkak të dështimit të rrjetit. Ju lutem kontrolloni lidhjen e rrjetit dhe provoni përsëri.
service.gui.ADD_GROUP_ERROR=Dështoj për të shtuar grupin me emrin: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=Grupit duhet patjetër t´´i ipet një emër.
-service.gui.ADD_GROUP=Krijo grup
-service.gui.ADD_SUBCONTACT=&Shto subkontakt
service.gui.ADMINISTRATOR=Administrator
service.gui.ADVANCED=&Përparuar
-service.gui.ALL=&Të gjitha
service.gui.ALL_CONTACTS=&Të gjitha kontaktet
service.gui.APPLY=&Apliko
service.gui.ARE_NOW=Ju jeni tani {0}
service.gui.AT=në
service.gui.AUTHENTICATION_FAILED=Identifikimi ka dështuar. Fjalëkalimi që futët nuk është i vlefshëm
-service.gui.AUTHENTICATION_REQUESTED=Kërkohet identifikimi
service.gui.AUTHENTICATION_REQUESTED_SERVER=Serveri {0} ka kërkuar identifikimin tuaj.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} identifikimi
service.gui.AUTHORIZATION_REQUESTED=Kërkohet autorizimi
@@ -95,12 +99,10 @@ service.gui.CHAT_ROOM_USER_KICKED=është përjashtuar nga {0}
service.gui.CHAT_ROOM_USER_QUIT=ka lënë {0}
service.gui.CHAT_ROOM_NAME=Emri i dhomës së chat-it
service.gui.ROOM_NAME=Dhoma e chat-it
-service.gui.AUTOJOIN=Vetbashkim
service.gui.CHAT_ROOM_NAME_INFO=Shkruani në fushën e mëposhtme emrin e dhomës chat, të cilën ju dëshironi për të krijuar.
service.gui.CHAT_ROOM_NOT_EXIST=Dhoma {0} nuk u gjet në server {1}. Ju lutem verifikoni nëse emri që keni shtypur është i saktë.
service.gui.CHAT_ROOM_NOT_CONNECTED=Ju duhet të hyni brenda (log in), në mënyrë që t''i bashkangjiteni dhomës së chat-it {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Ju duhet të hyni brenda (log in), për të lënë një chat-dhomë
-service.gui.CHAT_ROOM_NOT_JOINED=Ju duhet t''i bashkangjiteni chat-dhomës, në mënyrë që të bëni operacione të mëtejshme në të.
service.gui.CHAT_ROOM_OPTIONS=Mundësitë e chat-dhomës
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Chat-dhoma {0} kërkon që të regjistroheni, nëse doni t''i bashkangjiteni.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Chat-dhoma {0} kërkon një fjalkalim.
@@ -114,9 +116,7 @@ service.gui.CONNECTING=Lidh...
service.gui.CONNECTING_STATUS=Lidh
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Lidh*
service.gui.CONNECTION=Lidhje
-service.gui.CONNECTION_FAILED_MSG=Lidhja SSL dështoi për këtë llogari: Emri i përdoruesit: {0}, emri i Server: {1}. Ju lutem kontrolloni lidhjen e rrjetit ose kontaktoni administratorin e rrjetit për më shumë informacion.
service.gui.CONNECTION_EXPIRED_MSG=Ju jeni shkyçur aktualisht nga server {0}.
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Kontakti i zgjedhur {0} nuk mbështetë telefoninë
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Kontakti i zgjedhur {0} nuk përkrah chat konferenca.
service.gui.CONTACT_PAUSED_TYPING={0} ka ndaluar së shkruari mesazhin.
service.gui.CONTACT_TYPING={0} është duke shkruar mesazh
@@ -129,13 +129,10 @@ service.gui.CREATE_CHAT_ROOM=&Krijo chat-dhomë...
service.gui.CREATE_CHAT_ROOM_ERROR=Nuk arriti të krijoj chat-dhomën {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=Krijo chat-dhomë
service.gui.CREATE_CONFERENCE_CALL=&Krijo një thirrje-konferencë...
-service.gui.CREATE_CONFERENCE_CHAT=&Krijo një chat-konferencë...
service.gui.CREATE_GROUP=&Krijo grup...
service.gui.CREATE_GROUP_NAME=Në fushën e mëposhtme, shkruani emrin e grupit që doni të krijoni.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Lista juaj e kontakteve nuk përmban asnjë grup. Ju lutem krijoni një grup të parë (Skedar/Krijo grup).
service.gui.CONTACT_INFO_NOT_SUPPORTED=Ky kontakt nuk mbështet informacionet e web-kontaktit
service.gui.CUT=&Prerje
-service.gui.DATE=Data
service.gui.DELETE=Fshij
service.gui.DESKTOP_SHARING_WARNING=<b> Jeni i sigurt se doni te filloni ndarjen e ekranit? </ b> <br> Duke klikuar OK, ju do lejoni të njerëzit e kësaj thirrjeje që të shohin ekranin tuaj.
service.gui.DIALPAD=Tastiera për thirrje
@@ -154,7 +151,6 @@ service.gui.ERROR_WAS=Gabimi ishte: {0}
service.gui.ESTIMATED_TIME=koha e parashikuar:
service.gui.EVENTS=Ndodhi
service.gui.EXIT=D&alje
-service.gui.EXTENDED_CRITERIA=Kritere të zgjëruara
service.gui.GENERAL_ERROR=Gabim i përgjithshëm
service.gui.GROUP_NAME=Emri i grupit
service.gui.FAILED_STATUS=Thirrja dështoi
@@ -207,7 +203,6 @@ service.gui.HIDE_OFFLINE_CONTACTS=Fshih kontaktet jashtë linje
service.gui.HIDE_MAIN_WINDOW=<DIV> Duke klikuar butonin X, nuk do të dilni nga programi, por vetëm <BR> fshehni atë. Nëse ju dëshironi të dilni nga programi zgjidhni Skedë/Dalje. </ DIV>
service.gui.HISTORY=&Kronologjia
service.gui.HISTORY_CONTACT=Kronologjia - {0}
-service.gui.HOUR=Ora
service.gui.IDENTIFIER=Identifikues
service.gui.IGNORE=&Injorim
service.gui.INSERT_SMILEY=Fut "smiley"
@@ -225,7 +220,6 @@ service.gui.INVITE_REASON=Arsyeja e ftesës
service.gui.IS_NOW={0} është tani {1}
service.gui.JOIN=&Bashkangjitem
service.gui.JOIN_AS=B&ashkangjitu si...
-service.gui.CLOSE_CHAT_ROOM_DIALOG=M&byll
service.gui.JOIN_CHAT_ROOM=&Bashkohu në chat-dhomë...
service.gui.JOIN_CHAT_ROOM_TITLE=Bashkohu në chat-dhomë
service.gui.JOIN_CHAT_ROOM_NAME=Ju lutem shkruani emrin e chat-dhomës ku ju doni për t''u bashkuar.
@@ -235,7 +229,6 @@ service.gui.KICK_FAILED=Përjashtimi dështoi
service.gui.KICK_FAILED_GENERAL_ERROR=Nuk arriti të përjashtoi {0}. Ka ndodhur një gabim i përgjithshëm në server.
service.gui.KICK_FAILED_NOT_ALLOWED=Nuk arriti të përjashtoi {0}. Pronari dhe administratori i dhomës nuk mund të përjashtohen.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Nuk arriti të përjashtoi {0}. Ju nuk posedoni të drejtat për të bërë këtë.
-service.gui.LAST=I fundit
service.gui.LEAVE=&Lë
service.gui.LIMIT_REACHED_FOR_IP=Ju keni shumë regjistrime ekzistuese nga IP-adresa lokale dhe serveri {0} nuk lejon për të hapur më shumë prej tyre.
service.gui.LOADING_ROOMS=Ngarkimi i dhomave...
@@ -250,7 +243,6 @@ service.gui.MESSAGE=Mesazh
service.gui.MISSED_CALLS_TOOL_TIP=Thirrjet e humbura nga:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= dhe {0} më shumë
service.gui.MODERATOR=moderator
-service.gui.MORE=Më shumë
service.gui.MOVE=Çvendos
service.gui.MOVE_SUBCONTACT=Çv&endos kontaktin
service.gui.MOVE_SUBCONTACT_MSG=Zgjidhni kontaktin ose grupin, ku ju doni të çvendosni kontaktin e zgjedhur.
@@ -258,7 +250,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=Kontakti që ju keni zgjedhur është e njëj
service.gui.MOVE_SUBCONTACT_QUESTION=Jeni i sigurt se doni të çvendosni {0} në {1}?
service.gui.MOVE_TO_GROUP=Ç&vendose në grup
service.gui.MOVE_CONTACT=Çvendos kontaktin
-service.gui.MOVE_CONTACT_ERROR=&Kontakti nuk mund të çvendoset
service.gui.MSG_DELIVERY_FAILURE=Mesazhi i mësipërm nuk u dorëzua
service.gui.MSG_DELIVERY_NOT_SUPPORTED=Protokolli që ju jeni duke përdorur, nuk mbështet mesazhe offline. Ju mund të përpiqeni të dërgoni mesazhin me një tjetër protokoll ose prisni deri sa ai/ajo të vijë online.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Ka ndodhur një gabim intern. Kjo është me siguri një difekt. Ju lutem raportoni ketu: http://www.sip-communicator.org/index.php/Development/BugsAndIssues.
@@ -269,7 +260,6 @@ service.gui.MSG_NOT_POSSIBLE=Mesazhimi nuk është i mundur për këtë kontakt
service.gui.MSG_RECEIVED={0} shkroi
service.gui.MSG_SEND_CONNECTION_PROBLEM=Ju duhet të jeni i lidhur, për të qenë në gjendje që të dërgoni mesazhe.
service.gui.MULTIPLE_LOGINS=Ju keni hyrë më shumë se një herë me të njëjtën llogari. Llogaria: Emri i përdoruesit: {0}, emri i server: {1} është shkëputur për momentin.
-service.gui.MUTE=Pa zë
service.gui.MUTUALLY_ON_HOLD_STATUS=Reciprokisht në pritje
service.gui.NETWORK=Rrjeti
service.gui.NETWORK_FAILURE=Gabim në rrjet
@@ -289,7 +279,6 @@ service.gui.NON_EMPTY_CHAT_WINDOW_CLOSE=Ju doni të mbyllni bisedën dhe një me
service.gui.NON_EXISTING_USER_ID=Serveri {0} nuk njeh përdoruesin e specifikuar.
service.gui.OFFLINE=Jashtë linje
service.gui.OK=&OK
-service.gui.OLDER_CALLS=Thirrjet e vjetra
service.gui.ONLINE=Në linjë
service.gui.OPEN=Hap
service.gui.OPEN_FILE_FROM_IMAGE=Klikody herë për të hap skedarin.
@@ -297,7 +286,6 @@ service.gui.OPEN_FOLDER=Hap dosjen
service.gui.OPEN_IN_BROWSER=Hape në &shfletues
service.gui.OPTIONS=Mundësitë
service.gui.OR=ose
-service.gui.OR_ENTER_PHONE_NUMBER=Ose shkruani numrin e telefonit këtu ...
service.gui.OWNER=Pronar i dhomës
service.gui.PASSWORD=Fjalëkalimi
service.gui.PASTE=&Ngjit
@@ -305,7 +293,6 @@ service.gui.PORT=Porti
service.gui.PRESENCE=Prania
service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Enter' për sygjerime
service.gui.PREVIOUS=I mëparshëm
-service.gui.PREVIOUS_TOOLTIP=Shfleto biseda të vjetra
service.gui.PRINT=&Shtyp
service.gui.PROACTIVE_NOTIFICATION=është duke shkruar mesath
service.gui.PROTOCOL=Protokolli
@@ -341,24 +328,16 @@ service.gui.REVOKE_ADMIN=Heqja e administratorit
service.gui.REVOKE_MODERATOR=Heqja e moderatorit
service.gui.REVOKE_MEMBERSHIP=Heqja e anëtarësimit
service.gui.REVOKE_VOICE=Heqja e zërit
-service.gui.ROOT_GROUP=Grupi bazë
service.gui.SAVE=&Ruaj
service.gui.SEARCH=&Kërko
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Klikoni butonin më poshtë për të treguar të gjithë chat-dhomat ekzistuese në serverin e përzgjedhur. Atëherë zgjidhni atë që ju doni t''i bashkoheni dhe klikoni butonin "Bashkangjitu".
-service.gui.SELECT_ACCOUNT=Përzgjedh llogarinë
service.gui.SELECT_COLOR=Përzgjedh ngjyrën
service.gui.SELECT_GROUP=Përzgjedh grupin
-service.gui.SELECT_GROUP_WIZARD_MSG=Lista e mëposhtme përmban të gjitha grupet në listën tuaj të kontaktit. Përzgjidhni një, ku ju dëshironi të shtoni kontakt të ri.
service.gui.SELECT_NO_GROUP=S''ka grup
-service.gui.SELECT_GROUP_WIZARD=Specifikoni grupin
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=Lista e mëposhtme përmban të gjitha llogaritë që mbështesin funksionin e chat-iti për shumë përdorues. Përzgjedh llogarinë me të cilin ju dëshironi t''a krijoni chat-dhomën tuaj.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=Lista e mëposhtme përmban të gjitha llogaritë e regjistruar. Përzgjedh llogarinë të cilën dëshironi t''a përdorni për të komunikuar me kontakt të ri.
-service.gui.SELECT_PROVIDERS_WIZARD=Përzgjedh llogarinë
service.gui.SEND=&Dërgo
service.gui.SEND_FILE=Dërgo &skedar
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Nuk ka asnjë informacion për këtë kontakt.
service.gui.SEND_MESSAGE=&Dërgo një mesazh
-service.gui.SEND_AS_SMS=Dërgo si SMS
service.gui.SEND_SMS=Dë&rgo SMS
service.gui.SEND_SMS_DETAILS=Mos harroni se ju duhet të shkruani numrin në format ndërkombëtare p.sh. duke filluar me 355 për Shqipëri për shembull, 35577000000
service.gui.SEND_SMS_NOT_SUPPORTED=Protokolli i përzgjedhur nuk mbështet dërgimin e mesazheve SMS.
@@ -390,15 +369,18 @@ service.gui.STATUS_MESSAGE_INFO=Në fushën e mëposhtme ju mund të specifikoni
service.gui.STOP_SHARING=Ndal ndarjen
service.gui.SUBJECT=Subjekti
service.gui.SUMMARY=Përmbledhje
-service.gui.TODAY=Sot
service.gui.VOICEMAIL_NO_MESSAGES=Asnjë mesazh
+#enum values from IceProcessingState
+
+
+
+#service.gui.CERT_INFO_ are combined from Rdn names
-service.gui.security.COMPARE_WITH_PARTNER=Krahaso me partnerin dhe klikoni dryrin për të konfirmuar.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Krahaso me partnerin: {0}
@@ -407,9 +389,6 @@ service.gui.avatar.imagepicker.CANCEL=&Anulo
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
# systray
@@ -418,17 +397,19 @@ service.gui.avatar.imagepicker.CANCEL=&Anulo
# LDAP
impl.ldap.EDIT=&Redakto
-impl.ldap.REMOVE=&Largo
impl.ldap.SAVE=&Ruaj
impl.ldap.CANCEL=&Anulo
impl.ldap.SERVER_PORT=Porti
impl.ldap.PASSWORD=Fjalëkalimi
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
# Google Contacts
impl.googlecontacts.EDIT=&Redakto
-impl.googlecontacts.REMOVE=&Largo
impl.googlecontacts.SAVE=&Ruaj
impl.googlecontacts.CANCEL=&Anulo
impl.googlecontacts.PASSWORD=Fjalëkalimi
@@ -444,9 +425,6 @@ impl.googlecontacts.PASSWORD=Fjalëkalimi
# branding
plugin.branding.ABOUT_MENU_ENTRY=&Rreth
-# Dict protocol
-
-# facebookaccregwizz
# generalconfig
plugin.generalconfig.SHOW_HISTORY=Shfaq
@@ -459,22 +437,16 @@ plugin.generalconfig.SHOW_HISTORY=Shfaq
# jabber accregwizz
-# mailbox
-
-# msn accregwizz
-
# plugin manager
# simple accregwizz
# sipaccregwizz
plugin.sipaccregwizz.XCAP_PASSWORD=Fjalëkalimi
+#used from SecurityPanel
# skin manager
-# ssh accregwizz
-plugin.sshaccregwizz.OPTIONAL=Mundësitë
-
# status update
# updatechecker
@@ -487,26 +459,23 @@ plugin.whiteboard.OPEN=Hap
plugin.whiteboard.COLOR=Me ngjyra
plugin.whiteboard.DELETE=Fshij
-# yahoo accregwizz
-
-# zero accregwizz
-
# gtalk accregwizz
# iptel accregwizz
-# sip2sip accregwizz
-
# ippi accregwizz
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_COPY=&Kopjo
plugin.keybindings.CHAT_CUT=&Prerje
plugin.keybindings.CHAT_PASTE=&Ngjit
plugin.keybindings.MAIN_RENAME=Rie&mërto kontaktin
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Chat
# Notification Configuration Form
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Thirrje e ardhur
plugin.notificationconfig.event.IncomingFile=Thirrje e ardhur
plugin.notificationconfig.event.HangUp=Ul receptorin e telefonit
@@ -522,6 +491,7 @@ impl.media.security.zrtp.TITLE=Thirrje
+#in JNIEncoder
# The callrecordingconfig plugin was never really committed into trunk and its
# ConfigurationForm was actually put in the neomedia bundle.
@@ -530,7 +500,6 @@ impl.media.security.zrtp.TITLE=Thirrje
plugin.securityconfig.masterpassword.TITLE=Fjalëkalimi
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Mbaj mend fjalëkalimin
plugin.securityconfig.masterpassword.COL_PASSWORD=Fjalëkalimi
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=&Largo
# otr plugin
plugin.otr.authbuddydialog.CANCEL=&Anulo
@@ -559,7 +528,6 @@ plugin.dnsconfig.lblBackupPort.text=Porti
net.java.sip.communicator.util.dns.SecureResolveMode.IgnoreDnssec=&Injorim
#plugin spellcheck
-plugin.spellcheck.EDIT_PERSONAL_DICT=&Redakto
#Certificate configuration plugin
diff --git a/resources/languages/resources_sr.properties b/resources/languages/resources_sr.properties
index 3c9e19d..24c9b05 100644
--- a/resources/languages/resources_sr.properties
+++ b/resources/languages/resources_sr.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Ја
service.gui.ACCOUNT_REGISTRATION_WIZARD=Чаробњак за региÑтрацију налога
service.gui.ACCOUNTS=Ðалози
service.gui.ADD=&Додај
-service.gui.ADD_ACCOUNT=Додај налог
service.gui.ADD_CONTACT=&Додај контакт
service.gui.ADD_AUTHORIZED_CONTACT=Додај {0}у лиÑту контаката
service.gui.ADD_CONTACT_TO_CONTACTLIST=Додај контакт на лиÑту контаката
@@ -42,20 +52,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Грешка код додавања конÑ
service.gui.ADD_CONTACT_EXIST_ERROR=Контакт {0} већ поÑтоји у лиÑти контаката.
service.gui.ADD_CONTACT_NETWORK_ERROR=Сервер није препознао захтев за додавање контакта Ñа ид: {0}.
service.gui.ADD_CONTACT_NOT_SUPPORTED=ÐеуÑпело додавење контаката Ñа ид: {0}. Операција није подржана.
-service.gui.ADD_CONTACT_IDENTIFIER=У поље иÑпод унеÑите идентификацију контакта кога желите додати.
-service.gui.ADD_CONTACT_WIZARD=Чаробњак за додавање контакта
service.gui.ADD_CONTACT_NOT_CONNECTED=Морате бити повезани да би додали контакт. Повежите Ñе на одабраног провајдера и пробајте поново.
service.gui.ADD_GROUP_LOCAL_ERROR=ÐеуÑпело додавање групе Ñа именом: {0}. Проблем Ñе догодио током локален ИО операције.
service.gui.ADD_GROUP_EXIST_ERROR=Група {0} већ поÑтоји у вашој контакт лиÑти. Молим одаберите друго име.
service.gui.ADD_GROUP_NET_ERROR=ÐеуÑпело додавање групе Ñа именом: {0}. Проблем Ñе догодио због лоше везе. Молим проверите вашу мрежу и пробајте поново.
service.gui.ADD_GROUP_ERROR=ÐеуÑпело додавање групе Ñа именом: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=Група не мора бити празна.
-service.gui.ADD_GROUP=Ðаправи групу
-service.gui.ADD_SUBCONTACT=&Додај потконтакт
service.gui.ADDRESS=ÐдреÑа
service.gui.ADMINISTRATOR=админиÑтратор
service.gui.ADVANCED=&Ðапредно
-service.gui.ALL=&Сви
service.gui.ALL_CONTACTS=&Сви контакти
service.gui.ALTERNATE_ADDRESS=Резервна адреÑа
service.gui.APPLY=&Примени
@@ -65,7 +70,6 @@ service.gui.AT=у
service.gui.AUTHORIZE=&ОвлаÑти
service.gui.AUTHORIZATION_ACCEPTED={0} је прихватио захтев за овлашћење.
service.gui.AUTHENTICATION_FAILED=Пријава је неуÑпела за {0}. Унета лозинка није иÑправна.
-service.gui.AUTHENTICATION_REQUESTED=Потребна идентификација
service.gui.AUTHENTICATION_REQUESTED_SERVER=Сервер {0} захтева вашу идентификацију.
service.gui.AUTHENTICATION_REJECTED={0} је одбацио ваш захтев за идентификацију.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} идентификација
@@ -107,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=У поље иÑпод можете унети
service.gui.CHANGE_NICKNAME_ERROR=Грешка код промене надимка
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Ðадимак већ поÑтоји
service.gui.CHANGE_VIDEO_QUALITY=Промени квалитет видеа
-service.gui.CHAT_CONFERENCE_LABEL=Конференција
service.gui.CHAT_CONFERENCE_ITEM_LABEL={0}''име конференције
service.gui.CHAT_ROOM_ALREADY_JOINED=Соба {0} за ћаÑкање је већ приÑтупила.
service.gui.CHAT_ROOM_CONFIGURATION=Подешавање {0} Ñобе за ћаÑкање
@@ -121,18 +124,14 @@ service.gui.CHAT_ROOM_USER_LEFT=науÑтио {0}
service.gui.CHAT_ROOM_USER_KICKED=избачен је из {0}
service.gui.CHAT_ROOM_USER_QUIT=напуÑтио {0}
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=Слање поруке је забрањено
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Чување Ñобе за ћаÑкање за будуће коришћење
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Уклоните одабрану Ñобу Ñа лиÑте Ñачуваних Ñоба
service.gui.CHAT_ROOM_NAME=Име Ñобе за ћаÑкање
service.gui.CLEAR_CUSTOM_MESSAGES=Избриши произвољне поруке
service.gui.ROOM_NAME=Соба за ћаÑкање
-service.gui.AUTOJOIN=Ðуто-прикључење
service.gui.CHANGE_PASSWORD=Промена лозинке
service.gui.CHAT_ROOM_NAME_INFO=У поље иÑпод унеÑите име Ñобе за ћаÑкање коју би желели да креирате.
service.gui.CHAT_ROOM_NOT_EXIST=Соба није нађена на Ñерверу. Молим проверите да ли Ñте унели иÑправно име.
service.gui.CHAT_ROOM_NOT_CONNECTED=Потребно је да будете пријављени да би приÑтупили {0} Ñоби за ћаÑкање
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Морате бити пријављени да би напуÑтили Ñобу за ћаÑкање.
-service.gui.CHAT_ROOM_NOT_JOINED=Морате бити пријављени у Ñобу за ћаÑкање за даље операције.
service.gui.CHAT_ROOM_OPTIONS=ПоÑтавке Ñобе за ћаÑкање
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=Соба {0} за ћаÑкање захтева региÑтрацију за прикључивање.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Соба {0} за ћаÑкање захтева лозинку.
@@ -150,21 +149,17 @@ service.gui.CLEAR=ОчиÑти
service.gui.CLOSE=За&твори
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Ðе можете примити нову поруку за мање од 2 Ñекунде. Да ли Ñте Ñигурни да желите затворити ово ћаÑкање?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=Имате активан Ð¿Ñ€ÐµÐ½Ð¾Ñ Ñ„Ð°Ñ˜Ð»Ð°. Да ли Ñте Ñигурни да желите на прекинете?
-service.gui.CONFIRM=Потврди
service.gui.CONNECTED_STATUS=Повезан
service.gui.CONNECTING=Повезивање...
service.gui.CONNECTING_STATUS=УÑпоÑтављам везу
service.gui.CONNECTING_EARLY_MEDIA_STATUS=УÑпоÑтављам везу*
service.gui.CONNECTION=Веза
-service.gui.CONNECTION_FAILED_MSG=Повезивање није иÑправно за налог: КориÑничко име: {0}, Име Ñервера: {1}. Молим проверите вашу мрежу или контактирајте админиÑтратора за више информација.
service.gui.CONNECTION_EXPIRED_MSG=Веза Ñа Ñервером је {0} прекинута.
service.gui.CONTACT_NAME=ИД или број
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Изабрани {0} контакт не подржава телефонију.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Изабрани {0} контакт не подржава конференције.
service.gui.CONTACT_PAUSED_TYPING={0} заÑтој код куцања поруке
service.gui.CONTACT_TYPING={0} куца поруку
service.gui.CONTACT_INFO=&Контакт подаци
-service.gui.CONTACTLIST=ЛиÑта контаката
service.gui.CONTACTS=Контакти
service.gui.COPY=&Умножи
service.gui.COPY_LINK=Умножи &везу
@@ -174,17 +169,14 @@ service.gui.CREATE_CHAT_ROOM=&Креирај Ñобу за ћаÑкање...
service.gui.CREATE_CHAT_ROOM_ERROR=ÐеуÑпело креирање {0} Ñобе за ћаÑкање.
service.gui.CREATE_CHAT_ROOM_WIZARD=Креирај чаробњак Ñобе за ћаÑкање
service.gui.CREATE_CONFERENCE_CALL=&Креирај конференцијÑки позив...
-service.gui.CREATE_CONFERENCE_CHAT=&Креирај конференцијÑко ћаÑкање...
service.gui.CREATE_GROUP=&Креирај групу...
service.gui.CREATE_GROUP_NAME=У поље иÑпод унеÑи име групе коју желите да креирате.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Ваша контакт лиÑта не Ñадржи групе. Моли прво креирајте групу (Фајл/Креирај гурпу).
service.gui.CREATE_VIDEO_BRIDGE=Креирај &видео везу...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Креирај &видео везу
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Креирај / ПриÑтупи видео конференцији
service.gui.CREATE_VIDEO_CONFERENCE=Креирај нову видео конференцију за ову Ñобу
service.gui.CONTACT_INFO_NOT_SUPPORTED=Овај контакт не подржава веб контакт податке
service.gui.CUT=И&Ñеци
-service.gui.DATE=Датум
service.gui.DELETE=Обриши
service.gui.DENY=&Одбиј
service.gui.DESKTOP_SHARING_WARNING=<b>Да ли Ñте Ñигурни да желите дељење екрана?</b> <br> Кликом на У реду оÑобе на овом позиву ће видети ваш екран.
@@ -194,7 +186,6 @@ service.gui.DISCONNECTED_STATUS=Прекинута веза
service.gui.DND_STATUS=Ðе узнемиравај
service.gui.DO_NOT_ASK_AGAIN=Ðе питај поново
service.gui.DO_NOT_SHOW_AGAIN=Ðе показуј ову поруку поново
-service.gui.DOWNLOAD_NOW=&Преузми Ñада
service.gui.DRAG_FOR_SHARING=Превуци овде било шта што желиш да делиш...
service.gui.DURATION=трајање
service.gui.DESTROY_CHATROOM=Уништи Ñобу за ћаÑкање
@@ -215,7 +206,6 @@ service.gui.ERROR_RECEIVED_FROM=Грешка је примљена од {0}
service.gui.ESTIMATED_TIME=Процењено преоÑтало време:
service.gui.EVENTS=Догађаји
service.gui.EXIT=И&злаз
-service.gui.EXTENDED_CRITERIA=Проширени критеријуми
service.gui.GENERAL=Опште
service.gui.GENERAL_ERROR=Опште грешке
service.gui.GROUP_NAME=Име групе
@@ -257,7 +247,6 @@ service.gui.FONT_ITALIC=ИÑкошено
service.gui.FONT_SIZE=Величина
service.gui.FONT_STYLE=Изглед
service.gui.FONT_UNDERLINE=Подвучено
-service.gui.FROM={0} од {1}
service.gui.GRANT_OWNERSHIP=Додели влаÑништво...
service.gui.GRANT_ADMIN=Додели админиÑтратора...
service.gui.GRANT_MODERATOR=Додели модератора
@@ -283,7 +272,6 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=Да ли Ñте Ñигурни да же
service.gui.HISTORY_REMOVE_ERROR=Грешка код уклањања локално Ñачуваних порука.
service.gui.HOME=Лично
service.gui.HOME_PAGE=Матична Ñтрана
-service.gui.HOUR=Сат
service.gui.ICE=ICE
service.gui.IDENTIFIER=Идентификатор
service.gui.IGNORE=&Игнориши
@@ -305,13 +293,10 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Позови контакте за в
service.gui.INVITE_REASON=Разлог позивања
service.gui.IS_CALLING={0} позива...
service.gui.IS_NOW={0} је Ñад {1}
-service.gui.JITSI_WARNING=SIP комуникатор је недавно преименован у Jitsi.<br/>Ðко желите да ваша верзија буде ажурирана, преузмите одмах Jitsi.<br/><br/>Извињавамо Ñе због непријатноÑти коју Ñмо можда изазвали.<br/><br/>Jitsi развојни тим
-service.gui.JITSI_WARNING_TITLE=SIP комуникатор поÑтаје Jitsi
service.gui.JOIN=&Прикључи
service.gui.JOIN_AS=П&рикључи ка
service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=Прикључи Ñе поÑтојећој видео конференцији
service.gui.JOIN_VIDEO=Прикључи видео
-service.gui.CLOSE_CHAT_ROOM_DIALOG=З&атвори
service.gui.JOB_TITLE=Занимање
service.gui.JOIN_CHAT_ROOM=&Придружи Ñе ћаÑкању...
service.gui.JOIN_CHAT_ROOM_TITLE=Придружи Ñе ћаÑкању
@@ -324,7 +309,6 @@ service.gui.KICK_FAILED=ÐеуÑпело избацивање
service.gui.KICK_FAILED_GENERAL_ERROR=ÐеуÑпело избацивање {0}. Грешка на Ñерверу.
service.gui.KICK_FAILED_NOT_ALLOWED=ÐеуÑпело избацивање {0}. ВлаÑник и админиÑтратор Ñобе не могу бити избачени.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=ÐеуÑпело избацивање {0}. Ðемате довољно овлашћења да то учините.
-service.gui.LAST=ПоÑледњи
service.gui.LAST_NAME=Презиме
service.gui.LEAVE=&ÐапуÑти
service.gui.LIMIT_REACHED_FOR_IP=Имате превише региÑтрација Ñа локалне ИП адреÑе и {0} Ñервер не дозвољава отварање нових адреÑа.
@@ -344,7 +328,6 @@ service.gui.MESSAGE=Порука
service.gui.MISSED_CALLS_TOOL_TIP=Пропуштени позив од:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= и {0} више
service.gui.MODERATOR=модератор
-service.gui.MORE=Погледај више
service.gui.MORE_LABEL=Више
service.gui.MOVE=ПремеÑти
service.gui.MOVE_SUBCONTACT=П&ремеÑти контакт
@@ -353,7 +336,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=Контакт који Ñте одабран
service.gui.MOVE_SUBCONTACT_QUESTION=Да ли Ñте Ñигурни да желите премеÑтити {0} за {1}?
service.gui.MOVE_TO_GROUP=&ПремеÑти у групу
service.gui.MOVE_CONTACT=ПремеÑти контакт
-service.gui.MOVE_CONTACT_ERROR=&Контакт не може бити премештен
service.gui.MSG_DELIVERY_FAILURE=Порука изнад није могла бити иÑпоручена
service.gui.MSG_DELIVERY_NOT_SUPPORTED=Протокол који кориÑтите не подржава поруке ван мреже. Пробајте преко {0} другог протокола или чекајте док он/она поÑтане доÑтупан.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Догодила Ñе интерна грешка. Ово је највероватније баг. Молим пријавите овде: https://jitsi.org/Development/BugsAndIssues.
@@ -367,7 +349,6 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=Потребно је да Ñте пов
service.gui.MULTIPLE_LOGINS=Ви Ñте пријављени Ñа више од једног налога. Следећи налог: КориÑничко име: {0}, Име Ñервера: {1} је тренутно иÑкључен.
service.gui.MY_CHAT_ROOMS=Додај Ñобу за ћаÑкање
service.gui.MY_CHAT_ROOMS_TITLE=Додај Ñобу за ћаÑкање
-service.gui.MUTE=Утишај
service.gui.NAME=Име
service.gui.NETWORK=Мрежа
service.gui.NETWORK_FAILURE=Пад мреже
@@ -397,7 +378,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=ÐијеуконтактлиÑти
service.gui.SD_QUALITY=Стандардан квалитет
service.gui.OFFLINE=Ван мреже
service.gui.OK=&У реду
-service.gui.OLDER_CALLS=Старији позиви
service.gui.ONLINE=Ðа мрежи
service.gui.OPEN=Отвори
service.gui.OPEN_FILE_FROM_IMAGE=Двоклик за отварање фајла.
@@ -409,7 +389,6 @@ service.gui.OPEN_ON_ACTIVITY=Отвори на активноÑти
service.gui.OPEN_ON_MESSAGE=Отвори Ñамо на поруке
service.gui.OPEN_ON_IMPORTANT_MESSAGE=Отвори Ñамо на важне поруке
service.gui.OR=или
-service.gui.OR_ENTER_PHONE_NUMBER=Или унеÑи телефонÑки број овде...
service.gui.ORGANIZATION=Организација
service.gui.OTHER=Друго
service.gui.OWNER=влаÑник Ñобе
@@ -428,7 +407,6 @@ service.gui.PRESS_ENTER_FOR_SUGGESTIONS=ПритиÑни "Ентер" за ÑуÐ
service.gui.PRESS_FOR_CALL_INFO=ПритиÑни за податке позива
service.gui.PRESS_TO_OPEN_CRM=ПритиÑни за отварање ЦРМ апликације
service.gui.PREVIOUS=Претходно
-service.gui.PREVIOUS_TOOLTIP=Претражи Ñтарије конверзације
service.gui.PRINT=&Штампај
service.gui.PROACTIVE_NOTIFICATION=је пиÑање поруке
service.gui.PROBLEMS_ENCOUNTERED=Суочавајући проблеми
@@ -444,7 +422,6 @@ service.gui.RECONNECTION_LIMIT_EXCEEDED=Одјављивали и пријављ
service.gui.RE_REQUEST_AUTHORIZATION=Поново захтевај ауторизацију
service.gui.REFERRED_STATUS=Препоручено
service.gui.REJECT=&Одбаци
-service.gui.REMIND_ME_LATER=ПодÑети ме каÑније
service.gui.REMEMBER_PASSWORD=Запамти лозинку
service.gui.REMOVE=&Уклони
service.gui.REMOVE_ACCOUNT=&Уклони налог
@@ -470,29 +447,20 @@ service.gui.REVOKE_ADMIN=Опозови админиÑтратора
service.gui.REVOKE_MODERATOR=Опозови модератора
service.gui.REVOKE_MEMBERSHIP=Опозови чланÑтво
service.gui.REVOKE_VOICE=Укини глаÑ
-service.gui.ROOT_GROUP=Ðдмин група
service.gui.SAVE=&Сачувај
-service.gui.SAVE_AS_DEFAULT=Сачувај као подразумевано
service.gui.SEARCH=&Претражи
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Кликни на дугме иÑпод за приказ Ñвих Ñоба за ћаÑкање на одабраном Ñерверу. Онда одабери један коме желиш да приÑтупиш и кликни на приÑтупно дугме.
service.gui.SEARCH_STRING_CONTACT_SOURCE=Тражени контакт
service.gui.SECURITY=БезбедноÑÑ‚
-service.gui.SELECT_ACCOUNT=Одабери налог
service.gui.SELECT_COLOR=Одабери боју
service.gui.SELECT_GROUP=Одабери групу
-service.gui.SELECT_GROUP_WIZARD_MSG=ЛиÑта иÑпод Ñадржи Ñве групе у вашој контакт лиÑти. Одабери једну где желиш да додаш нови контакт.
service.gui.SELECT_NO_GROUP=Без групе
-service.gui.SELECT_GROUP_WIZARD=Одреди групу
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=ЛиÑта иÑпод Ñадржи Ñве налоге које подржавају функцију вишеÑтруког ћаÑкања. Одабери један који желиш за креирање Ñвоје Ñобе за ћаÑкање.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=ЛиÑта иÑпод Ñадржи Ñве региÑтроване налоге. Одабери један који желиш за комуникацију Ñа новим контактом.
-service.gui.SELECT_PROVIDERS_WIZARD=Одабери налог
service.gui.SELECT_VIDEO_CONFERENCE=Одавери видео конференцију
service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Одабери Ñобу за ћаÑкање Ñа лиÑте и притиÑни У реду за додавање.
service.gui.SEND=&Пошаљи
service.gui.SEND_FILE=Пошаљи &фајл
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Ðе поÑтоје подаци за овај контакт.
service.gui.SEND_MESSAGE=&Пошаљи поруку
-service.gui.SEND_AS_SMS=Пошаљи као СМС
service.gui.SEND_PRIVATE_MESSAGE=Пошаљи приватну поруку
service.gui.SEND_SMS=П&ошаљи СМС
service.gui.SEND_SMS_DETAILS=Запамти да је потребно унети број у интернационалном формату, нпр. почети Ñа +44 за UK као пример, +447777000000
@@ -531,7 +499,6 @@ service.gui.STREET=Улица
service.gui.SUBJECT=Субјект
service.gui.SUMMARY=Сажетак
service.gui.TELEPHONY=Телефонија
-service.gui.TODAY=ДанаÑ
service.gui.TOOLS=&Ðлати
service.gui.TRANSFER=Прен&оÑ
service.gui.TO=&За:
@@ -541,7 +508,6 @@ service.gui.TRANSFER_CALL_TO=ÐŸÑ€ÐµÐ½Ð¾Ñ Ð·Ð°:
service.gui.TRANSPARENCY_NOT_ENABLED=ПровидноÑÑ‚ није подржана за ваше тренутне поÑтавке.
service.gui.TYPE_YOUR_REQUEST=Укуцајте захтев овде
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Ðије могуће променити квалитет видеа за овај позив.
-service.gui.UNMUTE=Укључи звук
service.gui.USER_IDENTIFIER=Идентификатор кориÑника:
service.gui.USER_EXISTS_ERROR=КориÑник већ поÑтоји на одабраној мрежи. Молим одаберите другог кориÑника или мрежу
service.gui.USERNAME_NULL=Молим попуните ваше кориÑничко име и лозинку.
@@ -554,7 +520,6 @@ service.gui.USE_PROVISIONING=КориÑти провизију преко мре
service.gui.VALUE=ВредноÑÑ‚
service.gui.VIDEO_CALL=&Видео позив
service.gui.VIA=преко
-service.gui.VIA_SMS=преко СМС
service.gui.VIEW=&Приказ
service.gui.VIEW_HISTORY=Приказ &иÑторије
service.gui.VIEW_SMILEYS=Приказ &емотикона
@@ -574,9 +539,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=ПодеÑи јачину звука
service.gui.WAITING_AUTHORIZATION=Чекам за ауторизацију
service.gui.WARNING=Упозорење
service.gui.YES=Да
-service.gui.YESTERDAY=Јуче
-service.gui.EXISTING_ACCOUNT_ERROR=Ðалог који Ñте унели је већ инÑталиран.
-service.gui.NEW_MAIL=<b>Имате нову е-пошту!</b><br/><b>Од:</b> {0} {1} <br/><b>Субјект:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=Примили Ñте нову поруку е-поште у Ñату {0} <a href="{1}">примљено</a>:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=Примили Ñте {2} нову поруку е-поште у Ñату {0} <a href="{1}">примљено</a>:<br/>
service.gui.NEW_GMAIL_FOOTER=једна непрочитана порука у твом <a href="{0}">примљеном</a>.<br/>
@@ -600,7 +562,6 @@ service.gui.SECURITY_ERROR=БезбедоноÑна грешка
service.gui.SPEED=Брзина:
service.gui.SILENT_MEMBER=тихи члан
service.gui.NON_SECURE_CONNECTION=Ðебезбедне конекције могу бити направљене за овај налог {0}. Ðко желите повезивање Ñа небезбедним Ñервером, молим проверите "Омогући небезбедне конекције" у вашим поÑтавкама налога.
-service.gui.UPDATE=Ðжурирај
service.gui.MOBILE_PHONE=Мобилни
service.gui.VIDEO_PHONE=Видео
service.gui.WORK_PHONE=ПоÑао
@@ -635,7 +596,6 @@ service.gui.callinfo.CALL_INFORMATION=Подаци позива
service.gui.callinfo.CALL_IDENTITY=Идентитет
service.gui.callinfo.PEER_COUNT=Број учеÑника
service.gui.callinfo.IS_CONFERENCE_FOCUS=Ð¤Ð¾ÐºÑƒÑ ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ñ˜Ðµ
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Омогућено шифрофање
service.gui.callinfo.CALL_TRANSPORT=Сигнализација у току позива
service.gui.callinfo.CALL_DURATION=Трајање позива
service.gui.callinfo.TLS_PROTOCOL=ТЛС протокол
@@ -649,7 +609,6 @@ service.gui.callinfo.AUDIO_INFO=Звучни подаци
service.gui.callinfo.VIDEO_INFO=Видео подаци
service.gui.callinfo.LOCAL_IP=Локална ИП / Порт
service.gui.callinfo.REMOTE_IP=Удаљена ИП / Порт
-service.gui.callinfo.BANDWITH=Проток
service.gui.callinfo.LOSS_RATE=ÐиÑка Ñтопа
service.gui.callinfo.RTT=РТТ
service.gui.callinfo.JITTER=Померање
@@ -659,9 +618,12 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=СРТП
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=Кључ размене протокола
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=ICE кандидат проширеног типа
service.gui.callinfo.ICE_STATE=ICE обрада
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.RUNNING=Провера повезивања
service.gui.callinfo.ICE_STATE.COMPLETED=Завршено
service.gui.callinfo.ICE_STATE.FAILED=ÐеуÑпело
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=Локални рачунар ИП / Порт
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=ДаљинÑки пренета ИП / Порт
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=Локални ИП / Порт
@@ -683,6 +645,8 @@ service.gui.CERT_DIALOG_TITLE=Преглед Ñертификата
service.gui.CONTINUE_ANYWAY=Ипак наÑтави
service.gui.CERT_INFO_CHAIN=Ланац Ñертификата:
service.gui.CERT_INFO_ISSUED_TO=Издато за
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Средње име:
service.gui.CERT_INFO_O=Организација:
service.gui.CERT_INFO_C=Ðазив државе:
@@ -701,12 +665,10 @@ service.gui.CERT_INFO_SIGN_ALG=Ðлгоритам потпиÑа:
service.gui.CERT_INFO_PUB_KEY_INFO=Подаци о јавном кључу
service.gui.CERT_INFO_ALG=Ðлгоритам:
service.gui.CERT_INFO_PUB_KEY=Јавни кључ:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} бајтова: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} битова
service.gui.CERT_INFO_EXP=Изложилац:
service.gui.CERT_INFO_KEY_SIZE=Величина кључа:
service.gui.CERT_INFO_SIGN=ПотпиÑ:
-service.gui.CONTINUE=ÐаÑтави
service.gui.SHOW_CERT=Прикажи Ñертификат
service.gui.HIDE_CERT=Сакриј Ñертификат
@@ -728,12 +690,9 @@ service.gui.security.SECURE_AUDIO=БеÑбедан звук
service.gui.security.AUDIO_NOT_SECURED=Звук није безбедан
service.gui.security.SECURE_VIDEO=Безбедан видео
service.gui.security.VIDEO_NOT_SECURED=Видео није безбедан
-service.gui.security.NO_VIDEO=Без видеа
-service.gui.security.CIPHER=Шифра: {0}
service.gui.security.CALL_SECURED_TOOLTIP=Позив је безбедан. За више података притиÑни овде.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Позив није безбедан.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=ПритиÑни овде да упоредити безбедоноÑну тајну Ñа партнером.
-service.gui.security.COMPARE_WITH_PARTNER=Упореди Ñа партнером и кликни катанац за потврду.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Упореди Ñа партнером:
service.gui.security.SECURITY_ALERT=Покушавам да обезбедим позив. ИÑкључење у
@@ -749,19 +708,13 @@ service.gui.avatar.imagepicker.CLICK=Клик и емотикон
service.gui.avatar.imagepicker.IMAGE_FILES=Фајлови Ñлика
service.gui.avatar.imagepicker.IMAGE_PICKER=Слика
service.gui.avatar.imagepicker.IMAGE_SIZE=Величина Ñлике
-service.gui.avatar.imagepicker.INITIALIZING=Покрећем
service.gui.avatar.imagepicker.RESET=Поврати
service.gui.avatar.imagepicker.SET=ПодеÑи
service.gui.avatar.imagepicker.TAKE_PHOTO=Сними фотографију
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Грешка веб камере
service.gui.security.encryption.required=Захтева Ñе шифровање!
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
impl.protocol.sip.XCAP_ERROR_TITLE=Грешка у СИП Ñкладишту контакт лиÑти
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=РеÑÑƒÑ€Ñ Ñе не чита {0}. За {1}
@@ -791,9 +744,7 @@ impl.ldap.QUERY_CUSTOM=Прилагођени упит
impl.ldap.QUERY_CUSTOM_HINT=КориÑти {0} као чиновника за термин претраге.
impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=ÐутоматÑки додај џокере за термин упита
impl.ldap.QUERY_PHOTO_INLINE=ДонеÑи Ñлику Ñа другим атрибутима
-impl.ldap.NEW=Ðова
impl.ldap.EDIT=уреди
-impl.ldap.REMOVE=Уклони
impl.ldap.ENABLED=Омогућен
impl.ldap.SERVER_NAME=Име Ñервера
impl.ldap.SERVER_NAME_EXAMPLE=Мој ЛДÐП Ñервер
@@ -826,6 +777,10 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=кућнителефон
impl.ldap.PHONE_PREFIX=ÐŸÑ€ÐµÑ„Ð¸ÐºÑ Ñ‚ÐµÐ»ÐµÑ„Ð¾Ð½Ð°
impl.ldap.PHONE_PREFIX_EXAMPLE=Ex.: 00
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=ÐдреÑар
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=Омогући претрагу за MacOSX адреÑар
@@ -839,9 +794,7 @@ plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT=Ðаправи Outlook подр
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Google контакти
-impl.googlecontacts.NEW=Ðово
impl.googlecontacts.EDIT=уреди
-impl.googlecontacts.REMOVE=Уклони
impl.googlecontacts.ENABLED=Омогућен
impl.googlecontacts.ACCOUNT_NAME=Име налога
impl.googlecontacts.SAVE=Сачувај
@@ -879,11 +832,8 @@ plugin.accountinfo.ORGANIZATION=Ðазив организације:
plugin.accountinfo.JOB_TITLE=Ðазив поÑла:
plugin.accountinfo.ABOUT_ME=О мени:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
-plugin.accountinfo.USER_PICTURES=КориÑничке Ñлике
plugin.accountinfo.GLOBAL_ICON=КориÑти општу икону
plugin.accountinfo.LOCAL_ICON=КориÑти ову икону:
-plugin.accountinfo.CHANGE=Промени
-plugin.accountinfo.ONLY_MESSAGE=Само поруке
# connection info
plugin.connectioninfo.TITLE=Инфо повезивања
@@ -903,49 +853,12 @@ plugin.aimaccregwizz.USERNAME=AIM надимак:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Ðадимак и лозинка
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=РегиÑтруј нови налог
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=У Ñлучају да немате AIM налог, кликните на дугме за креирање новог.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Препиши подразумеване поÑтавке Ñервера
# branding
plugin.branding.ABOUT_WINDOW_TITLE=О {0}
plugin.branding.LOGO_MESSAGE=VoIP && инÑтант поруке отвореног кода
-plugin.branding.LOADING=Учитавам
plugin.branding.ABOUT_MENU_ENTRY=&О
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>Тренутно {1} је под активним развојем. Верзија коју Ñте поктенули је екÑпериментална и МОЖДРÐЕЋЕ радити као што очекујете. Молим погледајте {2} за више информација.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 Copyright <b>jitsi.org</b>. Сва права задржана. ПоÑетите <a href="https://jitsi.org">https://jitsi.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}><b>Jitsi</b> је диÑтрибуиран под уÑловима LGPL (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=Речници
-plugin.dictaccregwizz.ANY_DICTIONARY=Било који речник
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Било који речник од {0}
-plugin.dictaccregwizz.FIRST_MATCH=Први погодак
-plugin.dictaccregwizz.NO_MATCH=Без подударања
-plugin.dictaccregwizz.MATCH_RESULT=Без дефиниције нађене за "{0}", можда Ñте миÑлили:\n
-plugin.dictaccregwizz.INVALID_DATABASE=Тренутни речник "{0}" не поÑтоји било где на Ñерверу.
-plugin.dictaccregwizz.INVALID_STRATEGY=Тренутна Ñтратегија није доÑтупна на Ñерверу.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=Протокол Dict ÑервиÑа
-plugin.dictaccregwizz.HOST=Рачунар
-plugin.dictaccregwizz.SERVER_INFO=Подаци Ñервера
-plugin.dictaccregwizz.STRATEGY_SELECTION=Strategy Ñелекција
-plugin.dictaccregwizz.STRATEGY_LIST=ЛиÑта Ñтратегија:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Претрага Ñтратегија
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=Стратегија Ñе кориÑти за тражење Ñличних речи, ако превод није пронађен, захваљујући различитим приÑтупима. Ðа пример, Ð¿Ñ€ÐµÑ„Ð¸ÐºÑ Ñтратегије ће потражити речи које почињу као реч коју би превели.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Dict подаци о налогу
-plugin.dictaccregwizz.FIRST_ACCOUNT=Чаробњак ће креирати ваш први Dict налог за dict.org.\n\nМожете додати нови речник преко чаробњака за региÑтрацију. Попуните поље Ñа речником који желите да додате.
-plugin.dictaccregwizz.THREAD_CONNECT=Повезивање Ñа Ñервером
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=ÐеуÑпео покушај повезивања, то није dict Ñервер или је Ñервер ван мреже.
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=Довлачим Ñтратегије
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Стратегија није нађена на Ñерверу
-plugin.dictaccregwizz.POPULATE_LIST=ЛиÑта наÑељавања
-plugin.dictaccregwizz.CLOSING_CONNECTION=Затварање повезивања
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Да би кориÑтили Facebook ћаÑкање потребно је креирати "КориÑничко име" <br>на вашем "Подешавању налога" на Facebook.</a><br><br>Ðапомена: Кад креирате кориÑничко име морате Ñе одјавити Ñа веб Ñтране <br>и то може потрајати пре него што Ñе пријавите Ñа Ñвојим новим кориÑничким именом!</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=Протокол Facebook ћаÑкања
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=КориÑничко име:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=КориÑничко име и лозинка
+
# generalconfig
plugin.generalconfig.AUTO_START=ÐутоматÑки покрени {0} када Ñе рачунар поново покреће
@@ -956,9 +869,6 @@ plugin.generalconfig.SHOW_HISTORY=Прикажи
plugin.generalconfig.HISTORY_SIZE=недавне поруке у новим ћаÑкањима
plugin.generalconfig.SEND_MESSAGES_WITH=Пошаљи поруке Ñа:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=ПоÑтави напред прозор за ћаÑкање
-plugin.generalconfig.ERROR_PERMISSION=Ðемате довољно овлашћења у уклоните аутоÑтарт
-plugin.generalconfig.TRANSPARENCY=ПровидноÑÑ‚
-plugin.generalconfig.ENABLE_TRANSPARENCY=Омогући провидноÑÑ‚
plugin.generalconfig.DEFAULT_LANGUAGE=Језик Ñучеља
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Ваше промене ће бити примењене при Ñледећем покретању.
plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0}% преведено
@@ -1006,11 +916,9 @@ plugin.ircaccregwizz.IRC_SERVER=Сервер
plugin.ircaccregwizz.USE_SECURE_CONNECTION=КориÑти безбедну везу
# jabber accregwizz
-plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=XMPP протокол
plugin.jabberaccregwizz.USERNAME=XMPP надимак
plugin.jabberaccregwizz.PASSWORD_CONFIRM=Потврди лозинку
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=ИД или лозинка
plugin.jabberaccregwizz.CSERVER=Сервер
plugin.jabberaccregwizz.SERVER=Повезивање Ñа Ñервером
plugin.jabberaccregwizz.ENABLE_GMAIL_NOTIFICATIONS=Омогући Gmail обавештења за нове поруке
@@ -1025,13 +933,9 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Ðапомена
plugin.jabberaccregwizz.RESOURCE=РеÑурÑ
plugin.jabberaccregwizz.AUTORESOURCE=ÐутоматÑки генериши реÑурÑе
plugin.jabberaccregwizz.PRIORITY=Приоритет
-plugin.jabberaccregwizz.XMPP_ERROR=XMPP грешка
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Ðепозната XMPP грешка ({0}). Провери да ли је име Ñервера иÑправно.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Ваше лозинке Ñе не подударају.
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Препиши подразумеване поÑтавке Ñервера
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Ðапредне поÑтавке
plugin.jabberaccregwizz.USE_ICE=КориÑти ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=КориÑти Google's Jingle/ICE (екÑпериментално)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=ÐутоматÑка претрага STUN/TURN Ñервера
plugin.jabberaccregwizz.SUPPORT_TURN=TURN подршка
plugin.jabberaccregwizz.TURN_USERNAME=TURN кориÑничко име
@@ -1055,11 +959,8 @@ plugin.jabberaccregwizz.ALLOW_NON_SECURE=Омогући небезбедна пÐ
plugin.jabberaccregwizz.DTMF_AUTO=Ðуто: одаберите аутоматÑки између RTP и Inband
plugin.jabberaccregwizz.SERVER_OPTIONS=Опције Ñервера
plugin.jabberaccregwizz.CHANGE_PASSWORD=Промени лозинку налога
-plugin.jabberaccregwizz.NEW_PASSWORD=Ðова лозинка
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Потврди нову лозинку
plugin.jabberaccregwizz.PORT_FIELD_INVALID=Молим попуните иÑправан број порта како би наÑтавили.
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=Ваш налог мога бити пријављен пре промене лозинке.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=Лозинка је празна.
plugin.jabberaccregwizz.TLS_REQUIRED=Веза не кориÑти TLS, неће покушати промену лозинке.
plugin.jabberaccregwizz.PASSWORD_CHANGED=Лозинка је уÑпешно промењена
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=Ваш XMPP Ñервер не подржава промену лозинке.
@@ -1073,24 +974,9 @@ plugin.jabberaccregwizz.RESET=Поврати
plugin.jabberaccregwizz.RESET_DESCRIPTION=РеÑетуј општа подешавања
plugin.jabberaccregwizz.DISABLE_JINGLE=Онемогући Jingle (звучни и видо позиви Ñа XMPP).
-# mailbox
-plugin.mailbox.OUTGOING=Одлазна порука:
-plugin.mailbox.INCOMING=Долазна порука:
-plugin.mailbox.MAX_MESSAGE_TIME=МакÑимално трајање долазних порука
-plugin.mailbox.CONFIRM=Потврди
-plugin.mailbox.DEFAULTS=Подразумевано
-plugin.mailbox.MAILBOX=Сандуче
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=МСÐ
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Протокол за повезивање и ћаÑкање на МСРÑервиÑу.
-plugin.msnaccregwizz.USERNAME=Е-пошта:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=ИД и лозинка
-
# plugin manager
plugin.pluginmanager.INSTALL=ИнÑталирај
plugin.pluginmanager.UNINSTALL=ДеинÑталирај
-plugin.pluginmanager.UPDATE=Ðжурирај
plugin.pluginmanager.PLUGINS=Прикључци
plugin.pluginmanager.URL=ÐдреÑа
plugin.pluginmanager.CHOOSE_FILE=Одабери фајл
@@ -1115,7 +1001,6 @@ plugin.sipaccregwizz.SERVER_PORT=Порт Ñервера
plugin.sipaccregwizz.PROXY=ПрокÑи
plugin.sipaccregwizz.PROXY_PORT=ПрокÑи порт
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Жељени превоз
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Ðапредне опције
plugin.sipaccregwizz.PROXY_OPTIONS=Опције прокÑија
plugin.sipaccregwizz.PROXY_AUTO=ПодеÑи прокÑи аутоматÑки
plugin.sipaccregwizz.ENABLE_PRESENCE=Омогући приÑуÑтво (ЈЕДÐОСТÐÐ’ÐО)
@@ -1133,8 +1018,6 @@ plugin.sipaccregwizz.DTMF_METHOD=ДТМФ метод
plugin.sipaccregwizz.DTMF_AUTO=Ðуто: Одаберите аутоматÑки између RTP и Inband (без SIP инфа)
plugin.sipaccregwizz.DTMF_RTP=RTP ( RFC2833 / RFC 4733 )
plugin.sipaccregwizz.DTMF_SIP_INFO=SIP подаци
-plugin.sipaccregwizz.REGISTER=РЕГИСТÐР
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Препиши подразумеване опције Ñервера
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Омогући подршку за заштићене позиве
plugin.sipaccregwizz.AUTH_NAME=Име за пријаву
plugin.sipaccregwizz.DISPLAY_NAME=Приказно име
@@ -1154,6 +1037,7 @@ plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=Повера URI говорном поÑ
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Ваша лозинка Ñе не подудара.
plugin.sipaccregwizz.NO_CERTIFICATE=<ништа> (кориÑти званичну идентификацију)
plugin.sipaccregwizz.SAVP_OPTION=RTP/SAVP индикација
+#used from SecurityPanel
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=Изаберите омогућене протоколе шифровања и њихов приоритет (прво горњи протокол):
plugin.sipaccregwizz.CIPHER_SUITES=Омогућено шифровање:
plugin.sipaccregwizz.SHOW_ADVANCED=Ðапредна подешавања енкрипције
@@ -1166,15 +1050,6 @@ plugin.skinmanager.DEFAULT_SKIN=Подразумевани мотив
plugin.skinmanager.ADD_NEW_SKIN=Додај нови мотив...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=Подразумевани мотив апликације.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=ССХ
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=Протокол за повезивање удаљеног рачунара преко ССХ.
-plugin.sshaccregwizz.USERNAME=ИД налога:
-plugin.sshaccregwizz.IDENTITY_FILE=Идентификациони фајл:
-plugin.sshaccregwizz.KNOWN_HOSTS=Позната имена рачунара:
-plugin.sshaccregwizz.OPTIONAL=Опционо
-plugin.sshaccregwizz.ACCOUNT_DETAILS=Детаљи налога
-
# status update
plugin.autoaway.AUTO_STATUS=ÐутоматÑка одÑутноÑÑ‚
plugin.autoaway.ENABLE_CHANGE_STATUS=Промени ÑÑ‚Ð°Ñ‚ÑƒÑ Ñƒ одÑутноÑти
@@ -1220,22 +1095,6 @@ plugin.whiteboard.DESELECT=Поништи избор
plugin.whiteboard.DELETE=Обриши
plugin.whiteboard.PROPERTIES=СвојÑтва
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Протоко за повезивање и ћаÑкање на Yahoo! ÑервиÑу.
-plugin.yahooaccregwizz.USERNAME=КориÑничко име:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=ИД и лозинка
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=Zeroconf (Bonjour) протокол ÑервиÑа.
-plugin.zeroaccregwizz.FIRST_NAME=Име:
-plugin.zeroaccregwizz.LAST_NAME=Презиме:
-plugin.zeroaccregwizz.EMAIL=Е-пошта:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=Запамти Bonjour контакти?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=ИД и Лозинка
-plugin.zeroaccregwizz.USERID=КориÑников ИД
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Google Talk протокол
@@ -1249,19 +1108,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, ИП телекомуни
plugin.iptelaccregwizz.USERNAME=КориÑничко име
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=Претплата на iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.подаци
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIP и ћаÑкање
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=КориÑничко име
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Потврда лозинке
plugin.sip2sipaccregwizz.EMAIL=ÐдреÑа е-поште
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=За помоћ за овај ÑÐµÑ€Ð²Ð¸Ñ Ð¿Ð¾Ñетите<br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>ÐдреÑа е-поште Ñе кориÑти за Ñлање глаÑовних порука, <br>пропуштених позива и опоравак изгубљених лозинки</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>За помоћ у вези овог ÑервиÑа поÑетите <a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=ПоÑтојећи sip2sip.info налог
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Креирај беÑплатан sip2sip.info налог
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP && инÑтант поруке
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=За помоћ око овог ÑервиÑа поÑетите<br>http://ippi.fr
@@ -1270,6 +1121,7 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=ПоÑтојећи ippi налог
plugin.ippiaccregwizz.CREATE_ACCOUNT=Креирај беÑплатан ippi налог
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Затвори прозор за ћаÑкање
plugin.keybindings.CHAT_COPY=Умножи
plugin.keybindings.CHAT_CUT=ИÑеци
@@ -1292,10 +1144,10 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=Име
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=Примарна пречица
plugin.keybindings.globalchooser.SHORTCUT_SECOND=Секундарна пречица
plugin.keybindings.globalchooser.PRESS_BTN=ПритиÑни за подешавање пречице
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=Чекање
plugin.keybindings.globalchooser.PUSH_TO_TALK=Гурни за разговор
plugin.keybindings.globalchooser.ENABLE_SPECIAL=Омогући детекцију Ñпецијалног кључа
plugin.keybindings.PLUGIN_NAME=Пречице
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=ЋаÑкање
plugin.keybindings.MAIN=Главно
plugin.keybindings.GLOBAL=Опште пречице
@@ -1323,6 +1175,7 @@ plugin.notificationconfig.tableheader.SOUND=ПуÑти звук преко урÐ
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=ПуÑти звук преко уређаја за емитовање
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=ПуÑти збук преко ПЦ звучника
plugin.notificationconfig.tableheader.DESCRIPTION=ÐžÐ¿Ð¸Ñ Ð´Ð¾Ð³Ð°Ñ’Ð°Ñ˜Ð°
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Долазни позив
plugin.notificationconfig.event.SecurityMessage=Безбедна порука
plugin.notificationconfig.event.IncomingFile=Долазни фајл
@@ -1419,6 +1272,7 @@ impl.neomedia.configform.VIDEO=Видео
impl.neomedia.configform.H264=H.264
impl.neomedia.configform.H264.defaultIntraRefresh=Периодично оÑвежавање
impl.neomedia.configform.H264.defaultProfile=Подразумевани профил за декодирање у:
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=Подножје
impl.neomedia.configform.H264.defaultProfile.high=ВиÑоко
impl.neomedia.configform.H264.defaultProfile.main=Главно
@@ -1448,7 +1302,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=Тренутна лозиÐ
plugin.securityconfig.masterpassword.ENTER_PASSWORD=УнеÑи нову лозинку:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Поново унеÑи лозинку:
plugin.securityconfig.masterpassword.MP_TITLE=Главна лозинка
-plugin.securityconfig.masterpassword.MP_NOT_SET=(није подешено)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=ÐиÑте унели иÑправну главну лозинку. Молим пробајте поново.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=Главна лозинка није иÑправна!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=ÐеуÑпела промена лозинке
@@ -1464,7 +1317,6 @@ plugin.securityconfig.masterpassword.COL_PASSWORD=Лозинка
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(непознато)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(не може да дешифрује)
plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=Сачуване лозинке
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=Уклони
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=Уклони Ñве
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=Да ли Ñте Ñигурни да желите да уклоните Ñве лозинке?
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=Уклони Ñве лозинке
@@ -1549,7 +1401,6 @@ plugin.globalproxy.PROXY_ADDRESS=ПрокÑи Ñервер
plugin.globalproxy.PROXY_PORT=ПрокÑи порт
plugin.globalproxy.PROXY_USERNAME=ПрокÑи кориÑничко име
plugin.globalproxy.PROXY_PASSWORD=ПрокÑи лозинка
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>XMPP</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
plugin.globalproxy.FWD_DNS=ПрокÑи ДÐС
plugin.globalproxy.FWD_DNS_ADDR=ДÐС прокÑи адреÑа
@@ -1585,7 +1436,6 @@ plugin.provisioning.RESTART_WARNING=Ðапомена да ће промене б
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=Умноћи UUID у клипборд
plugin.provisioning.CLIPBOARD_FAILED=ÐеуÑпело умножавање UUID у клипборд
-plugin.provisioning.EXIT_ON_FAIL=Затвори апликацију ако не уÑпе резервиÑање
plugin.provisioning.CREDENTIALS=ПоÑледњи Ñачувани резервни акредитиви
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=Да ли Ñте Ñигурни да желите да уклоните резервну лозинку?
plugin.provisioning.PROV_FAILED=РезервиÑање није уÑпело
@@ -1644,8 +1494,6 @@ net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult
#plugin spellcheck
plugin.spellcheck.TITLE=Провера пиÑања и правопиÑа
plugin.spellcheck.MENU=Прикажи проверу пиÑања и правопиÑа
-plugin.spellcheck.LANG=Језик
-plugin.spellcheck.EDIT_PERSONAL_DICT=Уреди
plugin.spellcheck.ENABLE_SPELL_CHECK=Омогући проверу правопиÑа
plugin.spellcheck.dialog.FIND=Пронађи Ñледеће
plugin.spellcheck.dialog.REPLACE=Замени
diff --git a/resources/languages/resources_sv.properties b/resources/languages/resources_sv.properties
index f0ce7a6..cd9ba06 100644
--- a/resources/languages/resources_sv.properties
+++ b/resources/languages/resources_sv.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Jag
service.gui.ACCOUNT_REGISTRATION_WIZARD=Registreringsguide
service.gui.ACCOUNTS=Konton
service.gui.ADD=&Lägg till
-service.gui.ADD_ACCOUNT=Lägg till konto
service.gui.ADD_CONTACT=&Lägg till kontakt
service.gui.ADD_AUTHORIZED_CONTACT=Lägg till {0} i din kontaktlista
service.gui.ADD_CONTACT_TO_CONTACTLIST=Lägg till kontakten i din kontaktlista
@@ -42,20 +52,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Fel när kontakt lades till
service.gui.ADD_CONTACT_EXIST_ERROR={0} finns redan i din kontaktlista.
service.gui.ADD_CONTACT_NETWORK_ERROR=Servern svarade inte vid begäran om att lägga till kontakten {0}.
service.gui.ADD_CONTACT_NOT_SUPPORTED=Kunde inte lägga till kontakt med id: {0}. Åtgärden stöds inte.
-service.gui.ADD_CONTACT_IDENTIFIER=Ange identifierare för den kontakt du vill lägga till i fältet nedan.
-service.gui.ADD_CONTACT_WIZARD=Guide för att lägga till kontakt
service.gui.ADD_CONTACT_NOT_CONNECTED=Du måste vara ansluten för att lägga till kontakter. Logga in hos den valda leverantören och försök igen.
service.gui.ADD_GROUP_LOCAL_ERROR=Kunde inte lägga till gruppnamnet: {0}. Problemet uppstod under en lokal I/O-åtgärd.
service.gui.ADD_GROUP_EXIST_ERROR={0} finns redan i din kontaktlista. Välj ett annat gruppnamn.
service.gui.ADD_GROUP_NET_ERROR=Kunde inte lägga till gruppnamnet: {0}. Problemet uppstod på grund av ett nätverksfel. Kontrollera din nätverksanslutning och försök igen.
service.gui.ADD_GROUP_ERROR=Kunde inte lägga till grupp med namn: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=Gruppnamnet får inte lämnas tomt.
-service.gui.ADD_GROUP=Skapa grupp
-service.gui.ADD_SUBCONTACT=&Lägg till underkontakt
service.gui.ADDRESS=Adress
service.gui.ADMINISTRATOR=administratör
service.gui.ADVANCED=&Avancerat
-service.gui.ALL=&Alla
service.gui.ALL_CONTACTS=&Alla kontakter
service.gui.ALTERNATE_ADDRESS=Alternativ adress
service.gui.APPLY=&Verkställ
@@ -65,7 +70,6 @@ service.gui.AT=på
service.gui.AUTHORIZE=&Auktorisera
service.gui.AUTHORIZATION_ACCEPTED={0} har godkänt din auktoriseringsbegäran.
service.gui.AUTHENTICATION_FAILED=Autentisering av {0} misslyckades. Lösenordet är felaktigt.
-service.gui.AUTHENTICATION_REQUESTED=Auktorisering begärd
service.gui.AUTHENTICATION_REQUESTED_SERVER=Servern {0} begär att du autentiserar dig.
service.gui.AUTHENTICATION_REJECTED={0} har nekat din begäran om auktorisering.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} autentisering
@@ -107,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=I nedanstående fält kan du ange ditt nya anv
service.gui.CHANGE_NICKNAME_ERROR=Kunde inte byta användarnamn
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Användarnamnet finns redan
service.gui.CHANGE_VIDEO_QUALITY=Ändra videokvalitet
-service.gui.CHAT_CONFERENCE_LABEL=Konferenser
service.gui.CHAT_CONFERENCE_ITEM_LABEL={0}s konferens
service.gui.CHAT_ROOM_ALREADY_JOINED={0} är redan anslutet.
service.gui.CHAT_ROOM_CONFIGURATION=Konfiguration för {0}
@@ -121,18 +124,14 @@ service.gui.CHAT_ROOM_USER_LEFT=har lämnat {0}
service.gui.CHAT_ROOM_USER_KICKED=har kickats från {0}
service.gui.CHAT_ROOM_USER_QUIT=har kopplat ner {0}
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=Skicka meddelanden är inte tillåtet (återkallat)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Sparar chattrummet för framtida bruk
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Ta bort markerat rum från listan över sparade chattrum
service.gui.CHAT_ROOM_NAME=Namn på chattrum
service.gui.CLEAR_CUSTOM_MESSAGES=Rensa anpassade meddelanden
service.gui.ROOM_NAME=Chattrum
-service.gui.AUTOJOIN=Anslut automatiskt
service.gui.CHANGE_PASSWORD=Ändra lösenord
service.gui.CHAT_ROOM_NAME_INFO=Ange namnet på det chattrum du vill skapa, i nedanstående fält.
service.gui.CHAT_ROOM_NOT_EXIST={0} kunde inte hittas på {1}. Kontrollera att du angett rätt namn.
service.gui.CHAT_ROOM_NOT_CONNECTED=Du måste vara inloggad för att kunna ansluta till {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Du måste vara inloggad för att kunna lämna ett chattrum.
-service.gui.CHAT_ROOM_NOT_JOINED=Du måste vara ansluten till ett chattrum för att kunna vidta ytterligare åtgärder med det.
service.gui.CHAT_ROOM_OPTIONS=Alternativ för chattrum
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED={0} kräver registrering för att ansluta.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=Chattrummet {0} begär ett lösenord.
@@ -151,22 +150,18 @@ service.gui.CLEAR=Rensa
service.gui.CLOSE=St&äng
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=Det kom ett nytt meddelande för mindre än 2 sekunder sedan. Vill du verkligen stänga den här chatten?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=En eller flera filöverföringar pågår. Vill du verkligen avbryta?
-service.gui.CONFIRM=Bekräfta
service.gui.CONNECTED_STATUS=Ansluten
service.gui.CONNECTING=Ansluter...
service.gui.CONNECTING_STATUS=Ansluter
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Ansluter*
service.gui.CONNECTION=Anslutning
-service.gui.CONNECTION_FAILED_MSG=Anslutningen misslyckades för följande konto: {0}, Servernamn: {1}, Kontollera din nätverksanslutning eller kontakta din nätverksadministratör för mer information.
service.gui.CONNECTION_EXPIRED_MSG=Du är för närvarande bortkopplad från servern {0}.
service.gui.CONTACT_NAME=ID eller nummer
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY={0} saknar stöd för telefoni.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF={0} saknar stöd för chattkonferenser.
service.gui.CONTACT_PAUSED_TYPING={0} tog paus i skrivandet
service.gui.CONTACT_TYPING={0} skriver ett meddelande
service.gui.CONTACT_TYPING_SEND_FAILED=öööh... vi kunde inte meddela {0} att du skrev
service.gui.CONTACT_INFO=&Kontaktinfo
-service.gui.CONTACTLIST=Kontaktlista
service.gui.CONTACTS=Kontakter
service.gui.COPY=&Kopiera
service.gui.COPY_LINK=Kopiera &länk
@@ -176,17 +171,14 @@ service.gui.CREATE_CHAT_ROOM=&Skapa chattrum...
service.gui.CREATE_CHAT_ROOM_ERROR=Kunde inte skapa chattrummet {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=Chattrumsguide
service.gui.CREATE_CONFERENCE_CALL=&Skapa ett konferenssamtal...
-service.gui.CREATE_CONFERENCE_CHAT=&Skapa en konferenschatt...
service.gui.CREATE_GROUP=&Skapa grupp...
service.gui.CREATE_GROUP_NAME=Ange namnet på den grupp du vill skapa, i nedanstående fält.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Din kontaktlista innehåller inga grupper. Skapa en grupp först (Arkiv/Skapa grupp).
service.gui.CREATE_VIDEO_BRIDGE=Skapa en &videolänk...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Skapa en &videolänk
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Skapa / Anslut videokonferens
service.gui.CREATE_VIDEO_CONFERENCE=Skapa ny videkonferens för detta chattrum
service.gui.CONTACT_INFO_NOT_SUPPORTED=Den här kontakten saknar stöd för webbkontaktinfo
service.gui.CUT=K&lipp ut
-service.gui.DATE=Datum
service.gui.DELETE=Ta bort
service.gui.DENY=&Neka
service.gui.DESKTOP_SHARING_WARNING=<b>Vill du verkligen starta skärmdelning?</b> <br>Klickar du OK, kommer deltagare i den här konversationen att kunna se din skärm.
@@ -197,7 +189,6 @@ service.gui.DISCONNECTED_STATUS=Frånkopplad
service.gui.DND_STATUS=Stör ej
service.gui.DO_NOT_ASK_AGAIN=Fråga inte igen
service.gui.DO_NOT_SHOW_AGAIN=Visa inte det här meddelandet igen
-service.gui.DOWNLOAD_NOW=&Ladda ner nu
service.gui.DRAG_FOR_SHARING=Dra och släpp det du vill dela...
service.gui.DURATION=varaktighet
service.gui.DESTROY_CHATROOM=Ta bort chattrum
@@ -218,7 +209,6 @@ service.gui.ERROR_RECEIVED_FROM=Fel från {0}
service.gui.ESTIMATED_TIME=Uppskattad tid:
service.gui.EVENTS=Händelser
service.gui.EXIT=A&vsluta
-service.gui.EXTENDED_CRITERIA=Utökade kriterier
service.gui.GENERAL=Allmänt
service.gui.GENERAL_ERROR=Allmänt fel
service.gui.GROUP_NAME=Gruppnamn
@@ -260,7 +250,6 @@ service.gui.FONT_ITALIC=Kursiv
service.gui.FONT_SIZE=Storlek
service.gui.FONT_STYLE=Stil
service.gui.FONT_UNDERLINE=Understruken
-service.gui.FROM={0} från {1}
service.gui.GRANT_OWNERSHIP=Bevilja ägarskap...
service.gui.GRANT_ADMIN=Bevilja administratörsbefogenhet...
service.gui.GRANT_MODERATOR=Bevilja moderatorsbefogenhet
@@ -286,7 +275,6 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=Vill du verkligen ta bort alla lokalt lag
service.gui.HISTORY_REMOVE_ERROR=Kunde inte ta bort lokalt lagrade meddelanden.
service.gui.HOME=Hem
service.gui.HOME_PAGE=Hemsida
-service.gui.HOUR=Timma
service.gui.ICE=ICE
service.gui.IDENTIFIER=Identifierare
service.gui.IGNORE=&Ignorera
@@ -310,13 +298,10 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Bjud in kontakter till videolänk
service.gui.INVITE_REASON=Inbjudningsorsak
service.gui.IS_CALLING={0} ringer...
service.gui.IS_NOW={0} är nu {1}
-service.gui.JITSI_WARNING=SIP Communicator har nyligen bytt namn till Jitsi.<br/>Ladda ner Jitsi nu, om du vill att din version skall vara fortsatt aktuell.<br/><br/>Vi är ledsna för alla eventuella besvär som detta kan orsaka dig. <br/><br/>The Jitsi Dev Team
-service.gui.JITSI_WARNING_TITLE=SIP Communicator blir Jitsi
service.gui.JOIN=&Anslut
service.gui.JOIN_AS=A&nslut som
service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=Anslut till en pågående videokonferens
service.gui.JOIN_VIDEO=Anslut video
-service.gui.CLOSE_CHAT_ROOM_DIALOG=S&täng
service.gui.JOB_TITLE=Yrkestitel
service.gui.JOIN_CHAT_ROOM=&Anslut till chattrum...
service.gui.JOIN_CHAT_ROOM_TITLE=Anslut till chattrum
@@ -329,7 +314,6 @@ service.gui.KICK_FAILED=Det gick inte att kicka
service.gui.KICK_FAILED_GENERAL_ERROR=Kunde inte kicka {0}. Ett allmänt serverfel uppstod.
service.gui.KICK_FAILED_NOT_ALLOWED=Kunde inte kicka {0}. Ägare och administratörer i chattrummet kan inte kickas.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Kunde inte kicka {0}. Du har inte tillräcklig behörighet för att göra det.
-service.gui.LAST=Senast
service.gui.LAST_NAME=Senaste namnet
service.gui.LEAVE=&Lämna
service.gui.LIMIT_REACHED_FOR_IP=Du har för många befintliga registreringar från din IP-adress och servern {0} tillåter inte att du öppnar fler av dem.
@@ -349,7 +333,6 @@ service.gui.MESSAGE=Meddelande
service.gui.MISSED_CALLS_TOOL_TIP=Missade samtal från:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= och {0} till
service.gui.MODERATOR=moderator
-service.gui.MORE=Läs mer
service.gui.MORE_LABEL=Mer
service.gui.MOVE=Flytta
service.gui.MOVE_SUBCONTACT=F&lytta kontakt
@@ -358,7 +341,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=Den valda kontakten är densamma som källan.
service.gui.MOVE_SUBCONTACT_QUESTION=Vill du verkligen flytta {0} till {1}?
service.gui.MOVE_TO_GROUP=&Flytta till grupp
service.gui.MOVE_CONTACT=Flytta kontakt
-service.gui.MOVE_CONTACT_ERROR=&Kontakten kan inte flyttas
service.gui.MSG_DELIVERY_FAILURE=Meddelandet ovan kunde inte levereras
service.gui.MSG_DELIVERY_NOT_SUPPORTED=Det protokoll du använder, stöder inte offline-meddelanden. Du kan försöka nå {0} genom ett annat protokoll eller vänta tills han/hon är online.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Ett internt fel uppstod. Det är troligen en bugg. Rapportera den gärna här: https://jitsi.org/Development/BugsAndIssues.
@@ -372,7 +354,6 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=Du måste vara ansluten för att skicka
service.gui.MULTIPLE_LOGINS=Du har loggat in mer än en gång med samma konto. Följande konto är nu nerkopplat: Användarnamn: {0}, Servernamn: {1}
service.gui.MY_CHAT_ROOMS=Lägg till chattrum
service.gui.MY_CHAT_ROOMS_TITLE=Lägg till chattrum
-service.gui.MUTE=Ljud av
service.gui.MUTUALLY_ON_HOLD_STATUS=Ömsesidigt parkerad
service.gui.NAME=Namn
service.gui.NETWORK=Nätverk
@@ -404,7 +385,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=Inte på kontaktlistan
service.gui.SD_QUALITY=Standardkvalitet
service.gui.OFFLINE=Offline
service.gui.OK=&OK
-service.gui.OLDER_CALLS=Äldre samtal
service.gui.ONLINE=Online
service.gui.OPEN=Öppna
service.gui.OPEN_FILE_FROM_IMAGE=Dubbelklicka för att öppna en fil.
@@ -416,7 +396,6 @@ service.gui.OPEN_ON_ACTIVITY=Öppna vid aktivitet
service.gui.OPEN_ON_MESSAGE=Öppna enbart vid nytt meddelande
service.gui.OPEN_ON_IMPORTANT_MESSAGE=Öppna enbart vid viktiga meddelanden
service.gui.OR=eller
-service.gui.OR_ENTER_PHONE_NUMBER=Eller ange telefonnummer här...
service.gui.ORGANIZATION=Organisation
service.gui.OTHER=Annat
service.gui.chat.role.OWNER=Ägare
@@ -442,7 +421,6 @@ service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Retur' för förslag
service.gui.PRESS_FOR_CALL_INFO=Tryck för samtalsinfo
service.gui.PRESS_TO_OPEN_CRM=Klicka för att öppna CRM-program
service.gui.PREVIOUS=Föregående
-service.gui.PREVIOUS_TOOLTIP=Bläddra bland äldre konversationer
service.gui.PRINT=&Skriv ut
service.gui.PROACTIVE_NOTIFICATION=skriver ett meddelande
service.gui.PROBLEMS_ENCOUNTERED=Problem som uppstått
@@ -458,7 +436,6 @@ service.gui.RECONNECTION_LIMIT_EXCEEDED=Du har kopplat ner och återanslutit fö
service.gui.RE_REQUEST_AUTHORIZATION=Begär auktorisering igen
service.gui.REFERRED_STATUS=Hänvisning
service.gui.REJECT=&Avböj
-service.gui.REMIND_ME_LATER=PÃ¥minn mig senare
service.gui.REMEMBER_PASSWORD=Kom ihåg lösenordet
service.gui.REMOVE=&Ta bort
service.gui.REMOVE_ACCOUNT=&Ta bort konto
@@ -484,29 +461,20 @@ service.gui.REVOKE_ADMIN=Återkalla administratörstatus
service.gui.REVOKE_MODERATOR=Ã…terkalla moderatorstatus
service.gui.REVOKE_MEMBERSHIP=Ã…terkalla medlemskap
service.gui.REVOKE_VOICE=Återkalla röst
-service.gui.ROOT_GROUP=Root-grupp
service.gui.SAVE=&Spara
-service.gui.SAVE_AS_DEFAULT=Spara som standard
service.gui.SEARCH=&Sök
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Klicka på knappen nedan för att visa alla chattrum på den valda servern. Markera sedan det du vill ansluta till, och tryck på 'Anslut'.
service.gui.SEARCH_STRING_CONTACT_SOURCE=Sökt kontakt
service.gui.SECURITY=Säkerhet
-service.gui.SELECT_ACCOUNT=Välj konto
service.gui.SELECT_COLOR=Välj färg
service.gui.SELECT_GROUP=Välj grupp
-service.gui.SELECT_GROUP_WIZARD_MSG=Nedanstående lista innehåller alla grupper i din kontaktlista. Välj i vilken grupp du vill lägga till den nya kontakten.
service.gui.SELECT_NO_GROUP=Ingen grupp
-service.gui.SELECT_GROUP_WIZARD=Specificera grupp
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=Nedanstående lista innehåller alla konton som stöder fleranvändarchatt. Välj vilket du vill använda för att skapa ditt chattrum.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=Nedanstående lista innehåller alla registrerade konton. Välj vilket du vill använda för att kommunicera med den nya kontakten.
-service.gui.SELECT_PROVIDERS_WIZARD=Välj konto
service.gui.SELECT_VIDEO_CONFERENCE=Välj videokonferens
service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=Välj chatt från listan och tryck OK för att lägga till den.
service.gui.SEND=&Skicka
service.gui.SEND_FILE=Skicka &fil
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Det finns ingen info om den här kontakten.
service.gui.SEND_MESSAGE=&Skicka ett meddelande
-service.gui.SEND_AS_SMS=Skicka som SMS
service.gui.SEND_PRIVATE_MESSAGE=Skicka privat meddelande
service.gui.SEND_SMS=S&kicka SMS
service.gui.SEND_SMS_DETAILS=Kom ihåg att du måste ange numret i internationellt format med inledande landskod (+46 för Sverige). Exempel: +4670123456
@@ -545,7 +513,6 @@ service.gui.STREET=Gatuadress
service.gui.SUBJECT=Ämne
service.gui.SUMMARY=Sammandrag
service.gui.TELEPHONY=Telefoni
-service.gui.TODAY=I dag
service.gui.TOOLS=&Verktyg
service.gui.TRANSFER=&Överför
service.gui.TO=&Till:
@@ -555,7 +522,6 @@ service.gui.TRANSFER_CALL_TO=Överför till:
service.gui.TRANSPARENCY_NOT_ENABLED=Transparens stöds inte av din aktuella konfiguration.
service.gui.TYPE_YOUR_REQUEST=Ange din begäran här
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Videokvaliteten kunde inte ändras för det här samtalet.
-service.gui.UNMUTE=Ljud på
service.gui.USER_IDENTIFIER=Användaridentifierare:
service.gui.USER_EXISTS_ERROR=Den här användaren finns redan på det valda nätverket. Välj annan användare eller nätverk.
service.gui.USERNAME_NULL=Ange användarnamn och lösenord.
@@ -568,7 +534,6 @@ service.gui.USE_PROVISIONING=Använd online-etablering
service.gui.VALUE=Värde
service.gui.VIDEO_CALL=&Videosamtal
service.gui.VIA=via
-service.gui.VIA_SMS=Via SMS
service.gui.VIEW=&Visa
service.gui.VIEW_HISTORY=Visa &historik
service.gui.VIEW_SMILEYS=Visa &smileys
@@ -588,9 +553,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=Justera volymen
service.gui.WAITING_AUTHORIZATION=Väntar på auktorisation
service.gui.WARNING=Varning
service.gui.YES=Ja
-service.gui.YESTERDAY=I går
-service.gui.EXISTING_ACCOUNT_ERROR=Kontot du angett är redan installerat.
-service.gui.NEW_MAIL=<b>Du har ett nytt e-postmeddelande!</b><br/><b>Från:</b> {0} {1} <br/><b>Ämne:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=Det finns ett nytt e-postmeddelande i din {0} <a href="{1}">inbox</a>:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=Det finns {2} nya e-postmeddelande i din {0} <a href="{1}">inbox</a>:<br/>
service.gui.NEW_GMAIL_FOOTER=ett till oläst meddelande i din <a href="{0}">inbox</a>.<br/>
@@ -602,6 +564,8 @@ service.gui.ENTER_FULL_SCREEN_TOOL_TIP=Helskärmsläge
service.gui.EXIT_FULL_SCREEN_TOOL_TIP=Fönsterläge
service.gui.HOLD_BUTTON_TOOL_TIP=Parkera/Ã…teruppta
service.gui.MUTE_BUTTON_TOOL_TIP=Använd paus eller parkeringsknappen för att aktivera/avaktivera mikrofonljudet
+service.gui.PARK=Parkera
+service.gui.PARK_BUTTON_TOOL_TIP=Parkera samtal
service.gui.RECORD_BUTTON_TOOL_TIP=Spela in/Stoppa
service.gui.LOCAL_VIDEO_BUTTON_TOOL_TIP=Video på/av
service.gui.SHOW_LOCAL_VIDEO_BUTTON_TOOL_TIP=Visa/Dölj lokal video
@@ -614,7 +578,6 @@ service.gui.SECURITY_ERROR=Säkerhetsfel
service.gui.SPEED=Hastighet:
service.gui.SILENT_MEMBER=tyst medlem
service.gui.NON_SECURE_CONNECTION=Säker anslutning kan inte skapas för {0}. Om du vill ansluta till en icke säker server, måste du bocka för "Tillåt osäkra anslutningar" i dina kontoinställningar
-service.gui.UPDATE=Uppdatera
service.gui.MOBILE_PHONE=Mobil
service.gui.VIDEO_PHONE=Video
service.gui.WORK_PHONE=Arbete
@@ -649,12 +612,10 @@ service.gui.callinfo.CALL_INFORMATION=Samtalsinformation
service.gui.callinfo.CALL_IDENTITY=Identitet
service.gui.callinfo.PEER_COUNT=Antal deltagare
service.gui.callinfo.IS_CONFERENCE_FOCUS=Konferensfokus
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Kryptering aktiverad
service.gui.callinfo.CALL_TRANSPORT=Signalerar samtalsöverföring
service.gui.callinfo.CALL_DURATION=Samtalets varaktighet
service.gui.callinfo.TLS_PROTOCOL=TLS-protokoll
service.gui.callinfo.TLS_CIPHER_SUITE=TLS-chifferlista
-service.gui.callinfo.TLS_SERVER_CERTIFICATE_CHAIN=Certifikatkedja för TLS-server
service.gui.callinfo.TLS_CERTIFICATE_CONTENT=Innehållet i TLS servercertifikatet visas nedan.
service.gui.callinfo.VIEW_CERTIFICATE=Visa certifikat
service.gui.callinfo.CODEC=Codec /Frekvens
@@ -664,7 +625,6 @@ service.gui.callinfo.AUDIO_INFO=Ljudinfo
service.gui.callinfo.VIDEO_INFO=Videoinfo
service.gui.callinfo.LOCAL_IP=Lokalt IP / Port
service.gui.callinfo.REMOTE_IP=Fjärr-IP / Port
-service.gui.callinfo.BANDWITH=Bandbredd
service.gui.callinfo.LOSS_RATE=Förlustfrekvens
service.gui.callinfo.RTT=RTT
service.gui.callinfo.JITTER=Jitter
@@ -674,10 +634,13 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=Key exchange protocol
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=ICE-kandidat utökad typ
service.gui.callinfo.ICE_STATE=ICE processtatus
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=Insamlingskandidater
service.gui.callinfo.ICE_STATE.RUNNING=Anslutningskontroller
service.gui.callinfo.ICE_STATE.COMPLETED=Slutförd
service.gui.callinfo.ICE_STATE.FAILED=Misslyckades
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=Lokalt värd-IP / Port
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=Lokalt reflexivt IP / Port
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=Lokalt reläat IP / Port
@@ -698,11 +661,12 @@ service.gui.ALWAYS_TRUST=Lita alltid på det här certifikatet
service.gui.CERT_DIALOG_TITLE=Verifiera certifikat
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} kan inte verifiera serverns identitet vid anslutning till<br><b>{1}</b>.<br><br>Certifikatet är inte betrott, vilket innebär att serverns identitet inte kan verifieras automatiskt<br><br>Vill du tillåta anslutningen?<br>Klicka på ''Visa certifikat'' för mer information.</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0} kan inte verifiera serverns certifikat.<br><br>Certifikatet är inte betrott, vilket innebär att serverns identitet inte kan verifieras automatiskt. <br>Vill du tillåta anslutningen?<br><br>Klicka på ''Visa certifikat'' för mer information.</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} kan inte verifiera identiteten för anslutande klient.<br><br>Certifikatet är inte betrott, vilket innebär att klientens identitet inte kan<br>verifieras automatiskt. Vill du tillåta anslutningen?<br><br>Klicka på ''Visa certifikat'' för mer information.</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} kan inte verifiera identiteten för {1}.<br><br>Certifikatet är inte betrott, vilket innebär att peer-identitet inte kan<br>verifieras automatiskt. Vill du tillåta anslutningen?<br><br>Klicka på ''Visa certifikat'' för mer information.</html>
service.gui.CONTINUE_ANYWAY=Fortsätt ändå
service.gui.CERT_INFO_CHAIN=Certifikatkedja:
service.gui.CERT_INFO_ISSUED_TO=Utfärdat till
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Nätverksnamn:
service.gui.CERT_INFO_O=Organisation:
service.gui.CERT_INFO_C=Land:
@@ -721,12 +685,10 @@ service.gui.CERT_INFO_SIGN_ALG=Signaturalgoritm:
service.gui.CERT_INFO_PUB_KEY_INFO=Information om publik nyckel
service.gui.CERT_INFO_ALG=Algoritm:
service.gui.CERT_INFO_PUB_KEY=Publik nyckel:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} byte: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} bitar
service.gui.CERT_INFO_EXP=Exponent:
service.gui.CERT_INFO_KEY_SIZE=Nyckelstorlek:
service.gui.CERT_INFO_SIGN=Signatur:
-service.gui.CONTINUE=Fortsätt
service.gui.SHOW_CERT=Visa certifikat
service.gui.HIDE_CERT=Dölj certifikat
@@ -749,12 +711,9 @@ service.gui.security.SECURE_AUDIO=Säker ljudlänk
service.gui.security.AUDIO_NOT_SECURED=Ljudlänk ej säker
service.gui.security.SECURE_VIDEO=Säker videolänk
service.gui.security.VIDEO_NOT_SECURED=Videolänk ej säker
-service.gui.security.NO_VIDEO=Ingen video
-service.gui.security.CIPHER=Kryptering: {0}
service.gui.security.CALL_SECURED_TOOLTIP=Samtalsöverföring säker. Klicka här för mer information.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Samtalsöverföring ej säker.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Tryck här för att jämföra säkerhetssträng med din partner.
-service.gui.security.COMPARE_WITH_PARTNER=Jämför med din partner och klicka på hänglåset för att bekräfta.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Jämför med partner:
service.gui.security.STRING_COMPARED=Autentiseringssträngar jämförda!
@@ -772,20 +731,14 @@ service.gui.avatar.imagepicker.CLICK=Klicka ock le
service.gui.avatar.imagepicker.IMAGE_FILES=Bildfiler
service.gui.avatar.imagepicker.IMAGE_PICKER=Bild
service.gui.avatar.imagepicker.IMAGE_SIZE=Bildstorlek
-service.gui.avatar.imagepicker.INITIALIZING=Påbörjar
service.gui.avatar.imagepicker.RESET=Återställ
service.gui.avatar.imagepicker.SET=Verkställ
service.gui.avatar.imagepicker.TAKE_PHOTO=Ta ett foto
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Webbkamerafel
service.gui.security.encryption.required=Kryptering krävs!
service.protocol.ICE_FAILED=Kunde inte upprätta anslutningen (ICE misslyckades och ingen relay hittades)
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
impl.protocol.sip.XCAP_ERROR_TITLE=Fel i lagringen av SIP-kontaktlista
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=Resursen kan inte läsas {0}. För {1}
@@ -815,9 +768,7 @@ impl.ldap.QUERY_CUSTOM=Anpassad fråga
impl.ldap.QUERY_CUSTOM_HINT=Använd {0} som platshållare för sökbegreppet.
impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=Lägg automatiskt till jokertecken till sökbegreppet
impl.ldap.QUERY_PHOTO_INLINE=Hämta bild tillsammans med övriga attribut
-impl.ldap.NEW=Nytt
impl.ldap.EDIT=Redigera
-impl.ldap.REMOVE=Ta bort
impl.ldap.ENABLED=Aktiverad
impl.ldap.SERVER_NAME=Servernamn
impl.ldap.SERVER_NAME_EXAMPLE=Min LDAP-server
@@ -850,6 +801,10 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=Hemtelefon
impl.ldap.PHONE_PREFIX=Telefonprefix
impl.ldap.PHONE_PREFIX_EXAMPLE=Exempel: 00
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=Adressbok
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=Aktivera Mac OS X adressboksökning
@@ -864,9 +819,7 @@ plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT=Gör Outlook till förvald e-po
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Google-kontakter
-impl.googlecontacts.NEW=Nytt
impl.googlecontacts.EDIT=Redigera
-impl.googlecontacts.REMOVE=Ta bort
impl.googlecontacts.ENABLED=Aktiverad
impl.googlecontacts.ACCOUNT_NAME=Kontonamn
impl.googlecontacts.SAVE=Spara
@@ -905,11 +858,8 @@ plugin.accountinfo.ORGANIZATION=Organisation:
plugin.accountinfo.JOB_TITLE=Titel:
plugin.accountinfo.ABOUT_ME=Om mig:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
-plugin.accountinfo.USER_PICTURES=Användarbilder
plugin.accountinfo.GLOBAL_ICON=Använd standardbild
plugin.accountinfo.LOCAL_ICON=Använd denna bild:
-plugin.accountinfo.CHANGE=Ändra
-plugin.accountinfo.ONLY_MESSAGE=Endast meddelanden
# connection info
plugin.connectioninfo.TITLE=Anslutningsinformation
@@ -929,49 +879,13 @@ plugin.aimaccregwizz.USERNAME=AIM skärmnamn:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Skärmnamn och lösenord
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Registrera nytt konto
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Om du inte har något AIM-konto kan du klicka på denna knapp och skapa ett nytt.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Åsidosätt serverns standardalternativ
# branding
plugin.branding.ABOUT_WINDOW_TITLE=Om {0}
plugin.branding.LOGO_MESSAGE=VoIP && IM som öppen källkod
-plugin.branding.LOADING=Läser in
plugin.branding.ABOUT_MENU_ENTRY=&Om
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>{1} är under aktiv utveckling. Versionen du kör är endast experimentell och KANSKE INTE fungerar som förväntat. Se {2} för mer information.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 Copyright <b>jitsi.org</b>. Alla rättigheter reserverade. Besök <a href="https://jitsi.org">https://jitsi.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}><b>Jitsi</b> distribueras under villkoren för LGPL (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=Ordböcker
-plugin.dictaccregwizz.ANY_DICTIONARY=Valfri ordbok
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Valfri ordbok från {0}
-plugin.dictaccregwizz.FIRST_MATCH=Första träffen
-plugin.dictaccregwizz.NO_MATCH=Inga träffar
-plugin.dictaccregwizz.MATCH_RESULT=Inga definitioner hittades för "{0}", du kanske menade:\n
-plugin.dictaccregwizz.INVALID_DATABASE=Ordboken "{0}" finns inte längre på den här servern.
-plugin.dictaccregwizz.INVALID_STRATEGY=Aktuell strategi är inte tillgänglig på den här servern
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=Dict-protokollet
-plugin.dictaccregwizz.HOST=Värd
-plugin.dictaccregwizz.SERVER_INFO=Serverinformation
-plugin.dictaccregwizz.STRATEGY_SELECTION=Strategival
-plugin.dictaccregwizz.STRATEGY_LIST=Strategilista:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Sökstrategier
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=Strategi används för att söka efter liknande ord, om en översättning inte hittas tack vare olika synsätt. Som exempel, kommer prefixstrategierna att söka efter ord med samma inledning som det ord du vill översätta.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Dict-kontoinformation
-plugin.dictaccregwizz.FIRST_ACCOUNT=Den här guiden kommer att skapa ditt första Dict-konto på dict.org.\n\nDu kan lägga till nya ordböcker via kontoregistreringsguiden. I värdfältet anger du vilka ordböcker du vill lägga till.
-plugin.dictaccregwizz.THREAD_CONNECT=Försöker ansluta till servern
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=Anslutningsförsöket misslyckades. Det här är ingen Dict-server eller servern är offline.
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=Hämtar strategier
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Ingen strategi hittades på servern
-plugin.dictaccregwizz.POPULATE_LIST=Fyller listan
-plugin.dictaccregwizz.CLOSING_CONNECTION=Stänger anslutningen
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">För att använda Facebook-chatten måste du skapa ett "Användarnamn" <br>via dina "Kontoinställningar" på Facebook.</a><br><br>OBS! När du skapar användarnamn måste du logga ut från webbsidan <br>och det kan ta en stund innan du kan logga in med ditt nya användarnamn!</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=Facebook chattprotokoll
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Användarnamn:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Användarnamn och lösenord
+
+plugin.busylampfield.PICKUP=Ã…teruppta samtal
# generalconfig
plugin.generalconfig.AUTO_START=Starta {0} automatiskt vid systemstart
@@ -982,9 +896,6 @@ plugin.generalconfig.SHOW_HISTORY=Visa
plugin.generalconfig.HISTORY_SIZE=tidigare meddelanden i nya chattar
plugin.generalconfig.SEND_MESSAGES_WITH=Skicka meddelanden med:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=Visa chattfönster överst
-plugin.generalconfig.ERROR_PERMISSION=Du har inte tillräcklig behörighet för att ta bort autostart
-plugin.generalconfig.TRANSPARENCY=Transparens
-plugin.generalconfig.ENABLE_TRANSPARENCY=Aktivera transparens
plugin.generalconfig.DEFAULT_LANGUAGE=Språk
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Ändringar verkställs vid nästa programstart.
plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0}% översatt
@@ -1043,13 +954,13 @@ plugin.ircaccregwizz.EXAMPLE_SERVER=T.ex. chat.freenode.net
plugin.ircaccregwizz.USE_SECURE_CONNECTION=Använd säker anslutning
plugin.ircaccregwizz.ENABLE_CONTACT_PRESENCE=Aktivera kontaktnärvaro
plugin.ircaccregwizz.ENABLE_CHAT_ROOM_PRESENCE=Möjliggör närvaro i chattrum
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE={0} autentisering
+plugin.ircaccregwizz.SASL_USERNAME=Användarnamn
# jabber accregwizz
-plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=XMPP-protokollet
plugin.jabberaccregwizz.USERNAME=XMPP användarnamn
plugin.jabberaccregwizz.PASSWORD_CONFIRM=Bekräfta lösenord
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=ID och lösenord
plugin.jabberaccregwizz.CSERVER=Server
plugin.jabberaccregwizz.SERVER=Anslut server
plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=Aktivera "HÃ¥ll vid liv"
@@ -1065,13 +976,9 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Kommentar
plugin.jabberaccregwizz.RESOURCE=Resurs
plugin.jabberaccregwizz.AUTORESOURCE=Autogenerera resurs
plugin.jabberaccregwizz.PRIORITY=Prioritet
-plugin.jabberaccregwizz.XMPP_ERROR=XMPP-fel
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Okänt XMPP-fel ({0}). Kontrollera att servernamnet är rätt.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Dina lösenord är inte lika.
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Åsidosätt serverns standardalternativ
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Avancerat
plugin.jabberaccregwizz.USE_ICE=Använd ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=Använd Googles Jingle/ICE (Experimentell)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=Hitta STUN-/TURN-servrar automatiskt
plugin.jabberaccregwizz.SUPPORT_TURN=Stöd TURN
plugin.jabberaccregwizz.TURN_USERNAME=TURN-användarnamn
@@ -1099,11 +1006,8 @@ plugin.jabberaccregwizz.DISABLE_CARBON=Inaktivera meddelandekopia
plugin.jabberaccregwizz.DTMF_AUTO=Auto: Välj automatiskt mellan RTP och In-band
plugin.jabberaccregwizz.SERVER_OPTIONS=Serveralternativ
plugin.jabberaccregwizz.CHANGE_PASSWORD=Ändra kontolösenord
-plugin.jabberaccregwizz.NEW_PASSWORD=Nytt lösenord
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Bekräfta nytt lösenord
plugin.jabberaccregwizz.PORT_FIELD_INVALID=Ange ett giltigt portnummer för att fortsätta.
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=Kontot var inloggat före lösenordsändringen.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=Lösenord saknas.
plugin.jabberaccregwizz.TLS_REQUIRED=Anslutningen använder inte TLS. Lösenordsändring kommer inte att utföras.
plugin.jabberaccregwizz.PASSWORD_CHANGED=Lösenordet har ändrats
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=Din XMPP-server stöder inte lösenordsändring.
@@ -1117,25 +1021,9 @@ plugin.jabberaccregwizz.RESET=Återställ
plugin.jabberaccregwizz.RESET_DESCRIPTION=Återställ till globala inställningar
plugin.jabberaccregwizz.DISABLE_JINGLE=Inaktivera Jingle (röst och videosamtal med XMPP).
-# mailbox
-plugin.mailbox.OUTGOING=Utgående meddelande:
-plugin.mailbox.INCOMING=Inkommande meddelande:
-plugin.mailbox.WAIT_TIME=Fördröjning innan samtal vidarekopplas till röstbrevlåda
-plugin.mailbox.MAX_MESSAGE_TIME=Maxlängd på inkommande meddelande
-plugin.mailbox.CONFIRM=Bekräfta
-plugin.mailbox.DEFAULTS=Standard
-plugin.mailbox.MAILBOX=Brevlåda
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Protokoll för att ansluta och chatta på MSN.
-plugin.msnaccregwizz.USERNAME=E-post:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=ID och lösenord
-
# plugin manager
plugin.pluginmanager.INSTALL=Installera
plugin.pluginmanager.UNINSTALL=Avinstallera
-plugin.pluginmanager.UPDATE=Uppdatera
plugin.pluginmanager.PLUGINS=Insticksprogram
plugin.pluginmanager.URL=URL
plugin.pluginmanager.CHOOSE_FILE=Välj fil
@@ -1160,7 +1048,6 @@ plugin.sipaccregwizz.SERVER_PORT=Serverport
plugin.sipaccregwizz.PROXY=Proxy
plugin.sipaccregwizz.PROXY_PORT=Proxyport
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Föredragen transport
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Avancerat
plugin.sipaccregwizz.PROXY_OPTIONS=Proxyalternativ
plugin.sipaccregwizz.PROXY_AUTO=Automatiska proxyinställningar
plugin.sipaccregwizz.ENABLE_PRESENCE=Aktivera närvaro (ENKEL)
@@ -1180,8 +1067,6 @@ plugin.sipaccregwizz.DTMF_AUTO=Auto: Välj automatiskt mellan RTP och In-band (i
plugin.sipaccregwizz.DTMF_RTP=RTP ( RFC2833 / RFC 4733 )
plugin.sipaccregwizz.DTMF_SIP_INFO=SIP-INFO
plugin.sipaccregwizz.DTMF_INBAND=In-band
-plugin.sipaccregwizz.REGISTER=REGISTRERA
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Åsidosätt serverns standardalternativ
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Aktivera stöd för samtalskryptering
plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=Indikera stöd för ZRTP i signalprotokoll
plugin.sipaccregwizz.AUTH_NAME=Auktoriseringsnamn
@@ -1202,10 +1087,10 @@ plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=Adress till röstbrevlåda
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Dina lösenord är olika.
plugin.sipaccregwizz.NO_CERTIFICATE=<none> (använd reguljär autentisering)
plugin.sipaccregwizz.SAVP_OPTION=RTP/SAVP-indikation
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=Av (indikera endast RTP/AVP)
plugin.sipaccregwizz.SAVP_OPTION_1=Obligatorisk (erbjud och acceptera endast RTP/SAVP)
plugin.sipaccregwizz.SAVP_OPTION_2=Tillval (erbjud RTP/SAVP först, sen RTP/AVP)
-plugin.sipaccregwizz.ENABLE_SDES_ATTRIBUTE=Aktivera S-Descriptor (också känd som SDES eller SRTP)
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=Välj aktiverade krypteringsprotokoll och dess prioritet (översta protokollet först):
plugin.sipaccregwizz.CIPHER_SUITES=Aktiverade krypteringssviter:
plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>{0} försöker automatiskt säkra alla dina samtal med ZRTP och du kommer att både se och höra ett meddelande när en säker anslutning etablerats. Du bör inte ändra nedanstående avancerade inställningar om du inte vet exakt vad du gör.</div></html>
@@ -1219,15 +1104,6 @@ plugin.skinmanager.DEFAULT_SKIN=Standardtema
plugin.skinmanager.ADD_NEW_SKIN=Lägg till nytt tema...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=Standardtema för programmet.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=Protokoll för att ansluta till fjärrdatorer över SSH.
-plugin.sshaccregwizz.USERNAME=Konto-ID:
-plugin.sshaccregwizz.IDENTITY_FILE=Identitetsfil:
-plugin.sshaccregwizz.KNOWN_HOSTS=Kända värdar:
-plugin.sshaccregwizz.OPTIONAL=Tillval
-plugin.sshaccregwizz.ACCOUNT_DETAILS=Kontoinformation
-
# status update
plugin.autoaway.AUTO_STATUS=Auto-status
plugin.autoaway.ENABLE_CHANGE_STATUS=Ändra status vid "Ej närvarande"
@@ -1275,22 +1151,6 @@ plugin.whiteboard.DESELECT=Avmarkera
plugin.whiteboard.DELETE=Ta bort
plugin.whiteboard.PROPERTIES=Egenskaper
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Protokoll för att ansluta och chatta på Yahoo!
-plugin.yahooaccregwizz.USERNAME=Användarnamn:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=ID och lösenord
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=Protokoll för Zeroconf (Bonjour).
-plugin.zeroaccregwizz.FIRST_NAME=Förnamn:
-plugin.zeroaccregwizz.LAST_NAME=Efternamn:
-plugin.zeroaccregwizz.EMAIL=E-post:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=Kom ihåg Bonjour-kontakter?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=ID och lösenord
-plugin.zeroaccregwizz.USERID=Användar-ID
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Google Talk-protokollet
@@ -1304,19 +1164,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, IP Telecommunications Por
plugin.iptelaccregwizz.USERNAME=Användarnamn
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=Abonnera på iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIP och chat
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Användarnamn
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Upprepa lösenordet
plugin.sip2sipaccregwizz.EMAIL=E-postadress
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=För hjälp med den tjänsten, besök<br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>E-postadressen används för att skicka röstmeddelanden,<br>meddelanden om missade samtal och för att återställa förlorade lösenord</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>För hjälp med den här tjänsten, besök <a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=Befintligt sip2sip-konto
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Skapa ett gratis sip2sip-konto
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP && Snabbmeddelande
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=För hjälp med den tjänsten, besök<br>http://ippi.fr
@@ -1325,6 +1177,7 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=Befintligt ippi-konto
plugin.ippiaccregwizz.CREATE_ACCOUNT=Skapa ett gratis ippi-konto
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Stäng chattfönstret
plugin.keybindings.CHAT_COPY=Kopiera
plugin.keybindings.CHAT_CUT=Klipp ut
@@ -1347,10 +1200,10 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=Namn
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=Primär genväg
plugin.keybindings.globalchooser.SHORTCUT_SECOND=Sekundär genväg
plugin.keybindings.globalchooser.PRESS_BTN=Tryck för att ange genväg
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=Väntar
plugin.keybindings.globalchooser.PUSH_TO_TALK=Tryck för att prata
plugin.keybindings.globalchooser.ENABLE_SPECIAL=Aktivera snabbtangentupptäckt
plugin.keybindings.PLUGIN_NAME=Snabbtangenter
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Chatt
plugin.keybindings.MAIN=Grundläggande
plugin.keybindings.GLOBAL=Globala genvägar
@@ -1378,6 +1231,7 @@ plugin.notificationconfig.tableheader.SOUND=Spela upp ett ljud genom meddelandee
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=Spela upp ett ljud genom uppspelningsenheten
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=Spela upp ett ljud genom datorhögtalarna
plugin.notificationconfig.tableheader.DESCRIPTION=Händelsebeskrivning
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Inkommande samtal
plugin.notificationconfig.event.SecurityMessage=Säkerhetsmeddelande
plugin.notificationconfig.event.IncomingFile=Inkommande fil
@@ -1479,6 +1333,7 @@ impl.neomedia.configform.VIDEO=Video
impl.neomedia.configform.H264=H.264
impl.neomedia.configform.H264.defaultIntraRefresh=Periodic Intra Refresh
impl.neomedia.configform.H264.defaultProfile=Standardprofil för kodning:
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=Bas
impl.neomedia.configform.H264.defaultProfile.high=Hög
impl.neomedia.configform.H264.defaultProfile.main=Medel
@@ -1509,7 +1364,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=Aktuellt lösenord:
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Ange nytt lösenord:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Upprepa lösenordet:
plugin.securityconfig.masterpassword.MP_TITLE=Masterlösenord
-plugin.securityconfig.masterpassword.MP_NOT_SET=(ej angivet)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=Du angav inte rätt Masterlösenord. Försök igen.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=Masterlösenordet är felaktigt!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Lösenordsändringen misslyckades
@@ -1525,7 +1379,6 @@ plugin.securityconfig.masterpassword.COL_PASSWORD=Lösenord
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(okänd)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(kan inte dekryptera)
plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=Lagrade lösenord
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=Ta bort
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=Ta bort alla
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=Vill du verkligen ta bort alla lösenord?
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=Ta bort alla lösenord
@@ -1621,7 +1474,6 @@ plugin.globalproxy.PROXY_PORT=Port
plugin.globalproxy.PROXY_USERNAME=Användarnamn
plugin.globalproxy.PROXY_PASSWORD=Lösenord
plugin.globalproxy.DESCRIPTION={0} kommer att använda ovanstående proxyinställningar för alla nätverk du ansluter till, från och med nu.\nProxy-stödet är fortfarande experimentellt och fungerar bara med vissa protokoll. Se nedanstående tabell för ytterligare info:
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>XMPP</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
plugin.globalproxy.FWD_DNS=Också proxy-DNS
plugin.globalproxy.FWD_DNS_NOTE=Användbart med Tor. Hjälper dig att undvika DNS-läckage genom att vidarebefordra all DNS-trafik till Tor-proxyn. Kräver omstart.
@@ -1659,7 +1511,6 @@ plugin.provisioning.RESTART_WARNING=Notera att dina ändringar verkställs förs
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=Kopiera UUID till Urklipp
plugin.provisioning.CLIPBOARD_FAILED=Kunde inte kopiera UUID till Urklipp
-plugin.provisioning.EXIT_ON_FAIL=Avsluta programmet om nättjänsten misslyckas
plugin.provisioning.CREDENTIALS=Senast lagrade nättjänstreferenser
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=Vill du verkligen ta bort nättjänstlösenordet?
plugin.provisioning.PROV_FAILED=Nättjänsten misslyckades
@@ -1726,8 +1577,6 @@ util.dns.DNSSEC_WARNING=<html><div width="600">{0} har försökt ansluta till se
#plugin spellcheck
plugin.spellcheck.TITLE=Stavning och gramatik
plugin.spellcheck.MENU=Visa stavning och gramatik
-plugin.spellcheck.LANG=Språk
-plugin.spellcheck.EDIT_PERSONAL_DICT=Redigera
plugin.spellcheck.ENABLE_SPELL_CHECK=Aktivera stavningskontroll
plugin.spellcheck.dialog.FIND=Sök nästa
plugin.spellcheck.dialog.REPLACE=Ersätt
diff --git a/resources/languages/resources_tr.properties b/resources/languages/resources_tr.properties
index 474bf3a..1fc3ca6 100644
--- a/resources/languages/resources_tr.properties
+++ b/resources/languages/resources_tr.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -26,52 +37,49 @@
# ant -Duser.language=xx run
service.gui.ABOUT=Hakkında
-service.gui.ACCEPT=Cevapla
+service.gui.ACCEPT=&Kabul Et
service.gui.ACCOUNT=Hesap
service.gui.ACCOUNT_ME=Kendim
service.gui.ACCOUNT_REGISTRATION_WIZARD=Hesap Kayıt Sihirbazı
service.gui.ACCOUNTS=Hesaplar
service.gui.ADD=Ekle
-service.gui.ADD_ACCOUNT=Hesap Ekle
service.gui.ADD_CONTACT=KiÅŸi Ekle
service.gui.ADD_AUTHORIZED_CONTACT={0} KiÅŸilere ekle
-service.gui.ADD_CONTACT_TO=Åžuraya KiÅŸi Ekle
-service.gui.ADD_CONTACT_ERROR={0} nolu kiÅŸi ekleyemedi
+service.gui.ADD_CONTACT_TO_CONTACTLIST=Bu numarayı kişilere ekle
+service.gui.ADD_CONTACT_TO=KiÅŸi ekle
+service.gui.ADD_CONTACT_ERROR={0} nolu kiÅŸi eklenemedi
service.gui.ADD_CONTACT_ERROR_TITLE=Kişi Ekleme Hatası
service.gui.ADD_CONTACT_EXIST_ERROR={0} zaten kiÅŸi listesinde var.
service.gui.ADD_CONTACT_NETWORK_ERROR=Sunucu {0} nolu kiÅŸiyi ekleme isteÄŸine cevap vermedi.
-service.gui.ADD_CONTACT_NOT_SUPPORTED={0} nolu kiÅŸi ekleyemedi. Ä°ÅŸlem desteklenmiyor.
-service.gui.ADD_CONTACT_IDENTIFIER=Eklemek istediğiniz kişinin tanıtıcı kimliğini aşağıdaki bölüme giriniz.
-service.gui.ADD_CONTACT_WIZARD=Kişi Ekleme Sihirbazı
+service.gui.ADD_CONTACT_NOT_SUPPORTED={0} nolu kiÅŸi eklenemedi. Ä°ÅŸlem desteklenmiyor.
service.gui.ADD_CONTACT_NOT_CONNECTED=Kişi eklemek için bağlı olmalısınız. Lütfen seçili sağlayıcıya giriş yapın ve tekrar deneyin.
-service.gui.ADD_GROUP_LOCAL_ERROR={0} isimli grubu ekleyemedi. Yerel yazım işlemi sırasında bir hata oluştu.
-service.gui.ADD_GROUP_EXIST_ERROR={0} isimli grup zaten arkadaş listesinde mevcut. Lütfen başka bir grup ismi seçiniz.
+service.gui.ADD_GROUP_LOCAL_ERROR={0} isimli grup eklenemedi. Yerel Giriş/Çıkış işlemi sırasında bir hata oluştu.
+service.gui.ADD_GROUP_EXIST_ERROR={0} isimli grup zaten kişi listesinde mevcut. Lütfen başka bir grup ismi seçiniz.
service.gui.ADD_GROUP_NET_ERROR={0} isimli grubu ekleyemedi. Ağ bağlantısından dolayı bir hata oluştu. Lütfen ağ bağlantınızı kontrol edin ve tekrar deneyin.
service.gui.ADD_GROUP_ERROR={0} isimli grubu ekleyemedi.
service.gui.ADD_GROUP_EMPTY_NAME=Grup ismi boÅŸ olamaz.
-service.gui.ADD_GROUP=Grup oluÅŸtur
-service.gui.ADD_SUBCONTACT=Ä°kincil KiÅŸi Ekle
service.gui.ADDRESS=Adres
service.gui.ADMINISTRATOR=yönetici
service.gui.ADVANCED=GeliÅŸmiÅŸ
-service.gui.ALL=Hepsi
service.gui.ALL_CONTACTS=Bütün kişiler
+service.gui.ALTERNATE_ADDRESS=Ä°kinci adres
service.gui.APPLY=Uygula
-service.gui.ARE_CALLING=arıyor...
+service.gui.ARE_CALLING={0} arıyor...
service.gui.ARE_NOW=Siz ÅŸu an {0}
service.gui.AT=de
service.gui.AUTHORIZE=Yetkilendir
-service.gui.AUTHORIZATION_ACCEPTED=kiÅŸi sizin izin isteÄŸinizi kabul etti.
+service.gui.AUTHORIZATION_ACCEPTED={0}, yetkilendirme isteÄŸinizi kabul etti.
service.gui.AUTHENTICATION_FAILED=Kimlik {0} için başarısız oldu. Girdiğiniz şifre geçerli değil.
-service.gui.AUTHENTICATION_REQUESTED=Onay istendi
service.gui.AUTHENTICATION_REQUESTED_SERVER={0} sunucusu sizin onaylanmanızı istiyor.
-service.gui.AUTHENTICATION_REJECTED=kiÅŸi sizin izin isteÄŸinizi reddetti.
+service.gui.AUTHENTICATION_REJECTED={0}, yetkilendirme isteÄŸinizi reddetti.
service.gui.AUTHENTICATION_WINDOW_TITLE={0} onaylama
service.gui.AUTHORIZATION_REQUESTED=Ä°zin istendi
-service.gui.AUTHORIZATION_REQUESTED_INFO={0} arkadaÅŸ sizin izninizi istiyor.
+service.gui.AUTHORIZATION_REQUESTED_INFO={0} kiÅŸi sizin izninizi istiyor.
service.gui.AUTHORIZATION_RESPONSE=İzin cevabı
service.gui.AWAY_STATUS=Dışarda
+service.gui.EXTENDED_AWAY_STATUS=Uzun Süre Uzakta
service.gui.BAN=Yasakla
+service.gui.BANNED=yasaklı
service.gui.BAN_FAILED=Yasaklanamandı
service.gui.BAN_FAILED_GENERAL_ERROR={0} yasaklanamadı. Genel bir sunucu hatası oluştu.
service.gui.BAN_FAILED_NOT_ALLOWED={0} yasaklanamadı. Oda sahibi ve oda yöneticisi yasaklanamaz.
@@ -81,13 +89,17 @@ service.gui.BROWSE=Göz at
service.gui.BUSY_MESSAGE=Üzgünüm, şu an meşgulum.
service.gui.BUSY_STATUS=MeÅŸgul
service.gui.CALL=Ara
-service.gui.CALL_CONTACT=KiÅŸi ara
+service.gui.CALL_CONTACT=KiÅŸiyi ara
service.gui.CALL_FAILED=Arama başarısız oldu
service.gui.CALL_HISTORY_TOOL_TIP=Arama geçmişi için buraya tıkla
+service.gui.CALL_HISTORY_GROUP_NAME=Arama geçmişi
service.gui.CALL_VIA=Bunla ara:
service.gui.CALL_NAME_OR_NUMBER=Ä°sim veya numara gir
service.gui.CALL_NOT_SUPPORTING_PARTICIPANT=Bu arama sadece {0} ağından katılımcıları ve sizin {1} hesabınızı destekler. {2} bu ağdan veya hesabınızdan adres içermemektedir.
service.gui.CALL_WITH=Åžununla ara
+service.gui.CALL_NO_AUDIO_DEVICE=Yapılandırılmış bir ses aygıtınız yok.
+service.gui.CALL_NO_AUDIO_CODEC=Yapılandırılmış bir ses çözücünüz yok.
+service.gui.CALL_NO_DEVICE_CODECS_Q=Aramayı sürdürmek ister misiniz?
service.gui.CANCEL=Ä°ptal et
service.gui.CHAT=Sohbet
service.gui.CHANGE_FONT=Fontu deÄŸiÅŸtir
@@ -96,10 +108,13 @@ service.gui.CHANGE_ROOM_SUBJECT_LABEL=Aşağıdaki bölümde, odanın yeni konus
service.gui.CHANGE_NICK=Takma ismi deÄŸiÅŸtir
service.gui.CHANGE_NICKNAME=Takma ismi deÄŸiÅŸtir...
service.gui.CHANGE_NICKNAME_LABEL=Aşağıdaki bölümde, yeni takma isminizi girebilirsiniz.
-service.gui.CHANGE_VIDEO_QUALITY=Video kalitesini deÄŸiÅŸitir
+service.gui.CHANGE_NICKNAME_ERROR=Takma adı değiştirirken sorun oluştu
+service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=Takma ad zaten var
+service.gui.CHANGE_VIDEO_QUALITY=Uzak video kalitesini deÄŸiÅŸtir
+service.gui.CHAT_CONFERENCE_ITEM_LABEL={0}''ın konferansı
service.gui.CHAT_ROOM_ALREADY_JOINED={0} sohbet odasına zaten katılındı.
-service.gui.CHAT_ROOM_CONFIGURATION={0} sohbet odası konfigürasyonu
-service.gui.CHAT_ROOM_CONFIGURATION_FAILED={0} sohbet odası konfigürasyon formu alınamadı.
+service.gui.CHAT_ROOM_CONFIGURATION={0} sohbet odası ayarları
+service.gui.CHAT_ROOM_CONFIGURATION_FAILED={0} sohbet odası ayarları formu alınamadı.
service.gui.CHAT_ROOM_CONFIGURATION_SUBMIT_FAILED={0} sohbet odası konfigürasyonu kaydedilirken bir hata oluştu.
service.gui.CHAT_ROOM_USER_JOINED={0} katıldı
service.gui.CHAT_ROOM_USER_LEFT={0} ayrıldı
@@ -108,18 +123,16 @@ service.gui.CHAT_ROOM_USER_QUIT={0} çıktı
service.gui.CHAT_ROOM_NAME=Sohbet odası ismi
service.gui.CLEAR_CUSTOM_MESSAGES=Kişiselleştirilmiş mesajları temizle
service.gui.ROOM_NAME=Sohbet Odası
-service.gui.AUTOJOIN=Otomatik katıl
service.gui.CHANGE_PASSWORD=Şİfre değiştir
service.gui.CHAT_ROOM_NAME_INFO=Aşağıdaki bölümde, oluşturmak istediğiniz sohbet odasının ismini giriniz.
service.gui.CHAT_ROOM_NOT_EXIST={0} odası {1} sunucusunda bulunamadı. Lütfen girdiğiniz ismin doğruluğunu kontrol ediniz
service.gui.CHAT_ROOM_NOT_CONNECTED={0} sohbet odasına katılabilmek için önce oturum açmalısınız.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Sohbet odasından ayrılabilmek için önce oturum açmalısınız.
-service.gui.CHAT_ROOM_NOT_JOINED=Bir sohbet odasında işlem yapmak için önce o odaya katılmanız gerekir.
service.gui.CHAT_ROOM_OPTIONS=Sohbet odası seçenekleri
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED={0} sohbet odası katılmak için kayıt gerektirmektedir.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD={0} sohbet odası şifre gerektirmektedir.
service.gui.CHAT_ROOMS=Sohbet odaları
-service.gui.CHAT_ROOM=Sohbet odaları
+service.gui.CHAT_ROOM=Sohbet odası
service.gui.CHAT_ROOM_SUBJECT_CHANGED={0} konuyu {1}"e çevirdi.
service.gui.CHOOSE_CONTACT=Kişi seç
service.gui.CHOOSE_ACCOUNT=Lütfen listedeki hesaplardan birini seçiniz
@@ -130,22 +143,18 @@ service.gui.CLEAR=Temizle
service.gui.CLOSE=Kapat
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=2 saniyeden az bir süre önce bir mesaj aldınız? Bu sohbeti kapatmak istiyor musunuz?
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=Aktif dosya transferleriniz var. Bunları iptal etmek istiyor musunuz?
-service.gui.CONFIRM=Onayla
service.gui.CONNECTED_STATUS=Bağlandı
service.gui.CONNECTING=Bağlanıyor...
service.gui.CONNECTING_STATUS=Bağlantı
service.gui.CONNECTING_EARLY_MEDIA_STATUS=Bağlanıyor*
service.gui.CONNECTION=Bağlantı
-service.gui.CONNECTION_FAILED_MSG=Bu hesap için bağlantı sağlanmadı: Kullanıcı adı: {0}, Sunucu adı: {1}. Lütfen ağ bağlantılarınızı kontrol ediniz veya daha fazla bilgi için ağ yöneticinizle görüşünüz.
service.gui.CONNECTION_EXPIRED_MSG={0} sunucusundan koptunuz.
service.gui.CONTACT_NAME=ID veya Numara
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Seçilen {0} kişinin telefonu desteklemiyor.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Seçilen {0} kişi sohbeti desteklemiyor.
service.gui.CONTACT_PAUSED_TYPING={0} mesaj yazmaya ara verdi
service.gui.CONTACT_TYPING={0} mesaj yazıyor
service.gui.CONTACT_TYPING_SEND_FAILED=eyvah... {0}'a yazmakta olduğunuzu söyleyemedik
service.gui.CONTACT_INFO=KiÅŸi bilgisi
-service.gui.CONTACTLIST=KiÅŸilistesi
service.gui.CONTACTS=KiÅŸiler
service.gui.COPY=Kopyala
service.gui.COPY_LINK=Linki kopyala
@@ -155,25 +164,21 @@ service.gui.CREATE_CHAT_ROOM=Sohbet odası oluştur...
service.gui.CREATE_CHAT_ROOM_ERROR={0} sohbet odası oluşturulamadı.
service.gui.CREATE_CHAT_ROOM_WIZARD=Sohbet odası sihirbazı oluştur
service.gui.CREATE_CONFERENCE_CALL=Konferans arama oluÅŸtur...
-service.gui.CREATE_CONFERENCE_CHAT=Konferans sohbet oluÅŸtur...
service.gui.CREATE_GROUP=Grup oluÅŸtur...
service.gui.CREATE_GROUP_NAME=Aşağıdaki bölümde oluşturmak istediğiniz grubun adını giriniz.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Kişi listeniz hiç grup içermemektedir. Lütfen önce bir grup oluşturunuz(Dosya/Grup Oluştur).
service.gui.CREATE_VIDEO_BRIDGE=Bir &video köprüsü oluştur...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Bir &video köprüsü oluştur
service.gui.CONTACT_INFO_NOT_SUPPORTED=Bu kiÅŸi aÄŸ arkadaÅŸ bilgisini desteklememektedir
service.gui.CUT=Kes
-service.gui.DATE=Tarih
service.gui.DELETE=Sil
service.gui.DENY=Reddet
-service.gui.DESKTOP_SHARING_WARNING=<b>Ekran paylaşımını başlatmak istediğinizden emin misiniz</b> <br> Tamam'a basmak bu aramadaki insanların ekranınızı görmesini sağlar
+service.gui.DESKTOP_SHARING_WARNING=<b>Ekran paylaşımını başlatmak istediğinizden emin misiniz</b> <br> Bu aramadaki insanların ekranınızı görmesi için Tamam''a tıklayın.
service.gui.DIALPAD=Tuş takımı
service.gui.DISPLAY_NAME=Gösterilen isim
service.gui.DISCONNECTED_STATUS=Bağlantı kesildi
service.gui.DND_STATUS=Rahatsız etme
service.gui.DO_NOT_ASK_AGAIN=Tekrar sorma
service.gui.DO_NOT_SHOW_AGAIN=Bu mesajı tekrar gösterme
-service.gui.DOWNLOAD_NOW=Åžimdi indir
service.gui.DRAG_FOR_SHARING=Buraya paylaşmak istediğinizi sürükleyerek bırakınız....
service.gui.DURATION=süre
service.gui.EDIT=Düzenle
@@ -190,7 +195,6 @@ service.gui.ERROR_WAS={0} hatası çıktı
service.gui.ESTIMATED_TIME=Tahmin edilen süre:
service.gui.EVENTS=Aktiviteler
service.gui.EXIT=Çık
-service.gui.EXTENDED_CRITERIA=GeniÅŸletilmiÅŸ kriter
service.gui.GENERAL=Genel
service.gui.GENERAL_ERROR=Genel Hata
service.gui.GROUP_NAME=Grup ismi
@@ -224,7 +228,7 @@ service.gui.FOLDER_DOES_NOT_EXIST=Bu dosyayı içeren dizin bulunamadı. Silinmi
service.gui.FOLDER_OPEN_FAILED=Dizin açılamadı.
service.gui.FOLDER_OPEN_NO_PERMISSION=Bu dizini açmak için yeterli izniniz yok. Lütfen okuma izinlerinizi kontrol edip tekrar deneyiniz.
service.gui.FOLDER_OPEN_NO_APPLICATION=Bu dizini açabilecek program bulunamadı.
-service.gui.FONT=Punto
+service.gui.FONT=Yazıtipi
service.gui.FONT_BOLD=Kalın
service.gui.FONT_COLOR=Renk
service.gui.FONT_FAMILY=Aile
@@ -246,14 +250,15 @@ service.gui.HIDE_OFFLINE_CONTACTS=Çevrimdışı kişileri gizle
service.gui.HIDE_MAIN_WINDOW=<DIV>X pencere butonuna tıklamak programı kapatmaz, sadece gizler.<BR> Eğer kapatmak istiyorsanız Dosya/Çık seçilmeli.</DIV>
service.gui.HISTORY=Geçmiş
service.gui.HISTORY_CONTACT=Geçmiş - {0}
+service.gui.HISTORY_ERASE_PER_CHATROOM=Bu sohbet odasındaki bütün eski yazışmaları sil
service.gui.HOME=Ev
service.gui.HOME_PAGE=Ana sayfa
-service.gui.HOUR=Saat
service.gui.ICE=ICE
service.gui.IDENTIFIER=Belirleyici kimlik
service.gui.IGNORE=Yoksay
service.gui.INSERT_SMILEY=Gülücük koy
service.gui.INCOMING_CALL={0}"dan gelen arama alındı
+service.gui.INCOMING_SCREEN_SHARE={0}''dan gelen ekran paylaşımı alındı
service.gui.INCOMING_CALL_STATUS=Gelen arama
service.gui.INSTANT_MESSAGINGS=IM'ler
service.gui.INITIATING_CALL_STATUS=Başlatılan arama
@@ -267,13 +272,10 @@ service.gui.INVITE_CONTACT_TO_CHAT=KiÅŸileri sohbete davet et
service.gui.INVITE_CONTACT_TO_CALL=KiÅŸileri konuÅŸmaya davet et
service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Kişileri video köprüsüne davet et
service.gui.INVITE_REASON=Davet nedeni
-service.gui.IS_CALLING=arıyor...
+service.gui.IS_CALLING={0} arıyor...
service.gui.IS_NOW={0} ÅŸu an {1}
-service.gui.JITSI_WARNING=SIP Communicatorın ismi Jitsi olarak değişti.<br/>Eğer sürümünüzü güncellemek istiyorsanız Jitsi'yi indirebilirsiniz..<br/><br/>Sizi rahatsız ettiğimiz için özür dileriz.<br/><br/>The Jitsi Dev Team
-service.gui.JITSI_WARNING_TITLE=SIP Communicator Jitsi oluyor
service.gui.JOIN=Katıl
service.gui.JOIN_AS=Şu şekilde katıl
-service.gui.CLOSE_CHAT_ROOM_DIALOG=Kapat
service.gui.JOB_TITLE=İş tanımı
service.gui.JOIN_CHAT_ROOM=Sohbet odasına katıl...
service.gui.JOIN_CHAT_ROOM_TITLE=Sohbet odasına katıl
@@ -284,11 +286,10 @@ service.gui.KICK_FAILED=Atma başarısız
service.gui.KICK_FAILED_GENERAL_ERROR={0} atılamadı. Genel bir sunucu hatası oluştu.
service.gui.KICK_FAILED_NOT_ALLOWED={0} atılamadı. Odanın sahibi ve yöneticisi atılamaz.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS={0} atılamadı. Bu yapmak için yeterli izniniz yok.
-service.gui.LAST=Son
service.gui.LAST_NAME=Soyad
service.gui.LEAVE=Terk et
service.gui.LIMIT_REACHED_FOR_IP=Yerel IP adresinden çok fazla kaydınız var ve {0} sunucusu daha fazla açmanıza izin vermeyecek.
-service.gui.LIST=Son
+service.gui.LIST=Listele
service.gui.LOADING_ROOMS=Odalar yükleniyor...
service.gui.LOADING=Yükleniyor...
service.gui.LOCALLY_ON_HOLD_STATUS=Yerel olarak beklemede
@@ -304,8 +305,7 @@ service.gui.MESSAGE=Mesaj
service.gui.MISSED_CALLS_TOOL_TIP=Cevapsız çağrılar:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= ve {0} daha fazla
service.gui.MODERATOR=moderatör
-service.gui.MORE=Daha fazla gör
-service.gui.MORE_LABEL=Taşı
+service.gui.MORE_LABEL=Daha
service.gui.MOVE=Taşı
service.gui.MOVE_SUBCONTACT=Kişi taşı
service.gui.MOVE_SUBCONTACT_MSG=Seçtiğiniz kişiyi taşıyacağınız kişi veya grup seçiniz.
@@ -313,7 +313,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=SeçtiÄŸiniz kiÅŸi taşımak istediÄŸiniz kiÅ
service.gui.MOVE_SUBCONTACT_QUESTION={0}"ı {1}"e taşımak istediğinizden emin misiniz?
service.gui.MOVE_TO_GROUP=Gruba taşı
service.gui.MOVE_CONTACT=Kişi Taşı
-service.gui.MOVE_CONTACT_ERROR=Kişi taşınamaz
service.gui.MSG_DELIVERY_FAILURE=Yukarıdaki mesaj iletilemedi
service.gui.MSG_DELIVERY_NOT_SUPPORTED=Kullandığınız protokol çevrimdışı mesajları desteklememektedir. {0}'a başka bir protokolden ulaşmayı deneyebilir veya kişi çevrimiçi olana kadar bekleyebilirsiniz.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=Dahili bir hata oluştu. Bu büyük bir ihtimalle program hatası. Lütfen şuraya bildiriniz: http://jitsi.org/index.php/Development/BugAndIssues.
@@ -324,7 +323,6 @@ service.gui.MSG_NOT_POSSIBLE=Mesajlaşma bu kişi için imkansız(protokol taraf
service.gui.MSG_RECEIVED={0} yazdı
service.gui.MSG_SEND_CONNECTION_PROBLEM=Mesaj gönderebilmek için çevrimiçi olmalısınız.
service.gui.MULTIPLE_LOGINS=Aynı hesap ile birden fazla oturum açtınız. Şu hesabın bağlantısı koptu: Kullanıcı adı: {0}, Sunucu adı: {1}.
-service.gui.MUTE=Sessiz
service.gui.MUTUALLY_ON_HOLD_STATUS=Sessizce beklemede
service.gui.NAME=Ä°sim
service.gui.NETWORK=AÄŸ
@@ -335,6 +333,7 @@ service.gui.NEW_MESSAGE=Yeni mesaj
service.gui.NEW_NAME=Yeni isim
service.gui.NEW_STATUS_MESSAGE=Yeni durum mesajı
service.gui.NEW_STATUS_MESSAGE_SAVE=KiÅŸiselleÅŸtirilmiÅŸ mesaj olarak kaydet
+service.gui.NICKNAME=Rumuz
service.gui.NO=Hayır
service.gui.NONE=Hiç
service.gui.NO_CAMERA_AVAILABLE=Kamera yok
@@ -353,8 +352,7 @@ service.gui.NON_EXISTING_USER_ID={0} sunucusu belirtilen kullanıcı numarasınÄ
service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=KiÅŸilistesindedeÄŸil
service.gui.SD_QUALITY=Standart kalite
service.gui.OFFLINE=Çevrimdışı
-service.gui.OK=Tamam
-service.gui.OLDER_CALLS=Daha eski aramalar
+service.gui.OK=&Tamam
service.gui.ONLINE=Çevrimiçi
service.gui.OPEN=Aç
service.gui.OPEN_FILE_FROM_IMAGE=Dosyayı açmak için çift tıklayınız.
@@ -362,9 +360,12 @@ service.gui.OPEN_FOLDER=Dizini aç
service.gui.OPEN_IN_BROWSER=Web tarayıcısında aç
service.gui.OPTIONS=Ayarlar
service.gui.OR=veya
-service.gui.OR_ENTER_PHONE_NUMBER=Veya telefon numarasını buraya giriniz...
service.gui.ORGANIZATION=Organizasyon
service.gui.OTHER=DiÄŸer
+service.gui.chat.role.ADMINISTRATOR=Yönetici
+service.gui.chat.role.MODERATOR=Moderatör
+service.gui.chat.role.MEMBER=Ãœye
+service.gui.chat.role.SILENT_MEMBER=Sessiz üye
service.gui.OWNER=odanın sahibi
service.gui.PASSWORD=Åžifre
service.gui.PASSWORD_CHANGE_FAILURE=Şifre değiştirme başarısız oldu
@@ -378,7 +379,6 @@ service.gui.PRESENCE=Durum
service.gui.PRESS_ENTER_FOR_SUGGESTIONS=Öneriler için 'Enter'
service.gui.PRESS_FOR_CALL_INFO=Arama bilgisi için tıkla
service.gui.PREVIOUS=Önceki
-service.gui.PREVIOUS_TOOLTIP=Daha eski konuşmalara göz at
service.gui.PRINT=Yazdır
service.gui.PROACTIVE_NOTIFICATION=mesaj yazıyor
service.gui.PROTOCOL=Protokol
@@ -391,7 +391,6 @@ service.gui.RECONNECTION_LIMIT_EXCEEDED=Çok hızlı bir şekilde sunucudan kopu
service.gui.RE_REQUEST_AUTHORIZATION=Re-Ä°zin iste
service.gui.REFERRED_STATUS=BaÅŸvuruldu
service.gui.REJECT=Reddet
-service.gui.REMIND_ME_LATER=Daha sonra hatırlat
service.gui.REMEMBER_PASSWORD=Şifreyi hatırla
service.gui.REMOVE=Sil
service.gui.REMOVE_ACCOUNT=Hesabı sil
@@ -416,27 +415,18 @@ service.gui.REVOKE_ADMIN=Yöneticiliği geri al
service.gui.REVOKE_MODERATOR=Moderatörlüğü geri al
service.gui.REVOKE_MEMBERSHIP=ÃœyeliÄŸi geri al
service.gui.REVOKE_VOICE=Sesi geri al
-service.gui.ROOT_GROUP=Temel grup
service.gui.SAVE=Kaydet
-service.gui.SAVE_AS_DEFAULT=Varsayılan olarak kaydet
service.gui.SEARCH=Ara
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=Seçili sunucudaki bütün sohbet odalarını listelemek için aşağıdaki butona tıklayınız. Daha sonra katılmak istediğinizi seçiniz ve katıl butonuna tıklayınız
service.gui.SEARCH_STRING_CONTACT_SOURCE=Kişi arandı
service.gui.SECURITY=Güvenlik
-service.gui.SELECT_ACCOUNT=Hesap seç
service.gui.SELECT_COLOR=Renk seç
service.gui.SELECT_GROUP=Grup seç
-service.gui.SELECT_GROUP_WIZARD_MSG=Aşağıdaki liste sizin kişi listenizdeki bütün grupları içermektedir. Yeni kişi eklemek istediğiniz grubu seçiniz.
service.gui.SELECT_NO_GROUP=Grup yok
-service.gui.SELECT_GROUP_WIZARD=Grubu belirtiniz
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=Aşağıdaki liste çoklu kullanıcı sohbet modunu destekleyen bütün hesapları göstermektedir. Sohbet odası oluştururken kullanmak istediğiniz bir hesap seçiniz.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=Aşağıdaki liste bütün kayıtlı hesapları içermektedir. Yeni kişi ile iletişim kurmak için kullanacağınız bir hesap seçiniz.
-service.gui.SELECT_PROVIDERS_WIZARD=Hesap seç
service.gui.SEND=Gönder
service.gui.SEND_FILE=Dosya gönder
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Bu arkadaş için bilgi yok.
service.gui.SEND_MESSAGE=Mesaj gönder
-service.gui.SEND_AS_SMS=SMS olarak gönder
service.gui.SEND_SMS=SMS gönder
service.gui.SEND_SMS_DETAILS=Numarayı uluslararası formatta gireceğinizi unutmayın örneğin Birleşik Krallık için +44 ile başlıyor +447777000000
service.gui.SEND_SMS_NOT_SUPPORTED=Seçtiğiniz protokol SMS mesajlarını desteklemiyor.
@@ -471,7 +461,6 @@ service.gui.STREET=Sokak
service.gui.SUBJECT=Konu
service.gui.SUMMARY=Özet
service.gui.TELEPHONY=Telefon
-service.gui.TODAY=Bugün
service.gui.TOOLS=Araçlar
service.gui.TRANSFER=Transfer
service.gui.TO=Åžu kiÅŸiye:
@@ -481,7 +470,6 @@ service.gui.TRANSFER_CALL_TO=Åžu kiÅŸiye transfer et:
service.gui.TRANSPARENCY_NOT_ENABLED=Saydamlık şuanki konfigürasyonunuz tarafından desteklenmemektedir.
service.gui.TYPE_YOUR_REQUEST=Ä°steÄŸinizi buraya giriniz
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Bu çağrı için video kalitesini değiştiremiyoruz
-service.gui.UNMUTE=Sessiz modunu kapat
service.gui.USER_IDENTIFIER=Kullanıcı tanıtıcı kimlik:
service.gui.USER_EXISTS_ERROR=Bu kullanıcı seçilen ağda zaten mevcut. Lütfen başka bir kullanıcı veya ağ seçiniz.
service.gui.USERNAME_NULL=Lütfen kullanıcı adınızı ve şifrenizi doldurunuz
@@ -490,9 +478,8 @@ service.gui.UNKNOWN=Bilinmeyen kullanıcı
service.gui.UNKNOWN_STATUS=Bilinmeyen durum
service.gui.UNREGISTERED_MESSAGE=Şu hesaba bağlanılamadı: Kullanıcı adı : {0}, Sunucu adı: {1}. Şu an çevrimdışısınız.
service.gui.USE_PROVISIONING=Online provizyon kullan
-service.gui.VALUE=DeÄŸer:
+service.gui.VALUE=DeÄŸer
service.gui.VIDEO_CALL=Video araması
-service.gui.VIA_SMS=SMS ile gönder
service.gui.VIEW=Görünüm
service.gui.VIEW_HISTORY=Geçmiş görünümü
service.gui.VIEW_SMILEYS=Yüzler görünümü
@@ -512,9 +499,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=Ses ayarla
service.gui.WAITING_AUTHORIZATION=Yetki için bekleniyor
service.gui.WARNING=Uyarı
service.gui.YES=Evet
-service.gui.YESTERDAY=Dün
-service.gui.EXISTING_ACCOUNT_ERROR=Girdiğiniz hesap zaten yüklendi.
-service.gui.NEW_MAIL=<b>Bir yeni maliniz var!</b><br/><b>Den:</b> {0} {1} <br/><b>Konu:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=Sizin {0} <a href="{1}">gelen kutunuzda</a>, yeni bir mail mesajı aldınız:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=Sizin {0} <a href="{1}">gelen kutunuzda</a>, {2} tane yeni mail mesajı aldınız:<br/>
service.gui.NEW_GMAIL_FOOTER=Sizin <a href="{0}">gelen kutunuzda</a> bir tane daha okunmamış konuşma bulunmaktadır.<br/>
@@ -537,7 +521,6 @@ service.gui.SECURITY_ERROR=Güvenlik hatası
service.gui.SPEED=Hız:
service.gui.SILENT_MEMBER=sessiz üye
service.gui.NON_SECURE_CONNECTION={0} hesabı için güvenli bağlantı oluşturulamadı. Eğer güvensiz sunucuyabağlanmak istiyorsanız hesabınız ayarlarında "Güvensiz bağlantılara izin}seçiniz
-service.gui.UPDATE=Güncelle
service.gui.MOBILE_PHONE=Mobil
service.gui.VIDEO_PHONE=Video
service.gui.WORK_PHONE=Ä°ÅŸ
@@ -549,7 +532,7 @@ service.gui.ZID_NAME_SET=ZRTP tanımlayıcısının ismi:
service.gui.ZID_NAME_NOT_SET=ZRTP tanımlayıcısının ismi konulmamış.
service.gui.ZID_NAME_BUTTON=Bir ZRTP tanımlayıcısı ismi koymak için tıklayın.
service.gui.ZID_NAME_DIALOG=ZRTP tanımlayıcısının ismini düzenle
-service.gui.ZID_NAME_UNEXPECTED=<html>ZRTP tanımlayıcı ismi eşleşmiyor.<br><b>Doğrulama metni partneriniz ile karşılaştırın ve kontrol edin!</b><br>ZRTP tanımlayıcısının ismini düzenle ve sadece doğrulama metni tutuyorsa sakla.</html>
+service.gui.ZID_NAME_UNEXPECTED=<html>ZRTP tanımlayıcı ismi eşleşmiyor.<br><b>Doğrulama metni partneriniz ile karşılaştırın ve kontrol edin!</b><br>ZRTP tanımlayıcısının ismini düzenleyin ve sadece doğrulama metni tutuyorsa saklayın.</html>
service.gui.JANUARY=Oca
service.gui.FEBRUARY=Åžub
@@ -569,7 +552,6 @@ service.gui.callinfo.CALL_INFORMATION=Arama bilgisi
service.gui.callinfo.CALL_IDENTITY=Kimlik
service.gui.callinfo.PEER_COUNT=Katılımcı sayısı
service.gui.callinfo.IS_CONFERENCE_FOCUS=Konferans odağı
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Åžifreleme etkin
service.gui.callinfo.CALL_TRANSPORT=Çağrı ulaştırma sinyalleniyor
service.gui.callinfo.CALL_DURATION=Arama süresi
service.gui.callinfo.VIEW_CERTIFICATE=Sertifikayı göster
@@ -580,7 +562,6 @@ service.gui.callinfo.AUDIO_INFO=Ses bilgisi
service.gui.callinfo.VIDEO_INFO=Vieo bilgisi
service.gui.callinfo.LOCAL_IP=Yerel IP/ Port
service.gui.callinfo.REMOTE_IP=Uzak IP/ Port
-service.gui.callinfo.BANDWITH=Bandwith
service.gui.callinfo.LOSS_RATE=Kayıp oranı
service.gui.callinfo.RTT=RTT
service.gui.callinfo.JITTER=SeÄŸirme
@@ -590,10 +571,13 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=Anahtar değiştirme protokolü
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=ICE adayı genişletilmiş türü
service.gui.callinfo.ICE_STATE=ICE iÅŸleme durumu
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=Adayları topla
service.gui.callinfo.ICE_STATE.RUNNING=Bağlantı durumu kontrolleri
service.gui.callinfo.ICE_STATE.COMPLETED=Tamamlandı
service.gui.callinfo.ICE_STATE.FAILED=Başarısız oldu
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=Yerel istemci IP / Port
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=Yerel yansımalı IP / Port
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=Yerel aktarmalı IP / Port
@@ -612,11 +596,12 @@ service.gui.callinfo.JITTER_BUFFER_DELAY=Jitter önbelleği
service.gui.ALWAYS_TRUST=Bu sertifikaya her zaman güven
service.gui.CERT_DIALOG_TITLE=Sertifikayı doğrula
-service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html><br>{0}, {1}:{2}"e bağlanırken sunucunun kimliğini belirleyemez.<br> <br> Sertifika güvenilir değil, bunun anlamı sunucunun kimliği otomatik olarak belirlenemez. Bağlanmaya devam etmek istiyor musunuz?<br><br> Daha fazla bilgi için, "Sertifikayı göster" e tıklayınız.</html>
+service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} sunucunun kimliğini doğrulayamadı <br><b>{1}</b>''e bağlanırken.<br><br>Sertifika güvenilir değil, bunun anlamı sunucunun kimliği otomatik olarak doğrulanamaz.<br><br> Bağlanmaya devam etmek istiyor musunuz?<br> Daha fazla bilgi için, "Sertifikayı göster" e tıklayınız.</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html><br>{0}, {1}:{2}"e bağlanırken sunucunun kimliğini belirleyemez.<br> <br> Sertifika güvenilir değil, bunun anlamı sunucunun kimliği otomatik olarak belirlenemez. Bağlanmaya devam etmek istiyor musunuz?<br><br> Daha fazla bilgi için, "Sertifikayı göster" e tıklayınız.</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html><br>{0}, {1}:{2}"e bağlanırken sunucunun kimliğini belirleyemez.<br> <br> Sertifika güvenilir değil, bunun anlamı sunucunun kimliği otomatik olarak belirlenemez. Bağlanmaya devam etmek istiyor musunuz?<br><br> Daha fazla bilgi için, "Sertifikayı göster" e tıklayınız.</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html><br>{0}, {1}:{2}"e bağlanırken sunucunun kimliğini belirleyemez.<br> <br> Sertifika güvenilir değil, bunun anlamı sunucunun kimliği otomatik olarak belirlenemez. Bağlanmaya devam etmek istiyor musunuz?<br><br> Daha fazla bilgi için, "Sertifikayı göster" e tıklayınız.</html>
service.gui.CONTINUE_ANYWAY=Yine de devam et
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Yaygın isim:
service.gui.CERT_INFO_O=Organizasyon:
service.gui.CERT_INFO_C=Ãœlke ismi:
@@ -625,18 +610,16 @@ service.gui.CERT_INFO_L=İlçe/Mahalle ismi:
service.gui.CERT_INFO_OU=Organizasyon birimi:
service.gui.CERT_INFO_ISSUED_ON=Şu zamanda yayıldı:
service.gui.CERT_INFO_EXPIRES_ON=Åžu zamanda bitiyor:
-service.gui.CERT_INFO_FINGERPRINTS=Parmak Ä°zi
+service.gui.CERT_INFO_FINGERPRINTS=Parmak izleri
service.gui.CERT_INFO_SER_NUM=Seri Numarası:
service.gui.CERT_INFO_VER=Versiyon:
service.gui.CERT_INFO_SIGN_ALG=İmza Algoritması:
service.gui.CERT_INFO_ALG=Algoritma:
service.gui.CERT_INFO_PUB_KEY=Genel Anahtar:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} byte: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} bit
service.gui.CERT_INFO_EXP=Ãœst:
service.gui.CERT_INFO_KEY_SIZE=Anahtar Boyutu:
service.gui.CERT_INFO_SIGN=Ä°mza:
-service.gui.CONTINUE=Devam et
service.gui.SHOW_CERT=Sertifikayı göster
service.gui.HIDE_CERT=Sertifikayı gizle
@@ -657,12 +640,9 @@ service.gui.security.SECURE_AUDIO=Güvenli ses
service.gui.security.AUDIO_NOT_SECURED=Ses güvenli değil
service.gui.security.SECURE_VIDEO=Güvenli video
service.gui.security.VIDEO_NOT_SECURED=Video güvenli değil
-service.gui.security.NO_VIDEO=Video yok
-service.gui.security.CIPHER=Åžifre: {0}
service.gui.security.CALL_SECURED_TOOLTIP=Arama güvenlileştirildi. Daha fazla bilgi için buraya tıklayın.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Arama güvenli değil.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=Güvenlik sırrını partneriniz ile karşılaştırmak için buraya tıklayın.
-service.gui.security.COMPARE_WITH_PARTNER=Partneriniz ile karşılaştırınız ve onaylamak için kilite tıklayınız
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Partneriniz ile karşılaştırın:
service.gui.security.STRING_COMPARED=Metin karşılaştırıldı!
@@ -679,19 +659,13 @@ service.gui.avatar.imagepicker.CLICK=Tıkla ve Gülümse
service.gui.avatar.imagepicker.IMAGE_FILES=Resim dosyaları
service.gui.avatar.imagepicker.IMAGE_PICKER=Resim
service.gui.avatar.imagepicker.IMAGE_SIZE=Resim boyutu
-service.gui.avatar.imagepicker.INITIALIZING=Başlatılıyor
service.gui.avatar.imagepicker.RESET=Sıfırla
service.gui.avatar.imagepicker.SET=Ayarla
service.gui.avatar.imagepicker.TAKE_PHOTO=Resim çek
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Webcam hatası
service.gui.security.encryption.required=Åžifrleme gerekli!
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
impl.protocol.sip.XCAP_ERROR_TITLE=SIP kiÅŸi listesi depolamada hata
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=Kaynak okunamadı {0}. {1} için
@@ -714,9 +688,7 @@ impl.gui.main.account.DUMMY_PROTOCOL_DESCRIPTION=ağ seç
# LDAP
impl.ldap.CONFIG_FORM_TITLE=LDAP ayarları
impl.ldap.GENERAL=Genel
-impl.ldap.NEW=Yeni
impl.ldap.EDIT=düzenle
-impl.ldap.REMOVE=Sil
impl.ldap.ENABLED=Aktif et
impl.ldap.SERVER_NAME=Sunucu adı
impl.ldap.SERVER_NAME_EXAMPLE=LDAP sunucum
@@ -749,6 +721,10 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=ev telefonu
impl.ldap.PHONE_PREFIX=Telefon öneki
impl.ldap.PHONE_PREFIX_EXAMPLE=Ör:00
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=Adres defteri
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=MacOSX Adres Defterini aramayı etkinleştir
@@ -759,9 +735,7 @@ plugin.addrbook.PREFIX_EXAMPLE=Ör.:00
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Google KiÅŸiler
-impl.googlecontacts.NEW=Yeni
impl.googlecontacts.EDIT=düzenle
-impl.googlecontacts.REMOVE=Sil
impl.googlecontacts.ENABLED=Aktif et
impl.googlecontacts.ACCOUNT_NAME=Hesap Adı
impl.googlecontacts.SAVE=Kaydet
@@ -775,7 +749,7 @@ impl.googlecontacts.WRONG_CREDENTIALS={0} Google hesabı için yanlış kimlik b
plugin.accountinfo.TITLE=Hesap Bilgisi
plugin.accountinfo.EXTENDED=GeniÅŸletilmiÅŸ
plugin.accountinfo.NOT_SUPPORTED=Hesap bilgisi yok.
-plugin.accountinfo.DISPLAY_NAME=Gösterilen isim
+plugin.accountinfo.DISPLAY_NAME=Görünen isim:
plugin.accountinfo.FIRST_NAME=Ä°sim:
plugin.accountinfo.MIDDLE_NAME=Ä°kinci Ä°sim:
plugin.accountinfo.LAST_NAME=Soy Ä°sim:
@@ -783,16 +757,13 @@ plugin.accountinfo.NICKNAME=Takma ad:
plugin.accountinfo.AGE=YaÅŸ:
plugin.accountinfo.BDAY=DoÄŸum Tarihi:
plugin.accountinfo.GENDER=Cinsiyet:
-plugin.accountinfo.CITY=Åžehir
-plugin.accountinfo.POST=Posta kodu
-plugin.accountinfo.COUNTRY=Ãœlke
+plugin.accountinfo.CITY=Åžehir:
+plugin.accountinfo.POST=Posta kodu:
+plugin.accountinfo.COUNTRY=Ãœlke:
plugin.accountinfo.EMAIL=E-mail Adresi:
plugin.accountinfo.PHONE=Telefon:
plugin.accountinfo.MOBILE_PHONE=cep telefonu
plugin.accountinfo.JOB_TITLE=İş tanımı
-plugin.accountinfo.USER_PICTURES=Kullanıcı Resimleri
-plugin.accountinfo.CHANGE=DeÄŸiÅŸtir
-plugin.accountinfo.ONLY_MESSAGE=Sadece mesajlar
# connection info
@@ -811,49 +782,12 @@ plugin.aimaccregwizz.USERNAME=AIM Ekran Ä°smi
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Ekran Ä°smi ve Åžifre
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=Yeni hesap kaydet
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Eğer AIM hesabınız yoksa, bu butona tıklayarak yeni bir hesap alabilirsiniz.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Sunucu varsayılan ayarlarını üzerine yaz
# branding
plugin.branding.ABOUT_WINDOW_TITLE={0} hakkında
plugin.branding.LOGO_MESSAGE=Açık kaynak kodlu VoIP && Anlık Mesajlaşma
-plugin.branding.LOADING=Yükleniyor
plugin.branding.ABOUT_MENU_ENTRY=Hakkında
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>{1} aktif olarak geliştirilmektedir. Şu an kullanmakta olduğunuz versiyon test aşamasındadır ve beklendiği gibi ÇALIŞMAYABİLİR. Lütfen daha fazla bilgi için {2}.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 Copyright <b>jitsi.org</b>Bütün hakları gizlidir. Ziyaret et <a href="http://jitsi.org">http://jitsi.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}> <b>Jitsi</b> LGPL lisansı koşulları altında dağıtılmaktadır(<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=Sözlükler
-plugin.dictaccregwizz.ANY_DICTIONARY=Herhangi bir sözlük
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM={0}"dan herhangi bir sözlük
-plugin.dictaccregwizz.FIRST_MATCH=Ä°lk EÅŸleÅŸen
-plugin.dictaccregwizz.NO_MATCH=EÅŸleÅŸen yok
-plugin.dictaccregwizz.MATCH_RESULT="{0}" için tanım bulunamadı, belki bunu demek istediniz:\n
-plugin.dictaccregwizz.INVALID_DATABASE=Şuanki sözlük "{0}" artık sunucuda bulunmamaktadır.
-plugin.dictaccregwizz.INVALID_STRATEGY=Şuanki arama kriteri sunucuda hazır değildir.
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=Dict servis protokolü
-plugin.dictaccregwizz.HOST=Servis sağlayıcı
-plugin.dictaccregwizz.SERVER_INFO=Sunucu bilgileri
-plugin.dictaccregwizz.STRATEGY_SELECTION=Arama kriteri seçimi
-plugin.dictaccregwizz.STRATEGY_LIST=Arama kriterleri listesi
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Arama kriterlerini ara
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=Arama kriteri, eğer çviri yoksa benzer kelimeleri bulmak için kullanılır. Örneğin önden arama kriteri, sizin çevireceğiniz kelimenin ilk harfiyle başlayan kelimeleri arayacak.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Dict Hesap Bilgileri
-plugin.dictaccregwizz.FIRST_ACCOUNT=Bu sihirbaz sizin için dict.org'da bir Dict hesabı açacaktır.\n\nHesap Kayıt Sihirbazına giderek yeni bir sözlük ekleyebilirsiniz. Servis sağlayıcı kısmını eklemek istediğiniz sözlük ile doldurunuz.
-plugin.dictaccregwizz.THREAD_CONNECT=Sunucuya bağlanmaya çalışıyor
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=Bağlanamadı, bu dict sunucusu değil veya sunucu çevrim dışı
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=Arama kriterleri alınıyor
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Sunucuda arama kriteri bulunamadı
-plugin.dictaccregwizz.POPULATE_LIST=Liste dolduruluyor
-plugin.dictaccregwizz.CLOSING_CONNECTION=Bağlantı kapatılıyor
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Facebook sohbeti kullanabilmek için Hesap Ayarları sayfasından bir kullanıcı ismi oluşturmalısınız.a><br><br>Not: Kullanıcı ismi aldıktan sonra oturum kapatmalısınız ve yeni kullanıcı isminizle oturum açmak biraz zaman alabilir.</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=Facebook Sohbet Protokolü
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Kullanıcı Adı:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Kullanıcı Adı ve Şifre
+
# generalconfig
plugin.generalconfig.AUTO_START=Bilgisayar baştan başladığında otomatik başlat {0}.
@@ -864,9 +798,6 @@ plugin.generalconfig.SHOW_HISTORY=Göster
plugin.generalconfig.HISTORY_SIZE=Yeni sohbetlerdeki son mesajlar
plugin.generalconfig.SEND_MESSAGES_WITH=Mesajları şunla gönder:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=Sohbet penceresini öne getir
-plugin.generalconfig.ERROR_PERMISSION=Otomatik başlatı silmek için yeterli izniniz yok
-plugin.generalconfig.TRANSPARENCY=Saydamlık
-plugin.generalconfig.ENABLE_TRANSPARENCY=Saydamlığı aktif et
plugin.generalconfig.DEFAULT_LANGUAGE=Arabirim dili
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Değişiklikler tekrar başladığında aktif olacak.
plugin.generalconfig.SIP_CLIENT_PORT=SIP istemci portu
@@ -910,19 +841,20 @@ plugin.icqaccregwizz.REGISTER_NEW_ACCOUNT=Yeni hesap kaydet
plugin.ircaccregwizz.PROTOCOL_NAME=IRC
plugin.ircaccregwizz.PROTOCOL_DESCRIPTION=IRC protokol
plugin.ircaccregwizz.USERNAME_AND_PASSWORD=Kullanıcı ID ve Şifre
+plugin.ircaccregwizz.USERNAME=Rumuz
plugin.ircaccregwizz.INFO_PASSWORD=Genellikle IRC sunucuları şifre istemez.
plugin.ircaccregwizz.AUTO_NICK_CHANGE=Eğer takma ad daha önce kullanıldıysa otomatik olarak değiştir
plugin.ircaccregwizz.USE_DEFAULT_PORT=Varsayılan portu kullan
plugin.ircaccregwizz.PASSWORD_NOT_REQUIRED=Benim takma adım kimlik tanımlaması gerektirmez
plugin.ircaccregwizz.HOST=Servis sağlayıcı:
plugin.ircaccregwizz.IRC_SERVER=Sunucu
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE={0} onaylama
+plugin.ircaccregwizz.SASL_USERNAME=Kullanıcı adı
# jabber accregwizz
-plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=XMPP protokol
plugin.jabberaccregwizz.USERNAME=XMPP kullanıcı adı
plugin.jabberaccregwizz.PASSWORD_CONFIRM=Åžifreyi onayla
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=Kullanıcı ID ve Şifre
plugin.jabberaccregwizz.CSERVER=Sunucu
plugin.jabberaccregwizz.SERVER=Sunucuya BaÄŸlan
plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=Bağlantının canlı durmasını aktif et
@@ -938,13 +870,9 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Yorum
plugin.jabberaccregwizz.RESOURCE=Kaynak
plugin.jabberaccregwizz.AUTORESOURCE=Otomatik kaynak oluÅŸtur
plugin.jabberaccregwizz.PRIORITY=Öncelik
-plugin.jabberaccregwizz.XMPP_ERROR=XMPP Hatası
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Bilinmeyen XMPP hatası. Sunucu isminin doğruluğundan emin olunuz.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Åžifreler birbiri ile uyumlu deÄŸil
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Sunucu varsayılan ayarlarının üstüne yaz
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=GeliÅŸmiÅŸ ayarlar
plugin.jabberaccregwizz.USE_ICE=ICE kullan
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=Google Jingle/ICE kullan(deneysel)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=Otomatik STUN/TURN sunucularını ara
plugin.jabberaccregwizz.SUPPORT_TURN=TURN destekle
plugin.jabberaccregwizz.TURN_USERNAME=TURN kullanıcı adı
@@ -971,11 +899,8 @@ plugin.jabberaccregwizz.ALLOW_NON_SECURE=Güvensiz bağlantılara izin ver
plugin.jabberaccregwizz.DTMF_AUTO=Otomatik: RTP ve Inband arasında seçim yap
plugin.jabberaccregwizz.SERVER_OPTIONS=Sunucu seçenekleri
plugin.jabberaccregwizz.CHANGE_PASSWORD=Hesap parolasını değiştir
-plugin.jabberaccregwizz.NEW_PASSWORD=Yeni parola
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Yeni parolayı onayla
plugin.jabberaccregwizz.PORT_FIELD_INVALID=Devam etmek için lütfen geçerli bir port numarası girin.
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=Parola değiştirmeden önce bu hesaba giriş yapılmalıdır.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=Bu parola boÅŸ.
plugin.jabberaccregwizz.TLS_REQUIRED=Bağlantı TLS kullanmıyor, parola değişikliği girişiminde bulunulmayacak.
plugin.jabberaccregwizz.PASSWORD_CHANGED=Parola başarıyla değiştirildi
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=Jabber sunucunuz parola deÄŸiÅŸikliÄŸini desteklemiyor.
@@ -989,25 +914,9 @@ plugin.jabberaccregwizz.RESET=Sıfırla
plugin.jabberaccregwizz.RESET_DESCRIPTION=Sıfırlayarak evrensel ayarlara dön
plugin.jabberaccregwizz.DISABLE_JINGLE=Jingle'ı (XMPP ile sesli ve videolu aramalar) devredışı bırak
-# mailbox
-plugin.mailbox.OUTGOING=Giden Mesajlar
-plugin.mailbox.INCOMING=Gelen Mesajlar
-plugin.mailbox.WAIT_TIME=Arama sesli mesaja gönderilene kadar beklet
-plugin.mailbox.MAX_MESSAGE_TIME=Maksimum gelen mesaj süresi
-plugin.mailbox.CONFIRM=Onayla
-plugin.mailbox.DEFAULTS=Varsayılan
-plugin.mailbox.MAILBOX=Mail kutusu
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=MSN servise bağlanmak ve sohbet etmek için protokol.
-plugin.msnaccregwizz.USERNAME=E-mail adresi:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=Kullanıcı Adı ve Şifre
-
# plugin manager
plugin.pluginmanager.INSTALL=Yükle
plugin.pluginmanager.UNINSTALL=Kaldır
-plugin.pluginmanager.UPDATE=Güncelle
plugin.pluginmanager.PLUGINS=Eklentiler
plugin.pluginmanager.URL=Adresi
plugin.pluginmanager.CHOOSE_FILE=Dosya Seç
@@ -1032,7 +941,6 @@ plugin.sipaccregwizz.SERVER_PORT=Sunucu portu
plugin.sipaccregwizz.PROXY=Proxy
plugin.sipaccregwizz.PROXY_PORT=Proxy port
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Tercih edilen taşıma
-plugin.sipaccregwizz.ADVANCED_OPTIONS=GeliÅŸmiÅŸ ayarlar
plugin.sipaccregwizz.PROXY_OPTIONS=Proxy seçenekleri
plugin.sipaccregwizz.PROXY_AUTO=Proxy i otomatik ayarla
plugin.sipaccregwizz.ENABLE_PRESENCE=Durum Bilgisini(SIMPLE) aktif et
@@ -1049,8 +957,6 @@ plugin.sipaccregwizz.DTMF_AUTO=Otomatik: RTP ve Inband arasında otomatik seçim
plugin.sipaccregwizz.DTMF_RTP=RTP ( RFC2833 / RFC 4733 )
plugin.sipaccregwizz.DTMF_SIP_INFO=SIP bilgisi
plugin.sipaccregwizz.DTMF_INBAND=Inband
-plugin.sipaccregwizz.REGISTER=KAYDOL
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Varsayılan sunucu ayarlarının üzerine yaz
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Aramaları şifrelemeyi aktif et
plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=Sinyal protokolünde ZRTP desteğini belirt
plugin.sipaccregwizz.AUTH_NAME=Yetki ismi
@@ -1068,16 +974,16 @@ plugin.sipaccregwizz.VOICEMAIL=Sesli posta
plugin.sipaccregwizz.MWI=Mesaj bekleniyor (MWI)
plugin.sipaccregwizz.VOICEMAIL_URI=Sesli posta Abonelik URI
plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=Sesli posta kontrol URI
-plugin.sipaccregwizz.NOT_SAME_PASSWORD=Åžifrenler biribiri ile uyumlu deÄŸil
-plugin.sipaccregwizz.NO_CERTIFICATE=<hiçbiri>(düzenli kimlik bilgilerini kullan)
+plugin.sipaccregwizz.NOT_SAME_PASSWORD=<hiçbiri> (sıradan yetkilendirme kullan)
+plugin.sipaccregwizz.NO_CERTIFICATE=<hiçbiri> (sıradan yetkilendirme kullan)
plugin.sipaccregwizz.SAVP_OPTION=RTP/SAVP iÅŸareti
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=Kapat(yalnızca RTP/AVP işareti)
plugin.sipaccregwizz.SAVP_OPTION_1=Zorunlu (yalnızca RTP/SAVP öner ve kabul et)
plugin.sipaccregwizz.SAVP_OPTION_2=İsteğe bağlı(önce RTP/SAVP öner, sonra RTP/AVP )
-plugin.sipaccregwizz.ENABLE_SDES_ATTRIBUTE=S-Descriptor etkinleÅŸtir (SDES veya SRTP olarakta bilinir)
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=Devredeki şifreleme protokollerini ve öncelik sırasını seç (üstteki protokol önce gelir):
plugin.sipaccregwizz.CIPHER_SUITES=Şifre takımlarını etkinleştir
-plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>{0} ZRTP ile tüm çağrılarınızı otomatik olarak güvene
+plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>{0} tüm çağrılarınızı otomatik olarak ZRTP ile güvenli hale getirecek ve güvenli bağlantı kurulduğunda her iki tarafta da bir bildirim görünecek. Aşağıdaki ayarları yalnızca ne olduklarını biliyorsanız düzenlemelisiniz.</div></html>
plugin.sipaccregwizz.SHOW_ADVANCED=Gelişmiş şifreleme ayarları
plugin.sipaccregwizz.ZRTP_OPTION=ZRTP seçeneği
plugin.sipaccregwizz.SDES_OPTION=SDes seçeneği
@@ -1088,15 +994,6 @@ plugin.skinmanager.DEFAULT_SKIN=Varsayılan tema
plugin.skinmanager.ADD_NEW_SKIN=Yeni tema ekle
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=Programın varsayılan teması
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=SSH üzerinden uzaktaki makinalara bağlanırken kullanılan bir protokol.
-plugin.sshaccregwizz.USERNAME=Hesap ID:
-plugin.sshaccregwizz.IDENTITY_FILE=Kimlik Dosyası:
-plugin.sshaccregwizz.KNOWN_HOSTS=Bilinen Servis Sağlayıcılar
-plugin.sshaccregwizz.OPTIONAL=İsteğe bağlı
-plugin.sshaccregwizz.ACCOUNT_DETAILS=Hesap Detayları
-
# status update
plugin.autoaway.AUTO_STATUS=Otomatik olarak uzakta
plugin.autoaway.ENABLE_CHANGE_STATUS=Uzaktayken durumu deÄŸiÅŸtir
@@ -1141,27 +1038,11 @@ plugin.whiteboard.DESELECT=Seçme
plugin.whiteboard.DELETE=Sil
plugin.whiteboard.PROPERTIES=Özellikler
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Yahoo! servisine bağlanmak ve sohbet etmek için kullanılan bir protokol.
-plugin.yahooaccregwizz.USERNAME=Kullanıcı adı:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=Kullanıcı ID ve Şifre
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=Zeroconf(Bonjour) servis protokolü
-plugin.zeroaccregwizz.FIRST_NAME=Ä°sim:
-plugin.zeroaccregwizz.LAST_NAME=Soyisim:
-plugin.zeroaccregwizz.EMAIL=E-mail adresi:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=Bonjour kişilerini hatırla
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=Kullanıcı adı ve Şifre
-plugin.zeroaccregwizz.USERID=Kullanıcı ID
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Google Talk protokolü
plugin.googletalkaccregwizz.USERNAME=Google Talk kullanıcı adı
-plugin.googletalkaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Eğer Google Talk hesabınız yoksa, bu butona tıklayarak yeni bir tane alabilirsiniz.
+plugin.googletalkaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=Eğer Google Talk hesabınız yoksa,<br> bu butona tıklayarak yeni bir tane alabilirsiniz.
plugin.googletalkaccregwizz.NEW_ACCOUNT_TITLE=Google Talk yeni hesap kaydı
# iptel accregwizz
@@ -1170,19 +1051,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, IP telekomüniskasyon por
plugin.iptelaccregwizz.USERNAME=Kullanıcı adı
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=iptel.org'a abone ol
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=Internet arama ve sohbet
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Kullanıcı adı
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Åžifreyi tekrar giriniz
plugin.sip2sipaccregwizz.EMAIL=Email adresi
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=Servis hakkında yardım için <br>http://wiki.sip2sip.info 'yu ziyaret ediniz
-plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>Email adresi sesli mesaj göndermek, kaçırılan aramaların hatırlatmaları ve unutulan şifre için kullanılacaktır.</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>Servis hakkında yardım için ziyaret ediniz<a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=Varolan sip2sip.info hesabı
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Bedava sip2sip.info hesabı oluştur
-
-# ippi accregwizz
+plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>Email adresiniz sesli mesaj göndermek, cevapsız çağrı <br>hatırlatmaları ve unutulan şifre için kullanılacaktır.</html>
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP && Anlık Mesajlaşma
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=Servis hakkında yardım için <br>http://ippi.fr 'yu ziyaret ediniz
@@ -1191,6 +1064,7 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=Varolan ippi hesabı
plugin.ippiaccregwizz.CREATE_ACCOUNT=Bedava ippi hesabı oluştur
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Sohbet penceresini kapat
plugin.keybindings.CHAT_COPY=Kopyala
plugin.keybindings.CHAT_CUT=Kes
@@ -1213,9 +1087,9 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=Ä°sim
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=Ana kısayol
plugin.keybindings.globalchooser.SHORTCUT_SECOND=İkinci kısayol
plugin.keybindings.globalchooser.PRESS_BTN=Kısayolu atamak için bas
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=Bekleniyor
plugin.keybindings.globalchooser.ENABLE_SPECIAL=Özel tuş tanımlamayı etkinleştir
plugin.keybindings.PLUGIN_NAME=Tuş bağlayıcıları
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Sohbet
plugin.keybindings.MAIN=Ana
plugin.keybindings.GLOBAL=Genel kısayollar
@@ -1243,6 +1117,7 @@ plugin.notificationconfig.tableheader.SOUND=Bildirim aygıtından bir ses oynat
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=Geri oynatma aygıtından bir ses oynat
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=PC speaker aygıtından bir ses oynat
plugin.notificationconfig.tableheader.DESCRIPTION=Olayın tanımı
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Gelen arama
plugin.notificationconfig.event.SecurityMessage=Güvenlik mesajı
plugin.notificationconfig.event.IncomingFile=Gelen dosya
@@ -1340,6 +1215,7 @@ impl.neomedia.configform.VIDEO=Video
impl.neomedia.configform.H264=H.264
impl.neomedia.configform.H264.defaultProfile=Kodlama yapılacak varsayılan profil:
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=Baz Profil
impl.neomedia.configform.H264.defaultProfile.main=Ana Profil
impl.neomedia.configform.H264.preferredKeyFrameRequester=Anahtarları talep etmek için seçilen yöntem:
@@ -1368,7 +1244,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=Åžuanki ÅŸifre:
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Yeni ÅŸifre giriniz:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Åžifreyi tekrar giriniz:
plugin.securityconfig.masterpassword.MP_TITLE=Ana Åžifre
-plugin.securityconfig.masterpassword.MP_NOT_SET=(ayarlanmamış)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=Doğru ana şifreyi girmediniz. Lütfen tekrar deneyiniz.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=Ana ÅŸifre doÄŸru deÄŸil!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Åžifre deÄŸiÅŸtirilemedi
@@ -1384,7 +1259,6 @@ plugin.securityconfig.masterpassword.COL_PASSWORD=Åžifre
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(bilinmeyen)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(şifre çözülemiyor)
plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=Kayıtlı Şifreler
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=Sil
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=Hepsini sil
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=Bütün şifreleri silmek istiyor musunuz?
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=Bütün şifreleri sil
@@ -1403,7 +1277,7 @@ plugin.otr.menu.REFRESH_OTR=Özel konuşmayı tazele
plugin.otr.menu.AUTHENTICATE_BUDDY=Arkadaşı onayla
plugin.otr.menu.WHATS_THIS=Bu nedir
plugin.otr.menu.CB_AUTO=Otomatik olarak özel mesajlaşmayı başlat
-plugin.otr.menu.CB_AUTO_ALL=Otomatik olarak özel mesajlaşmayı başlat
+plugin.otr.menu.CB_AUTO_ALL=Tüm kişilerle özel mesajlaşmayı otomatik olarak başlat
plugin.otr.menu.CB_ENABLE=Özel mesajlaşmayı aktif et
plugin.otr.menu.CB_REQUIRE=Özel mesajlaşma iste
plugin.otr.menu.CB_RESET=Sıfırla
@@ -1448,7 +1322,6 @@ plugin.globalproxy.PROXY_PORT=Proxy Portu
plugin.globalproxy.PROXY_USERNAME=Proxy Kullanıcı Adı
plugin.globalproxy.PROXY_PASSWORD=Proxy ÅŸifresi
plugin.globalproxy.DESCRIPTION={0} bundan sonra sizin bağlı olduğunuz ve tekrar bağlandığınız bütün ağlar için yukarıdaki proxy ayarlarını kullanacaktır. \nProxy desteği şu an test aşamasındadır ve sadece bazı bağlantı protokolleri çalışmaktadır Daha fazla bilgi için aşağıdaki tabloyu kontrol ediniz:
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>JABBER</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
# plugin reconnect
@@ -1461,7 +1334,7 @@ plugin.reconnectplugin.NETWORK_DOWN=Ağ bağlantısı koptu!
plugin.chatconfig.TITLE=Sohbet
plugin.chatconfig.replacement.TITLE=Resim/Video:
plugin.chatconfig.replacement.ENABLE_SMILEY_STATUS=Gülücük değişimini etkinleştir
-plugin.chatconfig.replacement.REPLACEMENT_TITLE=Resim/Video deÄŸiÅŸimini etkinleÅŸtir
+plugin.chatconfig.replacement.REPLACEMENT_TITLE=Resim/Video deÄŸiÅŸimi
plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS=Aktif et
plugin.chatconfig.replacement.REPLACEMENT_SOURCES=Kaynaklar:
plugin.chatconfig.spellcheck.TITLE=Ä°mla Klavuzu
@@ -1479,7 +1352,6 @@ plugin.provisioning.RESTART_WARNING={0} değişiklikleriniz sonraki programı ye
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=UUID kopyala
plugin.provisioning.CLIPBOARD_FAILED=UUID kopyalama başarısız
-plugin.provisioning.EXIT_ON_FAIL=Provizyon sağlanamazsa programdan çık
plugin.provisioning.CREDENTIALS=Son kaydedilen provizyon bilgileri
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=Provizyon ÅŸifresini silmek istediÄŸinizden emin misiniz?
plugin.provisioning.PROV_FAILED=Provizyonlama başarısız oldu
@@ -1546,8 +1418,6 @@ util.dns.DNSSEC_WARNING=<html><div width="600">{0}, sunucuya <b>{1}</b>'den baÄŸ
#plugin spellcheck
plugin.spellcheck.TITLE=Ä°mla ve Dilbilgisi
plugin.spellcheck.MENU=İmla ve Dilbilgisi göster
-plugin.spellcheck.LANG=Dil
-plugin.spellcheck.EDIT_PERSONAL_DICT=Düzenle
plugin.spellcheck.ENABLE_SPELL_CHECK=İmla kontrolünü etkinleştir
plugin.spellcheck.dialog.FIND=Sonrakini bul
plugin.spellcheck.dialog.REPLACE=DeÄŸiÅŸtir
@@ -1592,5 +1462,5 @@ plugin.phonenumbercontactsource.DISPLAY_NAME=Telefon numaraları
# properties editor
#Thunderbird address book plugin
-plugin.thunderbird.ENABLED=Aktif et
-plugin.thunderbird.PHONE_PREFIX=Telefon öneki
+plugin.thunderbird.ENABLED=Etkin
+plugin.thunderbird.PHONE_PREFIX=Telefon öneki:
diff --git a/resources/languages/resources_uk.properties b/resources/languages/resources_uk.properties
index da09699..53e2064 100644
--- a/resources/languages/resources_uk.properties
+++ b/resources/languages/resources_uk.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -32,7 +43,6 @@ service.gui.ACCOUNT_ME=Я
service.gui.ACCOUNT_REGISTRATION_WIZARD=МайÑтер реєÑÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ñ… запиÑів
service.gui.ACCOUNTS=Облікові запиÑи
service.gui.ADD=&Додати
-service.gui.ADD_ACCOUNT=Додати обліковий запиÑ
service.gui.ADD_CONTACT=&Додати контакт
service.gui.ADD_AUTHORIZED_CONTACT=Додати {0} до ÑпиÑку контактів
service.gui.ADD_CONTACT_TO_CONTACTLIST=Додати контакт у ваш ÑпиÑок контактів
@@ -42,20 +52,15 @@ service.gui.ADD_CONTACT_ERROR_TITLE=Помилка Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ ÐºÐ¾Ð½Ñ‚Ð°
service.gui.ADD_CONTACT_EXIST_ERROR=Контакт {0} вже Ñ–Ñнує у ÑпиÑку контактів.
service.gui.ADD_CONTACT_NETWORK_ERROR=Сервер не відповів на запит Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ñƒ: {0}.
service.gui.ADD_CONTACT_NOT_SUPPORTED=Ðе вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ контакт: {0}. ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ðµ підтримуєтьÑÑ.
-service.gui.ADD_CONTACT_IDENTIFIER=Введіть ідентифікатор контакту, Ñкий хочете додати.
-service.gui.ADD_CONTACT_WIZARD=МайÑтер Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ñ–Ð²
service.gui.ADD_CONTACT_NOT_CONNECTED=Щоб додати контакт, необхідно підключитиÑÑ. Будь-лаÑка, виконайте вхід Ñ– Ñпробуйте знову.
service.gui.ADD_GROUP_LOCAL_ERROR=Ðе вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ групу: {0}. ВідбувÑÑ Ð·Ð±Ñ–Ð¹ операції вводу-виводу.
service.gui.ADD_GROUP_EXIST_ERROR=Група {0} вже Ñ–Ñнує у ÑпиÑку контактів. БудьлаÑка, оберіть інше ім’Ñ.
service.gui.ADD_GROUP_NET_ERROR=Ðе вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ групу: {0}. ВідбулаÑÑ Ð¼ÐµÑ€ÐµÐ¶ÐµÐ²Ð° помилка. БудьлаÑка, перевірте ваше мережеве Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ñ– Ñпробуйте знову.
service.gui.ADD_GROUP_ERROR=Ðе вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ групу: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=Ðазва групи не може бути порожньою.
-service.gui.ADD_GROUP=Створити групу
-service.gui.ADD_SUBCONTACT=&Додати додатковий контакт
service.gui.ADDRESS=ÐдреÑа
service.gui.ADMINISTRATOR=адмініÑтратор
service.gui.ADVANCED=&Розширені
-service.gui.ALL=&Ð’ÑÑ–
service.gui.ALL_CONTACTS=&Ð’ÑÑ– контакти
service.gui.ALTERNATE_ADDRESS=Ðльтернативна адреÑа
service.gui.APPLY=&ЗаÑтоÑувати
@@ -65,7 +70,6 @@ service.gui.AT=чаÑ
service.gui.AUTHORIZE=&Ðвторизувати
service.gui.AUTHORIZATION_ACCEPTED={0} прийнÑв запит авторизації.
service.gui.AUTHENTICATION_FAILED=Перевірити ÑправжніÑÑ‚ÑŒ {0} не вдалоÑÑ. Введений пароль невірний.
-service.gui.AUTHENTICATION_REQUESTED=Запит перевірки ÑправжноÑÑ‚Ñ–
service.gui.AUTHENTICATION_REQUESTED_SERVER=Сервер {0} запитує перевірку ÑправжноÑÑ‚Ñ–.
service.gui.AUTHENTICATION_REJECTED={0} відхилив запит авторизації.
service.gui.AUTHENTICATION_WINDOW_TITLE=Ð†Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ {0}
@@ -107,7 +111,6 @@ service.gui.CHANGE_NICKNAME_LABEL=Ð’ полі нижче ви можее ввеÑ
service.gui.CHANGE_NICKNAME_ERROR=Помилка при зміні прізвиÑька
service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=ПрізвиÑько вже Ñ–Ñнує
service.gui.CHANGE_VIDEO_QUALITY=Змінити ÑкіÑÑ‚ÑŒ вхідного відео
-service.gui.CHAT_CONFERENCE_LABEL=Конференції
service.gui.CHAT_CONFERENCE_ITEM_LABEL=ÐšÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ñ–Ñ ÐºÐ¾Ñ€Ð¸Ñтувача {0}
service.gui.CHAT_ROOM_ALREADY_JOINED=ÐšÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ñ–Ñ {0} вже підключена.
service.gui.CHAT_ROOM_CONFIGURATION=ÐšÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ñ–Ñ— {0}
@@ -121,18 +124,14 @@ service.gui.CHAT_ROOM_USER_LEFT=покинув {0}
service.gui.CHAT_ROOM_USER_KICKED=був виключений з {0}
service.gui.CHAT_ROOM_USER_QUIT=вийшов із {0}
service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=ÐадÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ заборонено (вимкнено звук)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=Зберігає конференцію Ð´Ð»Ñ Ð¿Ð¾Ð´Ð°Ð»ÑŒÑˆÐ¾Ð³Ð¾ викориÑтаннÑ
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=Вилучає вибрану конференцію зі ÑпиÑку збережених конференцій
service.gui.CHAT_ROOM_NAME=Ðазва конференції
service.gui.CLEAR_CUSTOM_MESSAGES=ОчиÑтити перÑоналізовані повідомленнÑ
service.gui.ROOM_NAME=КонференціÑ
-service.gui.AUTOJOIN=Ðвтоматичний вхід
service.gui.CHANGE_PASSWORD=Змінити пароль
service.gui.CHAT_ROOM_NAME_INFO=Ð’ полі нижче введіть Ñ–Ð¼â€™Ñ ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ñ–Ñ—, Ñку хочете Ñтворити.
service.gui.CHAT_ROOM_NOT_EXIST=ÐšÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ñ–Ñ {0} не знайдена на Ñервері {1}. БудьлаÑка, перевірте правильніÑÑ‚ÑŒ введеного імені.
service.gui.CHAT_ROOM_NOT_CONNECTED=Ви повинні бути зареєÑтровані, щоб мати можливіÑÑ‚ÑŒ приєднатиÑÑ Ð´Ð¾ конференції {0}.
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=Ви повинні бути підключені щоб мати можливіÑÑ‚ÑŒ вийти з конференції.
-service.gui.CHAT_ROOM_NOT_JOINED=Ви повинні ввійти в конференцію, щоб мати можливіÑÑ‚ÑŒ здійÑнювати операції з нею.
service.gui.CHAT_ROOM_OPTIONS=ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ñ–Ñ—
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=ÐšÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ñ–Ñ {0} вимагає реєÑÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ñƒ.
service.gui.CHAT_ROOM_REQUIRES_PASSWORD=ÐšÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ñ–Ñ {0} запитує пароль.
@@ -157,16 +156,13 @@ service.gui.CONNECTING=ПідключеннÑ...
service.gui.CONNECTING_STATUS=ПідключеннÑ
service.gui.CONNECTING_EARLY_MEDIA_STATUS=ПідключеннÑ*
service.gui.CONNECTION=З’єднаннÑ
-service.gui.CONNECTION_FAILED_MSG=Ðе вдалоÑÑ Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð½Ð°Ñтупного облікового запиÑу: Ð†Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача: {0}, Ðазва Ñервера: {1}. БудьлаÑка перевірте ваше мережеве Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð°Ð±Ð¾ звÑжітьÑÑ Ð· вашим мережевим адмініÑтратором Ð´Ð»Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¾Ð²Ð¾Ñ— інформації.
service.gui.CONNECTION_EXPIRED_MSG=Ð’ даний момент ви відключені від Ñервера {0}.
service.gui.CONTACT_NAME=ID або номер
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=Вибраний контакт {0} не підтримує голоÑовий звÑзок.
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=Вибраний контакт {0} не підтримує чат в конференції.
service.gui.CONTACT_PAUSED_TYPING={0} переÑлав друковане повідомленнÑ
service.gui.CONTACT_TYPING={0} друкує повідомленнÑ
service.gui.CONTACT_TYPING_SEND_FAILED=Ñпіврозмовник {0} не побачить Ð¿Ñ€Ð¾Ñ†ÐµÑ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ
service.gui.CONTACT_INFO=&Контактна інформаціÑ
-service.gui.CONTACTLIST=СпиÑок контактів
service.gui.CONTACTS=Контакти
service.gui.COPY=&Копіювати
service.gui.COPY_LINK=Копіювати &поÑиланнÑ
@@ -176,27 +172,24 @@ service.gui.CREATE_CHAT_ROOM=&Створити конференцію...
service.gui.CREATE_CHAT_ROOM_ERROR=Ðе вдалоÑÑ Ñтворити конференцію {0}.
service.gui.CREATE_CHAT_ROOM_WIZARD=МайÑтер ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ñ–Ð¹
service.gui.CREATE_CONFERENCE_CALL=&Створити багатокориÑтувацький дзвінок...
-service.gui.CREATE_CONFERENCE_CHAT=&Створити багатокориÑтувацький чат...
service.gui.CREATE_GROUP=&Створити групу...
service.gui.CREATE_GROUP_NAME=Ð’ полі нижче введіть Ñ–Ð¼â€™Ñ Ð³Ñ€ÑƒÐ¿Ð¸, Ñку хочете Ñтворити.
-service.gui.CREATE_FIRST_GROUP_WIZARD=Ваш ÑпиÑок контактів не міÑтить жодної групи. БудьлаÑка, Ñпочатку Ñтворіть групу (Файл/Створити групу).
service.gui.CREATE_VIDEO_BRIDGE=Створити &відеоміÑÑ‚...
service.gui.CREATE_VIDEO_BRIDGE_MENU=Створити &відеоміÑÑ‚
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=Створити / ДолучитиÑÑŒ до відео-конференції
service.gui.CREATE_VIDEO_CONFERENCE=Створити нову відео-конференцію Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— кімнати
service.gui.CONTACT_INFO_NOT_SUPPORTED=Даний контакт не підтримує мережеву контактну інформацію
service.gui.CUT=В&ирізати
-service.gui.DATE=Дата
service.gui.DELETE=Вилучити
service.gui.DENY=&Відхилити
service.gui.DESKTOP_SHARING_WARNING=<b>Ви впевнені, що хочете надати доÑтуп до вашого екрану?</b> <br> ÐатиÑÐ½ÐµÐ½Ð½Ñ OK дозволить абонентам, Ñкі беруть учаÑтину у розмові, бачити вміÑÑ‚ вашого екрану.
+service.gui.DESKTOP_SHARING_DIALOG_INDICATE=Ви демонÑтруєте ваш екран
service.gui.DIALPAD=Ðомеронабирач
service.gui.DISPLAY_NAME=Відображуване ім’Ñ
service.gui.DISCONNECTED_STATUS=Роз’єднано
service.gui.DND_STATUS=Ðе турбувати
service.gui.DO_NOT_ASK_AGAIN=Ðе питати знову
service.gui.DO_NOT_SHOW_AGAIN=Ðе показувати це Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð½Ð¾Ð²Ñƒ
-service.gui.DOWNLOAD_NOW=&Завантажити тепер
service.gui.DRAG_FOR_SHARING=ПеренеÑÑ–Ñ‚ÑŒ Ñюди Ð´Ð»Ñ Ñпільного доÑтупу...
service.gui.DURATION=триваліÑÑ‚ÑŒ
service.gui.DESTROY_CHATROOM=Видалити конференцію
@@ -217,7 +210,6 @@ service.gui.ERROR_RECEIVED_FROM=Помилка отримана від {0}
service.gui.ESTIMATED_TIME=Приблизний чаÑ:
service.gui.EVENTS=Події
service.gui.EXIT=В&ийти
-service.gui.EXTENDED_CRITERIA=Розширений критерій
service.gui.GENERAL=Загальні
service.gui.GENERAL_ERROR=Загальна помилка
service.gui.GROUP_NAME=Ð†Ð¼â€™Ñ Ð³Ñ€ÑƒÐ¿Ð¸
@@ -259,7 +251,6 @@ service.gui.FONT_ITALIC=КурÑив
service.gui.FONT_SIZE=Розмір
service.gui.FONT_STYLE=Стиль
service.gui.FONT_UNDERLINE=ПідкреÑленнÑ
-service.gui.FROM={0} від {1}
service.gui.GRANT_OWNERSHIP=Додати до влаÑників...
service.gui.GRANT_ADMIN=Додати до адмініÑтраторів...
service.gui.GRANT_MODERATOR=Додати до модераторів
@@ -271,7 +262,7 @@ service.gui.HD_QUALITY=HD відео
service.gui.HELP=&Допомога
service.gui.HIDE=Приховати
service.gui.HIDE_OFFLINE_CONTACTS=Приховати контакти не в мережі
-service.gui.HIDE_MAIN_WINDOW=<DIV>ÐатиÑÐ½ÐµÐ½Ð½Ñ Ñ…Ñ€ÐµÑтика у куті вікна не завершить додаток, а тільки <BR> Ñховає его. Якщо бажаєте завершить додаток, оберіть Файл/Вийти.</DIV>
+service.gui.HIDE_MAIN_WINDOW=<DIV>ÐатиÑÐ½ÐµÐ½Ð½Ñ Ñ…Ñ€ÐµÑтика у куті вікна не завершить додаток, а тільки <BR> Ñховає його. Якщо бажаєте завершить додаток, оберіть Файл/Вийти.</DIV>
service.gui.HISTORY=&ІÑторіÑ
service.gui.HISTORY_CONTACT=ІÑÑ‚Ð¾Ñ€Ñ–Ñ - {0}
service.gui.HISTORY_TOGGLE_PER_CONTACT=Вимкнути Ñ–Ñторію Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ контакту
@@ -285,12 +276,12 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=Ви дійÑно бажаєте наза
service.gui.HISTORY_REMOVE_ERROR=Помилка під Ñ‡Ð°Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¾ збережених повідомлень.
service.gui.HOME=Домашній
service.gui.HOME_PAGE=Ð”Ð¾Ð¼Ð°ÑˆÐ½Ñ Ñторінка
-service.gui.HOUR=Ð”Ð¾Ð¼Ð°ÑˆÐ½Ñ Ñторінка
service.gui.ICE=ICE
service.gui.IDENTIFIER=Ідентифікатор
service.gui.IGNORE=&Ігнорувати
service.gui.INSERT_SMILEY=Ð’Ñтавити Ñмайлик
service.gui.INCOMING_CALL=Вхідний дзвінок від: {0}
+service.gui.INCOMING_SCREEN_SHARE=Вхідний дзвінок від: {0}
service.gui.INCOMING_CALL_STATUS=Вхідний дзвінок
service.gui.INITIATING_CALL_STATUS=ЗдійÑÐ½ÐµÐ½Ð½Ñ Ð²Ð¸ÐºÐ»Ð¸ÐºÑƒ
service.gui.INVITATION=ТекÑÑ‚ запрошеннÑ
@@ -305,23 +296,21 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=Запитити контакти дÐ
service.gui.INVITE_REASON=Причина запрошеннÑ
service.gui.IS_CALLING=дзвонить...
service.gui.IS_NOW={0} тепер {1}
-service.gui.JITSI_WARNING=SIP Communicator був перейменований в Jitsi.<br/>Завантажуйте Jitsi, Ñкщо Ви хочете викориÑтовувати нову верÑÑ–ÑŽ програми.<br/><br/>Прийміть наші Ð²Ð¸Ð±Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð° можливі завдані ненезручноÑÑ‚Ñ–. З повагою,<br/><br/>Команда розробників Jitsi
-service.gui.JITSI_WARNING_TITLE=SIP Communicator тепер Ñтав Jitsi
service.gui.JOIN=&Війти
service.gui.JOIN_AS=Ð’&ійти Ñк
-service.gui.CLOSE_CHAT_ROOM_DIALOG=З&акрити
+service.gui.JOIN_VIDEO=ПриєднатиÑÑ Ð´Ð¾ відео
+service.gui.JOB_TITLE=ПоÑада
service.gui.JOIN_CHAT_ROOM=&Ввійти в конференцію...
service.gui.JOIN_CHAT_ROOM_TITLE=Ввійти в конференцію
service.gui.JOIN_CHAT_ROOM_NAME=Будь-лаÑка, введіть Ñ–Ð¼â€™Ñ ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ñ–Ñ—, в Ñку хочете ввійти.
service.gui.JOIN_CHAT_ROOM_WIZARD=МайÑтер Ð¿Ñ€Ð¸Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð¾ конференції
-service.gui.JOIN_AUTOMATICALLY=Приєднати автоматично
-service.gui.DONT_JOIN_AUTOMATICALLY=Ðе приєднувати автоматично
+service.gui.JOIN_AUTOMATICALLY=ПриєднуватиÑÑŒ автоматично
+service.gui.DONT_JOIN_AUTOMATICALLY=Ðе приєднуватиÑÑŒ автоматично
service.gui.KICK=&УÑунути
service.gui.KICK_FAILED=Ðе вдалоÑÑ ÑƒÑунути
service.gui.KICK_FAILED_GENERAL_ERROR=Ðе вдалоÑÑ ÑƒÑунути {0}. ВідбулаÑÑ Ð·Ð°Ð³Ð°Ð»ÑŒÐ½Ð° помилка Ñервера.
service.gui.KICK_FAILED_NOT_ALLOWED=Ðе вдалоÑÑ ÑƒÑунути {0}. ВлаÑник та адмініÑтратор конференції не може бути уÑунутий.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Ðе вдалоÑÑ ÑƒÑунути {0}. У Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” на це прав.
-service.gui.LAST=ОÑтанній
service.gui.LAST_NAME=Прізвище:
service.gui.LEAVE=&Покинути
service.gui.LIMIT_REACHED_FOR_IP=У Ð²Ð°Ñ Ð½Ð°Ð´Ñ‚Ð¾ багато реєÑтрацій з локальної IP-адреÑи. Сервер {0} більше не дозволÑÑ” реєÑтруваннÑ.
@@ -341,7 +330,6 @@ service.gui.MESSAGE=ПовідомленнÑ
service.gui.MISSED_CALLS_TOOL_TIP=Пропущені виклики від:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= та {0} більше
service.gui.MODERATOR=модератор
-service.gui.MORE=ПереглÑнути більше
service.gui.MORE_LABEL=Більше
service.gui.MOVE=ПереміÑтити
service.gui.MOVE_SUBCONTACT=П&ереміÑтити контакт
@@ -350,7 +338,6 @@ service.gui.MOVE_SUBCONTACT_FAILED=Вибраний вами контакт то
service.gui.MOVE_SUBCONTACT_QUESTION=Ви впевнені, що бажаєте переміÑтити {0} до {1}?
service.gui.MOVE_TO_GROUP=&ПереміÑтити в групу
service.gui.MOVE_CONTACT=ПереміÑтити контакт
-service.gui.MOVE_CONTACT_ERROR=&Контакт не може бути переміщений
service.gui.MSG_DELIVERY_FAILURE=Попереднє Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð½Ðµ може бути доÑтавлено
service.gui.MSG_DELIVERY_NOT_SUPPORTED=Протокол, Ñкий ви викориÑтовуєте підтримує offline-повідомленнÑ. Ви можее Ñпробувати зв’ÑзатиÑÑ Ð· {0} через інший протокол або зачекати доки він/вона подключітьÑÑ Ð´Ð¾ мережі.
service.gui.MSG_DELIVERY_INTERNAL_ERROR=ВідбулаÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° додатку. БудьлаÑка, повідомте про неї на адреÑу: http://www.jitsi.org/index.php/Development/BugsAndIssues.
@@ -361,7 +348,6 @@ service.gui.MSG_NOT_POSSIBLE=Обмін повідомленнÑми неможÐ
service.gui.MSG_RECEIVED={0} напиÑав
service.gui.MSG_SEND_CONNECTION_PROBLEM=Ви повинні бути підключені до мережі, щоб мати можливіÑÑ‚ÑŒ відправлÑÑ‚ÑŒ повідомленнÑ.
service.gui.MULTIPLE_LOGINS=Ви підключені більше одного разу тим же обліковим запиÑом. ÐаÑтупний обліковий запиÑ: Ð†Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача: {0}, Ðазва Ñервера: {1} на даний Ñ‡Ð°Ñ Ð²Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹.
-service.gui.MUTE=Вимкнути звук
service.gui.MUTUALLY_ON_HOLD_STATUS=Чекає
service.gui.NAME=ДіÑ
service.gui.NETWORK=Мережа
@@ -392,7 +378,6 @@ service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=Ðе в ÑпиÑку контакті
service.gui.SD_QUALITY=Стандартна ÑкіÑÑ‚ÑŒ
service.gui.OFFLINE=Ðе в мережі
service.gui.OK=&OK
-service.gui.OLDER_CALLS=Старі дзвінки
service.gui.ONLINE=В мережі
service.gui.OPEN=Відкрити
service.gui.OPEN_FILE_FROM_IMAGE=Двічі клацніть, щоб відкрити файл.
@@ -400,7 +385,6 @@ service.gui.OPEN_FOLDER=Відкрити теку
service.gui.OPEN_IN_BROWSER=Відкрити в &браузері
service.gui.OPTIONS=Опції
service.gui.OR=або
-service.gui.OR_ENTER_PHONE_NUMBER=Ðбо введіть номер телефону...
service.gui.ORGANIZATION=ОрганізаціÑ:
service.gui.OTHER=Інший
service.gui.chat.role.OWNER=ВлаÑник
@@ -424,7 +408,6 @@ service.gui.PRESENCE=ВітаннÑ
service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Enter' Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð¿Ð¾Ð·Ð¸Ñ†Ñ–Ð¹
service.gui.PRESS_FOR_CALL_INFO=ÐатиÑніть Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ— про дзвінок
service.gui.PREVIOUS=Попередній
-service.gui.PREVIOUS_TOOLTIP=ОглÑд Ñтарих розмов
service.gui.PRINT=&Друк
service.gui.PROACTIVE_NOTIFICATION=Друкує повідомленнÑ
service.gui.PROBLEMS_ENCOUNTERED=Виникли проблеми
@@ -439,7 +422,6 @@ service.gui.RECONNECTION_LIMIT_EXCEEDED=Ви були відключені та
service.gui.RE_REQUEST_AUTHORIZATION=Запит повторної авторизації
service.gui.REFERRED_STATUS=Переведений
service.gui.REJECT=&Відхилити
-service.gui.REMIND_ME_LATER=Ðагадати мені пізніше
service.gui.REMEMBER_PASSWORD=Запам’Ñтати пароль
service.gui.REMOVE=&Вилучити
service.gui.REMOVE_ACCOUNT=&Вилучити обліковий запиÑ
@@ -465,9 +447,7 @@ service.gui.REVOKE_ADMIN=Вилучити із адмініÑтраторів
service.gui.REVOKE_MODERATOR=Вилучити із модераторів
service.gui.REVOKE_MEMBERSHIP=Ðнулювати членÑтво
service.gui.REVOKE_VOICE=Вилучити із голоÑуваннÑ
-service.gui.ROOT_GROUP=Коренева група
service.gui.SAVE=&Зберегти
-service.gui.SAVE_AS_DEFAULT=Зберегти замовчувані
service.gui.SEARCH=&Пошук
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=ÐатиÑніть кнопку ниже, щоб показати вÑÑ– чати, Ñ–Ñнуючі на вибраному Ñервері. Потім оберіть той, до Ñкого хочете приєднатиÑÑ Ñ‚Ð° натиÑніть на кнопку з’єднаннÑ.
service.gui.SEARCH_STRING_CONTACT_SOURCE=Пошук контактів
@@ -475,17 +455,11 @@ service.gui.SECURITY=Безпека
service.gui.SELECT_ACCOUNT=Вибрати обліковий запиÑ
service.gui.SELECT_COLOR=Вибрати колір
service.gui.SELECT_GROUP=Вибрати групу
-service.gui.SELECT_GROUP_WIZARD_MSG=Ðаведений нижче ÑпиÑок міÑтить вÑÑ– групи у ÑпиÑку контактів. Виберіть одну, до Ñкої хочете додати новий контакт.
service.gui.SELECT_NO_GROUP=Без групи
-service.gui.SELECT_GROUP_WIZARD=Вкажіть групу
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=Ðаведений нижче ÑпиÑок міÑтить вÑÑ– облікові запиÑи, Ñкі підтримують багатокориÑтувацький чат. Виберіть той, Ñкий хочете викориÑтовувати Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ñ–Ñ—.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=Ðаведений нижче перелік міÑтить вÑÑ– зареєÑтровані облікові запиÑи. Виберіть той, Ñкий хочете викориÑтовувати Ð´Ð»Ñ ÑÐ¿Ñ–Ð»ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð· новим контактом.
-service.gui.SELECT_PROVIDERS_WIZARD=Виберіть обліковий запиÑ
service.gui.SEND=&ÐадіÑлати
service.gui.SEND_FILE=ÐадіÑлати &файл
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ цей контакт відÑутнÑ.
service.gui.SEND_MESSAGE=&ÐадіÑлати повідомленнÑ
-service.gui.SEND_AS_SMS=ÐадіÑлати Ñк SMS
service.gui.SEND_SMS=ÐадіÑлати SMS
service.gui.SEND_SMS_DETAILS=Пам’Ñтайте, що вам необхідно ввеÑти номер телефону в міжнародном форматі, наприклад, починаючи з +380 Ð´Ð»Ñ Ð£ÐºÑ€Ð°Ñ—Ð½Ð¸, +380112233445
service.gui.SEND_SMS_NOT_SUPPORTED=Вибраний протокол не підтримує SMS повідомлень.
@@ -519,7 +493,6 @@ service.gui.STOP_SHARING=Припинити загальний доÑтуп
service.gui.SUBJECT=Тема
service.gui.SUMMARY=ЗведеннÑ
service.gui.TELEPHONY=ТелефоніÑ
-service.gui.TODAY=Сьогодні
service.gui.TOOLS=&ІнÑтрументи
service.gui.TRANSFER=ПередаваннÑ
service.gui.TO=&Кому:
@@ -529,7 +502,6 @@ service.gui.TRANSFER_CALL_TO=ÐŸÐµÑ€ÐµÐ²ÐµÐ´ÐµÐ½Ð½Ñ Ð½Ð°:
service.gui.TRANSPARENCY_NOT_ENABLED=ПрозоріÑÑ‚ÑŒ не підтримуєтьÑÑ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¾ÑŽ конфігурацією.
service.gui.TYPE_YOUR_REQUEST=Введіть запит
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=Ðе вдалоÑÑ Ð·Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸ ÑкіÑÑ‚ÑŒ відео Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ виклику.
-service.gui.UNMUTE=Увімкнути звук
service.gui.USER_IDENTIFIER=Ідентифікатор кориÑтувача:
service.gui.USER_EXISTS_ERROR=Цей кориÑтувач вже Ñ–Ñнує у вибраній мережі. Будь-лаÑка, оберіть іншого кориÑтувача або мережу.
service.gui.USERNAME_NULL=Будь-лаÑка, заповніть Ñвоє Ñ–Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача та пароль.
@@ -541,7 +513,6 @@ service.gui.USE_PROVISIONING=ВикориÑтовувати автоналашт
service.gui.VALUE=ЗначеннÑ:
service.gui.VIDEO_CALL=&Відеовиклик
service.gui.VIA=через
-service.gui.VIA_SMS=Через SMS
service.gui.VIEW=&Показати
service.gui.VIEW_HISTORY=Показати &Ñ–Ñторію
service.gui.VIEW_SMILEYS=Показати &Ñмайли
@@ -561,9 +532,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=Ð ÐµÐ³ÑƒÐ»ÑŽÐ²Ð°Ð½Ð½Ñ Ð³ÑƒÑ‡Ð½Ð¾ÑÑ‚Ñ–
service.gui.WAITING_AUTHORIZATION=Чекаємо авторизації
service.gui.WARNING=ПопередженнÑ
service.gui.YES=Так
-service.gui.YESTERDAY=Вчора
-service.gui.EXISTING_ACCOUNT_ERROR=Введенний обліковий Ð·Ð°Ð¿Ð¸Ñ Ð²Ð¶Ðµ Ñ–Ñнує.
-service.gui.NEW_MAIL=<b>У Ð’Ð°Ñ Ð¾Ð´Ð¸Ð½ новий лиÑÑ‚!</b><br/><b>От:</b> {0} {1} <br/><b>Тема:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER=Ви відримали нового лиÑта до {0} <a href="{1}">вхідні</a>:<br/>
service.gui.NEW_GMAIL_MANY_HEADER=Ви відримали {2} нових лиÑтів до {0} <a href="{1}">вхідні</a>:<br/>
service.gui.NEW_GMAIL_FOOTER=ще одине непрочитане Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñƒ<a href="{0}">вхідних</a>.<br/>
@@ -586,7 +554,6 @@ service.gui.SECURITY_ERROR=Помилка безпеки
service.gui.SPEED=ШвидкіÑÑ‚ÑŒ:
service.gui.SILENT_MEMBER=мовчазний учаÑтник
service.gui.NON_SECURE_CONNECTION=Ðеможливо вÑтановити безпечне Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð»Ñ {0}. Якщо Ви хочете викориÑтовувати незахищене підключеннÑ, Будь-лаÑка, вÑтановіть ознаку "Дозволити незахищене з’єднаннÑ" в конфігурації облікового запиÑу
-service.gui.UPDATE=Оновити
service.gui.MOBILE_PHONE=Мобільний
service.gui.VIDEO_PHONE=Відеовиклики
service.gui.WORK_PHONE=Робочий
@@ -619,7 +586,6 @@ service.gui.callinfo.CALL_INFORMATION=Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ виклик
service.gui.callinfo.CALL_IDENTITY=Обліковий запиÑ
service.gui.callinfo.PEER_COUNT=КількіÑÑ‚ÑŒ учаÑників
service.gui.callinfo.IS_CONFERENCE_FOCUS=КонференціÑ
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=Ð¨Ð¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ ÑƒÐ²Ñ–Ð¼ÐºÐ½ÐµÐ½Ð¾
service.gui.callinfo.CALL_TRANSPORT=ТранÑпорт Ñигналізації
service.gui.callinfo.CALL_DURATION=ТриваліÑÑ‚ÑŒ виклику
service.gui.callinfo.VIEW_CERTIFICATE=Показати Ñертифікат
@@ -630,7 +596,6 @@ service.gui.callinfo.AUDIO_INFO=Ðудіо потік
service.gui.callinfo.VIDEO_INFO=Відео потік
service.gui.callinfo.LOCAL_IP=Локальний IP / Порт
service.gui.callinfo.REMOTE_IP=Віддалений IP / Порт
-service.gui.callinfo.BANDWITH=Смуга пропуÑканнÑ
service.gui.callinfo.LOSS_RATE=Втрата пакетів
service.gui.callinfo.RTT=RTT
service.gui.callinfo.JITTER=Джіттер
@@ -640,10 +605,13 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=Протокол обміну ключами
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=ICE кандидат розширеного типу
service.gui.callinfo.ICE_STATE=Стан ICE
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=ÐžÑ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ ÐºÐ°Ð½Ð´Ð¸Ð´Ð°Ñ‚Ñ–Ð²
service.gui.callinfo.ICE_STATE.RUNNING=Перевірка підключеннÑ
service.gui.callinfo.ICE_STATE.COMPLETED=Завершено
service.gui.callinfo.ICE_STATE.FAILED=Помилка
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=Локальний IP / Порт
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=Локальний вхідний IP / Порт
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=Локальний вихідний IP / Порт
@@ -662,9 +630,10 @@ service.gui.ALWAYS_TRUST=Завжди довірÑти цьому Ñертифі
service.gui.CERT_DIALOG_TITLE=Перевірити Ñертифікат
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} не може перевірити доÑтовірніÑÑ‚ÑŒ Ñервера при підключенні до<br><b>{1}</b>.<br><br>Ðе довірений Ñертифікат. Це означає, що Ñервер не може бути автоматично перевірений.<br><br> Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¾Ð²Ð¾Ñ— інформації, натиÑніть кнопку "Показати Ñертифікат".<br><br>Ви хочете продовжити підключеннÑ?</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0} не може перевірити доÑтовірніÑÑ‚ÑŒ Ñертифіката Ñервера<br><br>Ðе довірений Ñертифікат. Це означає, що Ñервер не може бути автоматично перевірений.<br><br> Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¾Ð²Ð¾Ñ— інформації, натиÑніть кнопку "Показати Ñертифікат".<br><br>Ви хочете продовжити підключеннÑ?</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} не може перевірити доÑтовірніÑÑ‚ÑŒ клієнта<br><br>Ðе довірений Ñертифікат. Це означає, що клієнт не може бути автоматично перевірений.<br><br> Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¾Ð²Ð¾Ñ— інформації, натиÑніть кнопку "Показати Ñертифікат".<br><br>Ви хочете дозволити підключеннÑ?</html>
service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} не може перевірити доÑтовірніÑÑ‚ÑŒ клієнта {1}<br><br>Ðе довірений Ñертифікат. Це означає, що клієнт не може бути автоматично перевірений.<br><br>Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¾Ð²Ð¾Ñ— інформації, натиÑніть кнопку "Показати Ñертифікат".<br><br>Ви хочете продовжити підключеннÑ?</html>
service.gui.CONTINUE_ANYWAY=Однак продовжити
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=Ðазва Ñертифіката:
service.gui.CERT_INFO_O=ОрганізаціÑ:
service.gui.CERT_INFO_C=Країна:
@@ -679,12 +648,10 @@ service.gui.CERT_INFO_VER=ВерÑÑ–Ñ:
service.gui.CERT_INFO_SIGN_ALG=Ðлгоритм підпиÑу:
service.gui.CERT_INFO_ALG=Ðлгоритм:
service.gui.CERT_INFO_PUB_KEY=Відкритий ключ:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} байт: {1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} біт
service.gui.CERT_INFO_EXP=ЕкÑпонента:
service.gui.CERT_INFO_KEY_SIZE=Розмір ключа:
service.gui.CERT_INFO_SIGN=ПідпиÑ:
-service.gui.CONTINUE=Продовжити
service.gui.SHOW_CERT=Показати Ñертифікат
service.gui.HIDE_CERT=Приховати Ñертифікат
@@ -705,15 +672,12 @@ service.gui.security.SECURE_AUDIO=Ðудіопотік захищено
service.gui.security.AUDIO_NOT_SECURED=Ðудіопотік не захищено
service.gui.security.SECURE_VIDEO=Відеопотік захищено
service.gui.security.VIDEO_NOT_SECURED=Відеопотік не захищено
-service.gui.security.NO_VIDEO=Без відео
-service.gui.security.CIPHER=Шифр: {0}
service.gui.security.CALL_SECURED_TOOLTIP=Розмову захищено.
service.gui.security.CALL_NOT_SECURED_TOOLTIP=Розмову не захищено.
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=ÐатиÑніть тут, щоб звірити ключ із Ñпіврозмовником.
-service.gui.security.COMPARE_WITH_PARTNER=Звірте ключ із Ñпіврозмовником та натиÑніть замочок Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ.
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=Звірте ключ із Ñпіврозмовником:
-service.gui.security.STRING_COMPARED=Ключ пошкоджено!
+service.gui.security.STRING_COMPARED=Ключ перевірено!
service.gui.security.SECURITY_ALERT=Ð†Ð½Ñ–Ñ†Ñ–Ð°Ð»Ñ–Ð·ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ñ…Ð¸Ñту виклику. Ð’Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ·
service.gui.avatar.CHOOSE_ICON=Вибрати аватар
@@ -727,19 +691,13 @@ service.gui.avatar.imagepicker.CLICK=Зробити знімок
service.gui.avatar.imagepicker.IMAGE_FILES=Файли зображень
service.gui.avatar.imagepicker.IMAGE_PICKER=ЗображеннÑ
service.gui.avatar.imagepicker.IMAGE_SIZE=Розмір зображеннÑ
-service.gui.avatar.imagepicker.INITIALIZING=ІніціалізуваннÑ
service.gui.avatar.imagepicker.RESET=Скинути
service.gui.avatar.imagepicker.SET=Задати
service.gui.avatar.imagepicker.TAKE_PHOTO=Зробити знімок
-service.gui.avatar.imagepicker.WEBCAM_ERROR=Помилка вебкамери
service.gui.security.encryption.required=Ðеобхідне шифруваннÑ!
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
impl.protocol.sip.XCAP_ERROR_TITLE=Помилка в адреÑній книзі SIP
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=Ðеможливо прочитати реÑÑƒÑ€Ñ {0}. Ð”Ð»Ñ {1}
@@ -762,9 +720,7 @@ impl.gui.main.account.DUMMY_PROTOCOL_DESCRIPTION=Оберіть мережу
# LDAP
impl.ldap.CONFIG_FORM_TITLE=ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ LDAP
impl.ldap.GENERAL=Загальні
-impl.ldap.NEW=Ðовий
impl.ldap.EDIT=змінити
-impl.ldap.REMOVE=Вилучити
impl.ldap.ENABLED=Ðктивний
impl.ldap.SERVER_NAME=Коротке ім’Ñ
impl.ldap.SERVER_NAME_EXAMPLE=ÐдреÑна книга LDAP
@@ -797,6 +753,10 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=homePhone
impl.ldap.PHONE_PREFIX=Телефонний префікÑ
impl.ldap.PHONE_PREFIX_EXAMPLE=Ðаприклад: +380
+# SIP Protocol
+
+#Jabber Protocol
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=ÐдреÑна книга
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=Увімкнути пошук в адреÑній книзі MacOSX
@@ -807,9 +767,7 @@ plugin.addrbook.PREFIX_EXAMPLE=Ðаприклад: +380
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Контакти Google
-impl.googlecontacts.NEW=Ðовий
impl.googlecontacts.EDIT=Змінити
-impl.googlecontacts.REMOVE=Вилучити
impl.googlecontacts.ENABLED=Ðктивний
impl.googlecontacts.ACCOUNT_NAME=Обліковий запиÑ
impl.googlecontacts.SAVE=Зберегти
@@ -837,9 +795,6 @@ plugin.accountinfo.COUNTRY=Країна
plugin.accountinfo.EMAIL=Електронна Ñкринька:
plugin.accountinfo.PHONE=Телефон:
plugin.accountinfo.MOBILE_PHONE=mobilePhone
-plugin.accountinfo.USER_PICTURES=Фотографії кориÑтувача
-plugin.accountinfo.CHANGE=Змінити
-plugin.accountinfo.ONLY_MESSAGE=Тільки повідомленнÑ
# connection info
@@ -858,49 +813,12 @@ plugin.aimaccregwizz.USERNAME=AIM Ім’Ñ:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=Ідентифікатор кориÑтувача та пароль
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=РеєÑÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ облікового запиÑу
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=У випадку, Ñкщо ви не маєте облікового запиÑу AIM, натиÑніть на цю кнопку, щоб Ñтворити новий.
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Перевизначити замовчувані параметри Ñервера
# branding
plugin.branding.ABOUT_WINDOW_TITLE=Про Ð½Ð°Ñ {0}
plugin.branding.LOGO_MESSAGE=Open Source VoIP && Обмін миттєвими повідомленнÑми
-plugin.branding.LOADING=ЗавантаженнÑ
plugin.branding.ABOUT_MENU_ENTRY=&Про програму
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>{1} наразі в Ñтадії активної розробки. ВерÑÑ–Ñ, запущена вами, екÑперіментальна та може працювати не так как ви чекаєте. Будь-лаÑка, звернітьÑÑ Ð´Ð¾ {2} Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¾Ð²Ð¾Ñ— інформації.</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2012 Copyright <b>jitsi.org</b>. Ð’ÑÑ– права захищено. Відвідайте <a href="http://jitsi.org">http://jitsi.org</a>.</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}><b>Jitsi</b> пиширюєтьÑÑ Ð·Ð° ліцензією LGPL (<a href="http://www.gnu.org">http://www.gnu.org</a>).</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=Словники
-plugin.dictaccregwizz.ANY_DICTIONARY=Будь-Ñкий Ñловник
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=Будь-Ñкий Ñловник від {0}
-plugin.dictaccregwizz.FIRST_MATCH=Перший збіг
-plugin.dictaccregwizz.NO_MATCH=Збіги відÑутні
-plugin.dictaccregwizz.MATCH_RESULT=Визначень Ð´Ð»Ñ "{0}" не знайдено, можливо, ви маєте на увазі:\n
-plugin.dictaccregwizz.INVALID_DATABASE=Поточного Ñловника "{0}" не Ñ–Ñнує на Ñервері.
-plugin.dictaccregwizz.INVALID_STRATEGY=Поточна ÑÑ‚Ñ€Ð°Ñ‚ÐµÐ³Ð¸Ñ Ð²Ñ–Ð´ÑÑƒÑ‚Ð½Ñ Ð½Ð° Ñервері.
-plugin.dictaccregwizz.PROTOCOL_NAME=DICT
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=DICT протокол
-plugin.dictaccregwizz.HOST=ХоÑÑ‚
-plugin.dictaccregwizz.SERVER_INFO=Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ Ñервер
-plugin.dictaccregwizz.STRATEGY_SELECTION=Вибір методу
-plugin.dictaccregwizz.STRATEGY_LIST=СпиÑок методів:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=Пошук методів
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=ВикориÑтовувати метод Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ Ñхожих Ñлів, Ñкщо переклад не був знайдений, завдÑки різним методам. Ðаприклад, номери Ñтратегії буде шукати Ñлова, Ñкі починаютьÑÑ, как Ñлово, Ñке бажано перклаÑти.
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ обліковий запиÑ
-plugin.dictaccregwizz.FIRST_ACCOUNT=Цей маÑтер допоможе Ñтворити ваш перший обліковий Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° Ñайте dict.org.\n\nВи можете додати новий Ñловник зареєÑтрувавши обліковий Ð·Ð°Ð¿Ð¸Ñ Ñƒ майÑтрі. Заповніть Ð¿Ð¾Ð»Ñ Ñловника Ñкий ви хочете додати.
-plugin.dictaccregwizz.THREAD_CONNECT=Спроба Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ Ñерверу
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=Спроба Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð½Ðµ вдалаÑÑ, це не Ñервер Ñловників або Ñервер недоÑтупний
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=ÐžÑ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð°
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=Метод не знайдено на Ñервері
-plugin.dictaccregwizz.POPULATE_LIST=Ð—Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ ÑпиÑку
-plugin.dictaccregwizz.CLOSING_CONNECTION=Ð—Ð°ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб викориÑтовувати Facebook чат необхідно Ñтворити "Обліковий Ð·Ð°Ð¿Ð¸Ñ ÐºÐ¾Ñ€Ð¸Ñтувача" <br>в "ÐалаштуваннÑÑ… облікового запиÑу " на Facebook.</a><br><br>Примітка: При Ñтворенні імені кориÑтувача необхідно вийти із Ñторінки <br>Ñ– може знадобитиÑÑ Ð´ÐµÑкий чаÑ, пред тим Ñк ви зможете війти з вашим новим іменем кориÑтувача!</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=Протокол чату Facebook
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=Ð†Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Ð†Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача та пароль
+
# generalconfig
plugin.generalconfig.AUTO_START=Ðвтоматичний запуÑк {0} при завантаженні компьютера
@@ -910,9 +828,6 @@ plugin.generalconfig.SHOW_HISTORY=Показувати
plugin.generalconfig.HISTORY_SIZE=оÑтанніх повідомлень в новому чаті
plugin.generalconfig.SEND_MESSAGES_WITH=ÐадÑилати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¸ натиÑненні:
plugin.generalconfig.BRING_WINDOW_TO_FRONT=ПереноÑити вікно чату поверх вÑÑ–Ñ… вікон при вхідному повідомленні
-plugin.generalconfig.ERROR_PERMISSION=У Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” доÑтатніх привілеїв Ð´Ð»Ñ Ð²Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð¿ÑƒÑку
-plugin.generalconfig.TRANSPARENCY=ПрозоріÑÑ‚ÑŒ
-plugin.generalconfig.ENABLE_TRANSPARENCY=Увімкнути прозоріÑÑ‚ÑŒ
plugin.generalconfig.DEFAULT_LANGUAGE=Мова інтерфейÑу
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=Зміни будуть заÑтоÑовані піÑÐ»Ñ Ð½Ð°Ñтупного запуÑку Jitsi.
plugin.generalconfig.SIP_CLIENT_PORT=Порт SIP
@@ -961,6 +876,8 @@ plugin.ircaccregwizz.USE_DEFAULT_PORT=ВикориÑтовувати замовÑ
plugin.ircaccregwizz.PASSWORD_NOT_REQUIRED=Мій пÑевдонім не вимагає ідентифікації
plugin.ircaccregwizz.HOST=ХоÑÑ‚:
plugin.ircaccregwizz.IRC_SERVER=Сервер
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE=Ð†Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ {0}
+plugin.ircaccregwizz.SASL_USERNAME=Ð†Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача
# jabber accregwizz
plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
@@ -983,13 +900,10 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=Коментар
plugin.jabberaccregwizz.RESOURCE=РеÑурÑ
plugin.jabberaccregwizz.AUTORESOURCE=Ðвтоматичне ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ€ÐµÑурÑу
plugin.jabberaccregwizz.PRIORITY=Приорітет
-plugin.jabberaccregwizz.XMPP_ERROR=Помилка XMPP
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=Ðевідома помилка XMPP. УпевнітьÑÑ, що назва Ñервера, правильна.
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=Паролі не Ñпівпадають.
plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Перевизначити параметри замовчувані Ñервера
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=Додаткові параметри
plugin.jabberaccregwizz.USE_ICE=ВикориÑтовувати ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=ВикориÑтовувати Google Jingle/ICE (екÑперіментальна функціÑ)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=Ðвтоматично знаходити STUN/TURN Ñервери
plugin.jabberaccregwizz.SUPPORT_TURN=Підтримувати TURN
plugin.jabberaccregwizz.TURN_USERNAME=Ð†Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача TURN
@@ -1016,11 +930,8 @@ plugin.jabberaccregwizz.ALLOW_NON_SECURE=Дозволити небезпечні
plugin.jabberaccregwizz.DTMF_AUTO=Ðвтоматично вибирати між RTP та Inband
plugin.jabberaccregwizz.SERVER_OPTIONS=Параметри Ñервера
plugin.jabberaccregwizz.CHANGE_PASSWORD=Змінити пароль
-plugin.jabberaccregwizz.NEW_PASSWORD=Ðовий пароль
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=Повторіть пароль
plugin.jabberaccregwizz.PORT_FIELD_INVALID=Будь-лаÑка, необхідно вказати вірний порт Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ.
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=Щоб змінити пароль необхідно війти на Ñервер.
-plugin.jabberaccregwizz.PASSWORD_EMPTY=Пароль порожній.
plugin.jabberaccregwizz.TLS_REQUIRED=Ð—â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð½Ðµ зашифрівано! Пароль не буде змінено.
plugin.jabberaccregwizz.PASSWORD_CHANGED=Пароль уÑпішно змінено
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=Ваш Ñервер не підтримує заміну паролÑ.
@@ -1034,21 +945,6 @@ plugin.jabberaccregwizz.RESET=Скинути
plugin.jabberaccregwizz.RESET_DESCRIPTION=Скинути до глобальнхе налаштуваннь
plugin.jabberaccregwizz.DISABLE_JINGLE=Вимкнути Jingle (ауіио та відеодзвінки через XMPP).
-# mailbox
-plugin.mailbox.OUTGOING=Вихідні повідомленнÑ:
-plugin.mailbox.INCOMING=Вхідні повідомленнÑ:
-plugin.mailbox.WAIT_TIME=Дзвінок переводитьÑÑ Ð½Ð° автоовідповідач
-plugin.mailbox.MAX_MESSAGE_TIME=МакÑимальна триваліÑÑ‚ÑŒ вхідних повідомлень
-plugin.mailbox.CONFIRM=Підтвердити
-plugin.mailbox.DEFAULTS=За замовчуваннÑм
-plugin.mailbox.MAILBOX=Поштова Ñкринька
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=Протокол Ð´Ð»Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ñ‚Ð° чату на MSN Ñлужбі.
-plugin.msnaccregwizz.USERNAME=Електронна Ñкринька:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=ID та пароль
-
# plugin manager
plugin.pluginmanager.INSTALL=Ð’Ñтановити
plugin.pluginmanager.UNINSTALL=Вилучити
@@ -1077,7 +973,6 @@ plugin.sipaccregwizz.SERVER_PORT=Порт Ñервера
plugin.sipaccregwizz.PROXY=ПрокÑÑ–
plugin.sipaccregwizz.PROXY_PORT=Порт прокÑÑ–
plugin.sipaccregwizz.PREFERRED_TRANSPORT=Ðадавати перевагу транÑпорту
-plugin.sipaccregwizz.ADVANCED_OPTIONS=Додаткові параметри
plugin.sipaccregwizz.PROXY_OPTIONS=ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾ÐºÑÑ–-Ñервера
plugin.sipaccregwizz.PROXY_AUTO=Ðвтоматичне Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾ÐºÑÑ–-Ñервера
plugin.sipaccregwizz.ENABLE_PRESENCE=Увімкнути приÑутніÑÑ‚ÑŒ (SIMPLE)
@@ -1094,8 +989,6 @@ plugin.sipaccregwizz.DTMF_AUTO=Ðвтоматично вибирати між RT
plugin.sipaccregwizz.DTMF_RTP=RTP (RFC2833 / RFC4733)
plugin.sipaccregwizz.DTMF_SIP_INFO=SIP INFO
plugin.sipaccregwizz.DTMF_INBAND=Inband
-plugin.sipaccregwizz.REGISTER=REGISTER
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Перевизначити замовчувані параметри Ñервера
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Увімкнути підтримку ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð·Ð²Ñ–Ð½ÐºÑ–Ð²
plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=ПовідомлÑти про підтримку ZRTP у протоколі Ñигналізації
plugin.sipaccregwizz.AUTH_NAME=Ð†Ð¼â€™Ñ Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ñ–Ñ—
@@ -1116,10 +1009,10 @@ plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=URI Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸ ГП
plugin.sipaccregwizz.NOT_SAME_PASSWORD=Паролі не Ñпівпадають.
plugin.sipaccregwizz.NO_CERTIFICATE=<не> (викориÑтовувати звичайну перевірку ÑправжноÑÑ‚Ñ–)
plugin.sipaccregwizz.SAVP_OPTION=ВикориÑÑ‚Ð°Ð½Ð½Ñ RTP/SAVP
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=Вимкнено (викориÑтовувати тільки RTP/AVP)
plugin.sipaccregwizz.SAVP_OPTION_1=Обов’Ñзково (пропонувати та приймати тільки RTP/SAVP)
plugin.sipaccregwizz.SAVP_OPTION_2=Додатково (Ñпочатку пропонувати RTP/SAVP, потім RTP/AVP)
-plugin.sipaccregwizz.ENABLE_SDES_ATTRIBUTE=Увімкнути S-деÑкриптор (також відомий Ñк SDES або SRTP)
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=Виберіть протоколи ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚Ð° їхній пріоритет (вгорі протокол з вищим пріоритетом):
plugin.sipaccregwizz.CIPHER_SUITES=ДоÑтупні набори шифрів:
plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>{0} намагатиметьÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾ захиÑтити вÑÑ– Ваши дзвінки за допомогою ZRTP. Ви будете поінформовані про це кожного разу, здійÑнюючи виклик. Ви можете змінювати додаткові Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ в тому випадку, Ñкщо добре розумієте, що робите.</div></html>
@@ -1133,15 +1026,6 @@ plugin.skinmanager.DEFAULT_SKIN=Скіни замовчувані
plugin.skinmanager.ADD_NEW_SKIN=Додати новий Ñкін...
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=Скини додатку замовчувані.
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=Протокол Ð´Ð»Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ віддаленого комп’ютера через SSH.
-plugin.sshaccregwizz.USERNAME=ID облікового запиÑу:
-plugin.sshaccregwizz.IDENTITY_FILE=ОÑобиÑтий файл:
-plugin.sshaccregwizz.KNOWN_HOSTS=Відомі хоÑти:
-plugin.sshaccregwizz.OPTIONAL=Ðеобов’Ñзковий
-plugin.sshaccregwizz.ACCOUNT_DETAILS=Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ обліковий запиÑ
-
# status update
plugin.autoaway.AUTO_STATUS=Ðвто відÑутніÑÑ‚ÑŒ
plugin.autoaway.ENABLE_CHANGE_STATUS=Змінити ÑтатуÑ, коли відійшов
@@ -1188,22 +1072,6 @@ plugin.whiteboard.DESELECT=Відмінити
plugin.whiteboard.DELETE=Вилучити
plugin.whiteboard.PROPERTIES=ВлаÑтивоÑÑ‚Ñ–
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=Протокол Yahoo.
-plugin.yahooaccregwizz.USERNAME=Ð†Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=ID та пароль
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=Zeroconf (Bonjour) протокол.
-plugin.zeroaccregwizz.FIRST_NAME=Ім’Ñ:
-plugin.zeroaccregwizz.LAST_NAME=Прізвище:
-plugin.zeroaccregwizz.EMAIL=Електронна Ñкринька:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=Запам’Ñтати Bonjour контакти?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=ID та пароль
-plugin.zeroaccregwizz.USERID=Ідентифікатор кориÑтувача
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=Протокол Google Talk
@@ -1217,19 +1085,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, портал IP ТелеÐ
plugin.iptelaccregwizz.USERNAME=Ð†Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=ПідпиÑатиÑÑ Ð½Ð° iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIP та чат
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=Ð†Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=Введіть пароль еще раз
plugin.sip2sipaccregwizz.EMAIL=ÐдреÑа електронної пошти
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾Ð²Ñ–Ð´ÐºÐ¸ про поÑлугу відвідайте<br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>ÐдреÑа електронної пошти викориÑтовуєтьÑÑ Ð´Ð»Ñ Ð²Ñ–Ð´Ð¿Ñ€Ð°Ð²ÐºÐ¸ голоÑових повідомлень, <br>інформувань про пропущені дзвінки, а також Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð¾Ð³Ð¾ паролю</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾Ð²Ñ–Ð´ÐºÐ¸ про поÑлугу відвідайте<a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=ІÑнуючий sip2sip.info обліковий запиÑ
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=Створити безкоштовний обліковий Ð·Ð°Ð¿Ð¸Ñ sip2sip.info
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP && Миттєві повідомленнÑ
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾Ð²Ñ–Ð´ÐºÐ¸ про поÑлугу відвідайте<br>http://ippi.fr
@@ -1238,6 +1098,7 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=ІÑнуючі ippi обліковий з
plugin.ippiaccregwizz.CREATE_ACCOUNT=Створити безкоштовний обліковий Ð·Ð°Ð¿Ð¸Ñ ippi
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=Закрити вікно чату
plugin.keybindings.CHAT_COPY=Копіювати
plugin.keybindings.CHAT_CUT=Вирізати
@@ -1260,9 +1121,9 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=ДіÑ
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=ÐŸÐ¾Ñ”Ð´Ð½Ð°Ð½Ð½Ñ ÐºÐ»Ð°Ð²Ñ–Ñˆ
plugin.keybindings.globalchooser.SHORTCUT_SECOND=Додатково
plugin.keybindings.globalchooser.PRESS_BTN=ÐатиÑніть Ð´Ð»Ñ Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ”Ð´Ð½ÑÐ½Ð½Ñ ÐºÐ»Ð°Ð²Ñ–Ñˆ
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=ЧеканнÑ
plugin.keybindings.globalchooser.ENABLE_SPECIAL=Увімкнути виÑÐ²Ð»ÐµÐ½Ð½Ñ Ñпеціальних клавіш
plugin.keybindings.PLUGIN_NAME=ÐŸÐ¾Ñ”Ð´Ð½Ð°Ð½Ð½Ñ ÐºÐ»Ð°Ð²Ñ–Ñˆ
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=Чат
plugin.keybindings.MAIN=ОÑновні
plugin.keybindings.GLOBAL=Глобальні
@@ -1290,6 +1151,7 @@ plugin.notificationconfig.tableheader.SOUND=СиÑтемний звуковий
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=Звуковий Ñигнал через динаміки
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=Звуковий Ñигнал через динамік ПК
plugin.notificationconfig.tableheader.DESCRIPTION=ÐžÐ¿Ð¸Ñ Ð¿Ð¾Ð´Ñ–Ñ—
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=Вхідний дзвінок
plugin.notificationconfig.event.SecurityMessage=ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð±ÐµÐ·Ð¿ÐµÐºÐ¸
plugin.notificationconfig.event.IncomingFile=Отримано файл
@@ -1380,6 +1242,7 @@ impl.neomedia.configform.VIDEO=Відео
impl.neomedia.configform.H264=H.264
impl.neomedia.configform.H264.defaultProfile=Профіль Ð´Ð»Ñ ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ:
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=Базовий
impl.neomedia.configform.H264.defaultProfile.main=ОÑновний
impl.neomedia.configform.H264.preferredKeyFrameRequester=Метод запиту ключових кадрів:
@@ -1407,7 +1270,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=Поточний пароÐ
plugin.securityconfig.masterpassword.ENTER_PASSWORD=Введіть новий пароль:
plugin.securityconfig.masterpassword.REENTER_PASSWORD=Введіть пароль повторно:
plugin.securityconfig.masterpassword.MP_TITLE=МайÑтер-пароль
-plugin.securityconfig.masterpassword.MP_NOT_SET=(не вÑтановлено)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=Ви ввели неправильний поточний МайÑтер-пароль. Будь-лаÑка, Ñпробуйте еще раз.
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=МайÑтер-пароль неправильний!
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=Замінити пароль не вдалоÑÑ
@@ -1486,7 +1348,6 @@ plugin.globalproxy.PROXY_PORT=Порт
plugin.globalproxy.PROXY_USERNAME=Ð†Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача
plugin.globalproxy.PROXY_PASSWORD=Пароль
plugin.globalproxy.DESCRIPTION={0} буде викориÑтовувати перелічені параметри прокÑÑ–-Ñервера Ð´Ð»Ñ Ð²ÑÑ–Ñ… мереж при наÑтупному підключенні. \nПідтримка прокÑÑ– в даний Ñ‡Ð°Ñ ÐµÐºÑперіментальна та працює тільки з деÑкими протоколами. ДивітьÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†ÑŽ нижче Ð´Ð»Ñ Ð±Ñ–Ð»ÑŒÑˆ докладної інформації:
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table><tralign="center"><td></td><td>SOCKS4/5</td><td>SOCKS4/5+Auth</td><td>HTTP</td><td>HTTP+Auth</td></tr><tralign="center"><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tralign="center"><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tralign="center"><td>XMPP</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tralign="center"><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
# plugin reconnect
@@ -1520,7 +1381,6 @@ plugin.provisioning.RESTART_WARNING=Зміни вÑтуплÑÑ‚ÑŒ в Ñилу Ñ‚
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=Скопіювати UUID до буфера
plugin.provisioning.CLIPBOARD_FAILED=Помилка ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ UUID до буфера
-plugin.provisioning.EXIT_ON_FAIL=Закривати Jitsi, Ñкщо Ð°Ð²Ñ‚Ð¾Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ виконано
plugin.provisioning.CREDENTIALS=Обліковий Ð·Ð°Ð¿Ð¸Ñ Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=Ви дійÑно хочете Ñкинути пароль Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ?
plugin.provisioning.PROV_FAILED=ÐÐ²Ñ‚Ð¾Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ вдале
@@ -1587,8 +1447,6 @@ util.dns.DNSSEC_WARNING=<html><div width="600">{0} намагавÑÑ Ð¿Ñ–Ð´ÐºÐ»
#plugin spellcheck
plugin.spellcheck.TITLE=ÐžÑ€Ñ„Ð¾Ð³Ñ€Ð°Ñ„Ñ–Ñ Ñ‚Ð° Граматика
plugin.spellcheck.MENU=Відкрити Ñловник
-plugin.spellcheck.LANG=Мова
-plugin.spellcheck.EDIT_PERSONAL_DICT=Правка
plugin.spellcheck.ENABLE_SPELL_CHECK=Перевірка правопиÑу
plugin.spellcheck.dialog.FIND=Знайти наÑтупне
plugin.spellcheck.dialog.REPLACE=Замінити
diff --git a/resources/languages/resources_zh_CN.properties b/resources/languages/resources_zh_CN.properties
index ebd3026..ad854c2 100644
--- a/resources/languages/resources_zh_CN.properties
+++ b/resources/languages/resources_zh_CN.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -25,92 +36,84 @@
# from your system's language, pass the language code to ant:
# ant -Duser.language=xx run
-service.gui.ABOUT=关于
-service.gui.ACCEPT=接å—
+service.gui.ABOUT=关于 (&A)
+service.gui.ACCEPT=æŽ¥å— (&A)
service.gui.ACCOUNT=å¸æˆ·
service.gui.ACCOUNT_ME=自己
service.gui.ACCOUNT_REGISTRATION_WIZARD=å¸å·æ³¨å†Œå‘导
service.gui.ACCOUNTS=å¸å·
service.gui.ADD=添加
-service.gui.ADD_ACCOUNT=添加å¸å·
service.gui.ADD_CONTACT=添加è”系人
-service.gui.ADD_AUTHORIZED_CONTACT=添加{0}到你的通讯簿上
+service.gui.ADD_AUTHORIZED_CONTACT=将{0}添加到通讯录
service.gui.ADD_CONTACT_TO_CONTACTLIST=将此è”系人添加到您的è”系人列表中
service.gui.ADD_CONTACT_TO=添加è”系人到
-service.gui.ADD_CONTACT_ERROR=添加è”系人:{0}失败
+service.gui.ADD_CONTACT_ERROR=添加以下è”系人是失败:{0}
service.gui.ADD_CONTACT_ERROR_TITLE=添加è”系人错误
-service.gui.ADD_CONTACT_EXIST_ERROR=è”系人{0}å·²ç»å­˜åœ¨äºŽæ‚¨çš„è”系人åå•ä¸­äº†ã€‚
-service.gui.ADD_CONTACT_NETWORK_ERROR=æœåŠ¡å™¨æœªèƒ½å“应你添加è”系人ID为{0}çš„è”系人的请求。
-service.gui.ADD_CONTACT_NOT_SUPPORTED=无法添加è”系人Id为{0}çš„è”系人。ä¸æ”¯æŒæ­¤æ“作。
-service.gui.ADD_CONTACT_IDENTIFIER=请在下é¢è¾“å…¥æ ä¸­è¾“入您想è¦æ·»åŠ çš„è”系人的称呼。
-service.gui.ADD_CONTACT_WIZARD=添加è”系人å‘导
-service.gui.ADD_CONTACT_NOT_CONNECTED=你需è¦è¿žæŽ¥ä»¥ä¾¿æ·»åŠ è”系人。请选择一个连接类型并é‡è¯•ã€‚
-service.gui.ADD_GROUP_LOCAL_ERROR=添加组:{0} 失败。错误出自本地IOæ“作。
+service.gui.ADD_CONTACT_EXIST_ERROR=è”系人{0}在通讯录中已存在。
+service.gui.ADD_CONTACT_NETWORK_ERROR=æœåŠ¡å™¨æœªå“应您添加以下è”系人的请求:{0}
+service.gui.ADD_CONTACT_NOT_SUPPORTED=添加è”系人{0}失败。ä¸æ”¯æŒçš„æ“作。
+service.gui.ADD_CONTACT_NOT_CONNECTED=添加è”系人时您必须处于连接状æ€ã€‚请登录到选择的æœåŠ¡æ供商并é‡è¯•ã€‚
+service.gui.ADD_GROUP_LOCAL_ERROR=添加组:{0} 失败。本地IOæ—¶å‘生错误。
service.gui.ADD_GROUP_EXIST_ERROR=组 {0} å·²ç»å­˜åœ¨äºŽæ‚¨çš„è”系人åå•ä¸­äº†ã€‚请选择å¦ä¸€ä¸ªå称。
service.gui.ADD_GROUP_NET_ERROR=添加组:{0} 失败。网络错误。请检查您的网络连接然åŽé‡è¯•ã€‚
service.gui.ADD_GROUP_ERROR=添加组:{0}失败。
service.gui.ADD_GROUP_EMPTY_NAME=组å称ä¸èƒ½ä¸ºç©ºã€‚
-service.gui.ADD_GROUP=创建组
-service.gui.ADD_SUBCONTACT=添加紧急è”络人
service.gui.ADDRESS=地å€
service.gui.ADMINISTRATOR=管ç†å‘˜
service.gui.ADVANCED=高级
-service.gui.ALL=所有
service.gui.ALL_CONTACTS=所有è”系人
service.gui.ALTERNATE_ADDRESS=备用地å€
service.gui.APPLY=应用
-service.gui.ARE_CALLING={0}正被呼å«ã€‚。。
+service.gui.ARE_CALLING={0}正在呼å«ã€‚。。
service.gui.ARE_NOW=你现在是{0}
service.gui.AT=ä½äºŽ
-service.gui.AUTHORIZE=认è¯
-service.gui.AUTHORIZATION_ACCEPTED={0}å·²ç»æŽ¥å—您的身份验è¯è¯·æ±‚。
+service.gui.AUTHORIZE=身份验è¯
+service.gui.AUTHORIZATION_ACCEPTED={0}已接å—您的身份验è¯è¯·æ±‚。
service.gui.AUTHENTICATION_FAILED=å¸å·{0}身份验è¯å¤±è´¥ã€‚您输入的密ç é”™è¯¯ã€‚
-service.gui.AUTHENTICATION_REQUESTED=认è¯è¯·æ±‚已被å“应
-service.gui.AUTHENTICATION_REQUESTED_SERVER=æœåŠ¡å™¨ {0} å·²å“应您的验è¯è¯·æ±‚。
-service.gui.AUTHENTICATION_REJECTED={0}å·²ç»æ‹’ç»æ‚¨çš„身份验è¯è¯·æ±‚。
-service.gui.AUTHENTICATION_WINDOW_TITLE={0}验è¯
-service.gui.AUTHORIZATION_REQUESTED=请求验è¯å·²è¢«å“应
-service.gui.AUTHORIZATION_REQUESTED_INFO=è”系人 {0} 需è¦æ‚¨æ供验è¯ä¿¡æ¯ã€‚
-service.gui.AUTHORIZATION_RESPONSE=认è¯å“应
+service.gui.AUTHENTICATION_REQUESTED_SERVER=æœåŠ¡å™¨ {0} å·²å‘é€äº†æ‚¨çš„身份验è¯è¯·æ±‚。
+service.gui.AUTHENTICATION_REJECTED={0 }已拒ç»äº†æ‚¨çš„身份验è¯è¯·æ±‚。
+service.gui.AUTHENTICATION_WINDOW_TITLE={0} 身份验è¯
+service.gui.AUTHORIZATION_REQUESTED=请求身份验è¯
+service.gui.AUTHORIZATION_REQUESTED_INFO=è”系人 {0} 请求您通过身份验è¯ã€‚
+service.gui.AUTHORIZATION_RESPONSE=身份验è¯å›žå¤
service.gui.AWAY_STATUS=离开
-service.gui.EXTENDED_AWAY_STATUS=离开
+service.gui.EXTENDED_AWAY_STATUS=远远离开
service.gui.BAN=ç¦æ­¢
-service.gui.BANNED=ç¦æ­¢
+service.gui.BANNED=å·²ç¦æ­¢
service.gui.BAN_FAILED=ç¦æ­¢æ“作失败
-service.gui.BAN_FAILED_GENERAL_ERROR=阻止 {0} 失败。æœåŠ¡å™¨ä¸€èˆ¬æ€§é”™è¯¯ã€‚
-service.gui.BAN_FAILED_NOT_ALLOWED=ç¦æ­¢{0} 失败。èŠå¤©å®¤çš„创建人或管ç†å‘˜ä¸èƒ½è¢«ç¦æ­¢ã€‚
+service.gui.BAN_FAILED_GENERAL_ERROR=ç¦æ­¢ {0} 失败。å‘生一般性æœåŠ¡å™¨é”™è¯¯ã€‚
+service.gui.BAN_FAILED_NOT_ALLOWED=ç¦æ­¢{0} 失败。èŠå¤©å®¤çš„所有人和管ç†å‘˜ä¸èƒ½è¢«ç¦æ­¢ã€‚
service.gui.BAN_FAILED_NOT_ENOUGH_PERMISSIONS=ç¦æ­¢{0}失败。您没有相关æƒé™ã€‚
-service.gui.BRB_MESSAGE=本人ä¸åœ¨ï¼Œç¨åŽå›žæ¥ã€‚
+service.gui.BRB_MESSAGE=我现在ä¸åœ¨ï¼Œç¨åŽå›žæ¥ã€‚
service.gui.BROWSE=æµè§ˆ
-service.gui.BUSY_MESSAGE=抱歉,业务正忙。
-service.gui.BUSY_STATUS=å¿™
+service.gui.BUSY_MESSAGE=抱歉,我现在有点忙。
+service.gui.BUSY_STATUS=å çº¿
service.gui.CALL=呼å«
service.gui.CALL_CONTACT=呼å«è”系人
service.gui.CALL_FAILED=呼å«å¤±è´¥
-service.gui.CALL_HISTORY_TOOL_TIP=点击这里显示呼å«åŽ†å²
-service.gui.CALL_HISTORY_GROUP_NAME=呼å«è®°å½•
-service.gui.CALL_VIA=转接呼å«ï¼š
-service.gui.CALL_NAME_OR_NUMBER=呼å«å称或å·ç 
-service.gui.CALL_NOT_SUPPORTING_PARTICIPANT=本次呼å«ä»…å…许æ¥è‡ª{0}网络的您的è”系人å¸å·{1}。{2}ä¸å±žäºŽè¯¥ç½‘络或此å¸æˆ·ä¸å­˜åœ¨ã€‚
-service.gui.CALL_WITH=呼å«å¯¹è¯
-service.gui.CALL_NO_AUDIO_DEVICE=无音频设备,请设置。
-service.gui.CALL_NO_AUDIO_CODEC=æ— å¯ç”¨çš„音频编ç æ–¹æ¡ˆï¼Œè¯·æ·»åŠ æˆ–å¯ç”¨ã€‚
-service.gui.CALL_NO_DEVICE_CODECS_Q=您需è¦ç»§ç»­æ­¤å‘¼å«ä¹ˆï¼Ÿ
+service.gui.CALL_HISTORY_TOOL_TIP=点击这里显示通è¯è®°å½•
+service.gui.CALL_HISTORY_GROUP_NAME=通è¯è®°å½•
+service.gui.CALL_VIA=通è¯æ–¹å¼ï¼š
+service.gui.CALL_NAME_OR_NUMBER=通è¯å称或å·ç 
+service.gui.CALL_NOT_SUPPORTING_PARTICIPANT=此通è¯ä»…支æŒæ¥è‡ªç½‘络{0}以åŠæ‚¨çš„账户{1}çš„å‚与者。{2}ä¸å±žäºŽè¿™ä¸ªç½‘络或账户。
+service.gui.CALL_WITH=通è¯
+service.gui.CALL_NO_AUDIO_DEVICE=您没有é…置音频设备。
+service.gui.CALL_NO_AUDIO_CODEC=您没有å¯ç”¨ä»»ä½•éŸ³é¢‘ç¼–ç å™¨ã€‚
+service.gui.CALL_NO_DEVICE_CODECS_Q=您è¦ç»§ç»­è¿›è¡Œå‘¼å«å—?
service.gui.CANCEL=å–消
service.gui.CHAT=èŠå¤©
service.gui.CHANGE_FONT=更改字体
-service.gui.CHANGE_ROOM_SUBJECT=修改èŠå¤©å®¤æ ‡é¢˜...
-service.gui.CHANGE_ROOM_SUBJECT_LABEL=请在下é¢çš„输入框内,您å¯ä»¥è¾“å…¥èŠå¤©å®¤çš„æ–°å称。
+service.gui.CHANGE_ROOM_SUBJECT=修改èŠå¤©å®¤ä¸»é¢˜...
+service.gui.CHANGE_ROOM_SUBJECT_LABEL=您å¯ä»¥åœ¨ä¸‹æ–¹è¾“入本èŠå¤©å®¤çš„新主题。
service.gui.CHANGE_NICK=更改昵称
-service.gui.CHANGE_NICKNAME=修改昵称...
-service.gui.CHANGE_NICKNAME_LABEL=请在下é¢çš„输入框内,您å¯ä»¥è¾“入您的新昵称。
+service.gui.CHANGE_NICKNAME=更改昵称...
+service.gui.CHANGE_NICKNAME_LABEL=您å¯ä»¥åœ¨ä¸‹æ–¹è¾“入新的昵称。
service.gui.CHANGE_NICKNAME_ERROR=更改昵称时出错
-service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=昵称存在é‡å¤
-service.gui.CHANGE_VIDEO_QUALITY=改å˜è¿œç«¯è§†é¢‘è´¨é‡
-service.gui.CHAT_CONFERENCE_LABEL=会议
-service.gui.CHAT_CONFERENCE_ITEM_LABEL={0}的会议
-service.gui.CHAT_ROOM_ALREADY_JOINED={0}已加入èŠå¤©å®¤ã€‚
-service.gui.CHAT_ROOM_CONFIGURATION={0}èŠå¤©å®¤çš„é…置信æ¯
+service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=昵称已存在
+service.gui.CHANGE_VIDEO_QUALITY=更改远程视频质é‡
+service.gui.CHAT_CONFERENCE_ITEM_LABEL={0} 的会议
+service.gui.CHAT_ROOM_ALREADY_JOINED=èŠå¤©å®¤ {0} 您已ç»åŠ å…¥ã€‚
+service.gui.CHAT_ROOM_CONFIGURATION=èŠå¤©å®¤ {0} é…ç½®
service.gui.CHAT_ROOM_CONFIGURATION_FAILED=获å–èŠå¤©å®¤ {0} é…置失败。
service.gui.CHAT_ROOM_CONFIGURATION_FORBIDDEN=ä¸èƒ½èŽ·å–{0}èŠå¤©å®¤é…置信æ¯ã€‚åªæœ‰èŠå¤©å®¤æ‹¥æœ‰è€…å¯ä»¥æµè§ˆå˜æ›´æ­¤é…置信æ¯ã€‚
service.gui.CHAT_ROOM_CONFIGURATION_SUBMIT_FAILED=当æ交èŠå¤©å®¤{0}çš„é…置时å‘生错误。
@@ -118,31 +121,28 @@ service.gui.CHAT_ROOM_CONFIGURATION_MEMBERS_EDIT_TITLE=编辑æˆå‘˜åˆ—表
service.gui.CHAT_ROOM_CONFIGURATION_MEMBERS_EDIT_DESCRIPTION=列在å³ä¾§çš„用户将拥有此èŠå¤©å®¤æˆå‘˜è§’色。当èŠå¤©å®¤è¢«è®¾ç½®ä¸ºâ€œä»…æˆå‘˜â€æ¨¡å¼æ—¶ä»…这些用户被å…许加入。
service.gui.CHAT_ROOM_USER_JOINED=已加入 {0}
service.gui.CHAT_ROOM_USER_LEFT=已离开 {0}
-service.gui.CHAT_ROOM_USER_KICKED=被é€å‡º {0}
+service.gui.CHAT_ROOM_USER_KICKED=已被踢出 {0}
service.gui.CHAT_ROOM_USER_QUIT=已退出 {0}
-service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=消æ¯å‘é€è¢«æ‹’(语音被撤销)
-service.gui.CHAT_ROOM_SAVE_BUTTON_TOOLTIP=收è—èŠå¤©å®¤ï¼Œä»¥ä¾¿å°†æ¥ä½¿ç”¨
-service.gui.CHAT_ROOM_REMOVE_BUTTON_TOOLTIP=从èŠå¤©å®¤æ”¶è—目录移除选择的èŠå¤©å®¤
+service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=消æ¯å‘é€è¢«æ‹’ç» (语音被撤销)
service.gui.CHAT_ROOM_NAME=èŠå¤©å®¤å
service.gui.CLEAR_CUSTOM_MESSAGES=清除临时消æ¯
service.gui.ROOM_NAME=èŠå¤©å®¤
-service.gui.AUTOJOIN=自动加入
service.gui.CHANGE_PASSWORD=修改密ç 
service.gui.CHAT_ROOM_NAME_INFO=请在下é¢è¾“å…¥æ ä¸­è¾“入您想è¦åˆ›å»ºçš„èŠå¤©å®¤å称。
service.gui.CHAT_ROOM_NOT_EXIST=在æœåŠ¡å™¨{1}上找ä¸åˆ°èŠå¤©å®¤ {0}。请检查你的输入是å¦æ­£ç¡®ã€‚
service.gui.CHAT_ROOM_NOT_CONNECTED=您必须先登录æœåŠ¡å™¨æ‰èƒ½åŠ å…¥{0}èŠå¤©å®¤ã€‚
service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=您必须先登录上æœåŠ¡å™¨æ‰èƒ½é€€å‡ºèŠå¤©å®¤ã€‚
-service.gui.CHAT_ROOM_NOT_JOINED=您需è¦å…ˆè¿›å…¥èŠå¤©å®¤, 然åŽæ‰èƒ½åšè¿›ä¸€æ­¥æ“作。
service.gui.CHAT_ROOM_OPTIONS=èŠå¤©å®¤é€‰é¡¹
service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=需è¦æ³¨å†Œæ‰èƒ½åŠ å…¥èŠå¤©å®¤{0}。
-service.gui.CHAT_ROOM_REQUIRES_PASSWORD=èŠå¤©å®¤{0}需凭密ç ç™»å…¥ã€‚
+service.gui.CHAT_ROOM_REQUIRES_PASSWORD=èŠå¤©å®¤ {0} è¦æ±‚输入密ç ã€‚
service.gui.CHAT_ROOMS=èŠå¤©å®¤
service.gui.CHAT_ROOM=èŠå¤©å®¤
-service.gui.CHAT_ROOM_SUBJECT_CHANGED={0} å·²ç»æ›´æ¢äº†æ–°ä¸»é¢˜ {1}
-service.gui.CHAT_ROOM_ALTERNATE_ADDRESS=您å¯åœ¨ä¸‹åˆ—èŠå¤©å®¤:{0}继续您的会è¯
+service.gui.CHAT_ROOM_SUBJECT_CHANGED={0} 已将èŠå¤©å®¤ä¸»é¢˜æ›´æ”¹ä¸º {1}
+service.gui.CHAT_ROOM_ALTERNATE_ADDRESS=您å¯ä¸‹åˆ—èŠå¤©å®¤ç»§ç»­æ‚¨çš„会è¯ï¼š{0}
+service.gui.CHAT_NICKNAME_CHANGE={0} 现在是 {1}
service.gui.CHOOSE_CONTACT=选择è”系人
service.gui.CHOOSE_NUMBER=选择å·ç 
-service.gui.CHOOSE_ACCOUNT=请从å¸å·åˆ—表选择一个å¸å·ã€‚
+service.gui.CHOOSE_ACCOUNT=请从列表中选择一个å¸å·ã€‚
service.gui.CITY=城市
service.gui.COUNTRY=国家
service.gui.SHOW_MORE_TOOLTIP=点击查看更多结果
@@ -150,22 +150,20 @@ service.gui.CLEAR=清除
service.gui.CLOSE=关闭
service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=您2秒å‰åˆšæ”¶åˆ°æ–°æ¶ˆæ¯ã€‚是å¦è¦ç»“æŸæœ¬æ¬¡èŠå¤©ï¼Ÿ
service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=有进行中的文件传输。你è¦å–消它们å—?
-service.gui.CONFIRM=确认
service.gui.CONNECTED_STATUS=已连接
service.gui.CONNECTING=连接中...
service.gui.CONNECTING_STATUS=连接中
service.gui.CONNECTING_EARLY_MEDIA_STATUS=连接中*
service.gui.CONNECTION=连接
-service.gui.CONNECTION_FAILED_MSG=è´¦å·ç™»å½•å¤±è´¥ï¼šç”¨æˆ·å:{0}ï¼›æœåŠ¡å™¨å:{1}。请检查您的网络连接或è”系管ç†å‘˜å¯»æ±‚更多信æ¯ã€‚
service.gui.CONNECTION_EXPIRED_MSG=您已ç»æ–­å¼€ä¸ŽæœåŠ¡å™¨ {0} 的连接。
service.gui.CONTACT_NAME=ID或å·ç 
-service.gui.CONTACT_NOT_SUPPORTING_TELEPHONY=您选择的è”系人{0}ä¸æ”¯æŒé€šè¯ã€‚
+service.gui.CONTACT_NAME_PROMPT=jane.doe@example.com
+service.gui.CONTACT_NAME_INFO=添加一个åŠæ—¶é€šè®¯åœ°å€ (比如 jane.doe@example.com)或者 VoIP å·ç 
service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=您选择的è”系人{0}ä¸æ”¯æŒç¾¤èŠã€‚
service.gui.CONTACT_PAUSED_TYPING={0} æš‚åœè¾“å…¥
service.gui.CONTACT_TYPING={0} 正在输入消æ¯
-service.gui.CONTACT_TYPING_SEND_FAILED=å•Š-哦...我们ä¸èƒ½å‘{0}宣告你正在书写
+service.gui.CONTACT_TYPING_SEND_FAILED=å•Š-哦...我们ä¸èƒ½å‘ {0} 宣告你正在键入
service.gui.CONTACT_INFO=è”系人信æ¯
-service.gui.CONTACTLIST=è”系人目录
service.gui.CONTACTS=è”系人
service.gui.COPY=å¤åˆ¶(&C)
service.gui.COPY_LINK=å¤åˆ¶é“¾æŽ¥(&L)
@@ -175,33 +173,32 @@ service.gui.CREATE_CHAT_ROOM=创建èŠå¤©å®¤(&C)...
service.gui.CREATE_CHAT_ROOM_ERROR=创建èŠå¤©å®¤ {0} 失败.
service.gui.CREATE_CHAT_ROOM_WIZARD=èŠå¤©å®¤æ–°å»ºå‘导
service.gui.CREATE_CONFERENCE_CALL=创建èŠå¤©å®¤(&C)
-service.gui.CREATE_CONFERENCE_CHAT=创建èŠå¤©å®¤(&C)
service.gui.CREATE_GROUP=新建组(&C)
service.gui.CREATE_GROUP_NAME=请在下é¢è¾“å…¥æ ä¸­è¾“入您想è¦åˆ›å»ºçš„组å.
-service.gui.CREATE_FIRST_GROUP_WIZARD=您的è”系人åå•ä¸­æ²¡æœ‰ä»»ä½•ç»„. 请创建一个组 (文件/新建组).
service.gui.CREATE_VIDEO_BRIDGE=创建视频桥接中...
service.gui.CREATE_VIDEO_BRIDGE_MENU=创建视频桥接
service.gui.CREATE_JOIN_VIDEO_CONFERENCE=创建/加入视频会议
service.gui.CREATE_VIDEO_CONFERENCE=为此èŠå¤©å®¤åˆ›å»ºä¸€ä¸ªæ–°çš„视频会议
service.gui.CONTACT_INFO_NOT_SUPPORTED=该è”系人ä¸æ”¯æŒç½‘络å片
service.gui.CUT=剪切(&U)
-service.gui.DATE=日期
service.gui.DELETE=删除
service.gui.DENY=æ‹’ç»(&D)
service.gui.DESKTOP_SHARING_WARNING=<b>您确定è¦å¼€å§‹å±å¹•å…±äº«?</b> <br> 点击确定将å…许对方查看您的å±å¹•.
+service.gui.DESKTOP_SHARING_DIALOG_INDICATE=您正在共享å±å¹•
service.gui.DIALPAD=拨å·é¢æ¿
service.gui.DISPLAY_NAME=显示å称
+service.gui.DISPLAY_NAME_PROMPT=Jane Doe
+service.gui.DISPLAY_NAME_INFO=为这个è”系人添加一个å称。如果留空的è¯ï¼Œå°†ä¼šä½¿ç”¨åŠæ—¶é€šè®¯åœ°å€æˆ– VoIP 填补。(å¯é€‰ï¼‰
service.gui.DISCONNECTED_STATUS=已断开
service.gui.DND_STATUS=请别打扰
service.gui.DO_NOT_ASK_AGAIN=请ä¸è¦é‡å¤è¯¢é—®
service.gui.DO_NOT_SHOW_AGAIN=请ä¸è¦é‡å¤æ­¤æ¶ˆæ¯
-service.gui.DOWNLOAD_NOW=马上下载(&D)
service.gui.DRAG_FOR_SHARING=将任何你想共享的东西拖动到这里...
service.gui.DURATION=æŒç»­æ—¶é—´
service.gui.DESTROY_CHATROOM=撤销èŠå¤©å®¤
service.gui.DESTROY_MESSAGE=告知其他å‚与者,请输入一个ç†ç”±å’ŒåŠ å…¥æ›¿ä»£èŠå¤©å®¤åœ°å€ã€‚
service.gui.EDIT=编辑(&E)
-service.gui.EDITED_AT={0}正在录入
+service.gui.EDITED_AT=编辑于 {0}
service.gui.EMAIL=Email
service.gui.EMAILS=电å­é‚®ä»¶
service.gui.EMPTY_HISTORY=清空历å²(&E)
@@ -216,7 +213,6 @@ service.gui.ERROR_RECEIVED_FROM=从{0}处收到错误信æ¯
service.gui.ESTIMATED_TIME=估计时间:
service.gui.EVENTS=事件
service.gui.EXIT=退出(&E)
-service.gui.EXTENDED_CRITERIA=延时标准
service.gui.GENERAL=通用
service.gui.GENERAL_ERROR=一般错误
service.gui.GROUP_NAME=组å
@@ -253,24 +249,23 @@ service.gui.FOLDER_OPEN_NO_APPLICATION=无法找到应用程åºæ‰“开这个文ä»
service.gui.FONT=字体
service.gui.FONT_BOLD=粗体
service.gui.FONT_COLOR=颜色
-service.gui.FONT_FAMILY=类型
+service.gui.FONT_FAMILY=家æ—
service.gui.FONT_ITALIC=斜体
service.gui.FONT_SIZE=大å°
-service.gui.FONT_STYLE=风格
+service.gui.FONT_STYLE=æ ·å¼
service.gui.FONT_UNDERLINE=下划线
-service.gui.FROM=从{1}到{0}
service.gui.GRANT_OWNERSHIP=授予所有æƒ
service.gui.GRANT_ADMIN=授予管ç†æƒ
-service.gui.GRANT_MODERATOR=授予群主æƒé™
+service.gui.GRANT_MODERATOR=授予主æŒäººæƒé™
service.gui.GRANT_MEMBERSHIP=授予æˆå‘˜æƒé™
-service.gui.GRANT_VOICE=å…许å‘言
-service.gui.GUEST=访问者
+service.gui.GRANT_VOICE=授予语音æƒé™
+service.gui.GUEST=访客
service.gui.HANG_UP=挂断
service.gui.HD_QUALITY=HD视频
service.gui.HELP=帮助(&H)
service.gui.HIDE=éšè—
service.gui.HIDE_OFFLINE_CONTACTS=éšè—离线è”系人
-service.gui.HIDE_MAIN_WINDOW=<DIV>点击快æ·é”® X éšè—窗å£ã€‚<BR>如果需è¦é€€å‡ºï¼Œè¯·é€‰æ‹© 文件/退出。</DIV>
+service.gui.HIDE_MAIN_WINDOW=<DIV>å•å‡»çª—å£ä¸Šçš„Xåªä¼šéšè—窗å£ï¼Œè€Œä¸ä¼šçœŸæ­£é€€å‡ºç¨‹åºã€‚<BR>如果您è¦é€€å‡ºç¨‹åºï¼Œè¯·é€‰æ‹©â€æ–‡ä»¶/退出“命令。</DIV>
service.gui.HISTORY=历å²(&H)
service.gui.HISTORY_CONTACT=历å²è®°å½• - {0}
service.gui.HISTORY_TOGGLE_PER_CONTACT=关闭此è”系人æ“作历å²
@@ -284,20 +279,21 @@ service.gui.HISTORY_REMOVE_ALL_WARNING=您确认想è¦æ°¸ä¹…删除本地存储ä¿
service.gui.HISTORY_REMOVE_ERROR=删除本地存储消æ¯æ—¶å‡ºé”™ã€‚
service.gui.HOME=首页
service.gui.HOME_PAGE=主页
-service.gui.HOUR=æ—¶
service.gui.ICE=ICE
service.gui.IDENTIFIER=称呼
service.gui.IGNORE=忽略(&I)
service.gui.INSERT_SMILEY=表情
-service.gui.INCOMING_CALL=æ¥è‡ª{0}的呼å«è¯·æ±‚
+service.gui.INCOMING_CALL=æ¥è‡ª{0}的通è¯è¯·æ±‚
+service.gui.INCOMING_SCREEN_SHARE=收到å±å¹•å…±äº«è¯·æ±‚,æ¥è‡ªï¼š{0}
service.gui.INCOMING_CALL_STATUS=æ¥ç”µ
-service.gui.INSTANT_MESSAGINGS=短信
-service.gui.IM=å³æ™‚èŠå¤©
-service.gui.INITIATING_CALL_STATUS=åˆå§‹åŒ–呼å«
-service.gui.INVITATION=邀请
+service.gui.INCOMING_SCREEN_SHARE_STATUS=传入的å±å¹•å…±äº«è¯·æ±‚
+service.gui.INSTANT_MESSAGINGS=å³æ—¶èŠå¤©
+service.gui.IM=å³æ—¶èŠå¤©
+service.gui.INITIATING_CALL_STATUS=正在åˆå§‹åŒ–呼å«
+service.gui.INVITATION=邀请文本
service.gui.INVITATION_RECEIVED=收到邀请
-service.gui.INVITATION_RECEIVED_MSG={0} 邀请 {1} 加入èŠå¤©å®¤. 您å¯ä»¥é€‰æ‹©åŒæ„, æ‹’ç»æˆ–者忽略这个邀请.
-service.gui.INVITATION_REJECTED={0}å·²ç»æ‹’ç»æ‚¨çš„加入èŠå¤©å®¤é‚€è¯·ã€‚原因:{1}。
+service.gui.INVITATION_RECEIVED_MSG={0} 邀请您加入èŠå¤©å®¤{1}。您å¯ä»¥é€‰æ‹©åŒæ„,拒ç»æˆ–忽略此邀请。
+service.gui.INVITATION_REJECTED={0} å·²ç»æ‹’ç»æ‚¨çš„加入èŠå¤©å®¤é‚€è¯·ã€‚原因:{1}。
service.gui.INVITE=邀请(&I)
service.gui.INVITE_CONTACT_MSG=如果想进行精确查找, 请输入该用户的å称.
service.gui.INVITE_CONTACT_TO_CHAT=邀请其他è”系人加入èŠå¤©
@@ -306,13 +302,10 @@ service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=邀请è”系人视频桥接
service.gui.INVITE_REASON=邀请ç†ç”±
service.gui.IS_CALLING={0}正在呼å«...
service.gui.IS_NOW={0}已更å为{1}
-service.gui.JITSI_WARNING=SIP Communicator 最近已ç»æ›´å为 Jitsi.<br/>如果您想ä¿æŒæ‚¨çš„版本最新,请下载Jitsi.<br/><br/>给您带æ¥çš„ä¸ä¾¿æ•¬è¯·è°…解.<br/><br/>Jitsi å¼€å‘å°ç»„
-service.gui.JITSI_WARNING_TITLE=SIP Communicator 已更å为 Jitsi
service.gui.JOIN=加入(&J)
-service.gui.JOIN_AS=选择å称加入(&O)
-service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=加入一个就绪的视频会议
+service.gui.JOIN_AS=加入为(&O)
+service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=加入现有的视频会议
service.gui.JOIN_VIDEO=加入视频会è¯
-service.gui.CLOSE_CHAT_ROOM_DIALOG=关闭(&L)
service.gui.JOB_TITLE=èŒä½
service.gui.JOIN_CHAT_ROOM=加入èŠå¤©å®¤(&J)...
service.gui.JOIN_CHAT_ROOM_TITLE=加入èŠå¤©å®¤
@@ -325,14 +318,13 @@ service.gui.KICK_FAILED=踢出æ“作失败
service.gui.KICK_FAILED_GENERAL_ERROR=踢出 {0} 失败, æœåŠ¡å™¨å‡ºé”™.
service.gui.KICK_FAILED_NOT_ALLOWED=踢出 {0} 失败, èŠå¤©å®¤çš„创建人或管ç†å‘˜ä¸èƒ½è¢«è¸¢å‡ºã€‚
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=踢出 {0} 失败, 您没有æƒé™ã€‚
-service.gui.LAST=上一个
-service.gui.LAST_NAME=姓
+service.gui.LAST_NAME=您的姓æ°
service.gui.LEAVE=离开(&L)
service.gui.LIMIT_REACHED_FOR_IP=本地IP地å€æ³¨å†Œè´¦æˆ·è¿‡å¤š, æœåŠ¡å™¨ {0} ä¸èƒ½æŽ¥å—更多注册.
service.gui.LIST=所有èŠå¤©å®¤
service.gui.LOADING_ROOMS=载入中...
service.gui.LOADING=正在加载...
-service.gui.LOCALLY_ON_HOLD_STATUS=本地挂起
+service.gui.LOCALLY_ON_HOLD_STATUS=本地正呼å«ç­‰å¾…中
service.gui.LOGIN_NETWORK_ERROR=由于网络连接原因,登录失败:用户å:{0},æœåŠ¡å™¨:{1}.请检查网络连接.
service.gui.LOGIN_GENERAL_ERROR=登录账户出错: 用户å: {0}, æœåŠ¡å™¨å: {1}.
service.gui.LOGIN_INTERNAL_ERROR=登录错误,用户å:{0},æœåŠ¡å™¨ï¼š{1}。这应该是一个应用程åºå†…部错误。请通过开å‘者邮件列表将问题报告给我们(dev@jitsi.java.net)。
@@ -340,12 +332,11 @@ service.gui.LOGIN_INVALID_PROPERTIES_ERROR=由于å¸å·é…置问题,登录失è
service.gui.LOGOFF_NOT_SUCCEEDED=退出账户出错: 用户å: {0}, æœåŠ¡å™¨å: {1}.
service.gui.LOW_QUALITY=低å“è´¨
service.gui.MEMBER=æˆå‘˜
-service.gui.MERGE_TO_CALL=åˆå¹¶å‘¼å«
+service.gui.MERGE_TO_CALL=åˆå¹¶æ‰€æœ‰é€šè¯
service.gui.MESSAGE=消æ¯
service.gui.MISSED_CALLS_TOOL_TIP=未接æ¥ç”µæ¥è‡ªï¼š
service.gui.MISSED_CALLS_MORE_TOOL_TIP= 还有{0}æ¡
-service.gui.MODERATOR=群主
-service.gui.MORE=查看更多
+service.gui.MODERATOR=主æŒäºº
service.gui.MORE_LABEL=展开
service.gui.MOVE=移动
service.gui.MOVE_SUBCONTACT=移动è”系人
@@ -354,12 +345,12 @@ service.gui.MOVE_SUBCONTACT_FAILED=您选择的è”系人已ç»å­˜åœ¨ã€‚\n请é‡æ
service.gui.MOVE_SUBCONTACT_QUESTION=您确认è¦å°†{0}移动到{1}?
service.gui.MOVE_TO_GROUP=移动到组(&M)
service.gui.MOVE_CONTACT=移动è”系人
-service.gui.MOVE_CONTACT_ERROR=è”系人ä¸èƒ½è¢«ç§»åŠ¨(&C)
service.gui.MSG_DELIVERY_FAILURE=上é¢æ¶ˆæ¯å‘é€å¤±è´¥
service.gui.MSG_DELIVERY_NOT_SUPPORTED=您正在使用的åè®®ä¸æ”¯æŒç¦»çº¿æ¶ˆæ¯ã€‚ 请å°è¯•å…¶ä»–åè®®è”ç³»{0}或者等待他/她上线。
service.gui.MSG_DELIVERY_INTERNAL_ERROR=内部出错。å¯èƒ½æ˜¯ç¨‹åºè‡ªèº«é”™è¯¯ã€‚请æ交您的错误报告到:http://www.jitsi.org/index.php/Development/BugsAndIssues。
service.gui.MSG_DELIVERY_ERROR=å‘é€æ¶ˆæ¯å¤±è´¥ã€‚
service.gui.MSG_DELIVERY_UNKNOWN_ERROR=å‘é€æ¶ˆæ¯å¤±è´¥, 未知错误.
+service.gui.MSG_DELIVERY_UNSUPPORTED_OPERATION=ä¸æ”¯æŒçš„æ“作。
service.gui.MSG_NOT_DELIVERED=网络错误。请检查网络é…置然åŽé‡è¯•ã€‚
service.gui.MSG_NOT_POSSIBLE=无法给该è”系人å‘消æ¯ï¼ˆåè®®ä¸æ”¯æŒï¼‰
service.gui.MSG_RECEIVED={0} å‘é€æ¶ˆæ¯ç»™ä½ äº†
@@ -367,9 +358,8 @@ service.gui.MSG_SEND_CONNECTION_PROBLEM=请先登录æœåŠ¡å™¨, 然åŽå‘é€æ¶ˆæ
service.gui.MULTIPLE_LOGINS=è´¦å·åœ¨å…¶ä»–地方登录, 本地连接断开: 用户å: {0}, æœåŠ¡å™¨: {1}.
service.gui.MY_CHAT_ROOMS=èŠå¤©å®¤
service.gui.MY_CHAT_ROOMS_TITLE=èŠå¤©å®¤
-service.gui.MUTE=é™éŸ³
-service.gui.MUTUALLY_ON_HOLD_STATUS=挂起(åŒæ–¹ï¼‰
-service.gui.NAME=姓å
+service.gui.MUTUALLY_ON_HOLD_STATUS=呼å«ç­‰å¾…é™éŸ³
+service.gui.NAME=å称
service.gui.NETWORK=网络
service.gui.NETWORK_FAILURE=网络错误
service.gui.NEXT=下一个(&N)
@@ -378,13 +368,14 @@ service.gui.NEW_MESSAGE=新消æ¯...
service.gui.NEW_NAME=æ–°å称:
service.gui.NEW_STATUS_MESSAGE=添加状æ€ä¿¡æ¯
service.gui.NEW_STATUS_MESSAGE_SAVE=存为自定义信æ¯
+service.gui.NICKNAME=昵称
service.gui.NO=å¦
-service.gui.NONE=沒有
-service.gui.NO_CAMERA_AVAILABLE=找ä¸åˆ°æ‘„åƒå¤´è®¾å¤‡
-service.gui.NO_DESKTOP_SHARING_FOR_PROTOCOL=æ¡Œé¢å…±äº«ä¸å—æ­¤å议支æŒ
-service.gui.NO_VIDEO_ENCODINGS=é…置中无视频编ç æ–¹å¼è¢«é€‰ä¸­
-service.gui.NO_VIDEO_FOR_PROTOCOL=视频ä¸è¢«æ­¤å议支æŒ
-service.gui.NO_AVAILABLE_ROOMS=该æœåŠ¡å™¨ä¸Šçš„èŠå¤©å®¤æ¸…å•æš‚æ—¶ä¸å¯èŽ·å¾—.
+service.gui.NONE=æ— 
+service.gui.NO_CAMERA_AVAILABLE=没有å¯ç”¨çš„æ‘„åƒå¤´
+service.gui.NO_DESKTOP_SHARING_FOR_PROTOCOL=此通信åè®®ä¸æ”¯æŒæ¡Œé¢å…±äº«ã€‚
+service.gui.NO_VIDEO_ENCODINGS=在é…置中没有å¯ç”¨ä»»ä½•è§†é¢‘解ç å™¨
+service.gui.NO_VIDEO_FOR_PROTOCOL=此通信åè®®ä¸æ”¯æŒè§†é¢‘通è¯
+service.gui.NO_AVAILABLE_ROOMS=æœåŠ¡å™¨ä¸Šçš„èŠå¤©å®¤åˆ—表暂时ä¸å¯ç”¨ã€‚
service.gui.NO_CONTACTS_FOUND=找ä¸åˆ°åŒ¹é…çš„è”系人。按下 Ctrl+Enter 或使用以下按钮 å‘¼å« {0}。
service.gui.NO_CONTACTS_FOUND_SHORT=未找到匹é…çš„è”系人
service.gui.NO_MESSAGE=没有消æ¯
@@ -392,27 +383,32 @@ service.gui.NO_GROUP_CHAT_ACCOUNT_AVAILABLE=ä¸æ”¯æŒç¾¤èŠã€‚ 进入 jitsi.org
service.gui.NO_ONLINE_CONFERENCING_ACCOUNT=æ— å¯ç”¨çš„会议账户。哪些å议支æŒä¼šè®®ï¼Œè¯·æŸ¥é˜…https://jitsi.org。
service.gui.NO_ONLINE_TELEPHONY_ACCOUNT=呼å«å‰å¿…须确ä¿è‡³å°‘一个电è¯å¸å·åœ¨çº¿ã€‚请登录您的一个电è¯å¸å·ç„¶åŽé‡è¯•ã€‚
service.gui.NOT_AUTHORIZED=未认è¯
-service.gui.NON_EMPTY_CHAT_WINDOW_CLOSE=消æ¯è¿˜æ²¡æœ‰å‘é€å‡ºåŽ», 是å¦ä¸€å®šé€€å‡º?
-service.gui.NON_EXISTING_USER_ID=æœåŠ¡å™¨ {0} ä¸èƒ½è¯†åˆ«ç”¨æˆ·èº«ä»½.
+service.gui.NON_EMPTY_CHAT_WINDOW_CLOSE=您正在å°è¯•å…³é—­ä¼šè¯ï¼Œä½†æ˜¯è¿˜æœ‰æœªå‘é€çš„消æ¯ã€‚您确定è¦å…³é—­ä¼šè¯å—?
+service.gui.NON_EXISTING_USER_ID=æœåŠ¡å™¨ {0} ä¸èƒ½è¯†åˆ«æŒ‡å®šçš„用户id。
service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=ä¸åœ¨è”系人列表中
service.gui.SD_QUALITY=标准质é‡
service.gui.OFFLINE=离线
-service.gui.OK=OK
-service.gui.OLDER_CALLS=之å‰çš„通è¯
+service.gui.OK=确定
service.gui.ONLINE=在线
service.gui.OPEN=打开
-service.gui.OPEN_FILE_FROM_IMAGE=åŒå‡»æ¥æ‰“开文件
+service.gui.OPEN_FILE_FROM_IMAGE=åŒå‡»ä»¥æ‰“开文件
service.gui.OPEN_FOLDER=打开文件夹
service.gui.OPEN_IN_BROWSER=在æµè§ˆå™¨ä¸­æ‰“å¼€(&B)
service.gui.OPTIONS=选项
-service.gui.OPEN_AUTOMATICALLY=自动开å¯èŠå¤©å®¤
-service.gui.OPEN_ON_ACTIVITY=活动开å¯
-service.gui.OPEN_ON_MESSAGE=仅消æ¯å¼€å¯
-service.gui.OPEN_ON_IMPORTANT_MESSAGE=ä»…é‡è¦æ¶ˆæ¯å¼€å¯
-service.gui.OR=或
-service.gui.OR_ENTER_PHONE_NUMBER=或者在此输入电è¯å·ç ...
+service.gui.OPEN_AUTOMATICALLY=在以下情况下自动打开本èŠå¤©å®¤
+service.gui.OPEN_ON_ACTIVITY=有活动时打开
+service.gui.OPEN_ON_MESSAGE=仅在有消æ¯æ—¶æ‰“å¼€
+service.gui.OPEN_ON_IMPORTANT_MESSAGE=仅在有é‡è¦æ¶ˆæ¯æ—¶æ‰“å¼€
+service.gui.OR=或者
service.gui.ORGANIZATION=组织
service.gui.OTHER=其他
+service.gui.chat.role.OWNER=所有者
+service.gui.chat.role.ADMINISTRATOR=管ç†å‘˜
+service.gui.chat.role.MODERATOR=主æŒäºº
+service.gui.chat.role.MEMBER=æˆå‘˜
+service.gui.chat.role.GUEST=游客
+service.gui.chat.role.SILENT_MEMBER=é™éŸ³æˆå‘˜
+service.gui.chat.role.OUTCAST=被ç¦æ­¢åŠ å…¥
service.gui.OWNER=房间所有者
service.gui.ON_MOBILE_TOOLTIP=(手机通è¯ä¸­)
service.gui.PASSWORD=密ç 
@@ -424,28 +420,26 @@ service.gui.PORT=端å£
service.gui.POSTAL_CODE=邮政编ç 
service.gui.PREFERENCES=首选项
service.gui.PREFIX=å‰ç¼€
-service.gui.PRESENCE=出席
-service.gui.PRESS_ENTER_FOR_SUGGESTIONS=按'回车'查看建议
-service.gui.PRESS_FOR_CALL_INFO=点击查看呼å«ä¿¡æ¯
+service.gui.PRESENCE=在线状æ€
+service.gui.PRESS_ENTER_FOR_SUGGESTIONS=按'Enter'键查看建议
+service.gui.PRESS_FOR_CALL_INFO=点击查看通è¯ä¿¡æ¯
service.gui.PRESS_TO_OPEN_CRM=点击打开CRM程åº
service.gui.PREVIOUS=上一个
-service.gui.PREVIOUS_TOOLTIP=查看更早对è¯
service.gui.PRINT=打å°(&P)
service.gui.PROACTIVE_NOTIFICATION=正在输入消æ¯
service.gui.PROBLEMS_ENCOUNTERED=é­é‡é—®é¢˜
service.gui.PROTOCOL=åè®®
-service.gui.PUT_OFF_HOLD=å–消挂起
-service.gui.PUT_ON_HOLD=挂起
+service.gui.PUT_OFF_HOLD=撤销呼å«ç­‰å¾…
+service.gui.PUT_ON_HOLD=呼å«ç­‰å¾…
service.gui.QUIT=退出(&Q)
service.gui.READY=就绪
-service.gui.RECENT_MESSAGES=最近的å°è¯
+service.gui.RECENT_MESSAGES=最近的对è¯
service.gui.REASON=原因
service.gui.RECEIVED=收到{0}
service.gui.RECONNECTION_LIMIT_EXCEEDED=该账户多次é‡å¤ç™»å½•æœåŠ¡å™¨: 用户å: {0}, æœåŠ¡å™¨å: {1} ç›®å‰å·²ç»è¢«ç¦æ­¢, 请等待一段时间åŽå†è¯•.
service.gui.RE_REQUEST_AUTHORIZATION=é‡æ–°è¯·æ±‚认è¯
service.gui.REFERRED_STATUS=转接
service.gui.REJECT=æ‹’ç»(&R)
-service.gui.REMIND_ME_LATER=以åŽæ醒我
service.gui.REMEMBER_PASSWORD=è®°ä½å¯†ç 
service.gui.REMOVE=删除(&R)
service.gui.REMOVE_ACCOUNT=删除账户(&R)
@@ -461,39 +455,32 @@ service.gui.RENAME_CONTACT_WIZARD=请在下é¢çš„输入æ ä¸­è¾“入您对该è”ç
service.gui.RENAME_GROUP=é‡å‘½å组(&N)
service.gui.RENAME_GROUP_INFO=请在下é¢çš„输入æ ä¸­è¾“入您对该组的新å称.
service.gui.RENAME_CLEAR_USER_DEFINED=还原
-service.gui.RINGING_STATUS=å“铃中
+service.gui.RINGING_STATUS=振铃中
service.gui.REQUEST=请求(&R)
service.gui.REQUEST_AUTHORIZATION=请求加为好å‹(&R)
service.gui.REQUEST_AUTHORIZATION_MSG=ä¸èƒ½æ·»åŠ  {0} 到您的è”系人åå•. 必须等待 {0} 加您为他/她的好å‹. 请输入您的请求信æ¯.
service.gui.RETRY=é‡è¯•
service.gui.REVOKE_OWNERSHIP=å–消所有者æƒé™
service.gui.REVOKE_ADMIN=å–消管ç†å‘˜æƒé™
-service.gui.REVOKE_MODERATOR=å–消群主æƒé™
+service.gui.REVOKE_MODERATOR=å–消主æŒäººæƒé™
service.gui.REVOKE_MEMBERSHIP=å–消æˆå‘˜æƒé™
-service.gui.REVOKE_VOICE=å–消å‘言æƒ
-service.gui.ROOT_GROUP=最上级组
+service.gui.REVOKE_VOICE=撤回语音æƒé™
service.gui.SAVE=ä¿å­˜(&S)
-service.gui.SAVE_AS_DEFAULT=ä¿å­˜ä¸ºé»˜è®¤å€¼
service.gui.SEARCH=æœç´¢(&S)
service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=点击按键显示æœåŠ¡å™¨ä¸Šæ‰€æœ‰èŠå¤©å®¤, 然åŽé€‰æ‹©æ‚¨æ„Ÿå…´è¶£çš„èŠå¤©å®¤, 点击加入.
service.gui.SEARCH_STRING_CONTACT_SOURCE=æœç´¢åˆ°çš„è”系人
service.gui.SECURITY=安全
-service.gui.SELECT_ACCOUNT=选择账户
+service.gui.SELECT_ACCOUNT_INFO=您想使用哪个å¸å·ä¸Žè¿™ä¸ªè”系人进行通讯?
service.gui.SELECT_COLOR=选择颜色
service.gui.SELECT_GROUP=选择组
-service.gui.SELECT_GROUP_WIZARD_MSG=下é¢çš„åå•ä¸­åŒ…å«æ‚¨æ‰€æœ‰è”系人组, 请选择一个, 然åŽåŠ å…¥æ–°çš„è”系人.
+service.gui.SELECT_GROUP_INFO=您想将此è”系人放置在哪个群组下显示?(å¯é€‰ï¼‰
service.gui.SELECT_NO_GROUP=未分组
-service.gui.SELECT_GROUP_WIZARD=指示组å
service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=下é¢çš„åå•ä¸­åŒ…å«æ‰€æœ‰æ”¯æŒç¾¤èŠçš„账户. 请选择一个, 然åŽåˆ›å»ºæ‚¨çš„èŠå¤©å®¤.
-service.gui.SELECT_PROVIDERS_WIZARD_MSG=下é¢çš„åå•ä¸­åŒ…å«æ‚¨æ‰€æœ‰çš„注册账户. 请选择一个和新è”系人对è¯.
-service.gui.SELECT_PROVIDERS_WIZARD=选择账户
service.gui.SELECT_VIDEO_CONFERENCE=选择视频会议
service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=èŠå¤©å®¤
service.gui.SEND=å‘é€(&S)
service.gui.SEND_FILE=å‘é€æ–‡ä»¶(&F)
-service.gui.SELECT_CONTACT_SUPPORTING_INFO=没有该è”系人信æ¯.
service.gui.SEND_MESSAGE=å‘é€æ¶ˆæ¯(&S)
-service.gui.SEND_AS_SMS=作为手机短信, å‘é€æ¶ˆæ¯
service.gui.SEND_PRIVATE_MESSAGE=å‘é€ç§ä¿¡
service.gui.SEND_SMS=å‘é€æ‰‹æœºçŸ­ä¿¡(&E)
service.gui.SEND_SMS_DETAILS=请记ä½ä½ å¿…须以国际电è¯å·ç æ ¼å¼è¾“入,例如 以 +44 打头的英国å·ç  +447777000000。
@@ -532,7 +519,6 @@ service.gui.STREET=è¡—é“
service.gui.SUBJECT=主题
service.gui.SUMMARY=概è¦
service.gui.TELEPHONY=电è¯
-service.gui.TODAY=今天
service.gui.TOOLS=工具(&T)
service.gui.TRANSFER=转接(&F)
service.gui.TO=到(&T)
@@ -542,7 +528,6 @@ service.gui.TRANSFER_CALL_TO=转接给:
service.gui.TRANSPARENCY_NOT_ENABLED=您当å‰è®¾ç½®ä¸æ”¯æŒé€æ˜Žã€‚
service.gui.TYPE_YOUR_REQUEST=请在这里输入您的请求
service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=我们无法改å˜æ­¤å‘¼å«çš„视频质é‡ã€‚
-service.gui.UNMUTE=å–消é™éŸ³
service.gui.USER_IDENTIFIER=用户ID:
service.gui.USER_EXISTS_ERROR=该网络上已存在该用户。请选择其他用户或网络æœåŠ¡ã€‚
service.gui.USERNAME_NULL=请输入用户å和密ç ã€‚
@@ -555,7 +540,6 @@ service.gui.USE_PROVISIONING=使用在线æ¡æ¬¾
service.gui.VALUE=值
service.gui.VIDEO_CALL=视频通è¯(&V)
service.gui.VIA=通过
-service.gui.VIA_SMS=通过短信
service.gui.VIEW=查看(&V)
service.gui.VIEW_HISTORY=查看历å²(&H)
service.gui.VIEW_SMILEYS=查看表情(&S)
@@ -575,9 +559,6 @@ service.gui.VOLUME_CONTROL_TOOL_TIP=调整音é‡
service.gui.WAITING_AUTHORIZATION=正在等待验è¯
service.gui.WARNING=警告
service.gui.YES=是
-service.gui.YESTERDAY=昨天
-service.gui.EXISTING_ACCOUNT_ERROR=您输入的å¸å·å·²åŠ å…¥ã€‚
-service.gui.NEW_MAIL=<b>你有一å°æ–°é‚®ä»¶!</b><br/><b>æ¥è‡ª:</b> {0} {1} <br/><b>标题:</b> {2} <br/>{3};
service.gui.NEW_GMAIL_HEADER={0}<a href="{1}">收件箱</a>:<br/>有一å°æ–°é‚®ä»¶
service.gui.NEW_GMAIL_MANY_HEADER={0}<a href="{1}">收件箱</a>:<br/>有{2}å°æ–°é‚®ä»¶
service.gui.NEW_GMAIL_FOOTER=多æ¡æœªè¯»ç•™è¨€åœ¨æ‚¨çš„<a href="{0}">收件箱</a>。<br/>
@@ -589,6 +570,9 @@ service.gui.ENTER_FULL_SCREEN_TOOL_TIP=å…¨å±
service.gui.EXIT_FULL_SCREEN_TOOL_TIP=退出全å±
service.gui.HOLD_BUTTON_TOOL_TIP=粗体切æ¢
service.gui.MUTE_BUTTON_TOOL_TIP=切æ¢é™éŸ³æˆ–者按ä½æŒ‰é’®ä»¥è°ƒæ•´éº¦å…‹é£ŽéŸ³é‡
+service.gui.PARK=ä¿æŒ
+service.gui.PARKING_SLOT=呼å«ä¿æŒé€šé“:
+service.gui.PARK_BUTTON_TOOL_TIP=呼å«ä¿æŒ
service.gui.RECORD_BUTTON_TOOL_TIP=å¼€å¯/åœæ­¢å½•éŸ³
service.gui.LOCAL_VIDEO_BUTTON_TOOL_TIP=视频切æ¢
service.gui.SHOW_LOCAL_VIDEO_BUTTON_TOOL_TIP=显示/éšè—本地视频
@@ -601,7 +585,6 @@ service.gui.SECURITY_ERROR=安全错误
service.gui.SPEED=速率:
service.gui.SILENT_MEMBER=é™éŸ³æˆå‘˜
service.gui.NON_SECURE_CONNECTION=无法为账户{0}建立安全连接。如果你想连接到一个éžå®‰å…¨æœåŠ¡å™¨ï¼Œè¯·åœ¨æ‚¨çš„账户é…置中选中 "å…许éžå®‰å…¨è¿žæŽ¥" 选项
-service.gui.UPDATE=æ›´æ–°
service.gui.MOBILE_PHONE=手机
service.gui.VIDEO_PHONE=视频
service.gui.WORK_PHONE=工作
@@ -636,12 +619,10 @@ service.gui.callinfo.CALL_INFORMATION=呼å«ä¿¡æ¯
service.gui.callinfo.CALL_IDENTITY=标识
service.gui.callinfo.PEER_COUNT=å‚与者计数
service.gui.callinfo.IS_CONFERENCE_FOCUS=会议焦点
-service.gui.callinfo.IS_DEFAULT_ENCRYPTED=å¯ç”¨åŠ å¯†
service.gui.callinfo.CALL_TRANSPORT=ä¿¡å·å‘¼å«ä¼ è¾“
service.gui.callinfo.CALL_DURATION=呼å«å‘¨æœŸ
service.gui.callinfo.TLS_PROTOCOL=TLS 安全åè®®
service.gui.callinfo.TLS_CIPHER_SUITE=TLS加密算法套件
-service.gui.callinfo.TLS_SERVER_CERTIFICATE_CHAIN=TLSæœåŠ¡å™¨è¯ä¹¦é“¾
service.gui.callinfo.TLS_CERTIFICATE_CONTENT=TLSæœåŠ¡å™¨è¯ä¹¦çš„内容显示在下é¢ã€‚
service.gui.callinfo.VIEW_CERTIFICATE=查看è¯ä¹¦
service.gui.callinfo.CODEC=编解ç å™¨/频率
@@ -661,10 +642,13 @@ service.gui.callinfo.MEDIA_STREAM_SRTP=RTP
service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=密钥交æ¢åè®®
service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=ICE候选者拓展类型
service.gui.callinfo.ICE_STATE=ICE作业处ç†çŠ¶æ€
+
+#enum values from IceProcessingState
service.gui.callinfo.ICE_STATE.WAITING=æœé›†å€™é€‰è€…
service.gui.callinfo.ICE_STATE.RUNNING=连通性检查
service.gui.callinfo.ICE_STATE.COMPLETED=已完æˆ
service.gui.callinfo.ICE_STATE.FAILED=失败
+
service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=本地主机IP/端å£
service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=本地自åIP/端å£
service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=本地中继IP/端å£
@@ -685,28 +669,34 @@ service.gui.ALWAYS_TRUST=总是信任这个è¯ä¹¦
service.gui.CERT_DIALOG_TITLE=验è¯è¯ä¹¦
service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>当{0}连接到æœåŠ¡å™¨<br><b>{1}</b>时无法确认æœåŠ¡å™¨èº«ä»½ã€‚<br><br>该æœåŠ¡å™¨è¯ä¹¦ä¸å¯ä¿¡ï¼Œè¿™æ„味ç€æ— æ³•è‡ªåŠ¨éªŒè¯æœåŠ¡å™¨èº«ä»½ã€‚<br><br>您确认è¦ç»§ç»­è¿žæŽ¥ï¼Ÿ<br>更多信æ¯ï¼Œç‚¹å‡» “显示è¯ä¹¦â€ã€‚</html>
service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0}无法确认æœåŠ¡å™¨è¯ä¹¦èº«ä»½ã€‚<br><br>该æœåŠ¡å™¨è¯ä¹¦ä¸å¯ä¿¡ï¼Œè¿™æ„味ç€æ— æ³•<br>自动验è¯æœåŠ¡å™¨èº«ä»½ã€‚您确认è¦ç»§ç»­è¿žæŽ¥å—?<br><br>更多信æ¯ï¼Œç‚¹å‡»â€œæŸ¥çœ‹è¯ä¹¦â€èŽ·å–详细信æ¯ã€‚</html>
-service.gui.CERT_DIALOG_CLIENT_DESCRIPTION_TXT=<html>{0} 无法验è¯æ­£åœ¨è¿žæŽ¥çš„客户端。<br><br>该客户端è¯ä¹¦ä¸å¯ä¿¡ä»»ï¼Œ <br>è¿™æ„味ç€æ— æ³•è‡ªåŠ¨éªŒè¯å…¶èº«ä»½ã€‚您确认è¦æŽ¥å—该连接?/<br><br>点击"查看è¯ä¹¦"获å–详细信æ¯ã€‚</html>
-service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} 无法确认{1}端的身份。<br><br>该è¯ä¹¦ä¸å¯ä¿¡ï¼Œ è¿™æ„味ç€æ— æ³•è‡ªåŠ¨éªŒè¯å…¶èº«ä»½ã€‚您确认è¦ç»§ç»­è¿žæŽ¥å—?<br><br>更多详情,点击“显示è¯ä¹¦â€ã€‚</html>
+service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} 无法确认 {1} 端的身份。<br><br>该è¯ä¹¦ä¸å¯ä¿¡ï¼Œ è¿™æ„味ç€æ— æ³•è‡ªåŠ¨éªŒè¯å…¶èº«ä»½ã€‚您确认è¦ç»§ç»­è¿žæŽ¥å—?<br><br>更多详情,请点击“显示è¯ä¹¦â€ã€‚</html>
service.gui.CONTINUE_ANYWAY=ä»ç„¶ç»§ç»­
+service.gui.CERT_INFO_CHAIN=è¯ä¹¦é“¾ï¼š
+service.gui.CERT_INFO_ISSUED_TO=é¢å‘ç»™
+
+#service.gui.CERT_INFO_ are combined from Rdn names
service.gui.CERT_INFO_CN=通用å:
service.gui.CERT_INFO_O=组织:
service.gui.CERT_INFO_C=国家:
service.gui.CERT_INFO_ST=å·ž/çœï¼š
service.gui.CERT_INFO_L=地å€ï¼š
+service.gui.CERT_INFO_ISSUED_BY=é¢å‘者
service.gui.CERT_INFO_OU=å•ä½ï¼š
+service.gui.CERT_INFO_VALIDITY=有效性
service.gui.CERT_INFO_ISSUED_ON=授æƒæ—¶é—´ï¼š
service.gui.CERT_INFO_EXPIRES_ON=失效时间:
+service.gui.CERT_INFO_FINGERPRINTS=指纹
+service.gui.CERT_INFO_CERT_DETAILS=è¯ä¹¦ä¿¡æ¯
service.gui.CERT_INFO_SER_NUM=åºåˆ—å·ï¼š
service.gui.CERT_INFO_VER=版本:
service.gui.CERT_INFO_SIGN_ALG=ç­¾å算法:
+service.gui.CERT_INFO_PUB_KEY_INFO=公钥信æ¯
service.gui.CERT_INFO_ALG=算法:
service.gui.CERT_INFO_PUB_KEY=公钥:
-service.gui.CERT_INFO_KEY_BYTES_PRINT={0} bytes:{1}
service.gui.CERT_INFO_KEY_BITS_PRINT={0} bits
service.gui.CERT_INFO_EXP=指数:
service.gui.CERT_INFO_KEY_SIZE=密钥长度:
service.gui.CERT_INFO_SIGN=ç­¾å:
-service.gui.CONTINUE=继续
service.gui.SHOW_CERT=显示è¯ä¹¦
service.gui.HIDE_CERT=éšè—è¯ä¹¦
@@ -729,15 +719,13 @@ service.gui.security.SECURE_AUDIO=加密音频
service.gui.security.AUDIO_NOT_SECURED=音频未加密
service.gui.security.SECURE_VIDEO=加密视频
service.gui.security.VIDEO_NOT_SECURED=未加密视频
-service.gui.security.NO_VIDEO=无视频
-service.gui.security.CIPHER=æš—ç ï¼š{0}
+service.gui.security.CALL_SECURED_TOOLTIP=呼å«å·²åŠ å¯†ã€‚更多详情请点击这里。
service.gui.security.CALL_NOT_SECURED_TOOLTIP=呼å«æœªåŠ å¯†
service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=点此åŒæ‚¨çš„伙伴校验安全密ç ã€‚
-service.gui.security.COMPARE_WITH_PARTNER=核对å‚与者然åŽç‚¹å‡»æŒ‚é”图标确认。
# keep the following string short
service.gui.security.COMPARE_WITH_PARTNER_SHORT=请核对å‚与者:
service.gui.security.STRING_COMPARED=字符串校验通过ï¼
-service.gui.security.SAS_INFO_TOOLTIP=<html>为了完æˆåŠ å¯†ä½ <br/>需è¦å£å¤´<b>校验</b>è”系人æ供的一å°æ®µéªŒè¯<br/>字段并当此字段被验è¯é€šè¿‡åŽç‚¹å‡»ç¡®è®¤ã€‚<br/><br/>如果你清除了此确认信æ¯ï¼Œå½“下次呼å«æ­¤è”系人时<br/>你将被è¦æ±‚å†æ¬¡éªŒè¯ã€‚</html>
+service.gui.security.SAS_INFO_TOOLTIP=<html> 为了完æˆåŠ å¯†ä½  <br/> 需è¦å£å¤´ <b> 校验 </b> è”系人æ供的一å°æ®µéªŒè¯ <br/> 字段并仅当此字段被验è¯é€šè¿‡åŽæ‰èƒ½ç‚¹å‡»ç¡®è®¤ã€‚<br/><br/> 如果你清除了此确认信æ¯ï¼Œå½“下次呼å«æ­¤è”系人时 <br/> 你将被è¦æ±‚å†æ¬¡éªŒè¯ã€‚</html>
service.gui.security.SECURITY_ALERT=å°è¯•åŠ å¯†å‘¼å«ã€‚会断开接入
service.gui.avatar.CHOOSE_ICON=选择图片
@@ -751,20 +739,14 @@ service.gui.avatar.imagepicker.CLICK=微笑然åŽå•å‡»
service.gui.avatar.imagepicker.IMAGE_FILES=图片文件
service.gui.avatar.imagepicker.IMAGE_PICKER=图片
service.gui.avatar.imagepicker.IMAGE_SIZE=图片大å°
-service.gui.avatar.imagepicker.INITIALIZING=åˆå§‹åŒ–中
service.gui.avatar.imagepicker.RESET=é‡ç½®
service.gui.avatar.imagepicker.SET=设置
service.gui.avatar.imagepicker.TAKE_PHOTO=æ‹ç…§
-service.gui.avatar.imagepicker.WEBCAM_ERROR=æ‘„åƒå¤´é”™è¯¯
service.gui.security.encryption.required=必须加密ï¼
service.protocol.ICE_FAILED=无法建立连接(ICE失败,并没有å‘现中继器)
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
-impl.protocol.ssh.DETAILS_SEPARATOR=~
impl.protocol.sip.XCAP_ERROR_TITLE=SIPè”系人列表存储错误
impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR=æºä¸èƒ½è¢«è¯»ä¸º{0}。对象{1}
@@ -794,9 +776,7 @@ impl.ldap.QUERY_CUSTOM=自定义查询
impl.ldap.QUERY_CUSTOM_HINT=使用 {0} 作为å ä½ç¬¦ç”¨äºŽæœç´¢æœ¯è¯­ã€‚
impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=在查询术语中自动增加通é…符
impl.ldap.QUERY_PHOTO_INLINE=通过其他属性获å–图片
-impl.ldap.NEW=新建
impl.ldap.EDIT=编辑
-impl.ldap.REMOVE=删除
impl.ldap.ENABLED=å¯ç”¨
impl.ldap.SERVER_NAME=æœåŠ¡å™¨å
impl.ldap.SERVER_NAME_EXAMPLE=我的LDAPæœåŠ¡å™¨
@@ -829,6 +809,12 @@ impl.ldap.HOMEPHONE_FIELD_EXAMPLE=家庭电è¯
impl.ldap.PHONE_PREFIX=电è¯å·ç å‰ç¼€
impl.ldap.PHONE_PREFIX_EXAMPLE=Ex.: 00
+# SIP Protocol
+impl.protocol.sip.INVALID_ADDRESS="{0}" ä¸æ˜¯ä¸€ä¸ªæœ‰æ•ˆçš„ SIP 地å€ã€‚
+
+#Jabber Protocol
+impl.protocol.jabber.INVALID_ADDRESS="{0}" ä¸æ˜¯ä¸€ä¸ªæœ‰æ•ˆçš„ XMPP JID。
+
# Address book plugin
plugin.addrbook.ADDRESS_BOOKS=地å€ç°¿
plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=å…许æœç´¢MaxOSX地å€ç°¿
@@ -843,9 +829,7 @@ plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT=使用Outlook为默认邮件用
# Google Contacts
impl.googlecontacts.CONFIG_FORM_TITLE=Google è”系人
-impl.googlecontacts.NEW=新建
impl.googlecontacts.EDIT=编辑
-impl.googlecontacts.REMOVE=删除
impl.googlecontacts.ENABLED=å¯ç”¨
impl.googlecontacts.ACCOUNT_NAME=å¸æˆ·å
impl.googlecontacts.SAVE=ä¿å­˜
@@ -854,6 +838,10 @@ impl.googlecontacts.USERNAME=å¸æˆ·å
impl.googlecontacts.PASSWORD=密ç 
impl.googlecontacts.PREFIX=电è¯å‰ç¼€
impl.googlecontacts.WRONG_CREDENTIALS=Google账户{0}è¯ä¹¦é”™è¯¯
+impl.googlecontacts.OAUTH_DIALOG_TITLE=Google 通讯录授æƒè®¤è¯
+impl.googlecontacts.INSTRUCTIONS=<html><p><b> 点击下é¢é“¾æŽ¥ä»¥æŽˆæƒ Google 通讯录æ’件访问您的账户。 </b><br><br> 点击此链接åŽï¼Œæ‚¨çš„æµè§ˆå™¨å°±ä¼šæ‰“开。请您登录指定的账户并授æƒã€‚在æˆåŠŸæŽˆæƒåŽï¼ŒGoogle 会显示一æ¡ä»£ç ã€‚请å¤åˆ¶è¿™æ¡ä»£ç å¹¶ç²˜è´´åˆ°ä¸‹é¢çš„文本框,然åŽç‚¹å‡» 'ä¿å­˜'。 </p><p> 这是一次性æ“作。授æƒä»¤ç‰Œå°†ä¼šç•™ä½œåŽç”¨ã€‚ </html>
+impl.googlecontacts.CODE=代ç :
+impl.googlecontacts.HYPERLINK_TEXT=点击这里以å…许访问 {0} 的授æƒè¯·æ±‚
# account info
plugin.accountinfo.TITLE=å¸å·ä¿¡æ¯
@@ -884,13 +872,11 @@ plugin.accountinfo.ORGANIZATION=组织å称:
plugin.accountinfo.JOB_TITLE=èŒä½ï¼š
plugin.accountinfo.ABOUT_ME=关于我们:
plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
-plugin.accountinfo.USER_PICTURES=头åƒ
plugin.accountinfo.GLOBAL_ICON=使用全局图标
plugin.accountinfo.LOCAL_ICON=使用此图标:
-plugin.accountinfo.CHANGE=更改
-plugin.accountinfo.ONLY_MESSAGE=åªå…许短消æ¯
# connection info
+plugin.connectioninfo.TITLE=连接信æ¯
# contact info
plugin.contactinfo.TITLE=è”系人详细信æ¯
@@ -907,49 +893,13 @@ plugin.aimaccregwizz.USERNAME=AIM用户å:
plugin.aimaccregwizz.USERNAME_AND_PASSWORD=用户å和密ç 
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=注册新å¸å·
plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=如果你没有AIMå¸å·ï¼Œç‚¹å‡»è¿™ä¸ªæŒ‰é’®è¿›è¡Œæ³¨å†Œã€‚
-plugin.aimaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=覆盖æœåŠ¡å™¨é»˜è®¤è®¾ç½®
# branding
plugin.branding.ABOUT_WINDOW_TITLE=关于 {0}
plugin.branding.LOGO_MESSAGE=å¼€æºVoIP&&å³æ—¶æ¶ˆæ¯
-plugin.branding.LOADING=加载中
plugin.branding.ABOUT_MENU_ENTRY=关于(&A)
-plugin.branding.WELCOME_MESSAGE=<DIV color={0}>{1} ç›®å‰å¤„于活跃开å‘中。 您目å‰è¿è¡Œçš„版本是测试版,å¯èƒ½ä¸é€‚åˆå®žé™…工作中使用。请访问 {2} 获å–更多信æ¯ã€‚</DIV>
-plugin.branding.COPYRIGHT=<DIV><font size=3 color={0}>(c)2003-2013 Copyright <b>jitsi.org</b>。All rights reserved。详情访问 <a href="https://jitsi.org">https://jitsi.org</a>。</font></DIV>
-plugin.branding.LICENSE=<DIV color={0}><b>Jitsi</b> 以LGPL(<a href="http://www.gnu.org">http://www.gnu.org</a>)åè®®å‘布。</DIV>
-
-# Dict protocol
-service.protocol.DICTIONARIES=å­—å…¸
-plugin.dictaccregwizz.ANY_DICTIONARY=ä»»æ„å­—å…¸
-plugin.dictaccregwizz.ANY_DICTIONARY_FORM=æ¥è‡ª {0} çš„ä»»æ„å­—å…¸
-plugin.dictaccregwizz.FIRST_MATCH=首次匹é…
-plugin.dictaccregwizz.NO_MATCH=没有匹é…结果
-plugin.dictaccregwizz.MATCH_RESULT=æ²¡æœ‰åŒ¹é… "{0}" 的结果, 您是ä¸æ˜¯è¦æ‰¾ï¼š\n
-plugin.dictaccregwizz.INVALID_DATABASE=当å‰ä½¿ç”¨çš„å­—å…¸ "{0}" 在æœåŠ¡å™¨ä¸Šä¸å­˜åœ¨ã€‚
-plugin.dictaccregwizz.INVALID_STRATEGY=æœåŠ¡å™¨ä¸æ”¯æŒå½“å‰ä½¿ç”¨çš„规则 "{0}"。
-plugin.dictaccregwizz.PROTOCOL_NAME=Dict
-plugin.dictaccregwizz.PROTOCOL_DESCRIPTION=å­—å…¸æœåŠ¡
-plugin.dictaccregwizz.HOST=主机
-plugin.dictaccregwizz.SERVER_INFO=æœåŠ¡å™¨ä¿¡æ¯
-plugin.dictaccregwizz.STRATEGY_SELECTION=选择规则
-plugin.dictaccregwizz.STRATEGY_LIST=规则列表:
-plugin.dictaccregwizz.SEARCH_STRATEGIES=æœç´¢è§„则
-plugin.dictaccregwizz.STRATEGY_DESCRIPTION=如果没有找到åˆé€‚的翻译,匹é…规则用æ¥æŸ¥æ‰¾è¿‘ä¼¼è¯è¯­ã€‚例如å‰ç¼€è§„则将查找以您的关键è¯å¼€å¤´çš„è¯è¯­ã€‚
-plugin.dictaccregwizz.ACCOUNT_INFO_TITLE=Dictå¸å·ä¿¡æ¯
-plugin.dictaccregwizz.FIRST_ACCOUNT=这个å‘导将为您创建dict.org上的Dictå¸å·ã€‚\n\n您å¯ä»¥é€šè¿‡å¸å·æ³¨å†Œå‘导添加新字典。 填写您è¦æ·»åŠ å­—典的主机字段。
-plugin.dictaccregwizz.THREAD_CONNECT=å°è¯•è¿žæŽ¥æœåŠ¡å™¨
-plugin.dictaccregwizz.THREAD_CONNECT_FAILED=å°è¯•è¿žæŽ¥å¤±è´¥ï¼Œ è¿™ä¸æ˜¯ä¸€ä¸ªå­—å…¸æœåŠ¡å™¨æˆ–者æœåŠ¡å™¨ä¸åœ¨çº¿
-plugin.dictaccregwizz.RETRIEVING_STRATEGIES=获å–规则列表
-plugin.dictaccregwizz.NO_STRATEGIES_FOUND=æœåŠ¡å™¨ä¸Šæ‰¾ä¸åˆ°è§„则策略
-plugin.dictaccregwizz.POPULATE_LIST=组æˆåˆ—表
-plugin.dictaccregwizz.CLOSING_CONNECTION=正在关闭连接
-
-# facebookaccregwizz
-plugin.facebookaccregwizz.DESCRIPTION=<html><body><center><a href="https://register.facebook.com/editaccount.php">使用FacebookèŠå¤©ä¹‹å‰ä½ å¿…须在Facebookçš„ <br>"å¸å·è®¾ç½®" 页é¢ä¸Šå…ˆåˆ›å»ºä¸€ä¸ªç”¨æˆ·å </a><br><br>注æ„: 创建完用户å你需è¦å…ˆä»Žè¯¥ç½‘页登出,<br>并且在你å¯ä»¥ä½¿ç”¨è¯¥ç”¨æˆ·å登录之å‰å¯èƒ½éœ€è¦ç­‰å¾…一段时间ï¼</center></body></html>
-plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=FacebookèŠå¤©åè®®
-plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
-plugin.facebookaccregwizz.USERNAME=用户å:
-plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=用户å和密ç 
+
+plugin.busylampfield.PICKUP=接å¬é€šè¯
# generalconfig
plugin.generalconfig.AUTO_START=开机或é‡å¯æ—¶è‡ªåŠ¨è¿è¡Œ {0}
@@ -960,9 +910,6 @@ plugin.generalconfig.SHOW_HISTORY=显示
plugin.generalconfig.HISTORY_SIZE=最近的èŠå¤©ä¿¡æ¯
plugin.generalconfig.SEND_MESSAGES_WITH=å‘é€æ¶ˆæ¯ç»ç”±ï¼š
plugin.generalconfig.BRING_WINDOW_TO_FRONT=èŠå¤©çª—å£å‰ç½®
-plugin.generalconfig.ERROR_PERMISSION=您没有æƒé™å–消自动å¯åŠ¨
-plugin.generalconfig.TRANSPARENCY=é€æ˜Žåº¦
-plugin.generalconfig.ENABLE_TRANSPARENCY=å¯ç”¨é€æ˜Ž
plugin.generalconfig.DEFAULT_LANGUAGE=ç•Œé¢è¯­è¨€
plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=您的设置将在下次å¯åŠ¨æ—¶ç”Ÿæ•ˆã€‚
plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0}%已翻译
@@ -978,6 +925,8 @@ plugin.generalconfig.REMOVE_SPECIAL_PHONE_SYMBOLS=呼å«ç”µè¯å·ç å‰åˆ é™¤ç‰¹
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS=转化电è¯å·ç ä¸­çš„字符
plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS_EXAMPLE=e.g. +1-800-MYPHONE -> +1-800-694663
plugin.generalconfig.SIP_CALL_CONFIG=SIP
+plugin.generalconfig.XMPP_CONFIG=XMPP
+plugin.generalconfig.XMPP_USE_ALL_RESOURCES=在检测è”系人的特性时使用所有资æº
plugin.generalconfig.OPUS_CONFIG=Opus
plugin.generalconfig.OPUS_AUDIO_BANDWIDTH=采样率:
plugin.generalconfig.OPUS_BITRATE=ç¼–ç å™¨å¹³å‡æ¯”特率(kbps):
@@ -1009,19 +958,30 @@ plugin.icqaccregwizz.REGISTER_NEW_ACCOUNT=创建新å¸å·
plugin.ircaccregwizz.PROTOCOL_NAME=IRC
plugin.ircaccregwizz.PROTOCOL_DESCRIPTION=IRCåè®®
plugin.ircaccregwizz.USERNAME_AND_PASSWORD=用户å和密ç 
+plugin.ircaccregwizz.USERNAME=昵称
+plugin.ircaccregwizz.EXAMPLE_USERNAME=例如:ircuser
plugin.ircaccregwizz.INFO_PASSWORD=大部分IRCæœåŠ¡å™¨ä¸éœ€è¦å¯†ç ã€‚
plugin.ircaccregwizz.AUTO_NICK_CHANGE=当该昵称已被å ç”¨æ—¶è‡ªåŠ¨é€‰æ‹©æ˜µç§°
plugin.ircaccregwizz.USE_DEFAULT_PORT=使用默认端å£
plugin.ircaccregwizz.PASSWORD_NOT_REQUIRED=我的昵称ä¸éœ€è¦èº«ä»½æ ¡éªŒ
plugin.ircaccregwizz.HOST=主机å:
plugin.ircaccregwizz.IRC_SERVER=æœåŠ¡å™¨
+plugin.ircaccregwizz.EXAMPLE_SERVER=例如:chat.freenode.net
+plugin.ircaccregwizz.USE_SECURE_CONNECTION=使用安全连接
+plugin.ircaccregwizz.ENABLE_CONTACT_PRESENCE=å¯ç”¨è”系人在线状æ€
+plugin.ircaccregwizz.ENABLE_CHAT_ROOM_PRESENCE=å¯ç”¨èŠå¤©å®¤åœ¨çº¿çŠ¶æ€
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE=SASL验è¯
+plugin.ircaccregwizz.ENABLE_SASL_AUTHENTICATION=å¯ç”¨SASL验è¯
+plugin.ircaccregwizz.SASL_USERNAME=用户å
+plugin.ircaccregwizz.SASL_AUTHZ_ROLE=角色
+plugin.ircaccregwizz.SASL_IRC_PASSWORD_USED=以上的IRC密ç ç”¨äºŽSASL验è¯
+plugin.ircaccregwizz.RESOLVE_DNS_THROUGH_PROXY=总是使用代ç†è¿›è¡ŒDNS解æž
# jabber accregwizz
plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=XMPPåè®®
plugin.jabberaccregwizz.USERNAME=XMPP用户å
plugin.jabberaccregwizz.PASSWORD_CONFIRM=确认密ç 
-plugin.jabberaccregwizz.USERNAME_AND_PASSWORD=å¸å·å’Œå¯†ç 
plugin.jabberaccregwizz.CSERVER=æœåŠ¡å™¨
plugin.jabberaccregwizz.SERVER=连接æœåŠ¡å™¨
plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=å…许ä¿æŒè¿žæŽ¥
@@ -1037,13 +997,9 @@ plugin.jabberaccregwizz.COMMENT_COLUMN=评论
plugin.jabberaccregwizz.RESOURCE=资æº
plugin.jabberaccregwizz.AUTORESOURCE=自动生æˆèµ„æºå
plugin.jabberaccregwizz.PRIORITY=优先级
-plugin.jabberaccregwizz.XMPP_ERROR=XMPP错误
plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=未知XMPP错误({0})。请确认æœåŠ¡å™¨åœ°å€æ˜¯å¦æ­£ç¡®ã€‚
plugin.jabberaccregwizz.NOT_SAME_PASSWORD=密ç ä¸åŒ¹é…。
-plugin.jabberaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=覆盖æœåŠ¡å™¨é»˜è®¤è®¾ç½®
-plugin.jabberaccregwizz.ADVANCED_OPTIONS=高级选项
plugin.jabberaccregwizz.USE_ICE=使用ICE
-plugin.jabberaccregwizz.USE_GOOGLE_ICE=使用Google Jingle/ICE(实验性)
plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=自动检测STUN/TURNæœåŠ¡å™¨
plugin.jabberaccregwizz.SUPPORT_TURN=支æŒTURN
plugin.jabberaccregwizz.TURN_USERNAME=TURN用户å
@@ -1071,11 +1027,8 @@ plugin.jabberaccregwizz.DISABLE_CARBON=ç¦ç”¨æ¶ˆæ¯ç¢³
plugin.jabberaccregwizz.DTMF_AUTO=自动:自动选择RTP或Inband
plugin.jabberaccregwizz.SERVER_OPTIONS=æœåŠ¡å™¨é€‰é¡¹
plugin.jabberaccregwizz.CHANGE_PASSWORD=更改账å·å¯†ç 
-plugin.jabberaccregwizz.NEW_PASSWORD=新密ç 
-plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM=确认新密ç 
plugin.jabberaccregwizz.PORT_FIELD_INVALID=请填入一个å¯ç”¨çš„端å£å·ä»¥ä¾¿ç»§ç»­ã€‚
plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=è´¦å·å˜æ›´å¯†ç å‰å¿…须登录。
-plugin.jabberaccregwizz.PASSWORD_EMPTY=密ç ä¸ºç©ºã€‚
plugin.jabberaccregwizz.TLS_REQUIRED=连接未使用TLS,ä¸ä¼šå°è¯•å¯†ç å˜æ›´ã€‚
plugin.jabberaccregwizz.PASSWORD_CHANGED=密ç å·²å˜æ›´æˆåŠŸ
plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=您的XMPPæœåŠ¡å™¨ä¸æ”¯æŒå¯†ç å˜æ›´ã€‚
@@ -1089,25 +1042,9 @@ plugin.jabberaccregwizz.RESET=é‡ç½®
plugin.jabberaccregwizz.RESET_DESCRIPTION=å¤ä½å…¨å±€è®¾ç½®
plugin.jabberaccregwizz.DISABLE_JINGLE=ç¦ç”¨Jingle(XMPP音频和视频呼å«)
-# mailbox
-plugin.mailbox.OUTGOING=å·²å‘é€çš„消æ¯ï¼š
-plugin.mailbox.INCOMING=已收到的消æ¯ï¼š
-plugin.mailbox.WAIT_TIME=转到语音信箱之å‰ç­‰å¾…时间
-plugin.mailbox.MAX_MESSAGE_TIME=最长留言
-plugin.mailbox.CONFIRM=确认
-plugin.mailbox.DEFAULTS=默认
-plugin.mailbox.MAILBOX=邮箱
-
-# msn accregwizz
-plugin.msnaccregwizz.PROTOCOL_NAME=MSN
-plugin.msnaccregwizz.PROTOCOL_DESCRIPTION=连接和使用MSNèŠå¤©å议。
-plugin.msnaccregwizz.USERNAME=Email:
-plugin.msnaccregwizz.USERNAME_AND_PASSWORD=å¸å·å’Œå¯†ç 
-
# plugin manager
plugin.pluginmanager.INSTALL=安装
plugin.pluginmanager.UNINSTALL=å¸è½½
-plugin.pluginmanager.UPDATE=æ›´æ–°
plugin.pluginmanager.PLUGINS=æ’件
plugin.pluginmanager.URL=地å€
plugin.pluginmanager.CHOOSE_FILE=选择文件
@@ -1132,9 +1069,9 @@ plugin.sipaccregwizz.SERVER_PORT=æœåŠ¡å™¨ç«¯å£
plugin.sipaccregwizz.PROXY=代ç†æœåŠ¡å™¨
plugin.sipaccregwizz.PROXY_PORT=代ç†ç«¯å£
plugin.sipaccregwizz.PREFERRED_TRANSPORT=首选
-plugin.sipaccregwizz.ADVANCED_OPTIONS=高级选项
plugin.sipaccregwizz.PROXY_OPTIONS=代ç†é€‰é¡¹
plugin.sipaccregwizz.PROXY_AUTO=自动é…置代ç†æœåŠ¡å™¨
+plugin.sipaccregwizz.PROXY_FORCE_BYPASS=在 HA 的情况下跳过代ç†å®‰å…¨æ£€æŸ¥ï¼ˆè¯·ä»…在需è¦æ—¶ä½¿ç”¨ï¼‰
plugin.sipaccregwizz.ENABLE_PRESENCE=å…许出席(SIMPLE)
plugin.sipaccregwizz.FORCE_P2P_PRESENCE=强制使用P2P出席模å¼
plugin.sipaccregwizz.OFFLINE_CONTACT_POLLING_PERIOD=离线è”系人拉å–é—´éš”(å•ä½ï¼šç§’)
@@ -1152,8 +1089,6 @@ plugin.sipaccregwizz.DTMF_AUTO=自动:从RTPå’ŒInband(æ— SIPä¿¡æ¯)自动选æ‹
plugin.sipaccregwizz.DTMF_RTP=RTP ( RFC2833 / RFC 4733 )
plugin.sipaccregwizz.DTMF_SIP_INFO=SIPä¿¡æ¯
plugin.sipaccregwizz.DTMF_INBAND=带内
-plugin.sipaccregwizz.REGISTER=注册
-plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=覆盖æœåŠ¡å™¨é»˜è®¤é€‰é¡¹
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=å¯ç”¨åŠ å¯†é€šè¯æ”¯æŒ
plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=表示支æŒZRTP的信令åè®®
plugin.sipaccregwizz.AUTH_NAME=授æƒå称
@@ -1174,10 +1109,10 @@ plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=语音邮件查阅URI
plugin.sipaccregwizz.NOT_SAME_PASSWORD=您的密ç ä¸åŒ¹é…。
plugin.sipaccregwizz.NO_CERTIFICATE=<none>(使用常规验è¯)
plugin.sipaccregwizz.SAVP_OPTION=RTP/SAVP表示
+#used from SecurityPanel
plugin.sipaccregwizz.SAVP_OPTION_0=Off(åªæ ‡æ˜ŽRTP/AVP)
plugin.sipaccregwizz.SAVP_OPTION_1=强制(åªæ供并接å—RTP/SAVP)
plugin.sipaccregwizz.SAVP_OPTION_2=å¯é€‰(å…ˆæä¾›RTP/SAVP,然åŽRTP/AVP)
-plugin.sipaccregwizz.ENABLE_SDES_ATTRIBUTE=å¯ç”¨S-Descriptor(å³SDES或SRTP)
plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=选择å¯ç”¨åŠ å¯†å议和它们的优先顺åº(顶端å议优先):
plugin.sipaccregwizz.CIPHER_SUITES=å¯ç”¨åŠ å¯†å¥—件:
plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>{0}会自动å°è¯•åŠ å¯†æ‚¨çš„所有ZRTP呼å«å¹¶ä¸”您会å¬åˆ°å’Œçœ‹åˆ°ä¸€ä¸ªå®‰å…¨è¿žæŽ¥å·²å°±ç»ªçš„æ示。如果您已了解您正在åšä»€ä¹ˆï¼Œæ‚¨ä»…需改å˜å¦‚下高级设置</div></html>
@@ -1191,15 +1126,6 @@ plugin.skinmanager.DEFAULT_SKIN=默认皮肤
plugin.skinmanager.ADD_NEW_SKIN=添加新皮肤
plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=应用程åºé»˜è®¤çš®è‚¤ã€‚
-# ssh accregwizz
-plugin.sshaccregwizz.PROTOCOL_NAME=SSH
-plugin.sshaccregwizz.PROTOCOL_DESCRIPTION=通过SSH连接远程计算机。
-plugin.sshaccregwizz.USERNAME=å¸å·ID:
-plugin.sshaccregwizz.IDENTITY_FILE=标识文件:
-plugin.sshaccregwizz.KNOWN_HOSTS=已知主机:
-plugin.sshaccregwizz.OPTIONAL=å¯é€‰
-plugin.sshaccregwizz.ACCOUNT_DETAILS=详细å¸å·ä¿¡æ¯
-
# status update
plugin.autoaway.AUTO_STATUS=自动切æ¢åˆ°ç¦»å¼€çŠ¶æ€
plugin.autoaway.ENABLE_CHANGE_STATUS=离开时修改状æ€
@@ -1247,22 +1173,6 @@ plugin.whiteboard.DESELECT=å选
plugin.whiteboard.DELETE=删除
plugin.whiteboard.PROPERTIES=属性
-# yahoo accregwizz
-plugin.yahooaccregwizz.PROTOCOL_NAME=Yahoo!
-plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION=一ç§è¿žæŽ¥Yahoo!èŠå¤©æœåŠ¡å¹¶èŠå¤©çš„å议。
-plugin.yahooaccregwizz.USERNAME=用户å:
-plugin.yahooaccregwizz.USERID_AND_PASSWORD=用户å和密ç 
-
-# zero accregwizz
-plugin.zeroaccregwizz.PROTOCOL_NAME=Zeroconf
-plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION=Zeroconf (Bonjour) æœåŠ¡å议。
-plugin.zeroaccregwizz.FIRST_NAME=å字:
-plugin.zeroaccregwizz.LAST_NAME=姓:
-plugin.zeroaccregwizz.EMAIL=Email:
-plugin.zeroaccregwizz.REMEMBER_CONTACTS=è®°ä½ Bonjour è”系人?
-plugin.zeroaccregwizz.USERID_AND_PASSWORD=å¸å·å’Œå¯†ç 
-plugin.zeroaccregwizz.USERID=用户ID
-
# gtalk accregwizz
plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=GOOGLE TALKåè®®
@@ -1276,19 +1186,11 @@ plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org, IP电è¯é—¨æˆ·
plugin.iptelaccregwizz.USERNAME=用户å
plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=订阅iptel.org
-# sip2sip accregwizz
-plugin.sip2sipaccregwizz.PROTOCOL_NAME=sip2sip.info
-plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION=VoIPå’ŒèŠå¤©
+# ippi accregwizz
plugin.sip2sipaccregwizz.USERNAME=用户å
plugin.sip2sipaccregwizz.RETYPE_PASSWORD=å†æ¬¡è¾“入密ç 
plugin.sip2sipaccregwizz.EMAIL=Email 地å€
-plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE=请查看以下网站查看æœåŠ¡ä»‹ç»<br>http://wiki.sip2sip.info
plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>这个 email 地å€å°†è¢«ç”¨æ¥å‘é€è¯­éŸ³ç•™è¨€ï¼Œ <br>未接æ¥ç”µæ醒和é‡ç½®å¯†ç æœåŠ¡</html>
-plugin.sip2sipaccregwizz.INFO_NOTE=<html>访问以下地å€èŽ·å–该æœåŠ¡ä»‹ç»ï¼š<a href=''>http://wiki.sip2sip.info</a></html>
-plugin.sip2sipaccregwizz.EXISTING_ACCOUNT=该sip2sip.infoå¸å·å·²å­˜åœ¨
-plugin.sip2sipaccregwizz.CREATE_ACCOUNT=创建å…费的sip2sip.infoå¸å·
-
-# ippi accregwizz
plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=VoIP && å³æ—¶é€šä¿¡
plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=请查看以下网站查看æœåŠ¡ä»‹ç»<br>http://ippi.fr
@@ -1297,6 +1199,7 @@ plugin.ippiaccregwizz.EXISTING_ACCOUNT=已添加的ippiè´¦å·
plugin.ippiaccregwizz.CREATE_ACCOUNT=创建å…费的ippiå¸å·
# key binding chooser
+#in new ChatWindow() -> manipulated
plugin.keybindings.CHAT_CLOSE=关闭èŠå¤©çª—å£
plugin.keybindings.CHAT_COPY=å¤åˆ¶
plugin.keybindings.CHAT_CUT=剪切
@@ -1319,15 +1222,16 @@ plugin.keybindings.globalchooser.SHORTCUT_NAME=姓å
plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=主快æ·é”®
plugin.keybindings.globalchooser.SHORTCUT_SECOND=第二快æ·æ–¹å¼
plugin.keybindings.globalchooser.PRESS_BTN=点击设置快æ·æ–¹å¼
-plugin.keybindings.globalchooser.PRESS_BTN_DOWN=等待中
plugin.keybindings.globalchooser.PUSH_TO_TALK=按键通è¯
plugin.keybindings.globalchooser.ENABLE_SPECIAL=å¯ç”¨ç‰¹æ®Šé”®æ£€æµ‹
plugin.keybindings.PLUGIN_NAME=å¿«æ·é”®
+#Enum KeybindingSet.Category
plugin.keybindings.CHAT=èŠå¤©
plugin.keybindings.MAIN=主è¦
plugin.keybindings.GLOBAL=全局快æ·é”®
# Notification Configuration Form
+plugin.notificationconfig.ENABLE_NOTIF=å¯ç”¨
plugin.notificationconfig.DESCRIPTION=æè¿°
plugin.notificationconfig.TURN_ON_ALL=全部å¯ç”¨
plugin.notificationconfig.TURN_OFF_ALL=全部ç¦ç”¨
@@ -1349,6 +1253,7 @@ plugin.notificationconfig.tableheader.SOUND=通过æ醒设备播放æ示音
plugin.notificationconfig.tableheader.PLAYBACK_SOUND=通过回放设备播放声音
plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=通过PC扬声器设备播放声音
plugin.notificationconfig.tableheader.DESCRIPTION=事件æè¿°
+#NotificationsTable constants
plugin.notificationconfig.event.IncomingCall=æ¥ç”µ
plugin.notificationconfig.event.SecurityMessage=安全消æ¯
plugin.notificationconfig.event.IncomingFile=正在传入的文件
@@ -1389,7 +1294,7 @@ impl.media.security.WARNING_NO_EXPECTED_RS_MATCH=<html>找ä¸åˆ°å…±äº«å¯†é’¥ã€‚<
impl.media.security.SEVERE_GENERIC_MSG=<html>检测到严é‡çš„æœåŠ¡å®‰å…¨é—®é¢˜ã€‚<br/><b>您的通è¯ä¸å®‰å…¨</b><br/>错误代ç ï¼š {0}</html>
impl.media.security.ZRTP_GENERIC_MSG=<html>检测到严é‡çš„ZRTP问题。<br/><b>您的通è¯ä¸å®‰å…¨</b><br/>错误代ç ï¼š {0}</html>
impl.media.security.INTERNAL_PROTOCOL_ERROR=<html>å‘生了å议内部错误。<br/><b>您的通è¯ä¸å®‰å…¨</b><br/>错误代ç ï¼š {0}</html>
-impl.media.security.CHECKSUM_MISMATCH=<html>内部ZRTP包的校验失败。<br/>如果您看到此消æ¯ï¼Œé€šå¸¸è¿™å¯èƒ½æ„味ç€æ‹’ç»æœåŠ¡æ”»å‡»ï¼</çš„HTML>
+impl.media.security.CHECKSUM_MISMATCH=<html> 内部ZRTP包的校验失败。<br/> 如果您看到此消æ¯ï¼Œé€šå¸¸è¿™å¯èƒ½æ„味ç€æ‹’ç»æœåŠ¡æ”»å‡»ï¼</html>
impl.media.security.RETRY_RATE_EXCEEDED=<html>å°è¯•å®‰å…¨å商次数过多。 这很å¯èƒ½æ„味ç€å¯¹æ–¹å­˜åœ¨ç½‘络连接问题.<br/><b>您的通è¯ä¸å®‰å…¨</b><br/>错误代ç ï¼š {0}</html>
impl.media.security.DATA_SEND_FAILED=<html>加密数æ®ä¼ è¾“失败。 网络数æ®è¿žæŽ¥æˆ–者对方已断开。<br/><b>您的呼å«ä¸å®‰å…¨</b><br/>错误代ç ï¼š {0}</html>
impl.media.security.SECURITY_OFF=加密通è¯å·²å…³é—­
@@ -1450,6 +1355,7 @@ impl.neomedia.configform.VIDEO=视频
impl.neomedia.configform.H264=H.264
impl.neomedia.configform.H264.defaultIntraRefresh=周期性内部刷新
impl.neomedia.configform.H264.defaultProfile=ç¼–ç ç¼ºçœé…置:
+#in JNIEncoder
impl.neomedia.configform.H264.defaultProfile.baseline=基线
impl.neomedia.configform.H264.defaultProfile.high=高
impl.neomedia.configform.H264.defaultProfile.main=主体
@@ -1480,7 +1386,6 @@ plugin.securityconfig.masterpassword.CURRENT_PASSWORD=当å‰å¯†ç ï¼š
plugin.securityconfig.masterpassword.ENTER_PASSWORD=新密ç ï¼š
plugin.securityconfig.masterpassword.REENTER_PASSWORD=确认密ç ï¼š
plugin.securityconfig.masterpassword.MP_TITLE=主密ç 
-plugin.securityconfig.masterpassword.MP_NOT_SET=(未设置)
plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=您输入的主密ç é”™è¯¯ã€‚ 请é‡è¯•ã€‚
plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=主密ç é”™è¯¯ï¼
plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=密ç ä¿®æ”¹å¤±è´¥
@@ -1496,7 +1401,6 @@ plugin.securityconfig.masterpassword.COL_PASSWORD=密ç 
plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(未知)
plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(无法解密)
plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=存储的密ç 
-plugin.securityconfig.masterpassword.REMOVE_PASSWORD_BUTTON=删除
plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=清空
plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=确认è¦åˆ é™¤å…¨éƒ¨ä¿å­˜çš„密ç ï¼Ÿ
plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=删除全部密ç 
@@ -1592,7 +1496,6 @@ plugin.globalproxy.PROXY_PORT=代ç†ç«¯å£
plugin.globalproxy.PROXY_USERNAME=代ç†ç”¨æˆ·å
plugin.globalproxy.PROXY_PASSWORD=代ç†å¯†ç 
plugin.globalproxy.DESCRIPTION={0} 将对所有网络连接应用以上代ç†è®¾ç½®ã€‚\nç›®å‰å¯¹ä»£ç†çš„支æŒå°šå¤„于试验阶段,并且åªæ”¯æŒéƒ¨åˆ†å议。详细信æ¯è¯·æŸ¥çœ‹ä¸‹è¡¨ï¼š
-plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> <tr><td></td><td> SOSCKS4/5 </td><td> SOSCKS4/5+Auth </td><td> HTTP </td><td> HTTP+Auth </td></tr><tr><td>Yahoo!</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>MSN</td><td>+</td><td>+</td><td>-</td><td>-</td></tr><tr><td>JABBER</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>ICQ/AIM</td><td>+</td><td>+</td><td>+</td><td>+</td></tr></table></html>
#plugin.globalproxy.PROTOCOL_SUPPORT
plugin.globalproxy.FWD_DNS=附加DNS代ç†
plugin.globalproxy.FWD_DNS_NOTE=Tor的作用。通过将所有的DNS查询路径转å‘到Tor代ç†è€Œæœ‰åŠ©äºŽå›žé¿DNSæ¼æ´žã€‚需è¦é‡å¯ã€‚
@@ -1609,6 +1512,11 @@ plugin.reconnectplugin.NETWORK_DOWN=网络连接已断开ï¼
plugin.chatconfig.TITLE=èŠå¤©
plugin.chatconfig.replacement.TITLE=图片/视频:
plugin.chatconfig.replacement.ENABLE_SMILEY_STATUS=å…许æ’入表情
+plugin.chatconfig.replacement.REPLACEMENT_TITLE=替æ¢å›¾åƒå’Œè§†é¢‘
+plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS=å¯ç”¨
+plugin.chatconfig.replacement.ENABLE_REPLACEMENT_PROPOSAL=ç¦ç”¨ï¼ˆæ˜¾ç¤ºé¢„览链接)
+plugin.chatconfig.replacement.DISABLE_REPLACEMENT=ç¦ç”¨
+plugin.chatconfig.replacement.CONFIGURE_REPLACEMENT=图åƒå’Œè§†é¢‘替æ¢è®¾ç½®é€‰é¡¹æ›´æ”¹
plugin.chatconfig.replacement.REPLACEMENT_SOURCES=æ¥æºï¼š
plugin.chatconfig.spellcheck.TITLE=拼写检查
@@ -1625,7 +1533,6 @@ plugin.provisioning.RESTART_WARNING=请注æ„所有修改仅在下次å¯åŠ¨{0}æ‰
plugin.provisioning.UUID=UUID
plugin.provisioning.COPYTOCLIPBOARD=å¤åˆ¶UUID到剪贴æ¿
plugin.provisioning.CLIPBOARD_FAILED=å¤åˆ¶UUID到剪贴æ¿å¤±è´¥
-plugin.provisioning.EXIT_ON_FAIL=如果é…置失败则退出程åº
plugin.provisioning.CREDENTIALS=最åŽå­˜å‚¨çš„é…ç½®è¯ä¹¦
plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=确认移除预置密ç ä¹ˆï¼Ÿ
plugin.provisioning.PROV_FAILED=预置失败
@@ -1692,8 +1599,6 @@ util.dns.DNSSEC_WARNING=<html><div width="600">{0}已视图连接ä½äºŽ<b>{1}</b
#plugin spellcheck
plugin.spellcheck.TITLE=拼写和语法检查
plugin.spellcheck.MENU=显示拼写和语法
-plugin.spellcheck.LANG=语言
-plugin.spellcheck.EDIT_PERSONAL_DICT=编辑
plugin.spellcheck.ENABLE_SPELL_CHECK=å¯ç”¨æ‹¼å†™æ£€æŸ¥
plugin.spellcheck.dialog.FIND=查找下一个
plugin.spellcheck.dialog.REPLACE=替æ¢
diff --git a/resources/languages/resources_zh_TW.properties b/resources/languages/resources_zh_TW.properties
index db996d1..b461fc9 100644
--- a/resources/languages/resources_zh_TW.properties
+++ b/resources/languages/resources_zh_TW.properties
@@ -1,7 +1,18 @@
# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
#
-# Distributable under LGPL license.
-# See terms of license at gnu.org.
+# Copyright @ 2015 Atlassian Pty Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# Translation files are automatically generated from:
#
@@ -27,147 +38,1617 @@
service.gui.ABOUT=關於
service.gui.ACCEPT=接å—
+service.gui.ACCOUNT=帳號
+service.gui.ACCOUNT_ME=自己
+service.gui.ACCOUNT_REGISTRATION_WIZARD=帳號註冊精éˆ
service.gui.ACCOUNTS=帳號
service.gui.ADD=新增
-service.gui.ADD_ACCOUNT=新增帳號
service.gui.ADD_CONTACT=新增è¯çµ¡äºº
-service.gui.ADD_AUTHORIZED_CONTACT=新增{0}到你的通訊錄上
-service.gui.ADD_CONTACT_TO_CONTACTLIST=將此è¯çµ¡äººæ–°å¢žåˆ°æ‚¨çš„è¯çµ¡äººåˆ—表中
+service.gui.ADD_AUTHORIZED_CONTACT=將 {0} 新增到您的通訊錄
+service.gui.ADD_CONTACT_TO_CONTACTLIST=將此è¯çµ¡äººæ–°å¢žåˆ°æ‚¨çš„通訊錄
service.gui.ADD_CONTACT_TO=新增è¯çµ¡äººåˆ°
-service.gui.ADD_CONTACT_ERROR=新增è¯çµ¡äººï¼š{0}失敗
+service.gui.ADD_CONTACT_ERROR=新增è¯çµ¡äºº {0} 失敗
service.gui.ADD_CONTACT_ERROR_TITLE=新增è¯çµ¡äººéŒ¯èª¤
-service.gui.ADD_CONTACT_EXIST_ERROR=è¯çµ¡äºº{0}已經存在於您的è¯çµ¡äººå單中了。
-service.gui.ADD_CONTACT_NETWORK_ERROR=伺æœå™¨æœªèƒ½å›žæ‡‰ä½ æ–°å¢žè¯çµ¡äººID為{0}çš„è¯çµ¡äººçš„請求。
-service.gui.ADD_CONTACT_NOT_SUPPORTED=無法新增è¯çµ¡äººId為{0}çš„è¯çµ¡äººã€‚ä¸æ”¯æ´æ­¤æ“作。
-
-
-
-
-
-
+service.gui.ADD_CONTACT_EXIST_ERROR=è¯çµ¡äºº {0} 已經存在於您的通訊錄中了。
+service.gui.ADD_CONTACT_NETWORK_ERROR=伺æœå™¨æœªå›žæ‡‰æ‚¨æ–°å¢žä»¥ä¸‹è¯çµ¡äººçš„請求: {0}
+service.gui.ADD_CONTACT_NOT_SUPPORTED=無法新增è¯çµ¡äººID為 {0} çš„è¯çµ¡äººï¼šä¸æ”¯æ´æ­¤æ“作。
+service.gui.ADD_CONTACT_NOT_CONNECTED=新增è¯çµ¡äººæ™‚必須連上伺æœå™¨ã€‚請登入後å†è©¦ã€‚
+service.gui.ADD_GROUP_LOCAL_ERROR=新增群組 {0} 失敗:本地資料存å–錯誤。
+service.gui.ADD_GROUP_EXIST_ERROR=群組 {0} 已經存在於您的通訊錄。請å¦å–一個å稱。
+service.gui.ADD_GROUP_NET_ERROR=新增群組 {0} 失敗:網路錯誤。請檢查您的網路連線然後é‡è©¦ã€‚
+service.gui.ADD_GROUP_ERROR=新增群組 {0} 失敗。
+service.gui.ADD_GROUP_EMPTY_NAME=群組å稱ä¸å¾—為空白。
+service.gui.ADDRESS=地å€
+service.gui.ADMINISTRATOR=管ç†å“¡
+service.gui.ADVANCED=進階
+service.gui.ALL_CONTACTS=所有è¯çµ¡äºº
+service.gui.ALTERNATE_ADDRESS=備用地å€
+service.gui.APPLY=套用
+service.gui.ARE_CALLING={0} 正在呼å«...
+service.gui.ARE_NOW=您ç¾åœ¨æ˜¯ {0}
+service.gui.AT=ä½æ–¼
+service.gui.AUTHORIZE=授權
+service.gui.AUTHORIZATION_ACCEPTED={0} 已接å—您的授權請求。
+service.gui.AUTHENTICATION_FAILED=帳號 {0} 身份驗證失敗:密碼輸入錯誤。
+service.gui.AUTHENTICATION_REQUESTED_SERVER=伺æœå™¨ {0} 已發é€äº†æ‚¨çš„身份驗證請求。
+service.gui.AUTHENTICATION_REJECTED={0 } 已拒絕了您的授權請求。
+service.gui.AUTHENTICATION_WINDOW_TITLE={0} 身份驗證
+service.gui.AUTHORIZATION_REQUESTED=已發é€æŽˆæ¬Šè«‹æ±‚
+service.gui.AUTHORIZATION_REQUESTED_INFO=è¯çµ¡äºº {0} 請求您的授權。
+service.gui.AUTHORIZATION_RESPONSE=授權回覆
+service.gui.AWAY_STATUS=離開
+service.gui.EXTENDED_AWAY_STATUS=長時間離開
+service.gui.BAN=å°éŽ–
+service.gui.BANNED=å·²å°éŽ–
+service.gui.BAN_FAILED=å°éŽ–失敗
+service.gui.BAN_FAILED_GENERAL_ERROR=å°éŽ– {0} 失敗:伺æœå™¨ç™¼ç”ŸéŒ¯èª¤ã€‚
+service.gui.BAN_FAILED_NOT_ALLOWED=å°éŽ– {0} 失敗:èŠå¤©å®¤çš„主人和管ç†å“¡ä¸èƒ½è¢«å°éŽ–。
+service.gui.BAN_FAILED_NOT_ENOUGH_PERMISSIONS=å°éŽ– {0} 失敗:您沒有足夠的權é™ã€‚
+service.gui.BRB_MESSAGE=我ç¾åœ¨ä¸åœ¨ï¼Œç¨å¾Œå›žä¾†ã€‚
+service.gui.BROWSE=ç€è¦½
+service.gui.BUSY_MESSAGE=抱歉,我ç¾åœ¨æœ‰é»žå¿™ã€‚
+service.gui.BUSY_STATUS=忙碌
+service.gui.CALL=呼å«
+service.gui.CALL_CONTACT=呼å«è¯çµ¡äºº
+service.gui.CALL_FAILED=呼å«å¤±æ•—
+service.gui.CALL_HISTORY_TOOL_TIP=點擊這裡顯示通話記錄
+service.gui.CALL_HISTORY_GROUP_NAME=通話記錄
+service.gui.CALL_VIA=通話方å¼ï¼š
+service.gui.CALL_NAME_OR_NUMBER=通話å稱或號碼
+service.gui.CALL_NOT_SUPPORTING_PARTICIPANT=本次通話僅å…許來自 {0} 網路以åŠæ‚¨çš„ {1} 帳號的è¯çµ¡äººåƒåŠ ï¼Œ{2} ä¸åœ¨ä¸Šè¿°ç¯„åœã€‚
+service.gui.CALL_WITH=與 ... 通話
+service.gui.CALL_NO_AUDIO_DEVICE=您沒有設定音頻設備。
+service.gui.CALL_NO_AUDIO_CODEC=您沒有啟用任何音頻編碼器。
+service.gui.CALL_NO_DEVICE_CODECS_Q=您è¦ç¹¼çºŒå‘¼å«å—Žï¼Ÿ
+service.gui.CANCEL=å–消
+service.gui.CHAT=èŠå¤©
+service.gui.CHANGE_FONT=變更字型
+service.gui.CHANGE_ROOM_SUBJECT=修改èŠå¤©å®¤ä¸»é¡Œ...
+service.gui.CHANGE_ROOM_SUBJECT_LABEL=您å¯ä»¥åœ¨ä¸‹æ–¹è¼¸å…¥æœ¬èŠå¤©å®¤çš„新主題。
+service.gui.CHANGE_NICK=修改暱稱
+service.gui.CHANGE_NICKNAME=修改暱稱...
+service.gui.CHANGE_NICKNAME_LABEL=請輸入您的新暱稱。
+service.gui.CHANGE_NICKNAME_ERROR=更改暱稱時發生錯誤
+service.gui.CHANGE_NICKNAME_CONFLICT_ERROR=暱稱已存在
+service.gui.CHANGE_VIDEO_QUALITY=更改é ç«¯è¦–訊å“質
+service.gui.CHAT_CONFERENCE_ITEM_LABEL={0} 的語音會議
+service.gui.CHAT_ROOM_ALREADY_JOINED=您已經加入 {0} èŠå¤©å®¤ã€‚
+service.gui.CHAT_ROOM_CONFIGURATION={0} èŠå¤©å®¤è¨­å®š
+service.gui.CHAT_ROOM_CONFIGURATION_FAILED=ç²å– {0} èŠå¤©å®¤è¨­å®šå¤±æ•—。
+service.gui.CHAT_ROOM_CONFIGURATION_FORBIDDEN=無法å–å¾— {0} èŠå¤©å®¤è¨­å®šã€‚åªæœ‰èŠå¤©å®¤çš„主人å¯ä»¥å–å¾—åŠè®Šæ›´è¨­å®šã€‚
+service.gui.CHAT_ROOM_CONFIGURATION_SUBMIT_FAILED=無法å–å¾— {0} èŠå¤©å®¤è¨­å®šã€‚åªæœ‰èŠå¤©å®¤çš„主人å¯ä»¥å–å¾—åŠè®Šæ›´è¨­å®šã€‚
+service.gui.CHAT_ROOM_CONFIGURATION_MEMBERS_EDIT_TITLE=編輯æˆå“¡æ¸…å–®
+service.gui.CHAT_ROOM_CONFIGURATION_MEMBERS_EDIT_DESCRIPTION=本èŠå¤©å®¤æˆå“¡åˆ—æ–¼å³å´ã€‚當èŠå¤©å®¤è¢«è¨­å®šç‚ºã€Œåƒ…æˆå“¡ã€æ¨¡å¼æ™‚,åªæœ‰é€™äº›ä½¿ç”¨è€…被å…許加入。
+service.gui.CHAT_ROOM_USER_JOINED={0} 加入èŠå¤©å®¤
+service.gui.CHAT_ROOM_USER_LEFT={0} 離開èŠå¤©å®¤
+service.gui.CHAT_ROOM_USER_KICKED={0} 被踢出èŠå¤©å®¤
+service.gui.CHAT_ROOM_USER_QUIT={0} 退出èŠå¤©å®¤
+service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN=訊æ¯ç™¼é€è¢«å°éŽ– (您被版主å–消發言權了)
+service.gui.CHAT_ROOM_NAME=èŠå¤©å®¤å稱
+service.gui.CLEAR_CUSTOM_MESSAGES=清除自訂訊æ¯
+service.gui.ROOM_NAME=èŠå¤©å®¤
+service.gui.CHANGE_PASSWORD=修改密碼
+service.gui.CHAT_ROOM_NAME_INFO=請輸入新èŠå¤©å®¤å稱。
+service.gui.CHAT_ROOM_NOT_EXIST=在伺æœå™¨ {1} 上找ä¸åˆ°èŠå¤©å®¤ {0} 。請檢查å稱是å¦æ­£ç¢ºã€‚
+service.gui.CHAT_ROOM_NOT_CONNECTED=您必須先登入伺æœå™¨æ‰èƒ½åŠ å…¥ {0} èŠå¤©å®¤ã€‚
+service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED=您必須先登入伺æœå™¨æ‰èƒ½é€€å‡ºèŠå¤©å®¤ã€‚
+service.gui.CHAT_ROOM_OPTIONS=èŠå¤©å®¤é¸é …
+service.gui.CHAT_ROOM_REGISTRATION_REQUIRED=需è¦è¨»å†Šæ‰èƒ½åŠ å…¥èŠå¤©å®¤ {0} 。
+service.gui.CHAT_ROOM_REQUIRES_PASSWORD=èŠå¤©å®¤ {0} è¦æ±‚輸入密碼。
+service.gui.CHAT_ROOMS=èŠå¤©å®¤
+service.gui.CHAT_ROOM=èŠå¤©å®¤
+service.gui.CHAT_ROOM_SUBJECT_CHANGED={0} 已將èŠå¤©å®¤ä¸»é¡Œæ”¹ç‚ºï¼š{1}
+service.gui.CHAT_ROOM_ALTERNATE_ADDRESS=您å¯æ–¼ä¸‹åˆ—èŠå¤©å®¤ç¹¼çºŒæ‚¨çš„å°è©±ï¼š{0}
+service.gui.CHAT_NICKNAME_CHANGE={0} ç¾åœ¨æ˜¯ {1}
+service.gui.CHOOSE_CONTACT=é¸æ“‡è¯çµ¡äºº
+service.gui.CHOOSE_NUMBER=é¸æ“‡è™Ÿç¢¼
+service.gui.CHOOSE_ACCOUNT=請從列表中é¸æ“‡ä¸€å€‹å¸³è™Ÿã€‚
+service.gui.CITY=城市
+service.gui.COUNTRY=國家
+service.gui.SHOW_MORE_TOOLTIP=點擊查看更多çµæžœ
+service.gui.CLEAR=清除
+service.gui.CLOSE=關閉
+service.gui.CLOSE_CHAT_AFTER_NEW_MESSAGE=您 2 秒å‰å‰›æ”¶åˆ°æ–°è¨Šæ¯ã€‚是å¦è¦çµæŸæœ¬æ¬¡èŠå¤©ï¼Ÿ
+service.gui.CLOSE_CHAT_ACTIVE_FILE_TRANSFER=還有檔案沒傳完。您è¦å–消它們嗎?
+service.gui.CONNECTED_STATUS=已連線
+service.gui.CONNECTING=連線中...
+service.gui.CONNECTING_STATUS=連線中
+service.gui.CONNECTING_EARLY_MEDIA_STATUS=連線中*
+service.gui.CONNECTION=連線
+service.gui.CONNECTION_EXPIRED_MSG=您已經中斷與伺æœå™¨ {0} 的連線。
+service.gui.CONTACT_NAME=ID或號碼
+service.gui.CONTACT_NAME_PROMPT=jane.doe@example.com
+service.gui.CONTACT_NAME_INFO=新增一個åŠæ™‚é€šè¨Šåœ°å€ ï¼ˆæ¯”å¦‚ jane.doe@example.com)或者 VoIP 號碼
+service.gui.CONTACT_NOT_SUPPORTING_CHAT_CONF=您é¸æ“‡çš„è¯çµ¡äºº {0} ä¸æ”¯æ´ç¾¤çµ„èŠå¤©ã€‚
+service.gui.CONTACT_PAUSED_TYPING={0} æš«åœè¼¸å…¥
+service.gui.CONTACT_TYPING={0} 正在輸入訊æ¯
+service.gui.CONTACT_TYPING_SEND_FAILED=噓ï¼æˆ‘們ä¸æœƒå‘Šè¨´ {0} 您正在輸入訊æ¯...
+service.gui.CONTACT_INFO=è¯çµ¡äººè¨Šæ¯
+service.gui.CONTACTS=è¯çµ¡äºº
+service.gui.COPY=複製
+service.gui.COPY_LINK=複製éˆçµ
+service.gui.CREATE=建立
+servoce.gui.CREATE_CALL_FAILED=通話建立失敗
+service.gui.CREATE_CHAT_ROOM=建立èŠå¤©å®¤...
+service.gui.CREATE_CHAT_ROOM_ERROR=建立èŠå¤©å®¤ {0} 失敗
+service.gui.CREATE_CHAT_ROOM_WIZARD=èŠå¤©å®¤å»ºç«‹ç²¾éˆ
+service.gui.CREATE_CONFERENCE_CALL=建立語音會議室...
+service.gui.CREATE_GROUP=建立新群組...
+service.gui.CREATE_GROUP_NAME=請在下é¢è¼¸å…¥æ¬„中輸入您想è¦å»ºç«‹çš„群組å.
+service.gui.CREATE_VIDEO_BRIDGE=建立視訊橋接中...
+service.gui.CREATE_VIDEO_BRIDGE_MENU=建立視訊橋接
+service.gui.CREATE_JOIN_VIDEO_CONFERENCE=建立/加入視訊會議
+service.gui.CREATE_VIDEO_CONFERENCE=為此èŠå¤©å®¤å»ºç«‹ä¸€å€‹æ–°çš„視訊會議
+service.gui.CONTACT_INFO_NOT_SUPPORTED=該è¯çµ¡äººä¸æ”¯æ´ç¶²è·¯å片
+service.gui.CUT=剪下
+service.gui.DELETE=刪除
+service.gui.DENY=拒絕
+service.gui.DESKTOP_SHARING_WARNING=<b>您確定è¦é–‹å§‹èž¢å¹•å…±äº«ï¼Ÿ</b> <br>這個動作將å…許å°æ–¹è§€çœ‹æ‚¨çš„螢幕畫é¢ã€‚
+service.gui.DESKTOP_SHARING_DIALOG_INDICATE=您正在共享螢幕
+service.gui.DIALPAD=撥號盤
+service.gui.DISPLAY_NAME=顯示å稱
+service.gui.DISPLAY_NAME_PROMPT=Jane Doe
+service.gui.DISPLAY_NAME_INFO=為這個è¯çµ¡äººæ–°å¢žä¸€å€‹å稱。如果留空的話,將會使用åŠæ™‚通訊地å€æˆ– VoIP 填補。(å¯é¸ï¼‰
+service.gui.DISCONNECTED_STATUS=已斷線
+service.gui.DND_STATUS=請勿打擾
+service.gui.DO_NOT_ASK_AGAIN=è«‹å‹¿é‡è¤‡è©¢å•
+service.gui.DO_NOT_SHOW_AGAIN=è«‹å‹¿é‡è¤‡æ­¤è¨Šæ¯
+service.gui.DRAG_FOR_SHARING=將任何您想共享的æ±è¥¿æ‹–動到這裡...
+service.gui.DURATION=æŒçºŒæ™‚é–“
+service.gui.DESTROY_CHATROOM=撤銷èŠå¤©å®¤
+service.gui.DESTROY_MESSAGE=è«‹æ供說明以åŠæ›¿ä»£èŠå¤©å®¤çš„å稱以告知其他åƒèˆ‡è€…。
+service.gui.EDIT=編輯
+service.gui.EDITED_AT=編輯於 {0}
+service.gui.EMAIL=é›»å­éƒµä»¶
+service.gui.EMAILS=é›»å­éƒµä»¶
+service.gui.EMPTY_HISTORY=清空歷å²ç´€éŒ„
+service.gui.ENABLE_DESKTOP_REMOTE_CONTROL=啟用é ç«¯æŽ§åˆ¶
+service.gui.ENABLE_TYPING_NOTIFICATIONS=讓其他人知é“我們正在發訊æ¯ï¼ˆç™¼é€å°è©±ç‹€æ…‹ï¼‰
+service.gui.END_CONFERENCE=çµæŸæœƒè­°
+service.gui.ENTER_PHONE_NUMBER=輸入電話號碼
+service.gui.ENTER_NAME_OR_NUMBER=輸入å稱或號碼
+service.gui.ERROR=錯誤
+service.gui.ERROR_WAS=錯誤訊æ¯ï¼š{0}
+service.gui.ERROR_RECEIVED_FROM=從 {0} 收到錯誤訊æ¯
+service.gui.ESTIMATED_TIME=é ä¼°æ™‚間:
+service.gui.EVENTS=事件
+service.gui.EXIT=退出
+service.gui.GENERAL=通用
+service.gui.GENERAL_ERROR=常見錯誤
+service.gui.GROUP_NAME=群組å稱
+service.gui.FAILED_STATUS=呼å«å¤±æ•—
+service.gui.FAILED_TO_JOIN_CHAT_ROOM=加入èŠå¤©å®¤ {0} 失敗
+service.gui.FAX=傳真
+service.gui.FFC_STATUS=有空èŠå¤©
+service.gui.FILE=檔案
+service.gui.FILE_WAITING_TO_ACCEPT=等待 {0} 接收您的檔案
+service.gui.FILE_UNABLE_TO_SEND=å‘ {0} 傳é€æª”案時發生錯誤
+service.gui.FILE_RECEIVE_FAILED=從 {0} 接收檔案時發生錯誤
+service.gui.FILE_SENDING_TO=æ­£åœ¨å‘ {0} 傳é€æª”案
+service.gui.FILE_RECEIVING_FROM=正在從 {0} 接收檔案
+service.gui.FILE_SEND_COMPLETED=å‘ {0} 傳é€æª”案æˆåŠŸ
+service.gui.FILE_RECEIVE_COMPLETED=從 {0} 接收檔案æˆåŠŸ
+service.gui.FILE_TRANSFER_CANCELED=檔案傳輸已å–消
+service.gui.FILE_SEND_FAILED=檔案傳é€å¤±æ•—:{0}
+service.gui.FILE_TOO_BIG=檔案大å°è¶…出通訊å”定å…許範åœï¼š{0}
+service.gui.FILE_SEND_REFUSED={0} 拒收這個檔案
+service.gui.FILE_TRANSFER_REFUSED=檔案傳輸被拒絕
+service.gui.FILE_TRANSFER_NOT_SUPPORTED=您é¸æ“‡çš„è¯çµ¡äººä¸æ”¯æŒæª”案傳輸。
+service.gui.FILE_TRANSFER_PREPARING=正在準備和 {0} 的檔案傳輸。請ç¨å€™...
+service.gui.FILE_TRANSFER_REQUEST_RECIEVED={0} 正在和您共享檔案
+service.gui.FILE_DOES_NOT_EXIST=無法找到這個檔案,它å¯èƒ½å·²è¢«åˆªé™¤æˆ–移動到別處。
+service.gui.FILE_OPEN_FAILED=開啟檔案失敗,它å¯èƒ½å·²è¢«åˆªé™¤æˆ–移動到別處。
+service.gui.FILE_OPEN_NOT_SUPPORTED=å°ä¸èµ·ï¼åœ¨ç•¶å‰å¹³å°ä¸Šç„¡æ³•é–‹å•Ÿæª”案
+service.gui.FILE_OPEN_NO_PERMISSION=您沒有足夠的權é™ä¾†é–‹å•Ÿé€™å€‹æª”案。請檢查後é‡è©¦ã€‚
+service.gui.FILE_OPEN_NO_APPLICATION=無法找到應用程å¼é–‹å•Ÿé€™ç¨®é¡žåž‹çš„檔案
+service.gui.FINISH=完æˆ
+service.gui.FOLDER_DOES_NOT_EXIST=無法找到包å«é€™å€‹æª”案的資料夾。它å¯èƒ½å·²è¢«åˆªé™¤æˆ–移動到別處。
+service.gui.FOLDER_OPEN_FAILED=開啟資料夾失敗
+service.gui.FOLDER_OPEN_NO_PERMISSION=您沒有足夠的權é™ä¾†é–‹å•Ÿé€™å€‹è³‡æ–™å¤¾ã€‚請檢查後é‡è©¦ã€‚
+service.gui.FOLDER_OPEN_NO_APPLICATION=無法找到應用程å¼é–‹å•Ÿé€™å€‹è³‡æ–™å¤¾
+service.gui.FONT=å­—åž‹
+service.gui.FONT_BOLD=ç²—é«”
+service.gui.FONT_COLOR=é¡è‰²
+service.gui.FONT_FAMILY=字型家æ—
+service.gui.FONT_ITALIC=斜體
+service.gui.FONT_SIZE=大å°
+service.gui.FONT_STYLE=樣å¼
+service.gui.FONT_UNDERLINE=底線
+service.gui.GRANT_OWNERSHIP=晉å‡ç‚ºä¸»äºº
+service.gui.GRANT_ADMIN=æ拔為管ç†å“¡
+service.gui.GRANT_MODERATOR=æ拔為主æŒäºº
+service.gui.GRANT_MEMBERSHIP=授予æˆå“¡æ¬Šé™
+service.gui.GRANT_VOICE=授予語音權é™
+service.gui.GUEST=訪客
+service.gui.HANG_UP=掛斷
+service.gui.HD_QUALITY=HD視訊
+service.gui.HELP=å”助
+service.gui.HIDE=éš±è—
+service.gui.HIDE_OFFLINE_CONTACTS=éš±è—離線è¯çµ¡äºº
+service.gui.HIDE_MAIN_WINDOW=<DIV>點擊視窗上的 X åªæœƒéš±è—視窗,ä¸æœƒé€€å‡ºç¨‹å¼ã€‚<BR>如果您è¦é€€å‡ºç¨‹å¼ï¼Œè«‹é¸æ“‡ã€Œæª”案/退出ã€ã€‚</DIV>
+service.gui.HISTORY=通訊紀錄
+service.gui.HISTORY_CONTACT=æ­·å²è¨˜éŒ„ - {0}
+service.gui.HISTORY_TOGGLE_PER_CONTACT=關閉此è¯çµ¡äººçš„æ­·å²è¨˜éŒ„
+service.gui.HISTORY_TOGGLE_PER_CHATROOM=關閉此èŠå¤©å®¤çš„æ­·å²è¨˜éŒ„
+service.gui.HISTORY_TOGGLE_ALL=關閉所有èŠå¤©å®¤åŠè¯çµ¡äººçš„æ­·å²è¨˜éŒ„
+service.gui.HISTORY_ERASE_PER_CONTACT=清除此è¯çµ¡äººçš„所有歷å²è¨˜éŒ„
+service.gui.HISTORY_ERASE_PER_CHATROOM=清除此èŠå¤©å®¤çš„所有歷å²è¨˜éŒ„
+service.gui.HISTORY_ERASE_ALL=清除在 {0} 的所有èŠå¤©è¨˜éŒ„
+service.gui.HISTORY_REMOVE_PER_CONTACT_WARNING=您確定è¦æ°¸ä¹…刪除 {0} 儲存在這部電腦上的所有訊æ¯å—Žï¼Ÿ
+service.gui.HISTORY_REMOVE_ALL_WARNING=您確èªè¦æ°¸ä¹…刪除儲存在這部電腦上的所有訊æ¯å—Žï¼Ÿ
+service.gui.HISTORY_REMOVE_ERROR=刪除在這部電腦上的訊æ¯æ™‚發生錯誤。
+service.gui.HOME=首é 
+service.gui.HOME_PAGE=首é 
+service.gui.ICE=ICE
+service.gui.IDENTIFIER=識別å稱
+service.gui.IGNORE=忽略
+service.gui.INSERT_SMILEY=表情
+service.gui.INCOMING_CALL=來自 {0} 的通話請求
+service.gui.INCOMING_SCREEN_SHARE=來自 {0} 的螢幕共享請求
+service.gui.INCOMING_CALL_STATUS=來電呼å«
+service.gui.INCOMING_SCREEN_SHARE_STATUS=收到螢幕共享請求
+service.gui.INSTANT_MESSAGINGS=å³æ™‚通訊
+service.gui.IM=å³æ™‚通訊
+service.gui.INITIATING_CALL_STATUS=通訊正在建立
+service.gui.INVITATION=邀請說明
+service.gui.INVITATION_RECEIVED=收到邀請
+service.gui.INVITATION_RECEIVED_MSG={0} 邀請您加入èŠå¤©å®¤ {1} 。您å¯ä»¥é¸æ“‡åŒæ„,拒絕或忽略此邀請。
+service.gui.INVITATION_REJECTED={0} 已經拒絕您的加入èŠå¤©å®¤é‚€è«‹ã€‚原因:{1}
+service.gui.INVITE=邀請
+service.gui.INVITE_CONTACT_MSG=如果想進行精確æœå°‹ï¼Œè«‹è¼¸å…¥è©²ä½¿ç”¨è€…çš„å稱。
+service.gui.INVITE_CONTACT_TO_CHAT=邀請其他è¯çµ¡äººåŠ å…¥èŠå¤©
+service.gui.INVITE_CONTACT_TO_CALL=邀請其他è¯çµ¡äººåŠ å…¥å‘¼å«
+service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE=邀請其他è¯çµ¡äººåŠ å…¥è¦–訊橋接
+service.gui.INVITE_REASON=邀請ç†ç”±
+service.gui.IS_CALLING={0} 正在呼å«...
+service.gui.IS_NOW={0} 已更å為 {1}
+service.gui.JOIN=加入
+service.gui.JOIN_AS=加入為...
+service.gui.JOIN_EXISTING_VIDEO_CONFERENCE=加入ç¾æœ‰çš„視訊會議
+service.gui.JOIN_VIDEO=加入視訊通話
+service.gui.JOB_TITLE=è·ç¨±
+service.gui.JOIN_CHAT_ROOM=加入èŠå¤©å®¤...
+service.gui.JOIN_CHAT_ROOM_TITLE=加入èŠå¤©å®¤
+service.gui.JOIN_CHAT_ROOM_NAME=請輸入您想加入的èŠå¤©å®¤å稱。
+service.gui.JOIN_CHAT_ROOM_WIZARD=èŠå¤©å®¤åŠ å…¥ç²¾éˆ
+service.gui.JOIN_AUTOMATICALLY=自動加入
+service.gui.DONT_JOIN_AUTOMATICALLY=ç¦æ­¢è‡ªå‹•åŠ å…¥
+service.gui.KICK=踢出
+service.gui.KICK_FAILED=踢出失敗
+service.gui.KICK_FAILED_GENERAL_ERROR=踢出 {0} 失敗:伺æœå™¨ç™¼ç”ŸéŒ¯èª¤ã€‚
+service.gui.KICK_FAILED_NOT_ALLOWED=踢出 {0} 失敗:èŠå¤©å®¤çš„主人或管ç†å“¡ä¸èƒ½è¢«è¸¢å‡ºã€‚
+service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=踢出 {0} 失敗:您沒有權é™
+service.gui.LAST_NAME=姓æ°
+service.gui.LEAVE=離開
+service.gui.LIMIT_REACHED_FOR_IP=來自這個本地IP地å€çš„註冊者太多,伺æœå™¨ {0} ä¸å†æŽ¥å—新註冊。
+service.gui.LIST=清單
+service.gui.LOADING_ROOMS=正在載入èŠå¤©å®¤...
+service.gui.LOADING=載入中...
+service.gui.LOCALLY_ON_HOLD_STATUS=本地通話ä¿ç•™
+service.gui.LOGIN_NETWORK_ERROR=使用者 {0} 登入 {1} 伺æœå™¨å¤±æ•—:請檢查您的網路連線。
+service.gui.LOGIN_GENERAL_ERROR=使用者 {0} 登入 {1} 伺æœå™¨æ™‚發生錯誤。
+service.gui.LOGIN_INTERNAL_ERROR=使用者 {0} 登入 {1} 伺æœå™¨æ™‚發生錯誤:這應該是一個 bugï¼è«‹å°‡å•é¡Œ email 回饋至 dev@jitsi.java.net。
+service.gui.LOGIN_INVALID_PROPERTIES_ERROR=使用者 {0} 登入 {1} 伺æœå™¨æ™‚發生錯誤:請檢查您的帳號設定。
+service.gui.LOGOFF_NOT_SUCCEEDED=使用者 {0} 登出 {1} 伺æœå™¨æ™‚發生錯誤。
+service.gui.LOW_QUALITY=低å“質
+service.gui.MEMBER=æˆå“¡
+service.gui.MERGE_TO_CALL=åˆä½µæ‰€æœ‰é€šè©±
+service.gui.MESSAGE=訊æ¯
+service.gui.MISSED_CALLS_TOOL_TIP=未接來電來自:
+service.gui.MISSED_CALLS_MORE_TOOL_TIP= 還有 {0} æ¢
+service.gui.MODERATOR=主æŒäºº
+service.gui.MORE_LABEL=展開
+service.gui.MOVE=移動
+service.gui.MOVE_SUBCONTACT=移動è¯çµ¡äºº
+service.gui.MOVE_SUBCONTACT_MSG=è«‹é¸æ“‡æ‚¨è¦ç§»å‹•è¯çµ¡äººåˆ°å“ªå€‹ç¾¤çµ„。
+service.gui.MOVE_SUBCONTACT_FAILED=您é¸æ“‡çš„è¯çµ¡äººå·²ç¶“存在。\nè«‹é‡æ–°é¸æ“‡ï¼
+service.gui.MOVE_SUBCONTACT_QUESTION=您確èªè¦å°‡ {0} 移動到 {1}?
+service.gui.MOVE_TO_GROUP=移動到群組
+service.gui.MOVE_CONTACT=移動è¯çµ¡äºº
+service.gui.MSG_DELIVERY_FAILURE=以上訊æ¯ç™¼é€å¤±æ•—
+service.gui.MSG_DELIVERY_NOT_SUPPORTED=您正在使用的通訊å”定ä¸æ”¯æ´é›¢ç·šè¨Šæ¯åŠŸèƒ½ã€‚請嘗試其他通訊å”定,或者等待 {0} 上線。
+service.gui.MSG_DELIVERY_INTERNAL_ERROR=程å¼å…§éƒ¨ç™¼ç”ŸéŒ¯èª¤ï¼šé€™å¯èƒ½æ˜¯ä¸€å€‹BUGï¼è«‹å›žé¥‹å•é¡Œåˆ°ï¼šhttp://www.jitsi.org/index.php/Development/BugsAndIssues
+service.gui.MSG_DELIVERY_ERROR=發é€è¨Šæ¯å¤±æ•—。
+service.gui.MSG_DELIVERY_UNKNOWN_ERROR=發é€è¨Šæ¯å¤±æ•—,原因ä¸æ˜Žã€‚
+service.gui.MSG_DELIVERY_UNSUPPORTED_OPERATION=ä¸æ”¯æŒçš„æ“作。
+service.gui.MSG_NOT_DELIVERED=網路錯誤。請檢查網路設定後é‡è©¦ã€‚
+service.gui.MSG_NOT_POSSIBLE=無法發é€è¨Šæ¯çµ¦è©²è¯çµ¡äººï¼ˆé€šè¨Šå”定ä¸æ”¯æ´ï¼‰
+service.gui.MSG_RECEIVED={0} 發é€è¨Šæ¯çµ¦æ‚¨äº†
+service.gui.MSG_SEND_CONNECTION_PROBLEM=請先登入伺æœå™¨å†ç™¼é€è¨Šæ¯ã€‚
+service.gui.MULTIPLE_LOGINS=使用者 {0} 在其他地方登入,{1} 伺æœå™¨é€£ç·šä¸­æ–·ã€‚
+service.gui.MY_CHAT_ROOMS=èŠå¤©å®¤
+service.gui.MY_CHAT_ROOMS_TITLE=新增èŠå¤©å®¤
+service.gui.MUTUALLY_ON_HOLD_STATUS=雙方等候接通
+service.gui.NAME=å稱
+service.gui.NETWORK=網路
+service.gui.NETWORK_FAILURE=網路錯誤
+service.gui.NEXT=下一個
+service.gui.NEW_ACCOUNT=建立新帳號...
+service.gui.NEW_MESSAGE=新訊æ¯...
+service.gui.NEW_NAME=æ–°å稱
+service.gui.NEW_STATUS_MESSAGE=新狀態訊æ¯
+service.gui.NEW_STATUS_MESSAGE_SAVE=存為自定義訊æ¯
+service.gui.NICKNAME=暱稱
+service.gui.NO=å¦
+service.gui.NONE=ç„¡
+service.gui.NO_CAMERA_AVAILABLE=沒有å¯ç”¨çš„æ”影機
+service.gui.NO_DESKTOP_SHARING_FOR_PROTOCOL=此通訊å”定ä¸æ”¯æ´æ¡Œé¢å…±äº«åŠŸèƒ½ã€‚
+service.gui.NO_VIDEO_ENCODINGS=在設定檔中沒有啟用任何視訊解碼器
+service.gui.NO_VIDEO_FOR_PROTOCOL=此通訊å”定ä¸æ”¯æŒè¦–訊通話
+service.gui.NO_AVAILABLE_ROOMS=ç›®å‰ç„¡æ³•å–得伺æœå™¨ä¸Šçš„èŠå¤©å®¤åˆ—表。
+service.gui.NO_CONTACTS_FOUND=找ä¸åˆ°ç›¸ç¬¦çš„è¯çµ¡äººã€‚按下 Ctrl+Enter æˆ–ä½¿ç”¨ä»¥ä¸‹æŒ‰éˆ•å‘¼å« {0} 。
+service.gui.NO_CONTACTS_FOUND_SHORT=未找到相符的è¯çµ¡äºº
+service.gui.NO_MESSAGE=沒有訊æ¯
+service.gui.NO_GROUP_CHAT_ACCOUNT_AVAILABLE=沒有å¯ç”¨çš„群組èŠå¤©å¸³è™Ÿã€‚請到 jitsi.org 查詢哪些通訊å”定支æ´ç¾¤çµ„èŠå¤©ã€‚
+service.gui.NO_ONLINE_CONFERENCING_ACCOUNT=沒有å¯ç”¨çš„會議帳號。請到 jitsi.org 查詢哪些通訊å”定支æ´æœƒè­°ã€‚
+service.gui.NO_ONLINE_TELEPHONY_ACCOUNT=呼å«å‰å¿…須確ä¿è‡³å°‘一個電話帳號在線。請登入您的一個電話帳號然後é‡è©¦ã€‚
+service.gui.NOT_AUTHORIZED=未授權
+service.gui.NON_EMPTY_CHAT_WINDOW_CLOSE=您正在嘗試關閉å°è©±ï¼Œä½†æ˜¯é‚„有未發é€çš„訊æ¯ã€‚您確定è¦é—œé–‰å°è©±å—Žï¼Ÿ
+service.gui.NON_EXISTING_USER_ID={0} 伺æœå™¨ç„¡æ³•è­˜åˆ¥é€™å€‹ä½¿ç”¨è€… ID。
+service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME=ä¸åœ¨é€šè¨ŠéŒ„中
+service.gui.SD_QUALITY=標準å“質
+service.gui.OFFLINE=離線
+service.gui.OK=確定
+service.gui.ONLINE=在線
+service.gui.OPEN=é–‹å•Ÿ
+service.gui.OPEN_FILE_FROM_IMAGE=雙擊以開啟檔案
+service.gui.OPEN_FOLDER=開啟資料夾
+service.gui.OPEN_IN_BROWSER=在ç€è¦½å™¨ä¸­é–‹å•Ÿ
+service.gui.OPTIONS=é¸é …
+service.gui.OPEN_AUTOMATICALLY=在下列情æ³æ™‚自動開啟本èŠå¤©å®¤
+service.gui.OPEN_ON_ACTIVITY=有活動時開啟
+service.gui.OPEN_ON_MESSAGE=僅在有訊æ¯æ™‚é–‹å•Ÿ
+service.gui.OPEN_ON_IMPORTANT_MESSAGE=僅在有é‡è¦è¨Šæ¯æ™‚é–‹å•Ÿ
+service.gui.OR=或者
+service.gui.ORGANIZATION=組織
+service.gui.OTHER=其他
+service.gui.chat.role.OWNER=主人
+service.gui.chat.role.ADMINISTRATOR=管ç†å“¡
+service.gui.chat.role.MODERATOR=主æŒäºº
+service.gui.chat.role.MEMBER=æˆå“¡
+service.gui.chat.role.GUEST=éŠå®¢
+service.gui.chat.role.SILENT_MEMBER=éœéŸ³æˆå“¡
+service.gui.chat.role.OUTCAST=被ç¦æ­¢åŠ å…¥
+service.gui.OWNER=èŠå¤©å®¤ä¸»äºº
+service.gui.ON_MOBILE_TOOLTIP=(手機通話中)
+service.gui.PASSWORD=密碼
+service.gui.PASSWORD_CHANGE_FAILURE=密碼修改失敗
+service.gui.PASSWORD_CHANGE_SUCCESS=密碼修改æˆåŠŸ
+service.gui.PASTE=貼上
+service.gui.PERSONAL=ç§äºº
+service.gui.PORT=通訊埠
+service.gui.POSTAL_CODE=郵éžå€è™Ÿ
+service.gui.PREFERENCES=å好設定
+service.gui.PREFIX=å‰ç½®å­—串
+service.gui.PRESENCE=上線狀æ³
+service.gui.PRESS_ENTER_FOR_SUGGESTIONS=按 Enter éµæŸ¥çœ‹å»ºè­°
+service.gui.PRESS_FOR_CALL_INFO=點擊查看通話訊æ¯
+service.gui.PRESS_TO_OPEN_CRM=點擊開啟CRM程å¼
+service.gui.PREVIOUS=上一個
+service.gui.PRINT=列å°
+service.gui.PROACTIVE_NOTIFICATION=正在輸入訊æ¯
+service.gui.PROBLEMS_ENCOUNTERED=é‡åˆ°å•é¡Œ
+service.gui.PROTOCOL=通訊å”定
+service.gui.PUT_OFF_HOLD=å–消等待通話
+service.gui.PUT_ON_HOLD=等待通話
+service.gui.QUIT=退出
+service.gui.READY=就緒
+service.gui.RECENT_MESSAGES=最近的å°è©±
+service.gui.REASON=原因
+service.gui.RECEIVED=收到 {0}
+service.gui.RECONNECTION_LIMIT_EXCEEDED=使用者 {0} é‡è¤‡ç™»å…¥ {1} 伺æœå™¨ï¼šè©²å¸³è™Ÿæš«æ™‚被å°éŽ–,請éŽä¸€æ®µæ™‚間後å†è©¦ã€‚
+service.gui.RE_REQUEST_AUTHORIZATION=é‡æ–°è«‹æ±‚授權
+service.gui.REFERRED_STATUS=轉接
+service.gui.REJECT=拒絕
+service.gui.REMEMBER_PASSWORD=記ä½å¯†ç¢¼
+service.gui.REMOVE=刪除
+service.gui.REMOVE_ACCOUNT=刪除帳號
+service.gui.REMOVE_ACCOUNT_MESSAGE=確定è¦åˆªé™¤é€™å€‹å¸³è™Ÿå—Žï¼Ÿ
+service.gui.REMOVE_CONTACT=刪除è¯çµ¡äºº
+service.gui.REMOVE_CONTACT_TEXT=<DIV>確定è¦å°‡<B> {0} </B><BR>從通訊錄中刪除嗎?</DIV>
+service.gui.REMOVE_CONTACT_NOT_CONNECTED=您需è¦é‡æ–°é€£ç·šä»¥ç§»é™¤æ­¤è¯çµ¡äººã€‚請登入後é‡è©¦ã€‚
+service.gui.REMOVE_GROUP=刪除群組
+service.gui.REMOTELY_ON_HOLD_STATUS=å°æ–¹ç­‰å€™é€šè©±
+service.gui.RENAME=é‡æ–°å‘½å
+service.gui.RENAME_CONTACT=é‡æ–°å‘½åè¯çµ¡äºº
+service.gui.RENAME_CONTACT_WIZARD=請輸入該è¯çµ¡äººçš„æ–°å稱。
+service.gui.RENAME_GROUP=é‡æ–°å‘½å群組
+service.gui.RENAME_GROUP_INFO=請輸入該群組的新å稱。
+service.gui.RENAME_CLEAR_USER_DEFINED=還原
+service.gui.RINGING_STATUS=響鈴中
+service.gui.REQUEST=請求
+service.gui.REQUEST_AUTHORIZATION=請求授權
+service.gui.REQUEST_AUTHORIZATION_MSG=無法新增 {0} 到您的通訊錄,必須等待 {0} 加您為好å‹ã€‚請輸入您的請求訊æ¯ã€‚
+service.gui.RETRY=é‡è©¦
+service.gui.REVOKE_OWNERSHIP=å–消所有權
+service.gui.REVOKE_ADMIN=å–消管ç†è€…權é™
+service.gui.REVOKE_MODERATOR=å–消主æŒäººæ¬Šé™
+service.gui.REVOKE_MEMBERSHIP=å–消æˆå“¡æ¬Šé™
+service.gui.REVOKE_VOICE=å–消發言權
+service.gui.SAVE=存檔
+service.gui.SEARCH=æœå°‹
+service.gui.SEARCH_FOR_CHAT_ROOMS_MSG=點擊顯示本伺æœå™¨ä¸Šæ‰€æœ‰èŠå¤©å®¤ï¼Œé¸æ“‡æ‚¨æƒ³åŠ å…¥çš„èŠå¤©å®¤å†é»žæ“Šã€ŒåŠ å…¥ã€ã€‚
+service.gui.SEARCH_STRING_CONTACT_SOURCE=æœå°‹åˆ°çš„è¯çµ¡äºº
+service.gui.SECURITY=安全
+service.gui.SELECT_ACCOUNT_INFO=您想使用哪個帳號與這個è¯çµ¡äººé€²è¡Œé€šè¨Šï¼Ÿ
+service.gui.SELECT_COLOR=é¸æ“‡é¡è‰²
+service.gui.SELECT_GROUP=é¸æ“‡ç¾¤çµ„
+service.gui.SELECT_GROUP_INFO=您想將此è¯çµ¡äººæ”¾ç½®åœ¨å“ªå€‹ç¾¤çµ„下顯示?(å¯é¸ï¼‰
+service.gui.SELECT_NO_GROUP=未加入群組
+service.gui.SELECT_PROVIDERS_FOR_CHAT_ROOM=以下是您所有支æ´ç¾¤çµ„èŠå¤©çš„帳號。請é¸æ“‡å…¶ä¸­ä¸€å€‹ä»¥å»ºç«‹èŠå¤©å®¤ã€‚
+service.gui.SELECT_VIDEO_CONFERENCE=é¸æ“‡è¦–訊會議
+service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT=èŠå¤©å®¤
+service.gui.SEND=發é€
+service.gui.SEND_FILE=傳é€æª”案
+service.gui.SEND_MESSAGE=發é€è¨Šæ¯
+service.gui.SEND_PRIVATE_MESSAGE=傳é€ç§å¯†è¨Šæ¯
+service.gui.SEND_SMS=發é€ç°¡è¨Š
+service.gui.SEND_SMS_DETAILS=請以國際電話號碼格å¼è¼¸å…¥ï¼Œä¾‹å¦‚以 +886 é–‹é ­çš„å°ç£æ‰‹æ©Ÿè™Ÿç¢¼ +886937123456。
+service.gui.SEND_SMS_NOT_SUPPORTED=您é¸æ“‡çš„通訊å”定ä¸æ”¯æ´ç°¡è¨Šç™¼é€åŠŸèƒ½ã€‚
+service.gui.SMS=簡訊
+service.gui.SEND_VIA=轉發訊æ¯
+service.gui.SENT=已發é€
+service.gui.SERVER_CHAT_ROOMS=èŠå¤©å®¤ä¼ºæœå™¨
+service.gui.SET_GLOBAL_STATUS=設定全域狀態
+service.gui.SET_STATUS_MESSAGE=設定狀態訊æ¯
+service.gui.SET_SUBJECT=設定主題
+service.gui.SETTINGS=é¸é …
+service.gui.SHARE_DESKTOP=共享桌é¢
+service.gui.SHARE_DESKTOP_WITH_CONTACT=共享桌é¢çµ¦è¯çµ¡äºº
+service.gui.SHARE_FULL_SCREEN=全螢幕共享
+service.gui.SHARE_REGION=局部螢幕共享
+service.gui.SHOW=顯示
+service.gui.SHOW_CONTACT_LIST_TOOL_TIP=點擊切æ›æ­·å²è¨˜éŒ„視窗åŠé€šè¨ŠéŒ„。
+service.gui.SHOW_MORE=顯示更多...
+service.gui.SHOW_OFFLINE_CONTACTS=顯示離線è¯çµ¡äºº
+service.gui.SIGN_IN=登入
+service.gui.SMS_SUCCESSFULLY_SENT=簡訊發é€æˆåŠŸï¼
+service.gui.SMS_SEND_CONNECTION_PROBLEM=必須先登入æ‰èƒ½ç™¼é€ç°¡è¨Šã€‚請登入您的簡訊æœå‹™å¸³è™Ÿã€‚
+service.gui.SPECIFY_REASON=請輸入您這麼åšçš„原因。
+service.gui.SPECIFY_SERVER=請補充您帳號設定的伺æœå™¨èªªæ˜Žã€‚
+service.gui.SOUND_OFF=關閉è²éŸ³
+service.gui.SOUND_ON=é–‹å•Ÿè²éŸ³
+service.gui.START_SHARING=開始共享
+service.gui.STATUS=狀態
+service.gui.STATUS_CHANGED_CHAT_MESSAGE={0} 已上線
+service.gui.STATUS_CHANGE_GENERAL_ERROR=使用者 {0} æ›´æ–° {1} 伺æœå™¨ç‹€æ…‹å¤±æ•—:常見錯誤。
+service.gui.STATUS_CHANGE_NETWORK_FAILURE=使用者 {0} æ›´æ–° {1} 伺æœå™¨ç‹€æ…‹å¤±æ•—:網路錯誤。
+service.gui.STATUS_MESSAGE_INFO=請輸入您的新狀態訊æ¯ã€‚
+service.gui.STOP_SHARING=åœæ­¢å…±äº«
+service.gui.STREET=è¡—é“
+service.gui.SUBJECT=標題
+service.gui.SUMMARY=摘è¦
+service.gui.TELEPHONY=電話
+service.gui.TOOLS=工具
+service.gui.TRANSFER=轉接
+service.gui.TO=到:
+service.gui.TRANSFER_CALL_MSG=å…ˆé¸æ“‡è¦è½‰æŽ¥è¯çµ¡äººå†é»žæ“Šã€Œè½‰æŽ¥ã€ã€‚
+service.gui.TRANSFER_CALL_TITLE=轉接來電
+service.gui.TRANSFER_CALL_TO=轉接給:
+service.gui.TRANSPARENCY_NOT_ENABLED=您當å‰çš„設定ä¸æ”¯æŒé€æ˜ŽåŒ–。
+service.gui.TYPE_YOUR_REQUEST=請在這裡輸入您的請求
+service.gui.UNABLE_TO_CHANGE_VIDEO_QUALITY=我們無法變更本通話的視訊å“質。
+service.gui.USER_IDENTIFIER=使用者ID:
+service.gui.USER_EXISTS_ERROR=所é¸çš„網路已存在該使用者。請é¸æ“‡å…¶ä»–使用者或網路。
+service.gui.USERNAME_NULL=請輸入使用者å稱和密碼。
+service.gui.WEBPAGE=開啟網é 
+service.gui.ACCOUNT_CREATION_FAILED=建立帳號失敗,原因:{0}
+service.gui.UNKNOWN=未知使用者
+service.gui.UNKNOWN_STATUS=未知狀態
+service.gui.UNREGISTERED_MESSAGE=使用者 {0} 連線 {1} 伺æœå™¨å¤±æ•—:您正處於離線狀態。
+service.gui.USE_PROVISIONING=使用在線é…ç½®
+service.gui.VALUE=數值
+service.gui.VIDEO_CALL=視訊通話
+service.gui.VIA=經由
+service.gui.VIEW=顯示
+service.gui.VIEW_HISTORY=檢視歷å²ç´€éŒ„
+service.gui.VIEW_SMILEYS=顯示表情
+service.gui.VIEW_TOOLBAR=顯示工具列
+service.gui.VIEW_SIMPLE_CHAT_THEME=ç°¡å–®èŠå¤©ä¸»é¡Œçš®è†š
+service.gui.VOICEMAIL_NEW_URGENT_OLD_RECEIVED={0} æ¢æ–°è¨Šæ¯ ( {1} æ¢ç·Šæ€¥ ) å’Œ {2} æ¢èˆŠè¨Šæ¯
+service.gui.VOICEMAIL_NEW_URGENT_RECEIVED={0} æ¢æ–°è¨Šæ¯ ( {1} æ¢ç·Šæ€¥ )
+service.gui.VOICEMAIL_NEW_OLD_RECEIVED={0} æ¢æ–°è¨Šæ¯å’Œ {1} æ¢èˆŠè¨Šæ¯
+service.gui.VOICEMAIL_NEW_RECEIVED={0} æ¢æ–°è¨Šæ¯
+service.gui.VOICEMAIL_OLD_RECEIVED={0} æ¢èˆŠè¨Šæ¯
+service.gui.VOICEMAIL_NO_MESSAGES=沒有訊æ¯
+service.gui.VOICEMAIL_TITLE=語音留言
+service.gui.VOICEMAIL_TOOLTIP=語音留言給:
+service.gui.VOICEMAIL_TIP=點擊通話按鈕以收è½æ‚¨çš„留言。
+service.gui.VOICEMAIL_TIP_NO_ACCOUNT=請在帳號精éˆä¸­è¨­å®šå¯ç”¨ä»¥è®€å–èªžéŸ³ä¿¡ç®±çš„ç¶²å€ (URI)
+service.gui.VOLUME_CONTROL_TOOL_TIP=調整音é‡
+service.gui.WAITING_AUTHORIZATION=正在等待授權
+service.gui.WARNING=警告
+service.gui.YES=是
+service.gui.NEW_GMAIL_HEADER=您有一å°æ–°éƒµä»¶ï¼æ”¶ä»¶ç®±ï¼š<a href="{1}">{0}</a><br/>
+service.gui.NEW_GMAIL_MANY_HEADER=收件箱:<a href="{1}">{0}</a><br/> 有 {2} å°æ–°éƒµä»¶ã€‚
+service.gui.NEW_GMAIL_FOOTER=多æ¢æœªè®€ç•™è¨€åœ¨æ‚¨çš„<a href="{0}">收件箱</a>。<br/>
+service.gui.NEW_GMAIL_MANY_FOOTER=有 {1} 個未讀留言在您的<a href="{0}">收件箱</a>。<br/>
+service.gui.ACTIVATE=啟用
+service.gui.DEACTIVATE=åœç”¨
+service.gui.NEW=新增
+service.gui.ENTER_FULL_SCREEN_TOOL_TIP=進入全螢幕模å¼
+service.gui.EXIT_FULL_SCREEN_TOOL_TIP=退出全螢幕模å¼
+service.gui.HOLD_BUTTON_TOOL_TIP=啟用/åœç”¨é€šè©±ç­‰å¾…
+service.gui.MUTE_BUTTON_TOOL_TIP=切æ›éœéŸ³æˆ–者按ä½æŒ‰éˆ•ä»¥èª¿æ•´éº¥å…‹é¢¨éŸ³é‡
+service.gui.PARK=ä¿æŒ
+service.gui.PARKING_SLOT=通話é§ç•™é€šé“:
+service.gui.PARK_BUTTON_TOOL_TIP=呼å«ä¿æŒ
+service.gui.RECORD_BUTTON_TOOL_TIP=é–‹å•Ÿ/åœæ­¢éŒ„音
+service.gui.LOCAL_VIDEO_BUTTON_TOOL_TIP=切æ›è¦–訊
+service.gui.SHOW_LOCAL_VIDEO_BUTTON_TOOL_TIP=顯示/éš±è—本地視訊
+service.gui.SHOW_HIDE_PEERS_TOOL_TIP=顯示/éš±è—通話åƒèˆ‡è€…列表
+service.gui.TRANSFER_BUTTON_TOOL_TIP=轉接來電
+service.gui.TRANSFER_TO=轉接給...
+service.gui.SECURITY_INFO=安全訊æ¯
+service.gui.SECURITY_WARNING=安全警告
+service.gui.SECURITY_ERROR=安全錯誤
+service.gui.SPEED=速率:
+service.gui.SILENT_MEMBER=éœéŸ³æˆå“¡
+service.gui.NON_SECURE_CONNECTION=無法為帳號 {0} 建立安全連線。如果您想連線到一個ä¸å®‰å…¨çš„伺æœå™¨ï¼Œè«‹åœ¨æ‚¨çš„帳號設定中勾é¸ã€Œå…許ä¸å®‰å…¨çš„連線ã€é¸é …
+service.gui.MOBILE_PHONE=手機
+service.gui.VIDEO_PHONE=視訊
+service.gui.WORK_PHONE=工作
+service.gui.PHONE=電話
+service.gui.PHONES=電話
+service.gui.EDIT_NOT_SUPPORTED=此帳號ä¸å¯ç·¨è¼¯
+service.gui.SHOW_PREVIEW=(顯示é è¦½)
+service.gui.SHOW_PREVIEW_WARNING_DESCRIPTION=您è¦ç¹¼çºŒé¡¯ç¤ºæ­¤åœ–片?\n\n顯示圖片/視訊 å¯èƒ½è®“您的匿å失效並且暴露您的活動狀態。
+service.gui.SHOW_PREVIEW_DIALOG_TITLE=顯示圖片/視訊é è¦½
+
+service.gui.ZID_NAME_SET=ZRTP 識別碼å稱:
+service.gui.ZID_NAME_NOT_SET=ZRTP 識別碼å稱未設定
+service.gui.ZID_NAME_BUTTON=點擊設定一個 ZRTP 識別碼å稱。
+service.gui.ZID_NAME_DIALOG=編輯 ZRTP 識別碼å稱
+service.gui.ZID_NAME_UNEXPECTED=<html>ZRTP 識別碼ä¸ç›¸ç¬¦ã€‚<br><b>請先比å°èº«ä»½é©—證識別碼是å¦èˆ‡å°æ–¹ä¸€è‡´ï¼</b><br>修改 ZRTP 身份驗證識別碼直至與å°æ–¹ä¸€è‡´å†å­˜æª”。</html>
+
+service.gui.JANUARY=一月
+service.gui.FEBRUARY=二月
+service.gui.MARCH=三月
+service.gui.APRIL=四月
+service.gui.MAY=五月
+service.gui.JUNE=六月
+service.gui.JULY=七月
+service.gui.AUGUST=八月
+service.gui.SEPTEMBER=ä¹æœˆ
+service.gui.OCTOBER=å月
+service.gui.NOVEMBER=å一月
+service.gui.DECEMBER=å二月
+
+service.gui.callinfo.TECHNICAL_CALL_INFO=技術呼å«è¨Šæ¯
+service.gui.callinfo.CALL_INFORMATION=通話訊æ¯
+service.gui.callinfo.CALL_IDENTITY=標識
+service.gui.callinfo.PEER_COUNT=åƒèˆ‡äººæ•¸
+service.gui.callinfo.IS_CONFERENCE_FOCUS=會議焦點
+service.gui.callinfo.CALL_TRANSPORT=信號呼å«å‚³è¼¸
+service.gui.callinfo.CALL_DURATION=通話週期
+service.gui.callinfo.TLS_PROTOCOL=TLS 通訊å”定
+service.gui.callinfo.TLS_CIPHER_SUITE=TLS 加密算法套件
+service.gui.callinfo.TLS_CERTIFICATE_CONTENT=以下是 TLS 伺æœå™¨æ†‘證內容。
+service.gui.callinfo.VIEW_CERTIFICATE=查看憑證
+service.gui.callinfo.CODEC=編碼器/頻率
+service.gui.callinfo.NA=ç„¡
+service.gui.callinfo.VIDEO_SIZE=視訊大å°
+service.gui.callinfo.AUDIO_INFO=音訊訊æ¯
+service.gui.callinfo.VIDEO_INFO=視訊訊æ¯
+service.gui.callinfo.LOCAL_IP=本地IP/通訊埠
+service.gui.callinfo.REMOTE_IP=é ç«¯IP/通訊埠
+service.gui.callinfo.BANDWITH=帶寬
+service.gui.callinfo.LOSS_RATE=æ失率
+service.gui.callinfo.RTT=RTT
+service.gui.callinfo.JITTER=抖動
+service.gui.callinfo.MEDIA_STREAM_TRANSPORT_PROTOCOL=多媒體串æµå‚³è¼¸é€šè¨Šå”定
+service.gui.callinfo.MEDIA_STREAM_RTP=RTP
+service.gui.callinfo.MEDIA_STREAM_SRTP=SRTP
+service.gui.callinfo.KEY_EXCHANGE_PROTOCOL=密鑰交æ›é€šè¨Šå”定
+service.gui.callinfo.ICE_CANDIDATE_EXTENDED_TYPE=ICE 候é¸è€…拓展類型
+service.gui.callinfo.ICE_STATE=ICE 作業處ç†ç‹€æ…‹
+
+#enum values from IceProcessingState
+service.gui.callinfo.ICE_STATE.WAITING=æœé›†å€™é¸è€…
+service.gui.callinfo.ICE_STATE.RUNNING=連通性檢查
+service.gui.callinfo.ICE_STATE.COMPLETED=已完æˆ
+service.gui.callinfo.ICE_STATE.FAILED=失敗
+
+service.gui.callinfo.ICE_LOCAL_HOST_ADDRESS=本地主機IP/通訊埠
+service.gui.callinfo.ICE_LOCAL_REFLEXIVE_ADDRESS=本地自åIP/通訊埠
+service.gui.callinfo.ICE_LOCAL_RELAYED_ADDRESS=本地中繼IP/通訊埠
+service.gui.callinfo.ICE_REMOTE_HOST_ADDRESS=é ç«¯ä¸»æ©ŸIP/通訊埠
+service.gui.callinfo.ICE_REMOTE_REFLEXIVE_ADDRESS=é ç«¯è‡ªåIP/通訊埠
+service.gui.callinfo.ICE_REMOTE_RELAYED_ADDRESS=é ç«¯ä¸­ç¹¼IP/通訊埠
+service.gui.callinfo.TOTAL_HARVESTING_TIME=回收時間總計
+service.gui.callinfo.HARVESTING_TIME=回收時間
+service.gui.callinfo.HARVESTING_MS_FOR=ms (為
+service.gui.callinfo.HARVESTS= 收æˆ)
+service.gui.callinfo.DECODED_WITH_FEC=用 FEC 解碼å°åŒ…
+service.gui.callinfo.DISCARDED_PERCENT=當å‰å°åŒ…被æ¨æ£„
+service.gui.callinfo.DISCARDED_TOTAL=被æ¨æ£„å°åŒ…數
+service.gui.callinfo.ADAPTIVE_JITTER_BUFFER=自é©æ‡‰æŠ–å‹•ç·©è¡å™¨
+service.gui.callinfo.JITTER_BUFFER_DELAY=抖動緩è¡å™¨
+
+service.gui.ALWAYS_TRUST=總是信任這個憑證
+service.gui.CERT_DIALOG_TITLE=驗證憑證
+service.gui.CERT_DIALOG_DESCRIPTION_TXT=<html>{0} 連接到 {1} 伺æœå™¨æ™‚無法驗證。<br><br>該伺æœå™¨æ†‘è­‰ä¸å—信任,因而無法自動驗證。<br><br>您確定è¦ç¹¼çºŒé€£ç·šï¼Ÿ<br>點擊 「檢視憑證ã€å¯å–得進一步資訊。</html>
+service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST=<html>{0} 連接伺æœå™¨æ™‚無法驗證。<br><br>該伺æœå™¨æ†‘è­‰ä¸å—信任,因而無法自動驗證。<br><br>您確定è¦ç¹¼çºŒé€£ç·šï¼Ÿ<br>點擊 「檢視憑證ã€å¯å–得進一步資訊。</html>
+service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT=<html>{0} 無法驗證客戶端 {1} 的身份。<br><br>該客戶端的證書ä¸å—信任,因此無法自動驗證其身份。<br>您確èªè¦ç¹¼çºŒé€£ç·šï¼Ÿ<br><br>點擊「查看證書ã€ç²å–詳細訊æ¯ã€‚</html>
+service.gui.CONTINUE_ANYWAY=ä»ç„¶ç¹¼çºŒ
+service.gui.CERT_INFO_CHAIN=證書éˆï¼š
+service.gui.CERT_INFO_ISSUED_TO=通用å:
+
+#service.gui.CERT_INFO_ are combined from Rdn names
+service.gui.CERT_INFO_CN=通用å:
+service.gui.CERT_INFO_O=組織:
+service.gui.CERT_INFO_C=國家:
+service.gui.CERT_INFO_ST=å·ž/çœï¼š
+service.gui.CERT_INFO_L=地å€ï¼š
+service.gui.CERT_INFO_ISSUED_BY=頒發者
+service.gui.CERT_INFO_OU=å–®ä½ï¼š
+service.gui.CERT_INFO_VALIDITY=有效性
+service.gui.CERT_INFO_ISSUED_ON=簽發日:
+service.gui.CERT_INFO_EXPIRES_ON=到期日:
+service.gui.CERT_INFO_FINGERPRINTS=數ä½æŒ‡ç´‹
+service.gui.CERT_INFO_CERT_DETAILS=åºè™Ÿï¼š
+service.gui.CERT_INFO_SER_NUM=åºè™Ÿï¼š
+service.gui.CERT_INFO_VER=版本:
+service.gui.CERT_INFO_SIGN_ALG=演算法簽章:
+service.gui.CERT_INFO_PUB_KEY_INFO=公鑰訊æ¯
+service.gui.CERT_INFO_ALG=演算法:
+service.gui.CERT_INFO_PUB_KEY=公鑰:
+service.gui.CERT_INFO_KEY_BITS_PRINT={0} bits
+service.gui.CERT_INFO_EXP=指數:
+service.gui.CERT_INFO_KEY_SIZE=密鑰長度:
+service.gui.CERT_INFO_SIGN=ç°½å:
+service.gui.SHOW_CERT=顯示憑證
+service.gui.HIDE_CERT=éš±è—憑證
+
+service.gui.AUTO_ANSWER=自動接è½å’Œè½‰æŽ¥
+service.gui.AUTO_ANSWER_LABEL=自動接è½
+service.gui.AUTO_ANSWER_ALL_CALLS=所有來電
+service.gui.AUTO_ANSWER_ALERT_INFO_FIELDS=åªç”¨æ–¼ä¾†é›» (é‚£äº›åŒ…å« "Alert-Info" 欄ä½çš„來電設定為「自動接è½ã€)
+service.gui.AUTO_ANSWER_CUSTOM_FIELDS=包å«ä¸‹åˆ—字段和數值的通話
+service.gui.AUTO_ANSWER_FIELD=字段/檔頭:
+service.gui.AUTO_ANSWER_VALUE=數值:
+service.gui.AUTO_ANSWER_DESCR_VLUE=始終留空
+service.gui.AUTO_ANSWER_FWD_CALLS=通話轉接
+service.gui.AUTO_ANSWER_FWD_CALLS_TO=è½‰æŽ¥æ‰€æœ‰é€šè©±åˆ°ä¸‹åˆ—è™Ÿç¢¼æˆ–ç¶²å€ (URI):
+service.gui.AUTO_ANSWER_VIDEO=視訊
+service.gui.AUTO_ANSWER_VIDEO_CALLS_WITH_VIDEO=用視訊接è½è¦–訊通話
+service.gui.LOCAL_VIDEO_ERROR_TITLE=本地端視訊錯誤
+service.gui.LOCAL_VIDEO_ERROR_MESSAGE=啟用/ç¦ç”¨æœ¬åœ°ç«¯è¦–訊失敗。
+
+service.gui.security.SECURE_AUDIO=加密音頻
+service.gui.security.AUDIO_NOT_SECURED=音訊未加密
+service.gui.security.SECURE_VIDEO=加密視訊
+service.gui.security.VIDEO_NOT_SECURED=視訊未加密
+service.gui.security.CALL_SECURED_TOOLTIP=通話已加密。更多詳情請點擊這裡。
+service.gui.security.CALL_NOT_SECURED_TOOLTIP=通話未加密
+service.gui.security.CALL_SECURED_COMPARE_TOOLTIP=點擊這裡與å°æ–¹æ ¸å°å®‰å…¨å¯†ç¢¼ã€‚
# keep the following string short
-
+service.gui.security.COMPARE_WITH_PARTNER_SHORT=請與åƒèˆ‡è€…進行字串比å°ï¼š
+service.gui.security.STRING_COMPARED=字串比å°æˆåŠŸï¼
+service.gui.security.SAS_INFO_TOOLTIP=<html>為了完æˆåŠ å¯†ï¼Œæ‚¨éœ€è¦<b>å£é ­è®€å‡º</b>å°æ–¹æ供的一å°æ®µèº«ä»½é©—證文字,通éŽé©—證後æ‰èƒ½ç¹¼çºŒé€šè©±ã€‚<br/><br/>如果您清除了這æ¢ç¢ºèªè¨Šæ¯ï¼Œä¸‹æ¬¡æ‚¨ä»å°‡è¢«è¦æ±‚é‡æ–°é©—證。</html>
+service.gui.security.SECURITY_ALERT=嘗試啟動加密通話,å³å°‡é‡æ–°é€£ç·šã€‚
+
+service.gui.avatar.CHOOSE_ICON=é¸æ“‡åœ–片
+service.gui.avatar.REMOVE_ICON=刪除這張圖片
+service.gui.avatar.CLEAR_RECENT=清除最近使用圖片:
+service.gui.avatar.RECENT_ICONS=最近使用圖片:
# service.gui.avatar.imagepicker
+service.gui.avatar.imagepicker.CANCEL=å–消
+service.gui.avatar.imagepicker.CHOOSE_FILE=é¸æ“‡...
+service.gui.avatar.imagepicker.CLICK=按一下,然後微笑 ^_^
+service.gui.avatar.imagepicker.IMAGE_FILES=圖片檔案
+service.gui.avatar.imagepicker.IMAGE_PICKER=圖片
+service.gui.avatar.imagepicker.IMAGE_SIZE=圖片大å°
+service.gui.avatar.imagepicker.RESET=é‡ç½®
+service.gui.avatar.imagepicker.SET=設定
+service.gui.avatar.imagepicker.TAKE_PHOTO=æ‹ç…§
+service.gui.security.encryption.required=必須加密ï¼
+service.protocol.ICE_FAILED=無法建立連線(ICE失敗,找ä¸åˆ°ä¸­ç¹¼å™¨ï¼‰
-# impl.protocol.ssh
-#Contact Details Seperator(must not be part of contact data stored as persistent
-# data)
+impl.protocol.sip.XCAP_ERROR_TITLE=SIP通訊錄存儲錯誤
+impl.protocol.sip.XCAP_ERROR_RESOURCE_ERR={1} çš„è³‡æº {0} 無法讀å–。
+impl.protocol.sip.XCAP_ERROR_UNAUTHORIZED={0} 用於 XCAP 的使用者å稱或密碼錯誤。
# systray
+impl.systray.SET_STATUS=設定狀態
+impl.systray.FAILED_TO_OPEN_ADD_CONTACT_DIALOG=開啟「新增è¯çµ¡äººã€ç²¾éˆå¤±æ•—。
+impl.systray.POPUP_MESSAGE_HANDLER=工作列冒泡æ示訊æ¯
+impl.swingnotification.POPUP_MESSAGE_HANDLER={0} 彈出視窗
+impl.growlnotification.POPUP_MESSAGE_HANDLER=è²éŸ³æ醒
+impl.galagonotification.POPUP_MESSAGE_HANDLER=freedesktop.org æ¡Œé¢æ醒
# New Account Dialog
+impl.gui.main.account.DEFAULT_PAGE_TITLE=帳號新增精éˆ
+impl.gui.main.account.DEFAULT_PAGE_BODY=您å¯åˆ©ç”¨ä¸Šè¿°æ¸…單來é¸æ“‡æ‚¨æƒ³è¦æ–°å¢žå¸³è™Ÿçš„網路。
+impl.gui.main.account.DUMMY_PROTOCOL_NAME=虛擬通訊å”定å稱
+impl.gui.main.account.DUMMY_PROTOCOL_DESCRIPTION=é¸æ“‡ç¶²è·¯
# LDAP
+impl.ldap.CONFIG_FORM_TITLE=LDAP 設定
+impl.ldap.GENERAL=通用
+impl.ldap.FIELDS=欄ä½
+impl.ldap.QUERY=查詢
+impl.ldap.QUERY_DEFAULT=自動建立
+impl.ldap.QUERY_CUSTOM=自定義查詢
+impl.ldap.QUERY_CUSTOM_HINT=使用 {0} 作為æœå°‹æ¢ä»¶ç•¶ä¸­çš„ä½ç½®æ¨™èªŒç¬¦è™Ÿã€‚
+impl.ldap.QUERY_CUSTOM_AUTO_WILDCARD=在æœå°‹æ¢ä»¶ç•¶ä¸­è‡ªå‹•è£œä¸Šé€šé…字符。
+impl.ldap.QUERY_PHOTO_INLINE=經由其他屬性ç²å–圖片
+impl.ldap.EDIT=編輯
+impl.ldap.ENABLED=啟用
+impl.ldap.SERVER_NAME=伺æœå™¨å稱
+impl.ldap.SERVER_NAME_EXAMPLE=我的 LDAP 伺æœå™¨
+impl.ldap.SERVER_HOSTNAME=主機å稱
+impl.ldap.SERVER_EXIST=該伺æœå™¨å稱已存在,請é‡æ–°å‘½å。
+impl.ldap.USE_SSL=使用 SSL
+impl.ldap.AUTH_NONE=沒有
+impl.ldap.AUTH_SIMPLE=簡易
+impl.ldap.SCOPE_SUB_TREE=å­ç¯€é»ž
+impl.ldap.SCOPE_ONE=一個
+impl.ldap.SAVE=存檔
+impl.ldap.CANCEL=å–消
+impl.ldap.SERVER_PORT=通訊埠
+impl.ldap.AUTHENTICATION=身份驗證
+impl.ldap.USERNAME=使用者å稱 (Bind DN)
+impl.ldap.PASSWORD=密碼
+impl.ldap.SEARCH_BASE=æœå°‹ç¯„åœ
+impl.ldap.SCOPE=範åœ
+impl.ldap.WRONG_CREDENTIALS=LDAP 目錄æœå‹™ {0} 驗證錯誤 (Wrong credentials)
+impl.ldap.MAIL_FIELD_NAME=é›»å­éƒµä»¶æ¬„ä½
+impl.ldap.MAILSUFFIX_FIELD_NAME=é›»å­éƒµä»¶å¾Œç¶´æ¬„ä½
+impl.ldap.WORKPHONE_FIELD_NAME=工作電話欄ä½
+impl.ldap.MOBILEPHONE_FIELD_NAME=移動電話欄ä½
+impl.ldap.HOMEPHONE_FIELD_NAME=ä½å®¶é›»è©±æ¬„ä½
+impl.ldap.MAIL_FIELD_EXAMPLE=é›»å­éƒµä»¶
+impl.ldap.MAILSUFFIX_FIELD_EXAMPLE=@domain.org (別忘了加上 '@')
+impl.ldap.WORKPHONE_FIELD_EXAMPLE=å…¬å¸é›»è©±
+impl.ldap.MOBILEPHONE_FIELD_EXAMPLE=行動電話
+impl.ldap.HOMEPHONE_FIELD_EXAMPLE=ä½å®¶é›»è©±
+impl.ldap.PHONE_PREFIX=國際電話碼
+impl.ldap.PHONE_PREFIX_EXAMPLE=例如 00
+
+# SIP Protocol
+impl.protocol.sip.INVALID_ADDRESS="{0}" ä¸æ˜¯ä¸€å€‹æœ‰æ•ˆçš„ SIP 地å€ã€‚
+
+#Jabber Protocol
+impl.protocol.jabber.INVALID_ADDRESS="{0}" ä¸æ˜¯ä¸€å€‹æœ‰æ•ˆçš„ XMPP JID。
# Address book plugin
+plugin.addrbook.ADDRESS_BOOKS=通訊錄
+plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK=å…許æœå°‹ MacOS X 通訊錄
+plugin.addrbook.ENABLE_MICROSOFT_OUTLOOK=å…許æœå°‹ Microsoft Outlook
+plugin.addrbook.DESCRIPTION=若啟用本功能,您於æœå°‹æ¡†è¼¸å…¥çš„文字會åŒæ™‚在線上和本機通訊錄進行æœå°‹ï¼Œæ‰€æœ‰ç¬¦åˆæ¢ä»¶çš„è¯çµ¡äººéƒ½èƒ½å¤ è¢«æ‰¾å‡ºä¾†ã€‚
+plugin.addrbook.DEFAULT_IM_APP=以 Jitsi 作為é è¨­çš„å³æ™‚通訊商 (與 Outlook æ•´åˆ)
+plugin.addrbook.PREFIX=國際電話冠碼
+plugin.addrbook.PREFIX_EXAMPLE=例如 00
+plugin.addrbook.OUTLOOK_IS_NOT_DEFAULT_MAIL_CLIENT_TITLE=å­˜å–您的 Microsoft Outlook è¯çµ¡äººç™¼ç”ŸéŒ¯èª¤ã€‚
+plugin.addrbook.OUTLOOK_IS_NOT_DEFAULT_MAIL_CLIENT={0} ç›®å‰ç„¡æ³•è¨ªå•æ‚¨çš„Microsoft Outlookè¯çµ¡äººï¼Œå› ç‚ºOutlookä¸æ˜¯æ‚¨çš„é è¨­é›»å­éƒµä»¶æ‡‰ç”¨ç¨‹å¼ã€‚
+plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT=使用 Outlook åšç‚ºé è¨­é›»å­éƒµä»¶è»Ÿé«”
# Google Contacts
+impl.googlecontacts.CONFIG_FORM_TITLE=Google è¯çµ¡äºº
+impl.googlecontacts.EDIT=編輯
+impl.googlecontacts.ENABLED=啟用
+impl.googlecontacts.ACCOUNT_NAME=帳號å稱
+impl.googlecontacts.SAVE=存檔
+impl.googlecontacts.CANCEL=å–消
+impl.googlecontacts.USERNAME=帳號å稱
+impl.googlecontacts.PASSWORD=密碼
+impl.googlecontacts.PREFIX=電話å€è™Ÿ
+impl.googlecontacts.WRONG_CREDENTIALS=Google 帳號 {0} 驗證錯誤
+impl.googlecontacts.OAUTH_DIALOG_TITLE=Google 通訊錄授權
+impl.googlecontacts.INSTRUCTIONS=<html><p><b> 點擊如下éˆæŽ¥ä»¥æŽˆæ¬Š Google 通訊錄外掛訪å•æ‚¨çš„帳戶。</b><br><br> 點擊此éˆæŽ¥å¾Œï¼Œæ‚¨çš„ç€è¦½å™¨å°±æœƒé–‹å•Ÿã€‚請您登入指定的帳號並完æˆæŽˆæ¬Šã€‚在æˆåŠŸæŽˆæ¬Šå¾Œï¼ŒGoogle 會æ供一串代碼。請複製這串代碼並粘貼到下é¢çš„文字å°è©±æ¡†ï¼Œç„¶å¾Œé»žæ“Šã€Œä¿å­˜ã€ã€‚ </p><p>本æ“作åªéœ€é€²è¡Œä¸€æ¬¡ï¼Œå¾€å¾Œä¸å¿…å覆授權。</html>
+impl.googlecontacts.CODE=代碼:
+impl.googlecontacts.HYPERLINK_TEXT=點擊這裡以å…è¨±è¨ªå• {0} 的授權請求
# account info
+plugin.accountinfo.TITLE=帳號訊æ¯
+plugin.accountinfo.EXTENDED=延伸訊æ¯
+plugin.accountinfo.NOT_SUPPORTED=無法ç²å–帳號訊æ¯ã€‚
+plugin.accountinfo.SELECT_ACCOUNT=è«‹é¸æ“‡ä¸€å€‹å¸³è™Ÿï¼š
+plugin.accountinfo.DISPLAY_NAME=顯示å稱:
+plugin.accountinfo.FIRST_NAME=å字:
+plugin.accountinfo.MIDDLE_NAME=字/號:
+plugin.accountinfo.LAST_NAME=姓æ°ï¼š
+plugin.accountinfo.NICKNAME=暱稱:
+plugin.accountinfo.URL=網å€(URL):
+plugin.accountinfo.AGE=年齡:
+plugin.accountinfo.BDAY=生日:
+plugin.accountinfo.BDAY_FORMAT=MMM月dd日, yyyy西元年
+plugin.accountinfo.GENDER=性別:
+plugin.accountinfo.STREET=è¡—é“地å€ï¼š
+plugin.accountinfo.CITY=城市:
+plugin.accountinfo.REGION=地å€ï¼š
+plugin.accountinfo.POST=郵éžå€è™Ÿï¼š
+plugin.accountinfo.COUNTRY=國家:
+plugin.accountinfo.EMAIL=E-mail:
+plugin.accountinfo.WORK_EMAIL=å…¬å¸ Email:
+plugin.accountinfo.PHONE=電話:
+plugin.accountinfo.WORK_PHONE=å…¬å¸é›»è©±ï¼š
+plugin.accountinfo.MOBILE_PHONE=行動電話:
+plugin.accountinfo.ORGANIZATION=組織å稱:
+plugin.accountinfo.JOB_TITLE=è·ç¨±ï¼š
+plugin.accountinfo.ABOUT_ME=關於我:
+plugin.accountinfo.ABOUT_ME_MAX_CHARACTERS=200
+plugin.accountinfo.GLOBAL_ICON=使用全域圖標
+plugin.accountinfo.LOCAL_ICON=使用此圖標:
# connection info
+plugin.connectioninfo.TITLE=連接訊æ¯
# contact info
+plugin.contactinfo.TITLE=è¯çµ¡äººè©³æƒ…
+plugin.contactinfo.CONTACT_SUMMARY_DESCRIPTION=è¯çµ¡äººæ‘˜è¦
+plugin.contactinfo.CONTACT_EXTENDED_DESCRIPTION=è¯çµ¡äººå‚™è¨»
+plugin.contactinfo.NOT_SPECIFIED=[未指定]
+plugin.contactinfo.USER_PICTURES=大頭照
+plugin.contactinfo.USER_STATUS_MESSAGE=狀態
# aimaccregwizz
+plugin.aimaccregwizz.PROTOCOL_NAME=AIM
+plugin.aimaccregwizz.PROTOCOL_DESCRIPTION=AIMæœå‹™é€šè¨Šå”定
+plugin.aimaccregwizz.USERNAME=AIMå³æ™‚通暱稱:
+plugin.aimaccregwizz.USERNAME_AND_PASSWORD=AIM å³æ™‚通暱稱和密碼
+plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT=註冊新帳號
+plugin.aimaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=如果您沒有 AIM 帳號,å¯é»žæ“Šé€™å€‹æŒ‰éˆ•è¨»å†Šä¸€å€‹æ–°å¸³è™Ÿã€‚
# branding
+plugin.branding.ABOUT_WINDOW_TITLE=關於 {0}
+plugin.branding.LOGO_MESSAGE=開放æºç¢¼ VoIP 以åŠå³æ™‚通訊
+plugin.branding.ABOUT_MENU_ENTRY=關於
-# Dict protocol
-
-# facebookaccregwizz
+plugin.busylampfield.PICKUP=接è½é€šè©±
# generalconfig
+plugin.generalconfig.AUTO_START=開機或é‡å•Ÿæ™‚自動é‹è¡Œ {0}
+plugin.generalconfig.CHATALERTS_ON_MESSAGE=以工作列圖標æ醒來電
+plugin.generalconfig.GROUP_CHAT_MESSAGES=集中èŠå¤©è¨Šæ¯åˆ°åŒä¸€å€‹è¦–窗
+plugin.generalconfig.LOG_HISTORY=ä¿å­˜èŠå¤©è¨˜éŒ„
+plugin.generalconfig.SHOW_HISTORY=顯示
+plugin.generalconfig.HISTORY_SIZE=最近的èŠå¤©è¨Šæ¯
+plugin.generalconfig.SEND_MESSAGES_WITH=發é€è¨Šæ¯ç¶“由:
+plugin.generalconfig.BRING_WINDOW_TO_FRONT=å°‡èŠå¤©è¦–窗ä¿æŒåœ¨æœ€ä¸Šå±¤
+plugin.generalconfig.DEFAULT_LANGUAGE=介é¢èªžè¨€
+plugin.generalconfig.DEFAULT_LANGUAGE_RESTART_WARN=您的設定將在下次啟動時生效。
+plugin.generalconfig.DEFAULT_LANGUAGE_TRANSLATED={0}% 已翻譯
+plugin.generalconfig.SIP_CLIENT_PORT=SIP 客戶端通訊埠
+plugin.generalconfig.SIP_CLIENT_SECURE_PORT=SIP 客戶端加密通訊埠
+plugin.generalconfig.SIP_SSL_PROTOCOLS=啟用 SSL/TLS 通訊å”定
+plugin.generalconfig.ERROR_PORT_NUMBER=錯誤的通訊埠號
+plugin.generalconfig.CHECK_FOR_UPDATES=啟動時檢查更新
+plugin.generalconfig.STARTUP_CONFIG=å•Ÿå‹•
+plugin.generalconfig.LEAVE_CHATROOM_ON_WINDOW_CLOSE=關閉視窗時退出èŠå¤©å®¤
+plugin.generalconfig.SHOW_RECENT_MESSAGES=顯示最近的å°è©±ï¼ˆä¾èŠå¤©è¨˜éŒ„)
+plugin.generalconfig.REMOVE_SPECIAL_PHONE_SYMBOLS=撥號å‰åˆªé™¤é›»è©±è™Ÿç¢¼ä¸­çš„特殊符號
+plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS=轉æ›é›»è©±è™Ÿç¢¼ä¸­çš„英文字æ¯
+plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS_EXAMPLE=例如 +1-800-MYPHONE -> +1-800-6974663
+plugin.generalconfig.SIP_CALL_CONFIG=SIP
+plugin.generalconfig.XMPP_CONFIG=XMPP
+plugin.generalconfig.XMPP_USE_ALL_RESOURCES=æœå°‹è¯çµ¡äººæ™‚使用所有資æº
+plugin.generalconfig.OPUS_CONFIG=Opus
+plugin.generalconfig.OPUS_AUDIO_BANDWIDTH=採樣率:
+plugin.generalconfig.OPUS_BITRATE=編碼器平å‡ä½å…ƒå‚³è¼¸çŽ‡(kbps):
+plugin.generalconfig.OPUS_USE_DTX=使用 DTX:
+plugin.generalconfig.OPUS_USE_FEC=使用 Inband FEC:
+plugin.generalconfig.OPUS_COMPLEXITY=編碼器複雜度:
+plugin.generalconfig.OPUS_MIN_EXPECTED_PACKET_LOSS=最低é æœŸä¸ŸåŒ…率(%):
+plugin.generalconfig.SILK_CONFIG=Silk
+plugin.generalconfig.SILK_USE_FEC=使用 Inband FEC:
+plugin.generalconfig.SILK_ALWAYS_ASSUME_PACKET_LOSS=始終å‡è¨­ä¸ŸåŒ…:
+plugin.generalconfig.SILK_SAT=語音活性閾值(0-1):
+plugin.generalconfig.SILK_ADVERTISE_FEC=SDP 支æ´çš„ FEC 宣告:
+plugin.generalconfig.RESTORE=æ¢å¾©é è¨­å€¼
# gibberish accregwizz
+plugin.gibberishaccregwizz.PROTOCOL_NAME=胡言亂語
+plugin.gibberishaccregwizz.PROTOCOL_DESCRIPTION=Jitsi 測試通訊å”定
+plugin.gibberishaccregwizz.USERNAME=使用者ID:
+plugin.gibberishaccregwizz.USERNAME_AND_PASSWORD=ID 設定
# icqaccregwizz
+plugin.icqaccregwizz.PROTOCOL_NAME=ICQ
+plugin.icqaccregwizz.PROTOCOL_DESCRIPTION=AOL ICQ æœå‹™é€šè¨Šå”定
+plugin.icqaccregwizz.USERNAME=ICQ 號碼:
+plugin.icqaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=如果您沒有 ICQ 帳號,å¯é»žæ“Šé€™å€‹æŒ‰éˆ•è¨»å†Šä¸€å€‹æ–°å¸³è™Ÿã€‚
+plugin.icqaccregwizz.REGISTER_NEW_ACCOUNT=建立新帳號
# irc accregwizz
+plugin.ircaccregwizz.PROTOCOL_NAME=IRC
+plugin.ircaccregwizz.PROTOCOL_DESCRIPTION=IRC 通訊å”定
+plugin.ircaccregwizz.USERNAME_AND_PASSWORD=IRC 使用者å稱 (UIN) 和密碼
+plugin.ircaccregwizz.USERNAME=暱稱
+plugin.ircaccregwizz.EXAMPLE_USERNAME=例如:ircuser
+plugin.ircaccregwizz.INFO_PASSWORD=大部分 IRC 伺æœå™¨ä¸éœ€è¦å¯†ç¢¼ã€‚
+plugin.ircaccregwizz.AUTO_NICK_CHANGE=當該暱稱已被佔用時,自動é¸æ“‡æš±ç¨±ã€‚
+plugin.ircaccregwizz.USE_DEFAULT_PORT=使用é è¨­é€šè¨ŠåŸ 
+plugin.ircaccregwizz.PASSWORD_NOT_REQUIRED=我的暱稱ä¸éœ€è¦èº«ä»½æ ¡é©—
+plugin.ircaccregwizz.HOST=主機å稱:
+plugin.ircaccregwizz.IRC_SERVER=伺æœå™¨
+plugin.ircaccregwizz.EXAMPLE_SERVER=例如:chat.freenode.net
+plugin.ircaccregwizz.USE_SECURE_CONNECTION=使用安全連接
+plugin.ircaccregwizz.ENABLE_CONTACT_PRESENCE=啟用è¯çµ¡äººåœ¨ç·šç‹€æ…‹
+plugin.ircaccregwizz.ENABLE_CHAT_ROOM_PRESENCE=啟用èŠå¤©å®¤åœ¨ç·šç‹€æ…‹
+plugin.ircaccregwizz.SASL_AUTHENTICATION_TITLE=SASL 身份驗證
+plugin.ircaccregwizz.ENABLE_SASL_AUTHENTICATION=啟用 SASL 身份驗證
+plugin.ircaccregwizz.SASL_USERNAME=使用者å稱
+plugin.ircaccregwizz.SASL_AUTHZ_ROLE=角色
+plugin.ircaccregwizz.SASL_IRC_PASSWORD_USED=以上的 IRC 密碼用於 SASL 身份驗證
+plugin.ircaccregwizz.RESOLVE_DNS_THROUGH_PROXY=總是使用代ç†é€²è¡ŒDNS解æž
# jabber accregwizz
-
-# mailbox
-
-# msn accregwizz
+plugin.jabberaccregwizz.PROTOCOL_NAME=XMPP
+plugin.jabberaccregwizz.PROTOCOL_DESCRIPTION=XMPP 通訊å”定
+plugin.jabberaccregwizz.USERNAME=XMPP 使用者å稱
+plugin.jabberaccregwizz.PASSWORD_CONFIRM=確èªå¯†ç¢¼
+plugin.jabberaccregwizz.CSERVER=伺æœå™¨
+plugin.jabberaccregwizz.SERVER=連接伺æœå™¨
+plugin.jabberaccregwizz.ENABLE_KEEP_ALIVE=å…許ä¿æŒé€£ç·š
+plugin.jabberaccregwizz.ENABLE_GMAIL_NOTIFICATIONS=有新訊æ¯æ™‚經由 Gmail æ醒
+plugin.jabberaccregwizz.ENABLE_GOOGLE_CONTACTS_SOURCE=å…許æœå°‹ Google è¯çµ¡äºº
+plugin.jabberaccregwizz.NEW_ACCOUNT_TITLE=註冊新的 XMPP 帳號
+plugin.jabberaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=建立新的 XMPP 帳號
+plugin.jabberaccregwizz.CHOOSE_SERVER_TITLE=XMPP 新帳號伺æœå™¨é¸æ“‡å™¨
+plugin.jabberaccregwizz.CHOOSE_SERVER_TEXT=從以下列表é¸æ“‡è¦å»ºç«‹å¸³è™Ÿçš„ XMPP 伺æœå™¨
+plugin.jabberaccregwizz.CHOOSE=é¸æ“‡
+plugin.jabberaccregwizz.SERVER_COLUMN=伺æœå™¨
+plugin.jabberaccregwizz.COMMENT_COLUMN=è©•è«–
+plugin.jabberaccregwizz.RESOURCE=資æº
+plugin.jabberaccregwizz.AUTORESOURCE=自動生æˆè³‡æºå稱
+plugin.jabberaccregwizz.PRIORITY=優先等級
+plugin.jabberaccregwizz.UNKNOWN_XMPP_ERROR=ä¸èªè­˜çš„ XMPP 錯誤 ({0}):請確èªä¼ºæœå™¨åœ°å€æ˜¯å¦æ­£ç¢ºã€‚
+plugin.jabberaccregwizz.NOT_SAME_PASSWORD=密碼ä¸ç›¸ç¬¦ã€‚
+plugin.jabberaccregwizz.USE_ICE=使用 ICE
+plugin.jabberaccregwizz.AUTO_DISCOVER_STUN=自動檢測 STUN/TURN 伺æœå™¨
+plugin.jabberaccregwizz.SUPPORT_TURN=æ”¯æ´ TURN
+plugin.jabberaccregwizz.TURN_USERNAME=TURN 使用者å稱
+plugin.jabberaccregwizz.IP_ADDRESS=IP 地å€
+plugin.jabberaccregwizz.ADD_STUN_SERVER=新增 STUN 伺æœå™¨
+plugin.jabberaccregwizz.EDIT_STUN_SERVER=編輯 STUN 伺æœå™¨
+plugin.jabberaccregwizz.ADDITIONAL_STUN_SERVERS=更多 STUN 伺æœå™¨
+plugin.jabberaccregwizz.NO_STUN_ADDRESS=請填寫åˆæ³•çš„ STUN 伺æœå™¨åœ°å€å†é€²è¡Œä¸‹ä¸€æ­¥ã€‚
+plugin.jabberaccregwizz.NO_STUN_USERNAME=請填寫åˆæ³•çš„ STUN 伺æœå™¨ä½¿ç”¨è€…å稱å†é€²è¡Œä¸‹ä¸€æ­¥ã€‚
+plugin.jabberaccregwizz.STUN_ALREADY_EXIST=該 STUN 伺æœå™¨å·²å­˜åœ¨
+plugin.jabberaccregwizz.USE_DEFAULT_STUN_SERVER=若是沒有å¯ç”¨çš„ STUN 伺æœå™¨ï¼Œå‰‡ä½¿ç”¨ {0} 作為é è¨­çš„ STUN 伺æœå™¨ã€‚
+plugin.jabberaccregwizz.USE_JINGLE_NODES=使用 Jingle Nodes
+plugin.jabberaccregwizz.AUTO_DISCOVER_JN=自動檢測 Jingle Nodes 中繼
+plugin.jabberaccregwizz.RELAY_SUPPORT=支æ´ä¸­ç¹¼ (relay)
+plugin.jabberaccregwizz.ADD_JINGLE_NODE=新增 Jingle Node
+plugin.jabberaccregwizz.EDIT_JINGLE_NODE=編輯 JINGLE NODE
+plugin.jabberaccregwizz.JID_ADDRESS=JID 地å€
+plugin.jabberaccregwizz.ADDITIONAL_JINGLE_NODES=更多 JINGLE NODES
+plugin.jabberaccregwizz.USE_UPNP=啟用 UPnP
+plugin.jabberaccregwizz.EXISTING_ACCOUNT=已新增的 XMPP 帳號
+plugin.jabberaccregwizz.DOMAIN_BYPASS_CAPS=將使用 GTalk 通話域
+plugin.jabberaccregwizz.TELEPHONY_DOMAIN=語音通話域
+plugin.jabberaccregwizz.ALLOW_NON_SECURE=å…許éžå®‰å…¨é€£ç·š
+plugin.jabberaccregwizz.DISABLE_CARBON=ç¦æ­¢è¨Šæ¯è¤‡è£½
+plugin.jabberaccregwizz.DTMF_AUTO=自動:自動é¸æ“‡ RTP 或 Inband
+plugin.jabberaccregwizz.SERVER_OPTIONS=伺æœå™¨é¸é …
+plugin.jabberaccregwizz.CHANGE_PASSWORD=更改帳號密碼
+plugin.jabberaccregwizz.PORT_FIELD_INVALID=請填入一個å¯ç”¨çš„通訊埠號碼,然後進行下一步。
+plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN=變更密碼å‰ï¼Œå¿…須先登入該帳號。
+plugin.jabberaccregwizz.TLS_REQUIRED=該連線未使用 TLS,ä¸æœƒå˜—試變更密碼。
+plugin.jabberaccregwizz.PASSWORD_CHANGED=密碼變更æˆåŠŸ
+plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE=您的 XMPP 伺æœå™¨ä¸æ”¯æ´å¯†ç¢¼è®Šæ›´ã€‚
+plugin.jabberaccregwizz.PASSWORD_NOT_STORED=密碼在伺æœå™¨ä¸Šå·²è®Šæ›´ï¼Œä½†æ˜¯æœ¬åœ°è¨­å®šæ²’有更新。
+plugin.jabberaccregwizz.ENTER_NEW_PASSWORD=è«‹åŒæ™‚在兩個輸入框中輸入新密碼:
+plugin.jabberaccregwizz.OVERRIDE_ENCODINGS=é‡è¼‰å…¨åŸŸç·¨ç¢¼è¨­å®š
+plugin.jabberaccregwizz.ENCODINGS=編碼
+plugin.jabberaccregwizz.AUDIO=音訊
+plugin.jabberaccregwizz.VIDEO=視訊
+plugin.jabberaccregwizz.RESET=é‡ç½®
+plugin.jabberaccregwizz.RESET_DESCRIPTION=é‡ç½®å…¨åŸŸè¨­å®š
+plugin.jabberaccregwizz.DISABLE_JINGLE=ç¦ç”¨ Jingle (XMPP 音訊和視訊呼å«)
# plugin manager
+plugin.pluginmanager.INSTALL=安è£
+plugin.pluginmanager.UNINSTALL=解除安è£
+plugin.pluginmanager.PLUGINS=外掛
+plugin.pluginmanager.URL=網å€
+plugin.pluginmanager.CHOOSE_FILE=é¸å–檔案
+plugin.pluginmanager.SHOW_SYSTEM_BUNDLES=顯示系統外掛
+plugin.pluginmanager.SYSTEM=系統
+plugin.pluginmanager.NEW=新建
# simple accregwizz
+plugin.simpleaccregwizz.LOGIN_USERNAME=使用者å稱
+plugin.simpleaccregwizz.INITIAL_ACCOUNT_REGISTRATION=åªéœ€é»žæ“Šä¸€æ¬¡å°±èƒ½è¨­å®šæ‰€æœ‰æ‚¨å好的通訊å”定。
+plugin.simpleaccregwizz.SIGNUP=還沒註冊帳號?
+plugin.simpleaccregwizz.SPECIAL_SIGNUP=還沒註冊帳號? - 點擊這裡ç²å–使用者å稱
# sipaccregwizz
+plugin.sipaccregwizz.PROTOCOL_NAME=SIP
+plugin.sipaccregwizz.PROTOCOL_DESCRIPTION=SIP 通訊å”定
+plugin.sipaccregwizz.USERNAME=SIP ID
+plugin.sipaccregwizz.USERNAME_AND_PASSWORD=帳號和密碼
+plugin.sipaccregwizz.CLIENT_CERTIFICATE=客戶 TLS 憑證
+plugin.sipaccregwizz.REGISTRAR=註冊
+plugin.sipaccregwizz.SERVER_PORT=伺æœå™¨é€šè¨ŠåŸ 
+plugin.sipaccregwizz.PROXY=代ç†ä¼ºæœå™¨
+plugin.sipaccregwizz.PROXY_PORT=代ç†é€šè¨ŠåŸ 
+plugin.sipaccregwizz.PREFERRED_TRANSPORT=首é¸å‚³è¼¸æ–¹å¼
+plugin.sipaccregwizz.PROXY_OPTIONS=代ç†é¸é …
+plugin.sipaccregwizz.PROXY_AUTO=自動設定代ç†ä¼ºæœå™¨
+plugin.sipaccregwizz.PROXY_FORCE_BYPASS=在 HA 的情æ³ä¸‹è·³éŽä»£ç†å®‰å…¨æª¢æŸ¥ï¼ˆè«‹åƒ…在需è¦æ™‚使用)
+plugin.sipaccregwizz.ENABLE_PRESENCE=å…許出席 (簡易)
+plugin.sipaccregwizz.FORCE_P2P_PRESENCE=強制使用 P2P 出席模å¼
+plugin.sipaccregwizz.OFFLINE_CONTACT_POLLING_PERIOD=離線è¯çµ¡äººæ‹‰å–é–“éš” (å–®ä½ï¼šç§’)
+plugin.sipaccregwizz.SUBSCRIPTION_EXPIRATION=é è¨­è¨‚閱周期 (å–®ä½ï¼šç§’)
+plugin.sipaccregwizz.PRESENCE_OPTIONS=出席é¸é …
+plugin.sipaccregwizz.KEEP_ALIVE=ä¿æŒé€£ç·š
+plugin.sipaccregwizz.KEEP_ALIVE_METHOD=ä¿æŒé€£ç·šæ–¹å¼
+plugin.sipaccregwizz.KEEP_ALIVE_INTERVAL=ä¿æŒé€£æŽ¥è‡ªå‹•è§¸ç™¼é–“隔時間
+plugin.sipaccregwizz.KEEP_ALIVE_INTERVAL_INFO=1 到 3600 秒
+plugin.sipaccregwizz.DTMF_MINIMAL_TONE_DURATION=æœ€å° RTP DTMF 校正周期(ms)
+plugin.sipaccregwizz.DTMF_MINIMAL_TONE_DURATION_INFO=é è¨­ RTP DTMF 周期是 70ms
+plugin.sipaccregwizz.DTMF=DTMF
+plugin.sipaccregwizz.DTMF_METHOD=DTMF æ–¹å¼
+plugin.sipaccregwizz.DTMF_AUTO=自動:從 RTP å’Œ Inband (ç„¡SIP訊æ¯) 自動é¸æ“‡
+plugin.sipaccregwizz.DTMF_RTP=RTP ( RFC2833 / RFC 4733 )
+plugin.sipaccregwizz.DTMF_SIP_INFO=SIP 訊æ¯
+plugin.sipaccregwizz.DTMF_INBAND=Inband
+plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=啟用支æ´åŠ å¯†é€šè©±
+plugin.sipaccregwizz.ENABLE_SIPZRTP_ATTRIBUTE=è¡¨ç¤ºæ”¯æ´ ZRTP 的信號通訊å”定
+plugin.sipaccregwizz.AUTH_NAME=授權å稱
+plugin.sipaccregwizz.DISPLAY_NAME=顯示å稱
+plugin.sipaccregwizz.EXISTING_ACCOUNT=已新增的 SIP 帳號
+plugin.sipaccregwizz.CREATE_ACCOUNT=建立å…費的 SIP 帳號
+plugin.sipaccregwizz.CREATE_ACCOUNT_TITLE=建立帳號
+plugin.sipaccregwizz.XCAP_OPTIONS=通訊錄é¸é …
+plugin.sipaccregwizz.CLIST_TYPE=é¡žåž‹
+plugin.sipaccregwizz.XCAP_USE_SIP_CREDENTIALS=使用 SIP èªè­‰
+plugin.sipaccregwizz.XCAP_USER=使用者
+plugin.sipaccregwizz.XCAP_PASSWORD=密碼
+plugin.sipaccregwizz.XCAP_SERVER_URI=伺æœå™¨ç¶²å€ (URI) 或 IP 地å€
+plugin.sipaccregwizz.VOICEMAIL=語音信箱
+plugin.sipaccregwizz.MWI=留言等待 (MWI)
+plugin.sipaccregwizz.VOICEMAIL_URI=èªžéŸ³ä¿¡ç®±è¨‚é–±ç¶²å€ (URI)
+plugin.sipaccregwizz.VOICEMAIL_CHECK_URI=èªžéŸ³ä¿¡ç®±æŸ¥é–±ç¶²å€ (URI)
+plugin.sipaccregwizz.NOT_SAME_PASSWORD=您的密碼ä¸ç›¸ç¬¦ã€‚
+plugin.sipaccregwizz.NO_CERTIFICATE=<none>(使用一般身份驗證)
+plugin.sipaccregwizz.SAVP_OPTION=RTP/SAVP 標示
+#used from SecurityPanel
+plugin.sipaccregwizz.SAVP_OPTION_0=關閉 (åªç”¨ RTP/AVP)
+plugin.sipaccregwizz.SAVP_OPTION_1=強制 (åªç”¨ RTP/SAVP)
+plugin.sipaccregwizz.SAVP_OPTION_2=å¯é¸ (先用 RTP/SAVP,然後æ‰ç”¨ RTP/AVP)
+plugin.sipaccregwizz.ENCRYPTION_PROTOCOL_PREFERENCES=é¸æ“‡å•Ÿç”¨åŠ å¯†é€šè¨Šå”å®šå’Œå®ƒå€‘çš„å„ªå…ˆé †åº (頂端通訊å”定優先):
+plugin.sipaccregwizz.CIPHER_SUITES=啟用加密套件:
+plugin.sipaccregwizz.SECURITY_WARNING=<html><div width=450>{0} 會自動嘗試加密您的所有 ZRTP 通話,åŒæ™‚您會è½åˆ°å’Œçœ‹åˆ°ä¸€å€‹å®‰å…¨é€£ç·šå·²å°±ç·’çš„æ示。如果您已了解您正在åšä»€éº¼ï¼Œæ‚¨åƒ…需改變如下進階設定</div></html>
+plugin.sipaccregwizz.SHOW_ADVANCED=進階加密設定
+plugin.sipaccregwizz.ZRTP_OPTION=ZRTP é¸é …
+plugin.sipaccregwizz.SDES_OPTION=SDes é¸é …
# skin manager
-
-# ssh accregwizz
+plugin.skinmanager.SKINS=佈景主題
+plugin.skinmanager.DEFAULT_SKIN=é è¨­ä½ˆæ™¯ä¸»é¡Œ
+plugin.skinmanager.ADD_NEW_SKIN=新增佈景主題
+plugin.skinmanager.DEFAULT_SKIN_DESCRIPTION=é è¨­çš„佈景主題
# status update
+plugin.autoaway.AUTO_STATUS=自動切æ›åˆ°é›¢é–‹ç‹€æ…‹
+plugin.autoaway.ENABLE_CHANGE_STATUS=離開時更改狀態
+plugin.autoaway.AWAY_MINUTES=閒置幾分é˜è‡ªå‹•åˆ‡æ›åˆ°é›¢é–‹ç‹€æ…‹ï¼š
# updatechecker
+plugin.updatechecker.DIALOG_TITLE=安è£ç³»çµ±æ›´æ–°
+plugin.updatechecker.DIALOG_MESSAGE=<html>有更新的 {0} 版本å¯ä»¥ä¸‹è¼‰ã€‚
+plugin.updatechecker.DIALOG_MESSAGE_2=<br>{0} ({1}):<br>
+plugin.updatechecker.BUTTON_DOWNLOAD=下載
+plugin.updatechecker.BUTTON_CLOSE=關閉
+plugin.updatechecker.BUTTON_INSTALL=安è£
+plugin.updatechecker.UPDATE_MENU_ENTRY=檢查更新
+plugin.updatechecker.DIALOG_WARN=安è£æ›´æ–°å‰éœ€è¦ç™»å‡º {0} 帳號。所有通話將臨時中斷。您需è¦ç¹¼çºŒå®‰è£æ›´æ–°å—Žï¼Ÿ
+plugin.updatechecker.DIALOG_NOUPDATE=您的版本已經是最新的。
+plugin.updatechecker.DIALOG_NOUPDATE_TITLE=沒有更新的版本
+plugin.updatechecker.DIALOG_MISSING_UPDATE=找ä¸åˆ°æ›´æ–°ç®¡ç†å™¨ã€‚
# usersearch
+plugin.usersearch.USER_SEARCH=使用者æœå°‹
# whiteboard
-
-# yahoo accregwizz
-
-# zero accregwizz
+plugin.whiteboard.TITLE=ç™½æ¿ [Beta]
+plugin.whiteboard.MENU_ITEM=白æ¿
+plugin.whiteboard.NOT_SUPPORTED=該è¯çµ¡äººä¸æ”¯æ´ç™½æ¿
+plugin.whiteboard.DRAW=繪圖
+plugin.whiteboard.OPEN=é–‹å•Ÿ
+plugin.whiteboard.PEN=ç•«ç­†
+plugin.whiteboard.SELECT=é¸å–
+plugin.whiteboard.LINE=ç·šæ¢
+plugin.whiteboard.RECTANGLE=矩形
+plugin.whiteboard.FILLED_RECTANGLE=實心矩形
+plugin.whiteboard.TEXT=文字
+plugin.whiteboard.IMAGE=圖片
+plugin.whiteboard.POLYGON=多邊形
+plugin.whiteboard.FILLEDPOLYGON=實心多邊形
+plugin.whiteboard.POLYLINE=折線
+plugin.whiteboard.CIRCLE=圓形
+plugin.whiteboard.FILLED_CIRCLE=實心圓形
+plugin.whiteboard.COLOR=é¡è‰²
+plugin.whiteboard.MODIFICATION=修改
+plugin.whiteboard.THICKNESS=ç²—ç´°:
+plugin.whiteboard.GRID=格線
+plugin.whiteboard.DESELECT=å–消é¸å–
+plugin.whiteboard.DELETE=刪除
+plugin.whiteboard.PROPERTIES=屬性
# gtalk accregwizz
+plugin.googletalkaccregwizz.PROTOCOL_NAME=Google Talk
+plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION=GOOGLE TALK 通訊å”定
+plugin.googletalkaccregwizz.USERNAME=Google Talk 使用者å稱
+plugin.googletalkaccregwizz.REGISTER_NEW_ACCOUNT_TEXT=如果您沒有 Google Talk 帳號,å¯é»žæ“Šé€™å€‹æŒ‰éˆ•è¨»å†Šä¸€å€‹æ–°å¸³è™Ÿã€‚
+plugin.googletalkaccregwizz.NEW_ACCOUNT_TITLE=Google Talk 帳號註冊
# iptel accregwizz
-
-# sip2sip accregwizz
+plugin.iptelaccregwizz.PROTOCOL_NAME=iptel.org
+plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION=iptel.org,IP 電訊平å°
+plugin.iptelaccregwizz.USERNAME=使用者å稱
+plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE=訂閱 iptel.org
# ippi accregwizz
+plugin.sip2sipaccregwizz.USERNAME=使用者å稱
+plugin.sip2sipaccregwizz.RETYPE_PASSWORD=å†æ¬¡è¼¸å…¥å¯†ç¢¼
+plugin.sip2sipaccregwizz.EMAIL=Email 地å€
+plugin.sip2sipaccregwizz.EMAIL_NOTE=<html>這個 email 地å€å°‡è¢«ç”¨ä¾†ç™¼é€èªžéŸ³ç•™è¨€ã€<br>未接來電æ醒和é‡ç½®å¯†ç¢¼æœå‹™ã€‚</html>
+plugin.ippiaccregwizz.PROTOCOL_NAME=ippi
+plugin.ippiaccregwizz.PROTOCOL_DESCRIPTION=網路電話 (VoIP) 與å³æ™‚通訊
+plugin.ippiaccregwizz.NEW_ACCOUNT_TITLE=查閱本æœå‹™èªªæ˜Žï¼š<br>http://ippi.fr
+plugin.ippiaccregwizz.INFO_NOTE=<html>查閱本æœå‹™èªªæ˜Žï¼š<a href=''>http://ippi.fr</a></html>
+plugin.ippiaccregwizz.EXISTING_ACCOUNT=已建立的 ippi 帳號
+plugin.ippiaccregwizz.CREATE_ACCOUNT=å…費建立 ippi 帳號
# key binding chooser
+#in new ChatWindow() -> manipulated
+plugin.keybindings.CHAT_CLOSE=關閉èŠå¤©è¦–窗
+plugin.keybindings.CHAT_COPY=複製
+plugin.keybindings.CHAT_CUT=剪下
+plugin.keybindings.CHAT_NEXT_TAB=下一個標籤
+plugin.keybindings.CHAT_OPEN_HISTORY=é–‹å•Ÿæ­·å²è¨˜éŒ„
+plugin.keybindings.CHAT_OPEN_SMILIES=開啟表情
+plugin.keybindings.CHAT_PASTE=貼上
+plugin.keybindings.CHAT_PREVIOUS_TAB=上一個標籤
+plugin.keybindings.MAIN_NEXT_TAB=下一個標籤
+plugin.keybindings.MAIN_PREVIOUS_TAB=上一個標籤
+plugin.keybindings.MAIN_RENAME=é‡æ–°å‘½åè¯çµ¡äºº
+plugin.keybindings.OPEN_HISTORY=顯示èŠå¤©è¨˜éŒ„
+plugin.keybindings.OPEN_SMILIES=顯示表情
+plugin.keybindings.globalchooser.ANSWER_CALL=通話應答
+plugin.keybindings.globalchooser.HANGUP_CALL=通話掛斷
+plugin.keybindings.globalchooser.ANSWER_HANGUP_CALL=通話應答/掛斷
+plugin.keybindings.globalchooser.SHOW_CONTACTLIST=顯示通訊錄
+plugin.keybindings.globalchooser.MUTE_CALLS=通話éœéŸ³
+plugin.keybindings.globalchooser.SHORTCUT_NAME=å¿«æ·éµåŠŸèƒ½
+plugin.keybindings.globalchooser.SHORTCUT_PRIMARY=主è¦å¿«æ·éµ
+plugin.keybindings.globalchooser.SHORTCUT_SECOND=次è¦å¿«æ·éµ
+plugin.keybindings.globalchooser.PRESS_BTN=點擊設定快æ·éµ
+plugin.keybindings.globalchooser.PUSH_TO_TALK=按éµé€šè©± (Push to Talk)
+plugin.keybindings.globalchooser.ENABLE_SPECIAL=啟用特殊éµåµæ¸¬
+plugin.keybindings.PLUGIN_NAME=å¿«æ·éµ
+#Enum KeybindingSet.Category
+plugin.keybindings.CHAT=èŠå¤©
+plugin.keybindings.MAIN=主è¦
+plugin.keybindings.GLOBAL=全域快æ·éµ
# Notification Configuration Form
+plugin.notificationconfig.ENABLE_NOTIF=啟用
+plugin.notificationconfig.DESCRIPTION=æè¿°
+plugin.notificationconfig.TURN_ON_ALL=全部啟用
+plugin.notificationconfig.TURN_OFF_ALL=全部ç¦ç”¨
+plugin.notificationconfig.ACTIONS=動作
+plugin.notificationconfig.QUICK_CONTROLS=å¿«æ·æŽ§åˆ¶
+plugin.notificationconfig.RESTORE=還原é è¨­å€¼
+plugin.notificationconfig.PLAY_SOUND=播放è²éŸ³ï¼š
+plugin.notificationconfig.EXEC_PROG=執行程å¼ï¼š
+plugin.notificationconfig.DISPLAY_POPUP=在彈出å¼è¦–窗中顯示訊æ¯
+plugin.notificationconfig.POPUP_NOTIF_HANDLER=彈出æ醒類型
+plugin.notificationconfig.SOUND_FILE=音效檔案:
+plugin.notificationconfig.PROGRAM_FILE=程å¼æª”案:
+plugin.notificationconfig.BROWSE_SOUND=é¸æ“‡éŸ³æ•ˆæª”
+plugin.notificationconfig.BROWSE_PROGRAM=é¸æ“‡ç¨‹å¼
+plugin.notificationconfig.tableheader.ENABLE=啟用或ç¦ç”¨é€™å€‹ç‰¹æ€§
+plugin.notificationconfig.tableheader.EXECUTE=執行程å¼
+plugin.notificationconfig.tableheader.POPUP=顯示訊æ¯æ¡†
+plugin.notificationconfig.tableheader.SOUND=用æ醒è£ç½®æ’­æ”¾æ示音
+plugin.notificationconfig.tableheader.PLAYBACK_SOUND=用回放è£ç½®æ’­æ”¾æ示音
+plugin.notificationconfig.tableheader.PCSPEAKER_SOUND=用電腦喇å­æ’­æ”¾è²éŸ³
+plugin.notificationconfig.tableheader.DESCRIPTION=事件æè¿°
+#NotificationsTable constants
+plugin.notificationconfig.event.IncomingCall=來電通知
+plugin.notificationconfig.event.SecurityMessage=安全訊æ¯
+plugin.notificationconfig.event.IncomingFile=è¦å‚³é€²ä¾†çš„檔案
+plugin.notificationconfig.event.LogFilesArchived=紀錄檔已å°å­˜
+plugin.notificationconfig.event.CallSecurityError=通話加密發生錯誤
+plugin.notificationconfig.event.NetworkNotifications=網路通知
+plugin.notificationconfig.event.Dialing=正在撥號
+plugin.notificationconfig.event.ProactiveNotification=主動輸入通知
+plugin.notificationconfig.event.CallSecurityOn=啟動加密通話
+plugin.notificationconfig.event.IncomingMessage=收到訊æ¯
+plugin.notificationconfig.event.OutgoingCall=通話撥出
+plugin.notificationconfig.event.BusyCall=通話忙線中
+plugin.notificationconfig.event.CallSaved=通話ä¿ç•™
+plugin.notificationconfig.event.HangUp=掛斷
+plugin.notificationconfig.event.DNSSEC_NOTIFICATION=DNSSEC 警告
+plugin.notificationconfig.event.DTMFTone.A=DTMF 音調 A
+plugin.notificationconfig.event.DTMFTone.B=DTMF 音調 B
+plugin.notificationconfig.event.DTMFTone.C=DTMF 音調 C
+plugin.notificationconfig.event.DTMFTone.D=DTMF 音調 D
+plugin.notificationconfig.event.DTMFTone.0=DTMF 音調 0
+plugin.notificationconfig.event.DTMFTone.1=DTMF 音調 1
+plugin.notificationconfig.event.DTMFTone.2=DTMF 音調 2
+plugin.notificationconfig.event.DTMFTone.3=DTMF 音調 3
+plugin.notificationconfig.event.DTMFTone.4=DTMF 音調 4
+plugin.notificationconfig.event.DTMFTone.5=DTMF 音調 5
+plugin.notificationconfig.event.DTMFTone.6=DTMF 音調 6
+plugin.notificationconfig.event.DTMFTone.7=DTMF 音調 7
+plugin.notificationconfig.event.DTMFTone.8=DTMF 音調 8
+plugin.notificationconfig.event.DTMFTone.9=DTMF 音調 9
+plugin.notificationconfig.event.DTMFTone.*=DTMF 音調 *
+plugin.notificationconfig.event.DTMFTone.#=DTMF 音調 #
+plugin.notificationconfig.event.DeviceConfigurationChanged=è£ç½®è¨­å®šå·²è®Šæ›´
+plugin.notificationconfig.event.NewSelectedDevice=æ–°é¸å–çš„è£ç½®
# ZRTP Securing
+impl.media.security.WARNING_NO_RS_MATCH=<html>沒有å¯ç”¨çš„共享密鑰。<br/><b>建議採用 SAS 驗證。</b></html>
+impl.media.security.WARNING_NO_EXPECTED_RS_MATCH=<html>找ä¸åˆ°å…±äº«å¯†é‘°ã€‚<br/><b>需è¦é€²è¡Œ SAS 驗證。</b><br/>如果 SAS 密碼ä¸ç›¸ç¬¦ï¼Œè«‹æŽ›æ–·é‡æ’¥ã€‚</html>
+impl.media.security.SEVERE_GENERIC_MSG=<html>檢測到嚴é‡çš„æœå‹™å®‰å…¨å•é¡Œã€‚<br/><b>您的通話ä¸å®‰å…¨ã€‚</b><br/>錯誤代碼:{0}</html>
+impl.media.security.ZRTP_GENERIC_MSG=<html>檢測到嚴é‡çš„ ZRTP å•é¡Œã€‚<br/><b>您的通話並未加密。</b><br/>錯誤代碼: {0}</html>
+impl.media.security.INTERNAL_PROTOCOL_ERROR=<html>發生了通訊å”定內部錯誤。<br/><b>您的通話ä¸å®‰å…¨ã€‚</b><br/>錯誤代碼:{0}</html>
+impl.media.security.CHECKSUM_MISMATCH=<html>內部 ZRTP å°åŒ…校驗失敗。<br/>如果您看到這æ¢è¨Šæ¯ï¼Œå¯èƒ½æ˜¯é­åˆ°äº†æ‹’絕æœå‹™(DoS)攻擊ï¼</html>
+impl.media.security.RETRY_RATE_EXCEEDED=<html>嘗試安全å”商次數éŽå¤šã€‚這很å¯èƒ½æ˜¯å°æ–¹çš„網路連線有å•é¡Œã€‚<br/><b>您的通話ä¸å®‰å…¨ã€‚</b><br/>錯誤代碼:{0}</html>
+impl.media.security.DATA_SEND_FAILED=<html>加密資料傳é€å¤±æ•—。資料連線中斷或是å°æ–¹å·²æ–·ç·šã€‚<br/><b>您的通話ä¸å®‰å…¨</b><br/>錯誤代碼:{0}</html>
+impl.media.security.SECURITY_OFF=加密通話已åœç”¨
+impl.media.security.SECURITY_ON=加密通話已啟用
# ZRTP Configuration
+impl.media.security.zrtp.CONFIG=ZRTP 設定
+impl.media.security.zrtp.TITLE=通話
+impl.media.security.zrtp.PUB_KEYS=公開金鑰
+impl.media.security.zrtp.HASHES=雜湊
+impl.media.security.zrtp.SYM_CIPHERS=å°ç¨±åŠ å¯†æ¼”算法
+impl.media.security.zrtp.SAS_TYPES=SAS é¡žåž‹
+impl.media.security.zrtp.SRTP_LENGTHS=SRTP 身份驗證長度
+impl.media.security.zrtp.STANDARD=標準
+impl.media.security.zrtp.MANDATORY=強制
+impl.media.security.zrtp.TRUSTED=å¯ä¿¡ä»»çš„ MitM
+impl.media.security.zrtp.SASSIGNATURE=SAS ç°½å進行中
+impl.media.security.zrtp.DESCRIPTION={0} 會自動嘗試加密您的所有通話,在此åŒæ™‚您會è½åˆ°å’Œçœ‹åˆ°ä¸€æ¢å®‰å…¨é€£ç·šå·²å°±ç·’çš„æ示。按下此按鈕表示您å…許 ZRTP 專家微調 {0} çš„ ZRTP å”商行為,您無需åšä»»ä½•èª¿æ•´å³å¯ç²å¾—安全呼å«ã€‚您應僅在已詳細了解 ZRTP 和一般的加密工作原ç†å¾Œå†è®Šæ›´æ­¤è¨­å®šã€‚
+impl.media.security.zrtp.ZRTP_NINJA=ZRTP 隱身
# Profiler4J
-
-
-
+plugin.profiler.PLUGIN_NAME=Profiler4j
+
+impl.media.configform.AUDIO=音訊系統:
+impl.media.configform.AUDIO_IN=音訊輸入:
+impl.media.configform.AUDIO_NOTIFY=通知:
+impl.media.configform.AUDIO_OUT=音訊輸出:
+impl.media.configform.AUTOMATICGAINCONTROL=自動å–得控制權
+impl.media.configform.DENOISE=é–‹å•Ÿé™å™ªåŠŸèƒ½
+impl.media.configform.DEVICES=è£ç½®
+impl.media.configform.DOWN=下移
+impl.media.configform.ECHOCANCEL=開啟回音消除功能
+impl.media.configform.ENCODINGS=編碼
+impl.media.configform.NO_AVAILABLE_AUDIO_DEVICE=ç„¡å¯ç”¨çš„音訊è£ç½®ã€‚請連接一個。
+impl.media.configform.NO_DEVICE=<沒有è£ç½®>
+impl.media.configform.NO_PREVIEW=é è¦½
+impl.media.configform.UP=上移
+impl.media.configform.VIDEO=æ”影機:
+impl.media.configform.VIDEO_MORE_SETTINGS=更多設定
+impl.media.configform.VIDEO_RESOLUTION=視訊解æžåº¦
+impl.media.configform.VIDEO_FRAME_RATE=自定義影格率(æ¯ç§’)
+impl.media.configform.VIDEO_PACKETS_POLICY=RTP 步進門檻 (kB/s)
+impl.media.configform.VIDEO_BITRATE=視訊ä½å…ƒå‚³è¼¸çŽ‡(kb/s)
+impl.media.configform.VIDEO_RESET=é‡ç½®ç‚ºé è¨­å€¼
+impl.media.configform.AUDIO_DEVICE_CONNECTED=已連線的設備:
+impl.media.configform.AUDIO_DEVICE_DISCONNECTED=斷線的設備:
+impl.media.configform.AUDIO_DEVICE_SELECTED_AUDIO_IN=æ–°é¸æ“‡çš„音訊輸入è£ç½®ï¼š
+impl.media.configform.AUDIO_DEVICE_SELECTED_AUDIO_OUT=æ–°é¸æ“‡çš„音訊輸出è£ç½®ï¼š
+impl.media.configform.AUDIO_DEVICE_SELECTED_AUDIO_NOTIFICATIONS=æ–°é¸æ“‡çš„æ醒è£ç½®ï¼š
+impl.media.configform.VIDEO_DEVICE_SELECTED=æ–°é¸æ“‡çš„視訊è£ç½®ï¼š
+impl.media.configform.AUDIO_DEVICE_CONFIG_MANAGMENT_CLICK=點此進行è£ç½®ç®¡ç†
+
+impl.neomedia.configform.AUDIO=音訊
+impl.neomedia.configform.VIDEO=視訊
+
+impl.neomedia.configform.H264=H.264
+impl.neomedia.configform.H264.defaultIntraRefresh=周期性內部更新
+impl.neomedia.configform.H264.defaultProfile=é è¨­ç·¨ç¢¼è¨­å®šï¼š
+#in JNIEncoder
+impl.neomedia.configform.H264.defaultProfile.baseline=基準線
+impl.neomedia.configform.H264.defaultProfile.high=高
+impl.neomedia.configform.H264.defaultProfile.main=主è¦
+impl.neomedia.configform.H264.keyint=é—œéµå½±æ ¼ä¹‹é–“的最大間隔
+impl.neomedia.configform.H264.preferredKeyFrameRequester=以å好方å¼è«‹æ±‚é—œéµå½±æ ¼ï¼š
+impl.neomedia.configform.H264.preferredKeyFrameRequester.rtcp=RTCP
+impl.neomedia.configform.H264.preferredKeyFrameRequester.signaling=發é€ä¿¡è™Ÿ
+impl.neomedia.configform.H264.preset=é è¨­ç·¨ç¢¼å™¨
# The callrecordingconfig plugin was never really committed into trunk and its
# ConfigurationForm was actually put in the neomedia bundle.
+plugin.callrecordingconfig.CALL_RECORDING_CONFIG=通話錄音
+plugin.callrecordingconfig.SAVE_CALLS=儲存錄音檔至:
+plugin.callrecordingconfig.SAVE_CALL=儲存錄音檔至...
+plugin.callrecordingconfig.CHOOSE_DIR=é¸æ“‡è³‡æ–™å¤¾...
+plugin.callrecordingconfig.SUPPORTED_FORMATS=錄音檔格å¼ï¼š
+plugin.callrecordingconfig.CALL_SAVED=錄音檔儲存æˆåŠŸ
+plugin.callrecordingconfig.CALL_SAVED_TO={0}
# Security configuration form title
+plugin.securityconfig.TITLE=安全
+plugin.securityconfig.masterpassword.TITLE=密碼
+plugin.securityconfig.masterpassword.CHANGE_MASTER_PASSWORD=修改主控密碼...
+plugin.securityconfig.masterpassword.USE_MASTER_PASSWORD=使用主控密碼
+plugin.securityconfig.masterpassword.SAVED_PASSWORDS=已儲存的密碼...
+plugin.securityconfig.masterpassword.INFO_TEXT=主控密碼是用來ä¿è­·æ‚¨å„²å­˜çš„帳號密碼。請務必牢記它。
+plugin.securityconfig.masterpassword.CURRENT_PASSWORD=ç›®å‰å¯†ç¢¼ï¼š
+plugin.securityconfig.masterpassword.ENTER_PASSWORD=輸入新密碼:
+plugin.securityconfig.masterpassword.REENTER_PASSWORD=å†è¼¸å…¥ä¸€æ¬¡æ–°å¯†ç¢¼ï¼š
+plugin.securityconfig.masterpassword.MP_TITLE=主控密碼
+plugin.securityconfig.masterpassword.MP_CURRENT_EMPTY=您輸入的主控密碼錯誤。請é‡è©¦ã€‚
+plugin.securityconfig.masterpassword.MP_VERIFICATION_FAILURE_MSG=主控密碼ä¸æ­£ç¢ºï¼
+plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE=密碼變更失敗
+plugin.securityconfig.masterpassword.MP_CHANGE_SUCCESS=å·²æˆåŠŸè®Šæ›´å¯†ç¢¼
+plugin.securityconfig.masterpassword.MP_CHANGE_SUCCESS_MSG=å·²æˆåŠŸè®Šæ›´ä¸»æŽ§å¯†ç¢¼ã€‚
+plugin.securityconfig.masterpassword.MP_CHANGE_FAILURE_MSG=無法用您æ供的主控密碼解開加密的密碼。\n已儲存的密碼å¯èƒ½å·²è¢«æ”¹å‹•ã€‚
+plugin.securityconfig.masterpassword.MP_REMOVE_FAILURE=密碼刪除失敗
+plugin.securityconfig.masterpassword.MP_REMOVE_SUCCESS=å·²æˆåŠŸåˆªé™¤å¯†ç¢¼
+plugin.securityconfig.masterpassword.MP_REMOVE_SUCCESS_MSG=您已æˆåŠŸåˆªé™¤ä¸»æŽ§å¯†ç¢¼ã€‚
+plugin.securityconfig.masterpassword.COL_TYPE=é¡žåž‹
+plugin.securityconfig.masterpassword.COL_NAME=å稱
+plugin.securityconfig.masterpassword.COL_PASSWORD=密碼
+plugin.securityconfig.masterpassword.PROTOCOL_UNKNOWN=(未知)
+plugin.securityconfig.masterpassword.CANNOT_DECRYPT=(無法解密)
+plugin.securityconfig.masterpassword.STORED_ACCOUNT_PASSWORDS=儲存的密碼
+plugin.securityconfig.masterpassword.REMOVE_ALL_PASSWORDS_BUTTON=全部刪除
+plugin.securityconfig.masterpassword.REMOVE_ALL_CONFIRMATION=您確定è¦åˆªé™¤æ‰€æœ‰å¯†ç¢¼å—Žï¼Ÿ
+plugin.securityconfig.masterpassword.REMOVE_ALL_TITLE=刪除所有密碼
+plugin.securityconfig.masterpassword.SHOW_PASSWORDS_BUTTON=顯示密碼
+plugin.securityconfig.masterpassword.HIDE_PASSWORDS_BUTTON=éš±è—密碼
+plugin.securityconfig.masterpassword.PASSWORD_QUALITY_METER=密碼強度
+plugin.securityconfig.masterpassword.MP_INPUT=請輸入主控密碼:\n\n
# otr plugin
+plugin.otr.menu.TITLE=密談
+plugin.otr.menu.START_OTR=開始ç§å¯†å°è©±
+plugin.otr.menu.END_OTR=çµæŸç§å¯†å°è©±
+plugin.otr.menu.FINISHED=您的好å‹å·²çµæŸäº†èˆ‡æ‚¨çš„ç§å¯†å°è©±ã€‚您也應該這麼åšã€‚
+plugin.otr.menu.VERIFIED=您的ç§å¯†å°è©±å·²è¢«ç¢ºèª
+plugin.otr.menu.UNVERIFIED=您的ç§å¯†å°è©±æœªè¢«ç¢ºèªã€‚請為您的好å‹é€²è¡Œèº«ä»½é©—證。
+plugin.otr.menu.LOADING_OTR=開始ç§å¯†å°è©±...
+plugin.otr.menu.TIMED_OUT=å•Ÿå‹•ç§å¯†å°è©±é€¾æ™‚。
+plugin.otr.menu.REFRESH_OTR=刷新ç§å¯†å°è©±
+plugin.otr.menu.AUTHENTICATE_BUDDY=好å‹èº«ä»½é©—è­‰
+plugin.otr.menu.WHATS_THIS=這是什麼
+plugin.otr.menu.CB_AUTO=自動發起與 {0} çš„ç§å¯†å°è©±
+plugin.otr.menu.CB_AUTO_ALL=自動建立與所有人的ç§å¯†å°è©±
+plugin.otr.menu.CB_ENABLE=å…許ç§å¯†å°è©±
+plugin.otr.menu.CB_REQUIRE=ç§å¯†å°è©±é‚€è«‹
+plugin.otr.menu.CB_RESET=é‡ç½®
+plugin.otr.menu.OTR_TOOLTIP=使用 OTR çš„ç§å¯†å°è©±
+plugin.otr.authbuddydialog.HELP_URI=https://jitsi.org/GSOC2009/OTR
+plugin.otr.authbuddydialog.AUTHENTICATION_INFO=驗證好å‹èƒ½å¤ ç¢ºä¿å°æ–¹çš„真實身份。
+plugin.otr.authbuddydialog.AUTHENTICATION_METHOD=您希望如何進行身份驗證?
+plugin.otr.authbuddydialog.AUTHENTICATION_METHOD_QUESTION=以å•ç­”題進行身份驗證
+plugin.otr.authbuddydialog.AUTHENTICATION_METHOD_SECRET=以共享密碼進行身份驗證
+plugin.otr.authbuddydialog.AUTHENTICATION_METHOD_FINGERPRINT=以數ä½æŒ‡ç´‹é€²è¡Œèº«ä»½é©—è­‰
+plugin.otr.authbuddydialog.AUTHENTICATION_FINGERPRINT=為了驗證數ä½æŒ‡ç´‹ï¼Œæ‚¨éœ€è¦é€šéŽå…¶ä»–途徑è¯çµ¡æ‚¨çš„好å‹ï¼Œä¾‹å¦‚電話或由 GPG 驗證的電å­éƒµä»¶ï¼Œå‘ŠçŸ¥å°æ–¹æ‚¨çš„數ä½æŒ‡ç´‹å­—串。如果字串相符,請在後續的å°è©±ä¸­é¸æ“‡æŽ¥å—此數ä½æŒ‡ç´‹é©—證。
+plugin.otr.authbuddydialog.LOCAL_FINGERPRINT=您 ({0}) 的數ä½æŒ‡ç´‹ï¼š{1}
+plugin.otr.authbuddydialog.REMOTE_FINGERPRINT={0} 的數ä½æŒ‡ç´‹ï¼š{1}
+plugin.otr.authbuddydialog.AUTH_BY_QUESTION_INFO_INIT=若希望以å•ç­”題來進行身份驗證,您需è¦è¨­å®šä¸€çµ„åªæœ‰æ‚¨å’Œæ‚¨çš„好å‹æ‰çŸ¥é“答案的å•é¡Œã€‚若您的答案與å°æ–¹æ出的å•é¡Œä¸ç›¸ç¬¦ï¼Œæ‚¨çš„真實身份將被質疑。
+plugin.otr.authbuddydialog.AUTH_BY_SECRET_INFO_INIT=若希望以共享密碼進行身份驗證,您需è¦è¨­å®šä¸€çµ„åªæœ‰æ‚¨å’Œæ‚¨çš„好å‹æ‰çŸ¥é“的密碼。若您輸入的密碼與å°æ–¹è¨­å®šçš„密碼ä¸ç›¸ç¬¦ï¼Œæ‚¨çš„真實身份將被質疑。
+plugin.otr.authbuddydialog.AUTH_BY_SECRET_INFO_RESPOND=您的好å‹å‘您æ出一個å•é¡Œä»¥ç¢ºèªæ‚¨çš„真實身份。若è¦é€šéŽèº«ä»½é©—證,請輸入您的答案。
+plugin.otr.authbuddydialog.SHARED_SECRET=輸入您們的共享密碼:
+plugin.otr.authbuddydialog.QUESTION_RESPOND=您的好å‹å•æ‚¨ï¼š
+plugin.otr.authbuddydialog.QUESTION_INIT=在此輸入您的å•é¡Œï¼š
+plugin.otr.authbuddydialog.ANSWER=在此輸入您的答案 (英文字æ¯å€åˆ†å¤§å°å¯«):
+plugin.otr.authbuddydialog.AUTHENTICATION_FROM=來自 {0} 的身份驗證。
+plugin.otr.authbuddydialog.CANCEL=å–消
+plugin.otr.authbuddydialog.HELP=求助
+plugin.otr.authbuddydialog.TITLE=好å‹èº«ä»½é©—è­‰
+plugin.otr.authbuddydialog.AUTHENTICATE_BUDDY=驗證好å‹èº«ä»½
+plugin.otr.authbuddydialog.I_HAVE=我已經
+plugin.otr.authbuddydialog.I_HAVE_NOT=我還沒有
+plugin.otr.authbuddydialog.VERIFY_ACTION=驗證了 {0} 的數ä½æŒ‡ç´‹æ­£ç¢ºæ€§ã€‚
+plugin.otr.authbuddydialog.FINGERPRINT_CHECK=請輸入從 {0} 收到的數ä½æŒ‡ç´‹ã€‚
+plugin.otr.smpprogressdialog.TITLE=身份驗證進度
+plugin.otr.smpprogressdialog.AUTHENTICATION_SUCCESS=身份驗證æˆåŠŸï¼
+plugin.otr.smpprogressdialog.AUTHENTICATION_FAIL=身份驗證失敗ï¼
+plugin.otr.configform.MY_PRIVATE_KEYS=我的ç§å¯†é‡‘é‘°
+plugin.otr.configform.KNOWN_FINGERPRINTS=已知的數ä½æŒ‡ç´‹
+plugin.otr.configform.CB_AUTO=自動啟動ç§å¯†å°è©±
+plugin.otr.configform.CB_ENABLE=å…許ç§å¯†å°è©±
+plugin.otr.configform.CB_REQUIRE=邀請ç§å¯†å°è©±
+plugin.otr.configform.NO_KEY_PRESENT=金鑰ä¸å­˜åœ¨
+plugin.otr.configform.GENERATE=產生
+plugin.otr.configform.REGENERATE=é‡æ–°ç”¢ç”Ÿ
+plugin.otr.configform.FINGERPRINT=數ä½æŒ‡ç´‹
+plugin.otr.configform.VERIFY_FINGERPRINT=確èªæ•¸ä½æŒ‡ç´‹
+plugin.otr.configform.FORGET_FINGERPRINT=ä¸è¦è¨˜ä½æ•¸ä½æŒ‡ç´‹
+plugin.otr.configform.COLUMN_NAME_CONTACT=è¯çµ¡äºº
+plugin.otr.configform.COLUMN_NAME_VERIFIED_STATUS=已驗證
+plugin.otr.configform.COLUMN_VALUE_VERIFIED_TRUE=是
+plugin.otr.configform.COLUMN_VALUE_VERIFIED_FALSE=å¦
+plugin.otr.activator.unverifiedsessionwarning={0} é€éŽä¾†è·¯ä¸æ˜Žçš„電腦與您通話。建議您<A href="jitsi://{1}/{2}?{3}">å° {0} 進行身份驗證</a>。
+plugin.otr.activator.unverifiedsessionstared=與 {0} çš„<b>未驗證</b>çš„ç§å¯†å°è©±é–‹å§‹ã€‚
+plugin.otr.activator.sessionstared=已開始和 {0} çš„ç§å¯†å°è©±
+plugin.otr.activator.sessionfinished={0} 已經çµæŸäº†å’Œæ‚¨çš„ç§å¯†å°è©±ï¼›æ‚¨ä¹Ÿæ‡‰è©²é€™æ¨£åšã€‚
+plugin.otr.activator.sessionlost=與 {0} çš„ç§å¯†å°è©±å·²ä¸­æ–·ã€‚
+plugin.otr.activator.historyon=正在記錄您與 {0} çš„å°è©±å…§å®¹ã€‚您å¯ä»¥<A href="jitsi://{1}/{2}">在此關閉èŠå¤©ç´€éŒ„</a>。
+plugin.otr.activator.historyoff=您與 {0} çš„å°è©±å…§å®¹æ²’有記錄。您å¯ä»¥<A href="jitsi://{1}/{2}">啟用èŠå¤©ç´€éŒ„</a>。
+plugin.otr.activator.sessionfinishederror=æ‚¨çš„è¨Šæ¯ "{0}" 未é€å‡ºã€‚è«‹çµæŸèˆ‡ {1} çš„ç§å¯†å°è©±ã€‚
+plugin.otr.activator.smpaborted={0} 已經終止了身份驗證程åºã€‚
+plugin.otr.activator.smperror=在身份驗證éŽç¨‹ä¸­å‡ºç¾äº†ä¸€å€‹éŒ¯èª¤ã€‚
+plugin.otr.activator.unencryptedmsgreceived=收到的訊æ¯æ˜¯æœªç¶“加密的。
+plugin.otr.activator.unreadablemsgreceived={0} 發é€çµ¦æ‚¨ä¸€æ¢ç„¡æ³•è®€å–的加密訊æ¯ã€‚
+plugin.otr.activator.requireencryption=æ‚¨çš„è¨Šæ¯ "{0}" 未é€å‡ºã€‚需è¦å•Ÿå‹•ç§å¯†å°è©±ã€‚
+plugin.otr.activator.unreadablemsgreply=您發é€çµ¦ {0} 的加密訊æ¯ç„¡æ³•è¢«è®€å–。請關閉與 {1} çš„ç§å¯†å°è©±æˆ–刷新å°è©±ã€‚
+plugin.otr.activator.fallbackmessage=<span style="font-weight: bold;">{0} 正試圖發起一個加密的<a href="http://en.wikipedia.org/wiki/Off-the-Record_Messaging">ç§å¯†å°è©±</a>。 然而您的軟體ä¸æ”¯æ´ç§å¯†å°è©±ã€‚ è«‹åƒé–±ï¼š<a href="http://en.wikipedia.org/wiki/Off-the-Record_Messaging">http://en.wikipedia.org/wiki/Off-the-Record_Messaging</a></span>
+plugin.otr.activator.multipleinstancesdetected=æ‚¨çš„å¥½å‹ {0} é‡è¤‡ç™»å…¥ä¸¦ä¸”建立了多組ç§å¯†å°è©±ã€‚您å¯ä»¥å¾žä¸‹åˆ—清單當中é¸æ“‡å…¶ä¸­ä¸€çµ„。
+plugin.otr.activator.msgfromanotherinstance={0} 發é€çµ¦æ‚¨ä¸€æ¢è¢«ç”¨æ–¼å¦ä¸€å°è©±çš„訊æ¯ã€‚若您é‡è¤‡ç™»å…¥ï¼Œé€™æ¢è¨Šæ¯æœƒåœ¨å¦ä¸€å°è©±æ”¶åˆ°ã€‚
# global proxy plugin
+plugin.globalproxy.GLOBAL_PROXY_CONFIG=全域代ç†è¨­å®š
+plugin.globalproxy.PROXY_TYPE=代ç†é¡žåž‹
+plugin.globalproxy.PROXY_ADDRESS=代ç†ä¼ºæœå™¨
+plugin.globalproxy.PROXY_PORT=代ç†é€šè¨ŠåŸ 
+plugin.globalproxy.PROXY_USERNAME=代ç†ä½¿ç”¨è€…å稱
+plugin.globalproxy.PROXY_PASSWORD=代ç†å¯†ç¢¼
+plugin.globalproxy.DESCRIPTION={0} å°‡å°æ‰€æœ‰ç¶²è·¯é€£æŽ¥å¥—用以上代ç†è¨­å®šã€‚\nç›®å‰å°ä»£ç†çš„支æ´å°šè™•æ–¼è©¦é©—階段,並且åªæ”¯æ´éƒ¨åˆ†é€šè¨Šå”定。詳情請åƒé–±ä¸‹è¡¨ï¼š
#plugin.globalproxy.PROTOCOL_SUPPORT
+plugin.globalproxy.FWD_DNS=åŒæ™‚ä»£ç† DNS
+plugin.globalproxy.FWD_DNS_NOTE=經由 Tor 的代ç†åŠŸèƒ½ï¼Œå¯å”助é¿å… DNS æ´©æ¼æ‚¨çš„行蹤。這項æœå‹™éœ€è¦é‡æ–°å•Ÿå‹•ç¨‹å¼ã€‚
+plugin.globalproxy.FWD_DNS_ADDR=DNS 代ç†åœ°å€
+plugin.globalproxy.FWD_DNS_PORT=DNS 代ç†é€šè¨ŠåŸ 
# plugin reconnect
+plugin.reconnectplugin.CONNECTION_FAILED_MSG=使用者 {0} 登入 {1} 伺æœå™¨å¤±æ•—ï¼\n請檢查您的系統設定或尋求網路管ç†å“¡å”助。
+plugin.reconnectplugin.NETWORK_DOWN=網路連接已中斷ï¼
#plugin chat config
+plugin.chatconfig.TITLE=èŠå¤©
+plugin.chatconfig.replacement.TITLE=圖片/視訊:
+plugin.chatconfig.replacement.ENABLE_SMILEY_STATUS=å…許æ’入表情
+plugin.chatconfig.replacement.REPLACEMENT_TITLE=替æ›åœ–åƒå’Œè¦–訊
+plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS=啟用
+plugin.chatconfig.replacement.ENABLE_REPLACEMENT_PROPOSAL=ç¦ç”¨ï¼ˆé¡¯ç¤ºé è¦½éˆæŽ¥ï¼‰
+plugin.chatconfig.replacement.DISABLE_REPLACEMENT=ç¦ç”¨
+plugin.chatconfig.replacement.CONFIGURE_REPLACEMENT=圖åƒå’Œè¦–訊替æ›è¨­å®šé¸é …更改
+plugin.chatconfig.replacement.REPLACEMENT_SOURCES=來æºï¼š
+plugin.chatconfig.spellcheck.TITLE=拼字檢查
#provisioning plugin
+plugin.provisioning.PROVISIONING=網路æœå‹™
+plugin.provisioning.ENABLE_DISABLE=å…許æ供網路æœå‹™
+plugin.provisioning.AUTO=自動åµæ¸¬é ç½®æœå‹™ç¶²å€ (URI)
+plugin.provisioning.DHCP=DHCP
+plugin.provisioning.DNS=DNS
+plugin.provisioning.BONJOUR=Bonjour
+plugin.provisioning.MANUAL=手動指定é ç½®æœå‹™ç¶²å€ (URI)
+plugin.provisioning.URI=ç¶²å€ (URI)
+plugin.provisioning.RESTART_WARNING=請注æ„:所有的變更需è¦åœ¨ä¸‹æ¬¡å•Ÿå‹• {0} 後æ‰æœƒç”Ÿæ•ˆï¼
+plugin.provisioning.UUID=UUID
+plugin.provisioning.COPYTOCLIPBOARD=複製 UUID 到剪貼簿
+plugin.provisioning.CLIPBOARD_FAILED=複製 UUID 到剪貼簿失敗
+plugin.provisioning.CREDENTIALS=最後存儲的é ç½®è­‰æ›¸
+plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE=確定è¦åˆªé™¤é ç½®çš„密碼嗎?
+plugin.provisioning.PROV_FAILED=é ç½®å¤±æ•—
+plugin.provisioning.PROV_FAILED_MSG=<html>{0} é ç½®å¤±æ•—ï¼<br>è«‹ç¨å¾Œå†è©¦ï¼Œæˆ–è¯çµ¡ç®¡ç†å“¡ã€‚</html>
+plugin.provisioning.FORGET_PASSWORD=忘記密碼
# packet logging service
+plugin.loggingutils.PACKET_LOGGING_CONFIG=記錄
+plugin.loggingutils.ENABLE_DISABLE=啟用紀錄包裹
+plugin.loggingutils.PACKET_LOGGING_RTP=RTP
+plugin.loggingutils.PACKET_LOGGING_RTP_DESCRIPTION=(æ¯5000 æ¢ç´€éŒ„儲存æˆä¸€å€‹åŒ…裹)
+plugin.loggingutils.PACKET_LOGGING_ICE4J=ice4j.org
+plugin.loggingutils.PACKET_LOGGING_DESCRIPTION=<html>使用 PCAP (tcpdump/wireshark) æ ¼å¼ï¼Œå°‡å„種<br>通訊å”定的除錯紀錄包裹存放到紀錄資料夾。</html>
+plugin.loggingutils.PACKET_LOGGING_FILE_COUNT=紀錄檔檔案數目
+plugin.loggingutils.PACKET_LOGGING_FILE_SIZE=æœ€å¤§çš„ç´€éŒ„æª”æª”æ¡ˆå¤§å° (å–®ä½ï¼šKB)
+plugin.loggingutils.ARCHIVE_BUTTON=將紀錄檔å°å­˜
+plugin.loggingutils.UPLOAD_LOGS_BUTTON=將紀錄檔上傳
+plugin.loggingutils.UPLOAD_BUTTON=上傳
+plugin.loggingutils.ARCHIVE_FILECHOOSE_TITLE=é¸æ“‡æª”案
+plugin.loggingutils.ARCHIVE_UPREPORT_EMAIL=johnsmith@email.com
+plugin.loggingutils.ARCHIVE_MESSAGE_OK=紀錄檔å°å­˜æˆåŠŸ\n{0}
+plugin.loggingutils.ARCHIVE_MESSAGE_NOTOK=紀錄檔å°å­˜éŒ¯èª¤ \n{0}
# dns config plugin
+plugin.dnsconfig.TITLE=DNS
+plugin.dnsconfig.DNSSEC=安全DNS(DNSSEC)
+plugin.dnsconfig.PARALLEL_DNS=DNS平行解æž
+plugin.dnsconfig.border.TITLE=備用解æžå™¨
+plugin.dnsconfig.chkBackupDnsEnabled.text=å…許 DNS 平行解æž
+plugin.dnsconfig.lblBackupResolver.text=主機å稱
+plugin.dnsconfig.lblBackupResolverFallbackIP.text=備用IP
+plugin.dnsconfig.lblBackupPort.text=通訊埠
+plugin.dnsconfig.lblRedemption.text=切æ›å›žä¸»è§£æžå™¨
+plugin.dnsconfig.lblRedemption.description=<html>在我們åœç”¨å‚™ç”¨è§£æžå™¨ä¹‹å‰ï¼Œä¸»è§£æžå™¨å¿…須返回的迅速回應次數。</html>
+plugin.dnsconfig.lblPatience.text=啟用備用解æžå™¨
+plugin.dnsconfig.lblPatience.description=<html>啟用備用解æžå™¨ä¹‹å‰æœ€é•·ç­‰å¾…主DNS回應時間(毫秒)</html>
+plugin.dnsconfig.dnssec.chkEnabled=啟用DNSSEC解æžå™¨
+plugin.dnsconfig.dnssec.lblDefault=é è¨­è¡Œç‚º
+plugin.dnsconfig.dnssec.chkAbsolute=處ç†æ‰€æœ‰åŸŸå為絕å°å€¼
+plugin.dnsconfig.dnssec.lblNameservers=自定義å稱伺æœå™¨
+plugin.dnsconfig.dnssec.lblNameserversHint=<html>多個伺æœå™¨å¯ä»¥ç”¨é€—號分隔,e.g. 149.20.64.20, 149.20.64.21 (OARC的公開DNSSEC驗證解æžä¼ºæœå™¨)</html>
+plugin.dnsconfig.dnssec.DOMAIN_NAME=域
+plugin.dnsconfig.dnssec.MODE=行為
+plugin.dnsconfig.dnssec.ENABLE_FAILED=狀態變更失敗
+plugin.dnsconfig.dnssec.ENABLE_FAILED_MSG=變更DNSSEC啟用狀態失敗。
+plugin.dnsconfig.dnssec.RESTART_WARNING=<html>注æ„因啟用或ç¦ç”¨DNSSEC而ç¦ç”¨å¹³è¡Œè§£æžå™¨æœƒåœ¨ä¸‹æ¬¡å•Ÿå‹• {0} 時生效。</html>
+net.java.sip.communicator.util.dns.SecureResolveMode.IgnoreDnssec=ç•¥éŽ
+net.java.sip.communicator.util.dns.SecureResolveMode.SecureOnly=必需
+net.java.sip.communicator.util.dns.SecureResolveMode.SecureOrUnsigned=ç°½åå€éœ€æ±‚
+net.java.sip.communicator.util.dns.SecureResolveMode.WarnIfBogus=輪詢å½å›žè¤‡
+net.java.sip.communicator.util.dns.SecureResolveMode.WarnIfBogusOrUnsigned=輪詢未簽å的或虛å‡å›žè¤‡
+util.dns.INSECURE_ANSWER_TITLE=DNSSEC失敗
+util.dns.INSECURE_ANSWER_MESSAGE_NO_REASON=DNSå° {0} 應答是éžå®‰å…¨çš„。
+util.dns.INSECURE_ANSWER_MESSAGE_REASON=DNS應答 {0} 是ä¸å®‰å…¨çš„。\n原因: {1}
+util.dns.DNSSEC_ADVANCED_OPTIONS=顯示進階é¸é …
+util.dns.DNSSEC_ADVANCED_REASON_BOGUS=<html>DNSSECç°½åå€ {0} 返回無效數據。<br>{1}</html>
+util.dns.DNSSEC_ADVANCED_REASON_UNSIGNED=為 {1} 執行的 {0} 查詢是未簽å的。
+net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.Accept=總是接å—
+net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.AlwaysAccept=總是接å—
+net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.Deny=拒絕
+net.java.sip.communicator.util.dns.ConfigurableDnssecResolver$DnssecDialogResult.AlwaysDeny=總是拒絕
+util.dns.DNSSEC_WARNING=<html><div width="600">{0} 已試圖連接ä½æ–¼<b>{1}</b>的伺æœå™¨ï¼Œæ­¤åŸŸç”±DNSSECæ供強安全防護。 {0} 從DNS伺æœå™¨è™•ç²å–的訊æ¯åŒæ­¤åŸŸDNSSECæ供的訊æ¯ä¸ç¬¦ã€‚<br><br><b>æ­¤å•é¡Œä¸€èˆ¬ä¸æœƒç™¼ç”Ÿï¼Œé™¤éž {1} 處發生éžå¸¸åš´é‡çš„錯誤。 它有力的表明您的網路連接å¯ä¿¡åº¦ç™¼ç”Ÿåš´é‡å•é¡Œã€‚</b> <br><br>如果您正在使用æŸäº›ç¶²è·¯(例如WiFi熱點)或基於特殊原因ä¸å†ä¿¡ä»»æ‚¨çš„互è¯ç¶²æœå‹™æ供商,我們強烈建議您立å³åœæ­¢ä½¿ç”¨ä¸¦å°‹æ‰¾ä¸€å€‹å¯ä¿¡çš„替代互è¯ç¶²æŽ¥å…¥é»žã€‚當您安全的接入å¦ä¸€å€‹ç¶²è·¯ï¼Œæ­¤å•é¡Œæœƒè‡ªå‹•æ¶ˆé™¤ã€‚如éžä¸Šè¿°åŽŸå› ï¼Œè«‹è¯çµ¡æ‚¨çš„æœå‹™æ供商並告知他們有關å•é¡Œã€‚</div></html>
#plugin spellcheck
-
+plugin.spellcheck.TITLE=拼寫和語法檢查
+plugin.spellcheck.MENU=顯示拼寫和語法
+plugin.spellcheck.ENABLE_SPELL_CHECK=啟用拼寫檢查
+plugin.spellcheck.dialog.FIND=查找下一個
+plugin.spellcheck.dialog.REPLACE=替æ›
+plugin.spellcheck.dialog.ADD=新增單詞
+plugin.spellcheck.DICT_ERROR_TITLE=切æ›å­—典錯誤
+plugin.spellcheck.DICT_ERROR=無法切æ›å­—å…¸
+plugin.spellcheck.DICT_RETRIEVE_ERROR=字典無法被ç²å–自
+plugin.spellcheck.DICT_PROCESS_ERROR=本地未識別
+plugin.spellcheck.UNINSTALL_DICTIONARY=å¸è¼‰
+plugin.spellcheck.DICT_ERROR_DELETE_TITLE=å¸è¼‰å­—典時發生錯誤
+plugin.spellcheck.DICT_ERROR_DELETE=無法å¸è¼‰å­—å…¸
+plugin.spellcheck.SPELLCHECK=拼寫檢查
+
+plugin.contactsourceconfig.CONTACT_SOURCE_TITLE=è¯çµ¡æº
#Certificate configuration plugin
+plugin.certconfig.TITLE=TLS設定
+plugin.certconfig.TRUSTSTORE_CONFIG=å—信任的根證書æº
+plugin.certconfig.JAVA_TRUSTSTORE=Java
+plugin.certconfig.WINDOWS_TRUSTSTORE=Windows
+plugin.certconfig.CERT_LIST_TITLE=TLS 客戶端身份驗證設定
+plugin.certconfig.CERT_LIST_DESCRIPTION=<html><body>這裡的設定å¯ä»¥è¢«ç”¨ä½œå¸³è™Ÿè¨­å®šä¸­çš„客戶端 TLS 證書 (亦å³ç”¨ SIP æ供的身份驗證憑證替代使用者å稱和密碼驗證)。</body></html>
+plugin.certconfig.ALIAS=密鑰庫中的別å稱
+plugin.certconfig.KEYSTORE_TYPE=é¡žåž‹
+plugin.certconfig.EDIT_ENTRY=編輯TLS客戶端證書設定
+plugin.certconfig.KEYSTORE=檔案
+plugin.certconfig.KEYSTORE_PASSWORD=密碼
+plugin.certconfig.INCOMPLETE=請為所有字段錄入值
+plugin.certconfig.SHOW_CERT_EXCEPTION=證書ä¸å¯é¡¯ç¤º({0})。
+plugin.certconfig.KEYSTORE_EXCEPTION=無法加載密鑰庫({0})。
+plugin.certconfig.FILE_TYPE_DESCRIPTION=證書存儲(PKCS#11 模å¼ï¼ŒPKCS#12檔案,Java ks 密鑰庫)
+plugin.certconfig.ALIAS_LOAD_EXCEPTION=無法從密鑰庫ç²å–別å({0})。
+plugin.certconfig.INVALID_KEYSTORE_TYPE=勾é¸çš„密鑰庫類型å¯èƒ½ä¸å¯ç”¨({0})。
+plugin.certconfig.BROWSE_KEYSTORE=開啟密鑰庫
+plugin.certconfig.REVOCATION_TITLE=證書åŠéŠ·é¸é …
+plugin.certconfig.REVOCATION_CHECK_ENABLED=啟用CRL(證書åŠéŠ·åˆ—表)
+plugin.certconfig.REVOCATION_OCSP_ENABLED=啟用OCSP(在線證書狀態通訊å”定)
# Phone number contact source plugin
+plugin.phonenumbercontactsource.DISPLAY_NAME=電話號碼
# properties editor
+plugin.propertieseditor.TITLE=屬性編輯器
+plugin.propertieseditor.NEW_PROPERTY_TITLE=增加新屬性
+plugin.propertieseditor.CHECK_BOX=下次顯示此警告
+plugin.propertieseditor.DESCRIPTION=下列按鈕å…許修改Jitsi性能設定。改變這些進階設定å¯èƒ½æœƒå¦¨å®³ç¨‹å¼çš„穩定性,安全性和性能。如果您確信已了解您的變更,請繼續。
+plugin.propertieseditor.IM_AWARE=我了解相關的風險
+plugin.propertieseditor.NEED_RESTART=注æ„:æŸäº›å±¬æ€§éœ€è¦é‡æ–°å•Ÿå‹•ï¼Œæ–°è¨­å®šæ‰æœƒç”Ÿæ•ˆã€‚
#Thunderbird address book plugin
+plugin.thunderbird.CONFIG_FORM_TITLE=Thunderbird
+plugin.thunderbird.ENABLED=已啟用
+plugin.thunderbird.PHONE_PREFIX=電話å€ç¢¼:
diff --git a/src/native/addrbook/msoutlook/MAPIBitness.cxx b/src/native/addrbook/msoutlook/MAPIBitness.cxx
index 46d80a4..9853b10 100644
--- a/src/native/addrbook/msoutlook/MAPIBitness.cxx
+++ b/src/native/addrbook/msoutlook/MAPIBitness.cxx
@@ -32,13 +32,14 @@
/**
* The number of registries known for the different Outlook version.
*/
-int nbOutlookRegister = 4;
+int nbOutlookRegister = 5;
/**
* The registries known for the different Outlook version.
*/
TCHAR outlookRegister[][MAX_PATH] = {
+ TEXT("{5812C571-53F0-4467-BEFA-0A4F47A9437C}"), // Outlook 2016
TEXT("{E83B4360-C208-4325-9504-0D23003A74A5}"), // Outlook 2013
TEXT("{1E77DE88-BCAB-4C37-B9E5-073AF52DFD7A}"), // Outlook 2010
TEXT("{24AAE126-0911-478F-A019-07B875EB9996}"), // Outlook 2007
@@ -91,6 +92,7 @@ int MAPIBitness_getOutlookBitnessVersion(void)
int MAPIBitness_getOutlookVersion(void)
{
int outlookVersions[] = {
+ 2016, // Outlook 2016
2013, // Outlook 2013
2010, // Outlook 2010
2007, // Outlook 2007
diff --git a/src/native/build.xml b/src/native/build.xml
index 3fe7794..8cdbc58 100644
--- a/src/native/build.xml
+++ b/src/native/build.xml
@@ -1,4 +1,4 @@
-<project name="jitsi-native" default="help-native">
+<project name="jitsi-native" default="help-native" xmlns:if="ant:if">
<import file="../../build.xml"/>
<!-- additionnal property -->
@@ -533,34 +533,6 @@
</cc>
</target>
- <target name="unbound"
- description="Build libjunbound"
- depends="init-native">
-
- <cc outtype="shared"
- name="g++"
- outfile="${native_install_dir}/junbound"
- objdir="${obj}">
- <!-- common compiler flags -->
- <compilerarg value="-Wall" />
- <compilerarg value="-Wreturn-type" />
- <compilerarg value="-fPIC"/>
- <compilerarg value="-D_JNI_IMPLEMENTATION_" />
-
- <compilerarg value="-I${system.JAVA_HOME}/include"
- if="is.running.linux" />
- <compilerarg value="-I${system.JAVA_HOME}/include/linux"
- if="is.running.linux" />
-
- <linkerarg value="-Wl,-z,relro" if="is.running.debian"/>
- <linkerarg value="-shared"/>
- <linkerarg value="-lunbound" if="is.running.linux"/>
-
- <fileset dir="${src}/native/libjunbound/src"
- includes="*.cpp"/>
- </cc>
- </target>
-
<!-- Cleanup object files and shared libraries -->
<target name="clean-native" description="Clean all object files and libraries.">
<delete failonerror="false" includeemptydirs="true">
@@ -592,6 +564,9 @@
can directly use command prompt
When changing idl file in visual studio console execute
midl <idl file>.
+
+ Microsoft MAPI headers won't compile with gcc. See:
+ http://lists.jitsi.org/pipermail/dev/2013-April/001313.html
-->
<target
name="msoutlookaddrbook"
@@ -641,7 +616,7 @@
http://www.microsoft.com/en-us/download/details.aspx?id=10176
- compile the tlb:
cd src/native/windows/msofficecomm
- midl "C:\Program Files (x86)\Microsoft Office Communicator\SDK\"
+ midl "C:\Program Files (x86)\Microsoft Office Communicator\SDK\msgrua.idl"
- run ant:
ant msofficecomm -DOCS2007SDK=<path here, escape \ with \\> -Darch=32
ant msofficecomm -DOCS2007SDK=<path here, escape \ with \\> -Darch=64
@@ -652,6 +627,15 @@
if="is.running.windows"
depends="init-native">
<fail message="OCS 2007 SDK not set!" unless="OCS2007SDK" />
+ <exec executable="windres">
+ <arg value="-i"/>
+ <arg value="${src}\native\windows\msofficecomm\Resources.rc"/>
+ <arg value="-o"/>
+ <arg value="${obj}\jmsofficecommtlb.o"/>
+ <arg value="-F"/>
+ <arg value="pe-i386" if:set="cross_32"/>
+ <arg value="pe-x86-64" if:set="cross_64"/>
+ </exec>
<cc
name="gcc"
objdir="${obj}"
@@ -679,6 +663,7 @@
<libset libs="advapi32, uuid, ole32, oleaut32, msi, stdc++" />
<fileset dir="${src}\native\windows\msofficecomm" includes="*.cxx" />
+ <fileset dir="${obj}" includes="jmsofficecommtlb.o"/>
</cc>
<exec executable="strip">
<arg value="-x"/>
diff --git a/src/native/libjunbound/Makefile.am b/src/native/libjunbound/Makefile.am
deleted file mode 100644
index 0182df2..0000000
--- a/src/native/libjunbound/Makefile.am
+++ /dev/null
@@ -1,2 +0,0 @@
-SUBDIRS = src
-ACLOCAL_AMFLAGS = -I m4
diff --git a/src/native/libjunbound/configure.ac b/src/native/libjunbound/configure.ac
deleted file mode 100644
index ddab6c3..0000000
--- a/src/native/libjunbound/configure.ac
+++ /dev/null
@@ -1,69 +0,0 @@
-# Prelude.
-AC_INIT([junbound], [1.0], [dev@jitsi.java.net])
-AM_INIT_AUTOMAKE([foreign -Wall -Werror])
-AC_CONFIG_MACRO_DIR([m4])
-LT_INIT
-
-# Checks for programs.
-AC_PROG_CXX
-# Checks for libraries.
-
-AC_CHECK_LIB([unbound], [ub_ctx_create], [], [AC_MSG_ERROR([libunbound not found (is libunbound-dev installed?)])])
-
-# Checks for header files.
-AC_MSG_CHECKING(for java include file jni.h)
-AC_ARG_WITH(javaincl, [ --with-javaincl=path Set location of Java include directory], [JAVAINCDIR="$withval"], [JAVAINCDIR=])
-
-if test -z "$JAVAINCDIR" ; then
- JAVAINCDIR="/usr/j2sdk*/include /usr/local/j2sdk*/include /usr/jdk*/include /usr/local/jdk*/include /opt/j2sdk*/include /opt/jdk*/include /usr/java/include /usr/java/j2sdk*/include /usr/java/jdk*/include /usr/local/java/include /opt/java/include /usr/include/java /usr/local/include/java /usr/lib/java/include /usr/lib/jvm/java*/include /usr/include/kaffe /usr/local/include/kaffe /usr/include"
-
- # Add in default installation directory on Windows for Cygwin
- case $host in
- *-*-cygwin* | *-*-mingw*) JAVAINCDIR="c:/Program*Files/Java/jdk*/include d:/Program*Files/Java/jdk*/include c:/j2sdk*/include d:/j2sdk*/include c:/jdk*/include d:/jdk*/include $JAVAINCDIR";;
- *-*-darwin*) JAVAINCDIR="/System/Library/Frameworks/JavaVM.framework/Headers $JAVAINCDIR";;
- *);;
- esac
-fi
-
-if test -z "$JAVA_HOME" ; then
- JAVA_HOME=":" # Something completely invalid
-fi
-VS_JNI_INCLUDE=""
-for d in "$JAVA_HOME/include" $JAVAINCDIR ; do
- if test -r "$d/jni.h" ; then
- AC_MSG_RESULT($d)
- JAVAINCDIR=$d
- VS_JNI_INCLUDE=-I\"$d\" #" quote here to fix nasty formatting bug in VIM
- break
- fi
-done
-
-if test "$VS_JNI_INCLUDE" = "" ; then
- AC_MSG_RESULT(not found)
- AC_MSG_FAILURE([Could not find required Java header file jni.h.
- Try defining JAVA_HOME to point to where you've
- installed the JAVA JDK])
-else
- # now look for <arch>/jni_md.h
- AC_MSG_CHECKING(for java include file jni_md.h)
- JAVAMDDIR=`find "$JAVAINCDIR" -follow -name jni_md.h -print`
- if test "$JAVAMDDIR" = "" ; then
- AC_MSG_RESULT(not found)
- AC_MSG_FAILURE([Could not find required Java header file jni_md.h.
- Try defining JAVA_HOME to point to where you've
- installed the JAVA JDK])
- else
- JAVAMDDIR=`dirname "$JAVAMDDIR" | tail -1`
- VS_JNI_INCLUDE="${VS_JNI_INCLUDE} -I\"$JAVAMDDIR\""
- AC_MSG_RESULT($JAVAMDDIR)
- fi
-fi
-
-AC_SUBST([VS_JNI_INCLUDE])
-#AC_CHECK_HEADERS([jni.h], [], [AC_MSG_ERROR([JNI headers not found])])
-# Checks for typedefs, structures, and compiler characteristics.
-# Checks for library functions.
-# Output files.
-# AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_FILES([Makefile src/Makefile])
-AC_OUTPUT \ No newline at end of file
diff --git a/src/native/libjunbound/make-linux.sh b/src/native/libjunbound/make-linux.sh
deleted file mode 100644
index 991eb17..0000000
--- a/src/native/libjunbound/make-linux.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-set -e
-
-out=`pwd`/build/linux
-prefix=$out/libs
-export JAVA_HOME=/usr/lib/jvm/default-java/
-
-mkdir -p $out
-mkdir -p $prefix
-
-cd $out
-
-expat=expat-2.1.0
-unbound=unbound-1.5.1
-
-wget -nc http://downloads.sourceforge.net/project/expat/expat/2.1.0/$expat.tar.gz
-wget -nc http://unbound.net/downloads/$unbound.tar.gz
-
-tar -xzvf $expat.tar.gz
-tar -xzvf $unbound.tar.gz
-
-cd $out/$expat
-./configure --with-pic --prefix=$prefix
-make
-make install
-
-cd $out/$unbound
-patch -p 1 -i $out/../../unbound.patch
-./configure --with-pic --prefix=$prefix --with-libexpat=$prefix
-make
-make install
-
-cd $out
-gcc $out/../../src/net_java_sip_communicator_impl_dns_UnboundApi.cpp -fpic -shared -o libjunbound.so -I$JAVA_HOME/include -Wl,-Bstatic -L$prefix/lib -lunbound -I$prefix/include -Wl,-Bdynamic -lcrypto -lssl
-strip libjunbound.so
diff --git a/src/native/libjunbound/make-mac.sh b/src/native/libjunbound/make-mac.sh
deleted file mode 100644
index 785adf8..0000000
--- a/src/native/libjunbound/make-mac.sh
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/bin/bash
-#-------------
-#Note: To compile the PPC support, you must have XCode 3.x installed!
-# Remove the "-arch ppc" arguments to build only for 32/64 bit
-#-------------
-
-set -e
-
-out=`pwd`/build/mac
-prefix=$out/libs
-
-mkdir -p $out
-mkdir -p $prefix/lib
-#mkdir -p $prefix/include
-
-cd $out
-
-expat=expat-2.0.1
-ldns=ldns-1.6.11
-unbound=unbound-1.4.14
-
-curl -L http://downloads.sourceforge.net/project/expat/expat/2.0.1/expat-2.0.1.tar.gz -o $expat.tar.gz
-curl -L http://nlnetlabs.nl/downloads/ldns/$ldns.tar.gz -o $ldns.tar.gz
-curl -L http://unbound.net/downloads/$unbound.tar.gz -o $unbound.tar.gz
-
-tar -xzvf $expat.tar.gz
-tar -xzvf $ldns.tar.gz
-tar -xzvf $unbound.tar.gz
-
-mv $expat expat
-mv $ldns ldns
-mv $unbound unbound
-
-export MACOSX_DEPLOYMENT_TARGET=10.5
-export CC="/usr/bin/gcc -arch i386 -arch x86_64 -mmacosx-version-min=10.5"
-export CPP="/usr/bin/gcc -E"
-
-function build_arch {
- prefixarch="${prefix}_$1"
- mkdir -p $prefixarch
-
- cd $out/$2
-
- ./configure --with-ssl=/usr --disable-gost --with-pic --with-ldns=$prefixarch --with-expat=$prefixarch --prefix=$prefixarch
-
- make clean
- make
- make install
-}
-
-function build_lib {
- build_arch all $1
-}
-
-build_lib expat
-build_lib ldns
-build_lib unbound
-
-cp -r ${prefix}_all/include $prefix/
-# remove all dynamic libs as we do not use them and compile is first searching
-# for them
-rm ${prefix}_all/lib/*.dylib
-cd $out
-g++ -mmacosx-version-min=10.4 -arch x86_64 -arch i386 \
- $out/../../src/net_java_sip_communicator_impl_dns_UnboundApi.cpp \
- -D_JNI_IMPLEMENTATION_ \
- -fPIC -shared -O2 -Wall \
- -I/System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers \
- -I${prefix}_all/include \
- -L${prefix}_all/lib \
- -L/usr/lib \
- -dynamiclib \
- -lunbound -lldns -lcrypto \
- -dynamic \
- -lcrypto -lssl \
- -o libjunbound.jnilib
diff --git a/src/native/libjunbound/makefile.linux b/src/native/libjunbound/makefile.linux
deleted file mode 100644
index f4e2124..0000000
--- a/src/native/libjunbound/makefile.linux
+++ /dev/null
@@ -1,16 +0,0 @@
-CC = g++ -O2
-TARGET_BASENAME = libjunbound.so
-
-CPPFLAGS = \
- -Wall -Wreturn-type \
- -fpic \
- -DJNI_IMPLEMENTATION \
- -I/usr/lib/jvm/java-6-openjdk/include
-
-LDFLAGS = -shared
-LIBS = -lunbound
-TARGET = $(TARGET_BASENAME)
-
-$(TARGET): src/*.cpp
- $(CC) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ $(LIBS)
- -strip $(TARGET)
diff --git a/src/native/libjunbound/makefile.w32 b/src/native/libjunbound/makefile.w32
deleted file mode 100644
index e57c030..0000000
--- a/src/native/libjunbound/makefile.w32
+++ /dev/null
@@ -1,25 +0,0 @@
-CC = g++ -O2
-TARGET_BASENAME = junbound.dll
-TARGET_DIR ?= ../../../lib/native/windows
-
-ifeq ($(wildcard /bin/cygpath.*),/bin/cygpath.exe)
- target.dir := $(shell cygpath --mixed "$(TARGET_DIR)")
- cygwin.target.dir := $(shell cygpath --unix "$(TARGET_DIR)")
-else
- target.dir := "$(TARGET_DIR)"
- cygwin.target.dir := "$(TARGET_DIR)"
-endif
-
-CPPFLAGS = \
- -Wall -Wreturn-type \
- -DWINVER=0x0502 -D_WIN32_WINNT=0x0502 \
- -DJNI_IMPLEMENTATION \
- -I"$(JAVA_HOME)/include" -I"$(JAVA_HOME)/include/win32" -Iwindows32
-
-LDFLAGS = -shared -static -Wl,--kill-at -Wl,--subsystem,windows
-LIBS = -Lwindows32 -lunbound -lldns -lcrypto -lws2_32 -lgdi32 -liphlpapi
-TARGET = $(TARGET_DIR)/$(TARGET_BASENAME)
-
-$(TARGET): src/*.cpp
- $(CC) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ $(LIBS)
- -strip $(TARGET)
diff --git a/src/native/libjunbound/makefile.w64 b/src/native/libjunbound/makefile.w64
deleted file mode 100644
index c3865f4..0000000
--- a/src/native/libjunbound/makefile.w64
+++ /dev/null
@@ -1,26 +0,0 @@
-CC = g++ -O2
-TARGET_BASENAME = junbound.dll
-TARGET_DIR ?= ../../../lib/native/windows-64
-JAVA_HOME = C:/Program Files/Java/jdk6
-
-ifeq ($(wildcard /bin/cygpath.*),/bin/cygpath.exe)
- target.dir := $(shell cygpath --mixed "$(TARGET_DIR)")
- cygwin.target.dir := $(shell cygpath --unix "$(TARGET_DIR)")
-else
- target.dir := "$(TARGET_DIR)"
- cygwin.target.dir := "$(TARGET_DIR)"
-endif
-
-CPPFLAGS = \
- -Wall -Wreturn-type \
- -DWINVER=0x0502 -D_WIN32_WINNT=0x0502 \
- -DJNI_IMPLEMENTATION \
- -I"$(JAVA_HOME)/include" -I"$(JAVA_HOME)/include/win32" -Iwindows64
-
-LDFLAGS = -shared -static -Wl,--kill-at -Wl,--subsystem,windows
-LIBS = -Lwindows64 -lunbound -lldns -lcrypto -lws2_32 -lgdi32 -liphlpapi
-TARGET = $(TARGET_DIR)/$(TARGET_BASENAME)
-
-$(TARGET): src/*.cpp
- $(CC) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ $(LIBS)
- -strip $(TARGET)
diff --git a/src/native/libjunbound/readme.txt b/src/native/libjunbound/readme.txt
deleted file mode 100644
index 4e7110a..0000000
--- a/src/native/libjunbound/readme.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-To compile libjunbound
-
-Linux (libunbound, libldns and lcrypto shared):
-----------------------------------------------
-a) With autoconf
-autoreconf --install
-./configure
-make
-cp ./libs/libjunbound.so ../../lib/native/linux
-
-b) With manual makefile
-make -f makefile.linux
-
-Linux (libunbound statically linked, lcrypto shared):
-----------------------------------------------------
-Use make-linux.sh
-
-Mac:
----
-Use make-mac.sh
-
-Windows:
--------
-- Get ldns, libexpat, unbound and compile them
-- make -f makefile.w32
-
-Expat Win64:
-./configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32
-
-Unbound Win64:
-The configure script wrongly detects getaddrinfo as Unix. Break the detection
-script at line 16085 (1.4.12)
-
-OpenSSL Win64:
-configure mingw64 -no-capieng -no-asm
-make
-make check (http://stackoverflow.com/questions/7256087/error-compiling-openssl-with-mingw-msys)
-mkdir lib
-cp libcrypto.a lib
-cp libssl.a lib
diff --git a/src/native/libjunbound/src/Makefile.am b/src/native/libjunbound/src/Makefile.am
deleted file mode 100644
index 9cdbd7f..0000000
--- a/src/native/libjunbound/src/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-lib_LTLIBRARIES = libjunbound.la
-libjunbound_la_SOURCES = net_java_sip_communicator_impl_dns_UnboundApi.cpp
-AM_CPPFLAGS = ${includedirs} ${VS_JNI_INCLUDE} -DJNI_IMPLEMENTATION
diff --git a/src/native/libjunbound/src/net_java_sip_communicator_impl_dns_UnboundApi.cpp b/src/native/libjunbound/src/net_java_sip_communicator_impl_dns_UnboundApi.cpp
deleted file mode 100644
index 05d6181..0000000
--- a/src/native/libjunbound/src/net_java_sip_communicator_impl_dns_UnboundApi.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <jni.h>
-#include <unbound.h>
-#include "net_java_sip_communicator_impl_dns_UnboundApi.h"
-
-void ub_async_cb(void* my_arg, int err, struct ub_result* result);
-jobject createUnboundResult(JNIEnv* env, ub_result* resolveResult);
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: setDebugLevel
- * Signature: (JI)V
- */
-JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_setDebugLevel
- (JNIEnv* env, jclass clazz, jlong context, jint level)
-{
- int result = ub_ctx_debuglevel((ub_ctx*)context, level);
- if(result != 0)
- {
- env->ThrowNew(env->FindClass("net/java/sip/communicator/impl/dns/UnboundException"), ub_strerror(result));
- return;
- }
-}
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: createContext
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_createContext
- (JNIEnv* env, jclass clazz)
-{
- return (jlong)ub_ctx_create();
-}
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: deleteContext
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_deleteContext
- (JNIEnv* env, jclass clazz, jlong context)
-{
- ub_ctx_delete((ub_ctx*)context);
-}
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: setForwarder
- * Signature: (JLjava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_setForwarder
- (JNIEnv* env, jclass clazz, jlong context, jstring server)
-{
- char* chars = (char*)env->GetStringUTFChars(server, NULL);
- int result = ub_ctx_set_fwd((ub_ctx*)context, chars);
- env->ReleaseStringUTFChars(server, chars);
- if(result != 0)
- {
- env->ThrowNew(env->FindClass("net/java/sip/communicator/impl/dns/UnboundException"), ub_strerror(result));
- return;
- }
-}
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: addTrustAnchor
- * Signature: (JLjava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_addTrustAnchor
- (JNIEnv* env, jclass clazz, jlong context, jstring anchor)
-{
- char* chars = (char*)env->GetStringUTFChars(anchor, NULL);
- int result = ub_ctx_add_ta((ub_ctx*)context, chars);
- env->ReleaseStringUTFChars(anchor, chars);
- if(result != 0)
- {
- env->ThrowNew(env->FindClass("net/java/sip/communicator/impl/dns/UnboundException"), ub_strerror(result));
- return;
- }
-}
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: resolve
- * Signature: (JLjava/lang/String;II)Lnet/java/sip/communicator/impl/dns/UnboundResult;
- */
-JNIEXPORT jobject JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_resolve
- (JNIEnv* env, jclass clazz, jlong context, jstring name, jint rrtype, jint rrclass)
-{
- char* chars = (char*)env->GetStringUTFChars(name, NULL);
- ub_result* resolveResult;
- int result = ub_resolve((ub_ctx*)context, chars, rrtype, rrclass, &resolveResult);
- env->ReleaseStringUTFChars(name, chars);
- if(result != 0)
- {
- env->ThrowNew(env->FindClass("net/java/sip/communicator/impl/dns/UnboundException"), ub_strerror(result));
- return NULL;
- }
- return createUnboundResult(env, resolveResult);
-}
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: resolveAsync
- * Signature: (JLjava/lang/String;IILnet/java/sip/communicator/impl/dns/UnboundApi/UnboundCallback;)J
- */
-JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_resolveAsync
- (JNIEnv* env, jclass clazz, jlong context, jstring name, jint rrtype, jint rrclass, jobject data, jobject cb)
-{
- JavaVM* jvm;
- if(env->GetJavaVM(&jvm) != 0)
- {
- env->ThrowNew(env->FindClass("net/java/sip/communicator/impl/dns/UnboundException"), "Unable to obtain Java VM pointer");
- return 0;
- }
-
- int result = ub_ctx_async((ub_ctx*)context, true);
- if(result != 0)
- {
- env->ThrowNew(env->FindClass("net/java/sip/communicator/impl/dns/UnboundException"), ub_strerror(result));
- return 0;
- }
-
- //ensure the objects stay alive when this method leaves
- void** cbData = new void*[3];
- cbData[0] = env->NewGlobalRef(data);
- cbData[1] = env->NewGlobalRef(cb);
- cbData[2] = jvm;
-
- int asyncId;
- char* chars = (char*)env->GetStringUTFChars(name, NULL);
- result = ub_resolve_async((ub_ctx*)context, chars, rrtype, rrclass, cbData, &ub_async_cb, &asyncId);
- env->ReleaseStringUTFChars(name, chars);
- if(result != 0)
- {
- delete[] cbData;
- env->ThrowNew(env->FindClass("net/java/sip/communicator/impl/dns/UnboundException"), ub_strerror(result));
- return 0;
- }
- return asyncId;
-}
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: cancelAsync
- * Signature: (JJ)V
- */
-JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_cancelAsync
- (JNIEnv* env, jclass clazz, jlong context, jint asyncId)
-{
- int result = ub_cancel((ub_ctx*)context, asyncId);
- if(result != 0)
- {
- env->ThrowNew(env->FindClass("net/java/sip/communicator/impl/dns/UnboundException"), ub_strerror(result));
- return;
- }
-}
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: errorCodeToString
- * Signature: (I)Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_errorCodeToString
- (JNIEnv* env, jclass clazz, jint code)
-{
- return env->NewStringUTF(ub_strerror(code));
-}
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: processAsync
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_processAsync
- (JNIEnv* env, jclass clazz, jlong context)
-{
- int result = ub_wait((ub_ctx*)context);
- if(result != 0)
- {
- env->ThrowNew(env->FindClass("net/java/sip/communicator/impl/dns/UnboundException"), ub_strerror(result));
- return;
- }
-}
-
-
-
-
-
-void ub_async_cb(void* my_arg, int err, struct ub_result* result)
-{
- void** cbData = (void**)my_arg;
- JavaVM* jvm = ((JavaVM*)cbData[2]);
- JNIEnv* env;
- if(jvm->AttachCurrentThreadAsDaemon((void**)&env, NULL) == 0)
- {
- jobject data = (jobject)cbData[0];
- jobject cb = (jobject)cbData[1];
- delete[] cbData;
-
- jobject ubResult = NULL;
- if(err == 0)
- {
- ubResult = createUnboundResult(env, result);
- }
- env->CallVoidMethod(
- cb, env->GetMethodID(
- env->FindClass("net/java/sip/communicator/impl/dns/UnboundApi$UnboundCallback"),
- "UnboundResolveCallback",
- "(Ljava/lang/Object;ILnet/java/sip/communicator/impl/dns/UnboundResult;)V"
- ), data, (jint)err, ubResult
- );
-
- env->DeleteGlobalRef(data);
- env->DeleteGlobalRef(cb);
- env->DeleteLocalRef(ubResult);
- }
- jvm->DetachCurrentThread();
-}
-
-
-
-
-jobject createUnboundResult(JNIEnv* env, ub_result* resolveResult)
-{
- jclass ubResultClass = env->FindClass("net/java/sip/communicator/impl/dns/UnboundResult");
- jmethodID constructor = env->GetMethodID(ubResultClass, "<init>", "()V");
- jobject ubResult = env->NewObject(ubResultClass, constructor);
-
- //copy data
- //int numData = 0;
- //char** data = resolveResult->data;
- //while(*(data++) != NULL)
- // numData++;
-
- //jobjectArray dataArray = env->NewObjectArray(numData, env->FindClass("[B"), NULL);
- //for(int i = 0; i < numData; i++)
- //{
- // jbyteArray dataEntry = env->NewByteArray(resolveResult->len[i]);
- // env->SetByteArrayRegion(dataEntry, 0, resolveResult->len[i], (jbyte*)resolveResult->data[i]);
- // env->SetObjectArrayElement(dataArray, i, dataEntry);
- // env->DeleteLocalRef(dataEntry);
- //}
-
- //copy answer packet
- jbyteArray answerPacket = env->NewByteArray(resolveResult->answer_len);
- env->SetByteArrayRegion(answerPacket, 0, resolveResult->answer_len, (jbyte*)resolveResult->answer_packet);
-
- //set fields
- env->SetObjectField( ubResult, env->GetFieldID(ubResultClass, "qname", "Ljava/lang/String;"), env->NewStringUTF(resolveResult->qname));
- env->SetIntField( ubResult, env->GetFieldID(ubResultClass, "qtype", "I"), resolveResult->qtype);
- env->SetIntField( ubResult, env->GetFieldID(ubResultClass, "qclass", "I"), resolveResult->qclass);
-
- //env->SetObjectField( ubResult, env->GetFieldID(ubResultClass, "data", "[[B"), dataArray);
- //env->SetObjectField( ubResult, env->GetFieldID(ubResultClass, "canonname", "Ljava/lang/String;"), env->NewStringUTF(resolveResult->canonname));
- env->SetIntField( ubResult, env->GetFieldID(ubResultClass, "rcode", "I"), resolveResult->rcode);
- env->SetObjectField( ubResult, env->GetFieldID(ubResultClass, "answerPacket", "[B"), answerPacket);
-
- env->SetBooleanField(ubResult, env->GetFieldID(ubResultClass, "haveData", "Z"), resolveResult->havedata);
- env->SetBooleanField(ubResult, env->GetFieldID(ubResultClass, "nxDomain", "Z"), resolveResult->nxdomain);
- env->SetBooleanField(ubResult, env->GetFieldID(ubResultClass, "secure", "Z"), resolveResult->secure);
- env->SetBooleanField(ubResult, env->GetFieldID(ubResultClass, "bogus", "Z"), resolveResult->bogus);
- env->SetObjectField( ubResult, env->GetFieldID(ubResultClass, "whyBogus", "Ljava/lang/String;"), env->NewStringUTF(resolveResult->why_bogus));
-
- ub_resolve_free(resolveResult);
- return ubResult;
-}
diff --git a/src/native/libjunbound/src/net_java_sip_communicator_impl_dns_UnboundApi.h b/src/native/libjunbound/src/net_java_sip_communicator_impl_dns_UnboundApi.h
deleted file mode 100644
index 71b59b9..0000000
--- a/src/native/libjunbound/src/net_java_sip_communicator_impl_dns_UnboundApi.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class net_java_sip_communicator_impl_dns_UnboundApi */
-
-#ifndef _Included_net_java_sip_communicator_impl_dns_UnboundApi
-#define _Included_net_java_sip_communicator_impl_dns_UnboundApi
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: setDebugLevel
- * Signature: (JI)V
- */
-JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_setDebugLevel
- (JNIEnv *, jclass, jlong, jint);
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: createContext
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_createContext
- (JNIEnv *, jclass);
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: deleteContext
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_deleteContext
- (JNIEnv *, jclass, jlong);
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: setForwarder
- * Signature: (JLjava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_setForwarder
- (JNIEnv *, jclass, jlong, jstring);
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: addTrustAnchor
- * Signature: (JLjava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_addTrustAnchor
- (JNIEnv *, jclass, jlong, jstring);
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: resolve
- * Signature: (JLjava/lang/String;II)Lnet/java/sip/communicator/impl/dns/UnboundResult;
- */
-JNIEXPORT jobject JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_resolve
- (JNIEnv *, jclass, jlong, jstring, jint, jint);
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: resolveAsync
- * Signature: (JLjava/lang/String;IILjava/lang/Object;Lnet/java/sip/communicator/impl/dns/UnboundApi/UnboundCallback;)I
- */
-JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_resolveAsync
- (JNIEnv *, jclass, jlong, jstring, jint, jint, jobject, jobject);
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: cancelAsync
- * Signature: (JI)V
- */
-JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_cancelAsync
- (JNIEnv *, jclass, jlong, jint);
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: errorCodeToString
- * Signature: (I)Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_errorCodeToString
- (JNIEnv *, jclass, jint);
-
-/*
- * Class: net_java_sip_communicator_impl_dns_UnboundApi
- * Method: processAsync
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_dns_UnboundApi_processAsync
- (JNIEnv *, jclass, jlong);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/src/native/libjunbound/src/net_java_sip_communicator_impl_dns_UnboundApi_UnboundCallback.h b/src/native/libjunbound/src/net_java_sip_communicator_impl_dns_UnboundApi_UnboundCallback.h
deleted file mode 100644
index f9b9de6..0000000
--- a/src/native/libjunbound/src/net_java_sip_communicator_impl_dns_UnboundApi_UnboundCallback.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class net_java_sip_communicator_impl_dns_UnboundApi_UnboundCallback */
-
-#ifndef _Included_net_java_sip_communicator_impl_dns_UnboundApi_UnboundCallback
-#define _Included_net_java_sip_communicator_impl_dns_UnboundApi_UnboundCallback
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/src/native/libjunbound/unbound.patch b/src/native/libjunbound/unbound.patch
deleted file mode 100644
index cc9aba6..0000000
--- a/src/native/libjunbound/unbound.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-diff -u -r unbound-1.5.1-orig/libunbound/context.c unbound-1.5.1/libunbound/context.c
---- unbound-1.5.1-orig/libunbound/context.c 2014-02-07 14:28:39.000000000 +0100
-+++ unbound-1.5.1/libunbound/context.c 2015-02-09 11:55:02.000000000 +0100
-@@ -125,7 +125,7 @@
- }
-
- struct ctx_query*
--context_new(struct ub_ctx* ctx, const char* name, int rrtype, int rrclass,
-+context_create(struct ub_ctx* ctx, const char* name, int rrtype, int rrclass,
- ub_callback_t cb, void* cbarg)
- {
- struct ctx_query* q = (struct ctx_query*)calloc(1, sizeof(*q));
-diff -u -r unbound-1.5.1-orig/libunbound/context.h unbound-1.5.1/libunbound/context.h
---- unbound-1.5.1-orig/libunbound/context.h 2014-02-07 14:28:39.000000000 +0100
-+++ unbound-1.5.1/libunbound/context.h 2015-02-09 11:54:44.000000000 +0100
-@@ -241,7 +241,7 @@
- * @param cbarg: user arg for async queries.
- * @return new ctx_query or NULL for malloc failure.
- */
--struct ctx_query* context_new(struct ub_ctx* ctx, const char* name, int rrtype,
-+struct ctx_query* context_create(struct ub_ctx* ctx, const char* name, int rrtype,
- int rrclass, ub_callback_t cb, void* cbarg);
-
- /**
-diff -u -r unbound-1.5.1-orig/libunbound/libunbound.c unbound-1.5.1/libunbound/libunbound.c
---- unbound-1.5.1-orig/libunbound/libunbound.c 2014-11-04 10:11:59.000000000 +0100
-+++ unbound-1.5.1/libunbound/libunbound.c 2015-02-09 11:55:20.000000000 +0100
-@@ -634,7 +634,7 @@
- }
- /* create new ctx_query and attempt to add to the list */
- lock_basic_unlock(&ctx->cfglock);
-- q = context_new(ctx, name, rrtype, rrclass, NULL, NULL);
-+ q = context_create(ctx, name, rrtype, rrclass, NULL, NULL);
- if(!q)
- return UB_NOMEM;
- /* become a resolver thread for a bit */
-@@ -687,7 +687,7 @@
- }
-
- /* create new ctx_query and attempt to add to the list */
-- q = context_new(ctx, name, rrtype, rrclass, (ub_callback_t)callback,
-+ q = context_create(ctx, name, rrtype, rrclass, (ub_callback_t)callback,
- mydata);
- if(!q)
- return UB_NOMEM;
-@@ -733,7 +733,7 @@
- }
-
- /* create new ctx_query and attempt to add to the list */
-- q = context_new(ctx, name, rrtype, rrclass, callback, mydata);
-+ q = context_create(ctx, name, rrtype, rrclass, callback, mydata);
- if(!q)
- return UB_NOMEM;
-
diff --git a/src/native/libjunbound/windows32/libcrypto.a b/src/native/libjunbound/windows32/libcrypto.a
deleted file mode 100644
index 6c7863e..0000000
--- a/src/native/libjunbound/windows32/libcrypto.a
+++ /dev/null
Binary files differ
diff --git a/src/native/libjunbound/windows32/libldns.a b/src/native/libjunbound/windows32/libldns.a
deleted file mode 100644
index 55837de..0000000
--- a/src/native/libjunbound/windows32/libldns.a
+++ /dev/null
Binary files differ
diff --git a/src/native/libjunbound/windows32/libunbound.a b/src/native/libjunbound/windows32/libunbound.a
deleted file mode 100644
index 8b5b7d5..0000000
--- a/src/native/libjunbound/windows32/libunbound.a
+++ /dev/null
Binary files differ
diff --git a/src/native/libjunbound/windows32/unbound.h b/src/native/libjunbound/windows32/unbound.h
deleted file mode 100644
index 14f1fea..0000000
--- a/src/native/libjunbound/windows32/unbound.h
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright (c) 2007, NLnet Labs. All rights reserved.
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * \file
- *
- * This file contains functions to resolve DNS queries and
- * validate the answers. Synchonously and asynchronously.
- *
- * Several ways to use this interface from an application wishing
- * to perform (validated) DNS lookups.
- *
- * All start with
- * ctx = ub_ctx_create();
- * err = ub_ctx_add_ta(ctx, "...");
- * err = ub_ctx_add_ta(ctx, "...");
- * ... some lookups
- * ... call ub_ctx_delete(ctx); when you want to stop.
- *
- * Application not threaded. Blocking.
- * int err = ub_resolve(ctx, "www.example.com", ...
- * if(err) fprintf(stderr, "lookup error: %s\n", ub_strerror(err));
- * ... use the answer
- *
- * Application not threaded. Non-blocking ('asynchronous').
- * err = ub_resolve_async(ctx, "www.example.com", ... my_callback);
- * ... application resumes processing ...
- * ... and when either ub_poll(ctx) is true
- * ... or when the file descriptor ub_fd(ctx) is readable,
- * ... or whenever, the app calls ...
- * ub_process(ctx);
- * ... if no result is ready, the app resumes processing above,
- * ... or process() calls my_callback() with results.
- *
- * ... if the application has nothing more to do, wait for answer
- * ub_wait(ctx);
- *
- * Application threaded. Blocking.
- * Blocking, same as above. The current thread does the work.
- * Multiple threads can use the *same context*, each does work and uses
- * shared cache data from the context.
- *
- * Application threaded. Non-blocking ('asynchronous').
- * ... setup threaded-asynchronous config option
- * err = ub_ctx_async(ctx, 1);
- * ... same as async for non-threaded
- * ... the callbacks are called in the thread that calls process(ctx)
- *
- * If no threading is compiled in, the above async example uses fork(2) to
- * create a process to perform the work. The forked process exits when the
- * calling process exits, or ctx_delete() is called.
- * Otherwise, for asynchronous with threading, a worker thread is created.
- *
- * The blocking calls use shared ctx-cache when threaded. Thus
- * ub_resolve() and ub_resolve_async() && ub_wait() are
- * not the same. The first makes the current thread do the work, setting
- * up buffers, etc, to perform the work (but using shared cache data).
- * The second calls another worker thread (or process) to perform the work.
- * And no buffers need to be set up, but a context-switch happens.
- */
-#ifndef _UB_UNBOUND_H
-#define _UB_UNBOUND_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * The validation context is created to hold the resolver status,
- * validation keys and a small cache (containing messages, rrsets,
- * roundtrip times, trusted keys, lameness information).
- *
- * Its contents are internally defined.
- */
-struct ub_ctx;
-
-/**
- * The validation and resolution results.
- * Allocated by the resolver, and need to be freed by the application
- * with ub_resolve_free().
- */
-struct ub_result {
- /** The original question, name text string. */
- char* qname;
- /** the type asked for */
- int qtype;
- /** the class asked for */
- int qclass;
-
- /**
- * a list of network order DNS rdata items, terminated with a
- * NULL pointer, so that data[0] is the first result entry,
- * data[1] the second, and the last entry is NULL.
- * If there was no data, data[0] is NULL.
- */
- char** data;
-
- /** the length in bytes of the data items, len[i] for data[i] */
- int* len;
-
- /**
- * canonical name for the result (the final cname).
- * zero terminated string.
- * May be NULL if no canonical name exists.
- */
- char* canonname;
-
- /**
- * DNS RCODE for the result. May contain additional error code if
- * there was no data due to an error. 0 (NOERROR) if okay.
- */
- int rcode;
-
- /**
- * The DNS answer packet. Network formatted. Can contain DNSSEC types.
- */
- void* answer_packet;
- /** length of the answer packet in octets. */
- int answer_len;
-
- /**
- * If there is any data, this is true.
- * If false, there was no data (nxdomain may be true, rcode can be set).
- */
- int havedata;
-
- /**
- * If there was no data, and the domain did not exist, this is true.
- * If it is false, and there was no data, then the domain name
- * is purported to exist, but the requested data type is not available.
- */
- int nxdomain;
-
- /**
- * True, if the result is validated securely.
- * False, if validation failed or domain queried has no security info.
- *
- * It is possible to get a result with no data (havedata is false),
- * and secure is true. This means that the non-existance of the data
- * was cryptographically proven (with signatures).
- */
- int secure;
-
- /**
- * If the result was not secure (secure==0), and this result is due
- * to a security failure, bogus is true.
- * This means the data has been actively tampered with, signatures
- * failed, expected signatures were not present, timestamps on
- * signatures were out of date and so on.
- *
- * If !secure and !bogus, this can happen if the data is not secure
- * because security is disabled for that domain name.
- * This means the data is from a domain where data is not signed.
- */
- int bogus;
-
- /**
- * If the result is bogus this contains a string (zero terminated)
- * that describes the failure. There may be other errors as well
- * as the one described, the description may not be perfectly accurate.
- * Is NULL if the result is not bogus.
- */
- char* why_bogus;
-};
-
-/**
- * Callback for results of async queries.
- * The readable function definition looks like:
- * void my_callback(void* my_arg, int err, struct ub_result* result);
- * It is called with
- * void* my_arg: your pointer to a (struct of) data of your choice,
- * or NULL.
- * int err: if 0 all is OK, otherwise an error occured and no results
- * are forthcoming.
- * struct result: pointer to more detailed result structure.
- * This structure is allocated on the heap and needs to be
- * freed with ub_resolve_free(result);
- */
-typedef void (*ub_callback_t)(void*, int, struct ub_result*);
-
-/**
- * Create a resolving and validation context.
- * The information from /etc/resolv.conf and /etc/hosts is not utilised by
- * default. Use ub_ctx_resolvconf and ub_ctx_hosts to read them.
- * @return a new context. default initialisation.
- * returns NULL on error.
- */
-struct ub_ctx* ub_ctx_create(void);
-
-/**
- * Destroy a validation context and free all its resources.
- * Outstanding async queries are killed and callbacks are not called for them.
- * @param ctx: context to delete.
- */
-void ub_ctx_delete(struct ub_ctx* ctx);
-
-/**
- * Set an option for the context.
- * @param ctx: context.
- * @param opt: option name from the unbound.conf config file format.
- * (not all settings applicable). The name includes the trailing ':'
- * for example ub_ctx_set_option(ctx, "logfile:", "mylog.txt");
- * This is a power-users interface that lets you specify all sorts
- * of options.
- * For some specific options, such as adding trust anchors, special
- * routines exist.
- * @param val: value of the option.
- * @return: 0 if OK, else error.
- */
-int ub_ctx_set_option(struct ub_ctx* ctx, char* opt, char* val);
-
-/**
- * Get an option from the context.
- * @param ctx: context.
- * @param opt: option name from the unbound.conf config file format.
- * (not all settings applicable). The name excludes the trailing ':'
- * for example ub_ctx_get_option(ctx, "logfile", &result);
- * This is a power-users interface that lets you specify all sorts
- * of options.
- * @param str: the string is malloced and returned here. NULL on error.
- * The caller must free() the string. In cases with multiple
- * entries (auto-trust-anchor-file), a newline delimited list is
- * returned in the string.
- * @return 0 if OK else an error code (malloc failure, syntax error).
- */
-int ub_ctx_get_option(struct ub_ctx* ctx, char* opt, char** str);
-
-/**
- * setup configuration for the given context.
- * @param ctx: context.
- * @param fname: unbound config file (not all settings applicable).
- * This is a power-users interface that lets you specify all sorts
- * of options.
- * For some specific options, such as adding trust anchors, special
- * routines exist.
- * @return: 0 if OK, else error.
- */
-int ub_ctx_config(struct ub_ctx* ctx, char* fname);
-
-/**
- * Set machine to forward DNS queries to, the caching resolver to use.
- * IP4 or IP6 address. Forwards all DNS requests to that machine, which
- * is expected to run a recursive resolver. If the proxy is not
- * DNSSEC-capable, validation may fail. Can be called several times, in
- * that case the addresses are used as backup servers.
- *
- * To read the list of nameservers from /etc/resolv.conf (from DHCP or so),
- * use the call ub_ctx_resolvconf.
- *
- * @param ctx: context.
- * At this time it is only possible to set configuration before the
- * first resolve is done.
- * @param addr: address, IP4 or IP6 in string format.
- * If the addr is NULL, forwarding is disabled.
- * @return 0 if OK, else error.
- */
-int ub_ctx_set_fwd(struct ub_ctx* ctx, char* addr);
-
-/**
- * Read list of nameservers to use from the filename given.
- * Usually "/etc/resolv.conf". Uses those nameservers as caching proxies.
- * If they do not support DNSSEC, validation may fail.
- *
- * Only nameservers are picked up, the searchdomain, ndots and other
- * settings from resolv.conf(5) are ignored.
- *
- * @param ctx: context.
- * At this time it is only possible to set configuration before the
- * first resolve is done.
- * @param fname: file name string. If NULL "/etc/resolv.conf" is used.
- * @return 0 if OK, else error.
- */
-int ub_ctx_resolvconf(struct ub_ctx* ctx, char* fname);
-
-/**
- * Read list of hosts from the filename given.
- * Usually "/etc/hosts".
- * These addresses are not flagged as DNSSEC secure when queried for.
- *
- * @param ctx: context.
- * At this time it is only possible to set configuration before the
- * first resolve is done.
- * @param fname: file name string. If NULL "/etc/hosts" is used.
- * @return 0 if OK, else error.
- */
-int ub_ctx_hosts(struct ub_ctx* ctx, char* fname);
-
-/**
- * Add a trust anchor to the given context.
- * The trust anchor is a string, on one line, that holds a valid DNSKEY or
- * DS RR.
- * @param ctx: context.
- * At this time it is only possible to add trusted keys before the
- * first resolve is done.
- * @param ta: string, with zone-format RR on one line.
- * [domainname] [TTL optional] [type] [class optional] [rdata contents]
- * @return 0 if OK, else error.
- */
-int ub_ctx_add_ta(struct ub_ctx* ctx, char* ta);
-
-/**
- * Add trust anchors to the given context.
- * Pass name of a file with DS and DNSKEY records (like from dig or drill).
- * @param ctx: context.
- * At this time it is only possible to add trusted keys before the
- * first resolve is done.
- * @param fname: filename of file with keyfile with trust anchors.
- * @return 0 if OK, else error.
- */
-int ub_ctx_add_ta_file(struct ub_ctx* ctx, char* fname);
-
-/**
- * Add trust anchors to the given context.
- * Pass the name of a bind-style config file with trusted-keys{}.
- * @param ctx: context.
- * At this time it is only possible to add trusted keys before the
- * first resolve is done.
- * @param fname: filename of file with bind-style config entries with trust
- * anchors.
- * @return 0 if OK, else error.
- */
-int ub_ctx_trustedkeys(struct ub_ctx* ctx, char* fname);
-
-/**
- * Set debug output (and error output) to the specified stream.
- * Pass NULL to disable. Default is stderr.
- * @param ctx: context.
- * @param out: FILE* out file stream to log to.
- * Type void* to avoid stdio dependency of this header file.
- * @return 0 if OK, else error.
- */
-int ub_ctx_debugout(struct ub_ctx* ctx, void* out);
-
-/**
- * Set debug verbosity for the context
- * Output is directed to stderr.
- * @param ctx: context.
- * @param d: debug level, 0 is off, 1 is very minimal, 2 is detailed,
- * and 3 is lots.
- * @return 0 if OK, else error.
- */
-int ub_ctx_debuglevel(struct ub_ctx* ctx, int d);
-
-/**
- * Set a context behaviour for asynchronous action.
- * @param ctx: context.
- * @param dothread: if true, enables threading and a call to resolve_async()
- * creates a thread to handle work in the background.
- * If false, a process is forked to handle work in the background.
- * Changes to this setting after async() calls have been made have
- * no effect (delete and re-create the context to change).
- * @return 0 if OK, else error.
- */
-int ub_ctx_async(struct ub_ctx* ctx, int dothread);
-
-/**
- * Poll a context to see if it has any new results
- * Do not poll in a loop, instead extract the fd below to poll for readiness,
- * and then check, or wait using the wait routine.
- * @param ctx: context.
- * @return: 0 if nothing to read, or nonzero if a result is available.
- * If nonzero, call ctx_process() to do callbacks.
- */
-int ub_poll(struct ub_ctx* ctx);
-
-/**
- * Wait for a context to finish with results. Calls ub_process() after
- * the wait for you. After the wait, there are no more outstanding
- * asynchronous queries.
- * @param ctx: context.
- * @return: 0 if OK, else error.
- */
-int ub_wait(struct ub_ctx* ctx);
-
-/**
- * Get file descriptor. Wait for it to become readable, at this point
- * answers are returned from the asynchronous validating resolver.
- * Then call the ub_process to continue processing.
- * This routine works immediately after context creation, the fd
- * does not change.
- * @param ctx: context.
- * @return: -1 on error, or file descriptor to use select(2) with.
- */
-int ub_fd(struct ub_ctx* ctx);
-
-/**
- * Call this routine to continue processing results from the validating
- * resolver (when the fd becomes readable).
- * Will perform necessary callbacks.
- * @param ctx: context
- * @return: 0 if OK, else error.
- */
-int ub_process(struct ub_ctx* ctx);
-
-/**
- * Perform resolution and validation of the target name.
- * @param ctx: context.
- * The context is finalized, and can no longer accept config changes.
- * @param name: domain name in text format (a zero terminated text string).
- * @param rrtype: type of RR in host order, 1 is A (address).
- * @param rrclass: class of RR in host order, 1 is IN (for internet).
- * @param result: the result data is returned in a newly allocated result
- * structure. May be NULL on return, return value is set to an error
- * in that case (out of memory).
- * @return 0 if OK, else error.
- */
-int ub_resolve(struct ub_ctx* ctx, char* name, int rrtype,
- int rrclass, struct ub_result** result);
-
-/**
- * Perform resolution and validation of the target name.
- * Asynchronous, after a while, the callback will be called with your
- * data and the result.
- * @param ctx: context.
- * If no thread or process has been created yet to perform the
- * work in the background, it is created now.
- * The context is finalized, and can no longer accept config changes.
- * @param name: domain name in text format (a string).
- * @param rrtype: type of RR in host order, 1 is A.
- * @param rrclass: class of RR in host order, 1 is IN (for internet).
- * @param mydata: this data is your own data (you can pass NULL),
- * and is passed on to the callback function.
- * @param callback: this is called on completion of the resolution.
- * It is called as:
- * void callback(void* mydata, int err, struct ub_result* result)
- * with mydata: the same as passed here, you may pass NULL,
- * with err: is 0 when a result has been found.
- * with result: a newly allocated result structure.
- * The result may be NULL, in that case err is set.
- *
- * If an error happens during processing, your callback will be called
- * with error set to a nonzero value (and result==NULL).
- * @param async_id: if you pass a non-NULL value, an identifier number is
- * returned for the query as it is in progress. It can be used to
- * cancel the query.
- * @return 0 if OK, else error.
- */
-int ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype,
- int rrclass, void* mydata, ub_callback_t callback, int* async_id);
-
-/**
- * Cancel an async query in progress.
- * Its callback will not be called.
- *
- * @param ctx: context.
- * @param async_id: which query to cancel.
- * @return 0 if OK, else error.
- * This routine can return an error if the async_id passed does not exist
- * or has already been delivered. If another thread is processing results
- * at the same time, the result may be delivered at the same time and the
- * cancel fails with an error. Also the cancel can fail due to a system
- * error, no memory or socket failures.
- */
-int ub_cancel(struct ub_ctx* ctx, int async_id);
-
-/**
- * Free storage associated with a result structure.
- * @param result: to free
- */
-void ub_resolve_free(struct ub_result* result);
-
-/**
- * Convert error value to a human readable string.
- * @param err: error code from one of the ub_val* functions.
- * @return pointer to constant text string, zero terminated.
- */
-const char* ub_strerror(int err);
-
-/**
- * Debug routine. Print the local zone information to debug output.
- * @param ctx: context. Is finalized by the routine.
- * @return 0 if OK, else error.
- */
-int ub_ctx_print_local_zones(struct ub_ctx* ctx);
-
-/**
- * Add a new zone with the zonetype to the local authority info of the
- * library.
- * @param ctx: context. Is finalized by the routine.
- * @param zone_name: name of the zone in text, "example.com"
- * If it already exists, the type is updated.
- * @param zone_type: type of the zone (like for unbound.conf) in text.
- * @return 0 if OK, else error.
- */
-int ub_ctx_zone_add(struct ub_ctx* ctx, char *zone_name, char *zone_type);
-
-/**
- * Remove zone from local authority info of the library.
- * @param ctx: context. Is finalized by the routine.
- * @param zone_name: name of the zone in text, "example.com"
- * If it does not exist, nothing happens.
- * @return 0 if OK, else error.
- */
-int ub_ctx_zone_remove(struct ub_ctx* ctx, char *zone_name);
-
-/**
- * Add localdata to the library local authority info.
- * Similar to local-data config statement.
- * @param ctx: context. Is finalized by the routine.
- * @param data: the resource record in text format, for example
- * "www.example.com IN A 127.0.0.1"
- * @return 0 if OK, else error.
- */
-int ub_ctx_data_add(struct ub_ctx* ctx, char *data);
-
-/**
- * Remove localdata from the library local authority info.
- * @param ctx: context. Is finalized by the routine.
- * @param data: the name to delete all data from, like "www.example.com".
- * @return 0 if OK, else error.
- */
-int ub_ctx_data_remove(struct ub_ctx* ctx, char *data);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _UB_UNBOUND_H */
diff --git a/src/native/libjunbound/windows64/libcrypto.a b/src/native/libjunbound/windows64/libcrypto.a
deleted file mode 100644
index 71a8fde..0000000
--- a/src/native/libjunbound/windows64/libcrypto.a
+++ /dev/null
Binary files differ
diff --git a/src/native/libjunbound/windows64/libldns.a b/src/native/libjunbound/windows64/libldns.a
deleted file mode 100644
index 2a094a9..0000000
--- a/src/native/libjunbound/windows64/libldns.a
+++ /dev/null
Binary files differ
diff --git a/src/native/libjunbound/windows64/libunbound.a b/src/native/libjunbound/windows64/libunbound.a
deleted file mode 100644
index 47d1902..0000000
--- a/src/native/libjunbound/windows64/libunbound.a
+++ /dev/null
Binary files differ
diff --git a/src/native/libjunbound/windows64/unbound.h b/src/native/libjunbound/windows64/unbound.h
deleted file mode 100644
index 14f1fea..0000000
--- a/src/native/libjunbound/windows64/unbound.h
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright (c) 2007, NLnet Labs. All rights reserved.
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * \file
- *
- * This file contains functions to resolve DNS queries and
- * validate the answers. Synchonously and asynchronously.
- *
- * Several ways to use this interface from an application wishing
- * to perform (validated) DNS lookups.
- *
- * All start with
- * ctx = ub_ctx_create();
- * err = ub_ctx_add_ta(ctx, "...");
- * err = ub_ctx_add_ta(ctx, "...");
- * ... some lookups
- * ... call ub_ctx_delete(ctx); when you want to stop.
- *
- * Application not threaded. Blocking.
- * int err = ub_resolve(ctx, "www.example.com", ...
- * if(err) fprintf(stderr, "lookup error: %s\n", ub_strerror(err));
- * ... use the answer
- *
- * Application not threaded. Non-blocking ('asynchronous').
- * err = ub_resolve_async(ctx, "www.example.com", ... my_callback);
- * ... application resumes processing ...
- * ... and when either ub_poll(ctx) is true
- * ... or when the file descriptor ub_fd(ctx) is readable,
- * ... or whenever, the app calls ...
- * ub_process(ctx);
- * ... if no result is ready, the app resumes processing above,
- * ... or process() calls my_callback() with results.
- *
- * ... if the application has nothing more to do, wait for answer
- * ub_wait(ctx);
- *
- * Application threaded. Blocking.
- * Blocking, same as above. The current thread does the work.
- * Multiple threads can use the *same context*, each does work and uses
- * shared cache data from the context.
- *
- * Application threaded. Non-blocking ('asynchronous').
- * ... setup threaded-asynchronous config option
- * err = ub_ctx_async(ctx, 1);
- * ... same as async for non-threaded
- * ... the callbacks are called in the thread that calls process(ctx)
- *
- * If no threading is compiled in, the above async example uses fork(2) to
- * create a process to perform the work. The forked process exits when the
- * calling process exits, or ctx_delete() is called.
- * Otherwise, for asynchronous with threading, a worker thread is created.
- *
- * The blocking calls use shared ctx-cache when threaded. Thus
- * ub_resolve() and ub_resolve_async() && ub_wait() are
- * not the same. The first makes the current thread do the work, setting
- * up buffers, etc, to perform the work (but using shared cache data).
- * The second calls another worker thread (or process) to perform the work.
- * And no buffers need to be set up, but a context-switch happens.
- */
-#ifndef _UB_UNBOUND_H
-#define _UB_UNBOUND_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * The validation context is created to hold the resolver status,
- * validation keys and a small cache (containing messages, rrsets,
- * roundtrip times, trusted keys, lameness information).
- *
- * Its contents are internally defined.
- */
-struct ub_ctx;
-
-/**
- * The validation and resolution results.
- * Allocated by the resolver, and need to be freed by the application
- * with ub_resolve_free().
- */
-struct ub_result {
- /** The original question, name text string. */
- char* qname;
- /** the type asked for */
- int qtype;
- /** the class asked for */
- int qclass;
-
- /**
- * a list of network order DNS rdata items, terminated with a
- * NULL pointer, so that data[0] is the first result entry,
- * data[1] the second, and the last entry is NULL.
- * If there was no data, data[0] is NULL.
- */
- char** data;
-
- /** the length in bytes of the data items, len[i] for data[i] */
- int* len;
-
- /**
- * canonical name for the result (the final cname).
- * zero terminated string.
- * May be NULL if no canonical name exists.
- */
- char* canonname;
-
- /**
- * DNS RCODE for the result. May contain additional error code if
- * there was no data due to an error. 0 (NOERROR) if okay.
- */
- int rcode;
-
- /**
- * The DNS answer packet. Network formatted. Can contain DNSSEC types.
- */
- void* answer_packet;
- /** length of the answer packet in octets. */
- int answer_len;
-
- /**
- * If there is any data, this is true.
- * If false, there was no data (nxdomain may be true, rcode can be set).
- */
- int havedata;
-
- /**
- * If there was no data, and the domain did not exist, this is true.
- * If it is false, and there was no data, then the domain name
- * is purported to exist, but the requested data type is not available.
- */
- int nxdomain;
-
- /**
- * True, if the result is validated securely.
- * False, if validation failed or domain queried has no security info.
- *
- * It is possible to get a result with no data (havedata is false),
- * and secure is true. This means that the non-existance of the data
- * was cryptographically proven (with signatures).
- */
- int secure;
-
- /**
- * If the result was not secure (secure==0), and this result is due
- * to a security failure, bogus is true.
- * This means the data has been actively tampered with, signatures
- * failed, expected signatures were not present, timestamps on
- * signatures were out of date and so on.
- *
- * If !secure and !bogus, this can happen if the data is not secure
- * because security is disabled for that domain name.
- * This means the data is from a domain where data is not signed.
- */
- int bogus;
-
- /**
- * If the result is bogus this contains a string (zero terminated)
- * that describes the failure. There may be other errors as well
- * as the one described, the description may not be perfectly accurate.
- * Is NULL if the result is not bogus.
- */
- char* why_bogus;
-};
-
-/**
- * Callback for results of async queries.
- * The readable function definition looks like:
- * void my_callback(void* my_arg, int err, struct ub_result* result);
- * It is called with
- * void* my_arg: your pointer to a (struct of) data of your choice,
- * or NULL.
- * int err: if 0 all is OK, otherwise an error occured and no results
- * are forthcoming.
- * struct result: pointer to more detailed result structure.
- * This structure is allocated on the heap and needs to be
- * freed with ub_resolve_free(result);
- */
-typedef void (*ub_callback_t)(void*, int, struct ub_result*);
-
-/**
- * Create a resolving and validation context.
- * The information from /etc/resolv.conf and /etc/hosts is not utilised by
- * default. Use ub_ctx_resolvconf and ub_ctx_hosts to read them.
- * @return a new context. default initialisation.
- * returns NULL on error.
- */
-struct ub_ctx* ub_ctx_create(void);
-
-/**
- * Destroy a validation context and free all its resources.
- * Outstanding async queries are killed and callbacks are not called for them.
- * @param ctx: context to delete.
- */
-void ub_ctx_delete(struct ub_ctx* ctx);
-
-/**
- * Set an option for the context.
- * @param ctx: context.
- * @param opt: option name from the unbound.conf config file format.
- * (not all settings applicable). The name includes the trailing ':'
- * for example ub_ctx_set_option(ctx, "logfile:", "mylog.txt");
- * This is a power-users interface that lets you specify all sorts
- * of options.
- * For some specific options, such as adding trust anchors, special
- * routines exist.
- * @param val: value of the option.
- * @return: 0 if OK, else error.
- */
-int ub_ctx_set_option(struct ub_ctx* ctx, char* opt, char* val);
-
-/**
- * Get an option from the context.
- * @param ctx: context.
- * @param opt: option name from the unbound.conf config file format.
- * (not all settings applicable). The name excludes the trailing ':'
- * for example ub_ctx_get_option(ctx, "logfile", &result);
- * This is a power-users interface that lets you specify all sorts
- * of options.
- * @param str: the string is malloced and returned here. NULL on error.
- * The caller must free() the string. In cases with multiple
- * entries (auto-trust-anchor-file), a newline delimited list is
- * returned in the string.
- * @return 0 if OK else an error code (malloc failure, syntax error).
- */
-int ub_ctx_get_option(struct ub_ctx* ctx, char* opt, char** str);
-
-/**
- * setup configuration for the given context.
- * @param ctx: context.
- * @param fname: unbound config file (not all settings applicable).
- * This is a power-users interface that lets you specify all sorts
- * of options.
- * For some specific options, such as adding trust anchors, special
- * routines exist.
- * @return: 0 if OK, else error.
- */
-int ub_ctx_config(struct ub_ctx* ctx, char* fname);
-
-/**
- * Set machine to forward DNS queries to, the caching resolver to use.
- * IP4 or IP6 address. Forwards all DNS requests to that machine, which
- * is expected to run a recursive resolver. If the proxy is not
- * DNSSEC-capable, validation may fail. Can be called several times, in
- * that case the addresses are used as backup servers.
- *
- * To read the list of nameservers from /etc/resolv.conf (from DHCP or so),
- * use the call ub_ctx_resolvconf.
- *
- * @param ctx: context.
- * At this time it is only possible to set configuration before the
- * first resolve is done.
- * @param addr: address, IP4 or IP6 in string format.
- * If the addr is NULL, forwarding is disabled.
- * @return 0 if OK, else error.
- */
-int ub_ctx_set_fwd(struct ub_ctx* ctx, char* addr);
-
-/**
- * Read list of nameservers to use from the filename given.
- * Usually "/etc/resolv.conf". Uses those nameservers as caching proxies.
- * If they do not support DNSSEC, validation may fail.
- *
- * Only nameservers are picked up, the searchdomain, ndots and other
- * settings from resolv.conf(5) are ignored.
- *
- * @param ctx: context.
- * At this time it is only possible to set configuration before the
- * first resolve is done.
- * @param fname: file name string. If NULL "/etc/resolv.conf" is used.
- * @return 0 if OK, else error.
- */
-int ub_ctx_resolvconf(struct ub_ctx* ctx, char* fname);
-
-/**
- * Read list of hosts from the filename given.
- * Usually "/etc/hosts".
- * These addresses are not flagged as DNSSEC secure when queried for.
- *
- * @param ctx: context.
- * At this time it is only possible to set configuration before the
- * first resolve is done.
- * @param fname: file name string. If NULL "/etc/hosts" is used.
- * @return 0 if OK, else error.
- */
-int ub_ctx_hosts(struct ub_ctx* ctx, char* fname);
-
-/**
- * Add a trust anchor to the given context.
- * The trust anchor is a string, on one line, that holds a valid DNSKEY or
- * DS RR.
- * @param ctx: context.
- * At this time it is only possible to add trusted keys before the
- * first resolve is done.
- * @param ta: string, with zone-format RR on one line.
- * [domainname] [TTL optional] [type] [class optional] [rdata contents]
- * @return 0 if OK, else error.
- */
-int ub_ctx_add_ta(struct ub_ctx* ctx, char* ta);
-
-/**
- * Add trust anchors to the given context.
- * Pass name of a file with DS and DNSKEY records (like from dig or drill).
- * @param ctx: context.
- * At this time it is only possible to add trusted keys before the
- * first resolve is done.
- * @param fname: filename of file with keyfile with trust anchors.
- * @return 0 if OK, else error.
- */
-int ub_ctx_add_ta_file(struct ub_ctx* ctx, char* fname);
-
-/**
- * Add trust anchors to the given context.
- * Pass the name of a bind-style config file with trusted-keys{}.
- * @param ctx: context.
- * At this time it is only possible to add trusted keys before the
- * first resolve is done.
- * @param fname: filename of file with bind-style config entries with trust
- * anchors.
- * @return 0 if OK, else error.
- */
-int ub_ctx_trustedkeys(struct ub_ctx* ctx, char* fname);
-
-/**
- * Set debug output (and error output) to the specified stream.
- * Pass NULL to disable. Default is stderr.
- * @param ctx: context.
- * @param out: FILE* out file stream to log to.
- * Type void* to avoid stdio dependency of this header file.
- * @return 0 if OK, else error.
- */
-int ub_ctx_debugout(struct ub_ctx* ctx, void* out);
-
-/**
- * Set debug verbosity for the context
- * Output is directed to stderr.
- * @param ctx: context.
- * @param d: debug level, 0 is off, 1 is very minimal, 2 is detailed,
- * and 3 is lots.
- * @return 0 if OK, else error.
- */
-int ub_ctx_debuglevel(struct ub_ctx* ctx, int d);
-
-/**
- * Set a context behaviour for asynchronous action.
- * @param ctx: context.
- * @param dothread: if true, enables threading and a call to resolve_async()
- * creates a thread to handle work in the background.
- * If false, a process is forked to handle work in the background.
- * Changes to this setting after async() calls have been made have
- * no effect (delete and re-create the context to change).
- * @return 0 if OK, else error.
- */
-int ub_ctx_async(struct ub_ctx* ctx, int dothread);
-
-/**
- * Poll a context to see if it has any new results
- * Do not poll in a loop, instead extract the fd below to poll for readiness,
- * and then check, or wait using the wait routine.
- * @param ctx: context.
- * @return: 0 if nothing to read, or nonzero if a result is available.
- * If nonzero, call ctx_process() to do callbacks.
- */
-int ub_poll(struct ub_ctx* ctx);
-
-/**
- * Wait for a context to finish with results. Calls ub_process() after
- * the wait for you. After the wait, there are no more outstanding
- * asynchronous queries.
- * @param ctx: context.
- * @return: 0 if OK, else error.
- */
-int ub_wait(struct ub_ctx* ctx);
-
-/**
- * Get file descriptor. Wait for it to become readable, at this point
- * answers are returned from the asynchronous validating resolver.
- * Then call the ub_process to continue processing.
- * This routine works immediately after context creation, the fd
- * does not change.
- * @param ctx: context.
- * @return: -1 on error, or file descriptor to use select(2) with.
- */
-int ub_fd(struct ub_ctx* ctx);
-
-/**
- * Call this routine to continue processing results from the validating
- * resolver (when the fd becomes readable).
- * Will perform necessary callbacks.
- * @param ctx: context
- * @return: 0 if OK, else error.
- */
-int ub_process(struct ub_ctx* ctx);
-
-/**
- * Perform resolution and validation of the target name.
- * @param ctx: context.
- * The context is finalized, and can no longer accept config changes.
- * @param name: domain name in text format (a zero terminated text string).
- * @param rrtype: type of RR in host order, 1 is A (address).
- * @param rrclass: class of RR in host order, 1 is IN (for internet).
- * @param result: the result data is returned in a newly allocated result
- * structure. May be NULL on return, return value is set to an error
- * in that case (out of memory).
- * @return 0 if OK, else error.
- */
-int ub_resolve(struct ub_ctx* ctx, char* name, int rrtype,
- int rrclass, struct ub_result** result);
-
-/**
- * Perform resolution and validation of the target name.
- * Asynchronous, after a while, the callback will be called with your
- * data and the result.
- * @param ctx: context.
- * If no thread or process has been created yet to perform the
- * work in the background, it is created now.
- * The context is finalized, and can no longer accept config changes.
- * @param name: domain name in text format (a string).
- * @param rrtype: type of RR in host order, 1 is A.
- * @param rrclass: class of RR in host order, 1 is IN (for internet).
- * @param mydata: this data is your own data (you can pass NULL),
- * and is passed on to the callback function.
- * @param callback: this is called on completion of the resolution.
- * It is called as:
- * void callback(void* mydata, int err, struct ub_result* result)
- * with mydata: the same as passed here, you may pass NULL,
- * with err: is 0 when a result has been found.
- * with result: a newly allocated result structure.
- * The result may be NULL, in that case err is set.
- *
- * If an error happens during processing, your callback will be called
- * with error set to a nonzero value (and result==NULL).
- * @param async_id: if you pass a non-NULL value, an identifier number is
- * returned for the query as it is in progress. It can be used to
- * cancel the query.
- * @return 0 if OK, else error.
- */
-int ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype,
- int rrclass, void* mydata, ub_callback_t callback, int* async_id);
-
-/**
- * Cancel an async query in progress.
- * Its callback will not be called.
- *
- * @param ctx: context.
- * @param async_id: which query to cancel.
- * @return 0 if OK, else error.
- * This routine can return an error if the async_id passed does not exist
- * or has already been delivered. If another thread is processing results
- * at the same time, the result may be delivered at the same time and the
- * cancel fails with an error. Also the cancel can fail due to a system
- * error, no memory or socket failures.
- */
-int ub_cancel(struct ub_ctx* ctx, int async_id);
-
-/**
- * Free storage associated with a result structure.
- * @param result: to free
- */
-void ub_resolve_free(struct ub_result* result);
-
-/**
- * Convert error value to a human readable string.
- * @param err: error code from one of the ub_val* functions.
- * @return pointer to constant text string, zero terminated.
- */
-const char* ub_strerror(int err);
-
-/**
- * Debug routine. Print the local zone information to debug output.
- * @param ctx: context. Is finalized by the routine.
- * @return 0 if OK, else error.
- */
-int ub_ctx_print_local_zones(struct ub_ctx* ctx);
-
-/**
- * Add a new zone with the zonetype to the local authority info of the
- * library.
- * @param ctx: context. Is finalized by the routine.
- * @param zone_name: name of the zone in text, "example.com"
- * If it already exists, the type is updated.
- * @param zone_type: type of the zone (like for unbound.conf) in text.
- * @return 0 if OK, else error.
- */
-int ub_ctx_zone_add(struct ub_ctx* ctx, char *zone_name, char *zone_type);
-
-/**
- * Remove zone from local authority info of the library.
- * @param ctx: context. Is finalized by the routine.
- * @param zone_name: name of the zone in text, "example.com"
- * If it does not exist, nothing happens.
- * @return 0 if OK, else error.
- */
-int ub_ctx_zone_remove(struct ub_ctx* ctx, char *zone_name);
-
-/**
- * Add localdata to the library local authority info.
- * Similar to local-data config statement.
- * @param ctx: context. Is finalized by the routine.
- * @param data: the resource record in text format, for example
- * "www.example.com IN A 127.0.0.1"
- * @return 0 if OK, else error.
- */
-int ub_ctx_data_add(struct ub_ctx* ctx, char *data);
-
-/**
- * Remove localdata from the library local authority info.
- * @param ctx: context. Is finalized by the routine.
- * @param data: the name to delete all data from, like "www.example.com".
- * @return 0 if OK, else error.
- */
-int ub_ctx_data_remove(struct ub_ctx* ctx, char *data);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _UB_UNBOUND_H */
diff --git a/src/native/windows/msofficecomm/OutOfProcessServer.cxx b/src/native/windows/msofficecomm/OutOfProcessServer.cxx
index 5311471..416ba76 100644
--- a/src/native/windows/msofficecomm/OutOfProcessServer.cxx
+++ b/src/native/windows/msofficecomm/OutOfProcessServer.cxx
@@ -244,6 +244,11 @@ HRESULT OutOfProcessServer::loadRegTypeLib()
LPTYPELIB iTypeLib;
HRESULT hr = ::LoadRegTypeLib(LIBID_CommunicatorUA, 1, 0, 0, &iTypeLib);
+ Log::d(
+ _T("OutOfProcessServer::loadRegTypeLib:")
+ _T(" LoadRegTypeLib=%08X;")
+ _T("\n"),
+ hr);
if (SUCCEEDED(hr))
_iTypeLib = iTypeLib;
else
@@ -261,50 +266,41 @@ HRESULT OutOfProcessServer::loadRegTypeLib()
WCHAR path[MAX_PATH + 1];
DWORD pathCapacity = sizeof(path) / sizeof(WCHAR);
DWORD pathLength = ::GetModuleFileNameW(module, path, pathCapacity);
-
if (pathLength && (pathLength < pathCapacity))
{
hr = ::LoadTypeLibEx(path, REGKIND_NONE, &iTypeLib);
+ Log::d(
+ _T("OutOfProcessServer::loadRegTypeLib:")
+ _T(" LoadTypeLibEx(%s)=%08X;")
+ _T("\n"),
+ path,
+ hr);
if (SUCCEEDED(hr))
{
- HMODULE oleaut32 = ::GetModuleHandle(_T("oleaut32.dll"));
-
- if (oleaut32)
+ hr = ::RegisterTypeLibForUser(iTypeLib, path, NULL);
+ Log::d(
+ _T("OutOfProcessServer::loadRegTypeLib:")
+ _T(" RegisterTypeLibForUser=%08X;")
+ _T("\n"),
+ hr);
+ if (SUCCEEDED(hr))
{
- typedef HRESULT (WINAPI *RTLFU)(LPTYPELIB,LPOLESTR,LPOLESTR);
- RTLFU registerTypeLibForUser
- = (RTLFU)
- ::GetProcAddress(
- oleaut32,
- "RegisterTypeLibForUser");
-
- if (registerTypeLibForUser)
- {
- hr = registerTypeLibForUser(iTypeLib, path, NULL);
- if (SUCCEEDED(hr))
- {
- /*
- * The whole point of what has been done till
- * now is securing the success of future calls
- * to LoadRegTypeLib. Make sure that is indeed
- * the case.
- */
-
- iTypeLib->Release();
-
- hr
- = ::LoadRegTypeLib(
- LIBID_CommunicatorUA,
- 1,
- 0,
- 0,
- &iTypeLib);
- if (SUCCEEDED(hr))
- _iTypeLib = iTypeLib;
- }
- }
- else
- hr = E_UNEXPECTED;
+ /*
+ * The whole point of what has been done till
+ * now is securing the success of future calls
+ * to LoadRegTypeLib. Make sure that is indeed
+ * the case.
+ */
+ iTypeLib->Release();
+ hr = ::LoadRegTypeLib(
+ LIBID_CommunicatorUA, 1, 0, 0, &iTypeLib);
+ Log::d(
+ _T("OutOfProcessServer::loadRegTypeLib:")
+ _T(" LoadRegTypeLib=%08X;")
+ _T("\n"),
+ hr);
+ if (SUCCEEDED(hr))
+ _iTypeLib = iTypeLib;
}
else
hr = E_UNEXPECTED;
@@ -429,12 +425,28 @@ unsigned __stdcall OutOfProcessServer::run(void *)
HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
unsigned ret = 0;
+ Log::d(
+ _T("OutOfProcessServer::run:")
+ _T(" CoInitializeEx=%08X;")
+ _T("\n"),
+ hr);
if (SUCCEEDED(hr))
{
hr = loadRegTypeLib();
+ Log::d(
+ _T("OutOfProcessServer::run:")
+ _T(" loadRegTypeLib=%08X;")
+ _T("\n"),
+ hr);
if (SUCCEEDED(hr))
{
- if (ERROR_SUCCESS == setIMProvidersCommunicatorUpAndRunning(1))
+ hr = setIMProvidersCommunicatorUpAndRunning(1);
+ Log::d(
+ _T("OutOfProcessServer::run:")
+ _T(" setIMProvidersCommunicatorUpAndRunning(1)=%08X;")
+ _T("\n"),
+ hr);
+ if (ERROR_SUCCESS == hr)
{
MSG msg;
@@ -446,10 +458,20 @@ unsigned __stdcall OutOfProcessServer::run(void *)
::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
hr = registerClassObjects();
+ Log::d(
+ _T("OutOfProcessServer::run:")
+ _T(" registerClassObjects=%08X;")
+ _T("\n"),
+ hr);
if (SUCCEEDED(hr))
{
- if (ERROR_SUCCESS
- == setIMProvidersCommunicatorUpAndRunning(2))
+ hr = setIMProvidersCommunicatorUpAndRunning(2);
+ Log::d(
+ _T("OutOfProcessServer::run:")
+ _T(" setIMProvidersCommunicatorUpAndRunning(2)=%08X;")
+ _T("\n"),
+ hr);
+ if (ERROR_SUCCESS == hr)
{
HANDLE threadHandle = _threadHandle;
BOOL logMsgWaitForMultipleObjectsExFailed = TRUE;
@@ -526,51 +548,12 @@ unsigned __stdcall OutOfProcessServer::run(void *)
DWORD OutOfProcessServer::setIMProvidersCommunicatorUpAndRunning(DWORD dw)
{
- DWORD lastError;
-
- if (dw)
- {
- /*
- * Testing on various machines/setups has shown that the following may
- * or may not succeed without affecting the presence integration so just
- * try them and then go on with the rest regardless of their success.
- */
- lastError = ERROR_SUCCESS;
- regCreateKeyAndSetValue(
- _T("Software\\Microsoft\\Office\\11.0\\Common\\PersonaMenu"),
- _T("RTCApplication"),
- 3);
- regCreateKeyAndSetValue(
- _T("Software\\Microsoft\\Office\\12.0\\Common\\PersonaMenu"),
- _T("RTCApplication"),
- 3);
- regCreateKeyAndSetValue(
- _T("Software\\Microsoft\\Office\\11.0\\Common\\PersonaMenu"),
- _T("QueryServiceForStatus"),
- 2);
- regCreateKeyAndSetValue(
- _T("Software\\Microsoft\\Office\\12.0\\Common\\PersonaMenu"),
- _T("QueryServiceForStatus"),
- 2);
- regCreateKeyAndSetValue(
- _T("Software\\Microsoft\\Office\\11.0\\Outlook\\IM"),
- _T("SetOnlineStatusLevel"),
- 3);
- regCreateKeyAndSetValue(
- _T("Software\\Microsoft\\Office\\12.0\\Outlook\\IM"),
- _T("SetOnlineStatusLevel"),
- 3);
- }
- else
- lastError = ERROR_SUCCESS;
- if (ERROR_SUCCESS == lastError)
- {
- lastError
+ DWORD lastError
= regCreateKeyAndSetValue(
- _T("Software\\IM Providers\\Communicator"),
+ _T("Software\\IM Providers\\Jitsi"),
_T("UpAndRunning"),
dw);
- }
+
return lastError;
}
diff --git a/src/native/windows/msofficecomm/msofficecomm.vcxproj b/src/native/windows/msofficecomm/msofficecomm.vcxproj
index 96391df..b74f1d9 100644
--- a/src/native/windows/msofficecomm/msofficecomm.vcxproj
+++ b/src/native/windows/msofficecomm/msofficecomm.vcxproj
@@ -74,11 +74,13 @@
<LinkIncremental>true</LinkIncremental>
<IncludePath>C:\Program Files (x86)\Microsoft Office Communicator\SDK;C:\Java\jdk8\include;C:\Java\jdk8\include\win32;$(IncludePath)</IncludePath>
<TargetName>j$(ProjectName)</TargetName>
+ <OutDir>..\..\..\..\lib\native\windows\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<TargetName>j$(ProjectName)</TargetName>
<IncludePath>C:\Program Files %28x86%29\Microsoft Office Communicator\SDK;C:\Java\JDK8x64\include;C:\Java\JDK8x64\include\win32;$(IncludePath)</IncludePath>
+ <OutDir>..\..\..\..\lib\native\windows-64\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
diff --git a/src/native/windows/run/run.c b/src/native/windows/run/run.c
index 7f152e9..4bae363 100644
--- a/src/native/windows/run/run.c
+++ b/src/native/windows/run/run.c
@@ -525,6 +525,7 @@ Run_getJavaVMOptionStrings
= {
_T("lib\\felix.jar"),
_T("sc-bundles\\sc-launcher.jar"),
+ _T("sc-bundles\\dnsjava.jar"),
_T("sc-bundles\\util.jar"),
_T("lib"),
NULL
diff --git a/src/net/java/sip/communicator/impl/certificate/CertificateServiceImpl.java b/src/net/java/sip/communicator/impl/certificate/CertificateServiceImpl.java
index 7bf29d1..bb888ad 100644
--- a/src/net/java/sip/communicator/impl/certificate/CertificateServiceImpl.java
+++ b/src/net/java/sip/communicator/impl/certificate/CertificateServiceImpl.java
@@ -211,49 +211,6 @@ public class CertificateServiceImpl
System.getProperties().remove("javax.net.ssl.trustStorePassword");
}
- /**
- * Appends an index number to the alias of each entry in the KeyStore.
- *
- * The Windows TrustStore might contain multiple entries with the same
- * "Friendly Name", which is directly used as the "Alias" for the KeyStore.
- * As all operations of the KeyStore operate with these non-unique names,
- * PKIX path building could fail and in the end lead to certificate warnings
- * for perfectly valid certificates.
- *
- * @throws Exception when the aliases could not be renamed.
- */
- private static int keyStoreAppendIndex(KeyStore ks) throws Exception
- {
- Field keyStoreSpiField = ks.getClass().getDeclaredField("keyStoreSpi");
- keyStoreSpiField.setAccessible(true);
- KeyStoreSpi keyStoreSpi = (KeyStoreSpi) keyStoreSpiField.get(ks);
-
- if ("sun.security.mscapi.KeyStore$ROOT".equals(keyStoreSpi.getClass()
- .getName()))
- {
- Field entriesField =
- keyStoreSpi.getClass().getEnclosingClass()
- .getDeclaredField("entries");
- entriesField.setAccessible(true);
- Collection<?> entries =
- (Collection<?>) entriesField.get(keyStoreSpi);
-
- int i = 0;
- for (Object entry : entries)
- {
- Field aliasField = entry.getClass().getDeclaredField("alias");
- aliasField.setAccessible(true);
- String alias = (String) aliasField.get(entry);
- aliasField.set(entry,
- alias.concat("_").concat(Integer.toString(i++)));
- }
-
- return i;
- }
-
- return -1;
- }
-
// ------------------------------------------------------------------------
// Client authentication configuration
// ------------------------------------------------------------------------
@@ -678,10 +635,6 @@ public class CertificateServiceImpl
{
ks = KeyStore.getInstance(tsType);
ks.load(null, null);
- int numEntries = keyStoreAppendIndex(ks);
- logger.info(
- "Using Windows-ROOT. Aliases sucessfully renamed on "
- + numEntries + " root certificates.");
}
catch (Exception e)
{
@@ -784,8 +737,7 @@ public class CertificateServiceImpl
propNames.add(propName);
message =
- R.getI18NString("service.gui."
- + "CERT_DIALOG_DESCRIPTION_TXT_NOHOST",
+ R.getI18NString("service.gui.CERT_DIALOG_DESCRIPTION_TXT_NOHOST",
new String[] {
appName
}
@@ -809,8 +761,7 @@ public class CertificateServiceImpl
{
message =
R.getI18NString(
- "service.gui."
- + "CERT_DIALOG_DESCRIPTION_TXT",
+ "service.gui.CERT_DIALOG_DESCRIPTION_TXT",
new String[] {
appName,
identitiesToTest.toString()
@@ -821,8 +772,7 @@ public class CertificateServiceImpl
{
message =
R.getI18NString(
- "service.gui."
- + "CERT_DIALOG_PEER_DESCRIPTION_TXT",
+ "service.gui.CERT_DIALOG_PEER_DESCRIPTION_TXT",
new String[] {
appName,
identitiesToTest.toString()
diff --git a/src/net/java/sip/communicator/impl/configuration/ConfigurationActivator.java b/src/net/java/sip/communicator/impl/configuration/ConfigurationActivator.java
index 1553658..a77b2f5 100644
--- a/src/net/java/sip/communicator/impl/configuration/ConfigurationActivator.java
+++ b/src/net/java/sip/communicator/impl/configuration/ConfigurationActivator.java
@@ -28,6 +28,9 @@ import org.jitsi.util.*;
import org.osgi.framework.*;
import java.io.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.util.*;
/**
*
@@ -64,39 +67,38 @@ public class ConfigurationActivator
if (fas != null)
{
- File useDatabaseConfig;
-
+ File usePropFileConfig;
try
{
- useDatabaseConfig
+ usePropFileConfig
= fas.getPrivatePersistentFile(
- ".usedatabaseconfig",
+ ".usepropfileconfig",
FileCategory.PROFILE);
}
catch (Exception ise)
{
-
// There is somewhat of a chicken-and-egg dependency between
// FileConfigurationServiceImpl and ConfigurationServiceImpl:
// FileConfigurationServiceImpl throws IllegalStateException if
// certain System properties are not set,
// ConfigurationServiceImpl will make sure that these properties
- //are set but it will do that later.
+ // are set but it will do that later.
// A SecurityException is thrown when the destination
// is not writable or we do not have access to that folder
- useDatabaseConfig = null;
+ usePropFileConfig = null;
}
- // BETA: if the marker file exists, use the database configuration
- if ((useDatabaseConfig != null) && useDatabaseConfig.exists())
+ if (usePropFileConfig != null && usePropFileConfig.exists())
{
- logger.info("Using database configuration store.");
- this.cs = new JdbcConfigService(fas);
+ logger.info("Using properties file configuration store.");
+ this.cs = LibJitsi.getConfigurationService();
}
}
if (this.cs == null)
- this.cs = LibJitsi.getConfigurationService();
+ {
+ this.cs = new JdbcConfigService(fas);
+ }
bundleContext.registerService(
ConfigurationService.class.getName(),
@@ -139,17 +141,30 @@ public class ConfigurationActivator
// let's check config file and config folder
File homeFolder
= new File(cs.getScHomeDirLocation(), cs.getScHomeDirName());
- CLibrary libc = (CLibrary) Native.loadLibrary("c", CLibrary.class);
-
- libc.chmod(homeFolder.getAbsolutePath(), 0700);
+ Set<PosixFilePermission> perms =
+ new HashSet<PosixFilePermission>()
+ {{
+ add(PosixFilePermission.OWNER_READ);
+ add(PosixFilePermission.OWNER_WRITE);
+ add(PosixFilePermission.OWNER_EXECUTE);
+ }};
+ Files.setPosixFilePermissions(
+ Paths.get(homeFolder.getAbsolutePath()), perms);
String fileName = cs.getConfigurationFilename();
-
if(fileName != null)
{
File cf = new File(homeFolder, fileName);
if(cf.exists())
- libc.chmod(cf.getAbsolutePath(), 0600);
+ {
+ perms = new HashSet<PosixFilePermission>()
+ {{
+ add(PosixFilePermission.OWNER_READ);
+ add(PosixFilePermission.OWNER_WRITE);
+ }};
+ Files.setPosixFilePermissions(
+ Paths.get(cf.getAbsolutePath()), perms);
+ }
}
}
catch(Throwable t)
@@ -164,24 +179,4 @@ public class ConfigurationActivator
throw (ThreadDeath) t;
}
}
-
- /**
- * The JNA interface to the <tt>c</tt> library and the <tt>chmod</tt>
- * function we use to fix permissions of user files and folders.
- */
- public interface CLibrary
- extends Library
- {
- /**
- * Changes file permissions.
- *
- * @param path the path to the file or folder the permissions of which
- * are to be changed.
- * @param mode the mode operand
- * @return <tt>0</tt> upon successful completion; otherwise,
- * <tt>-1</tt>. If <tt>-1</tt> is returned, no change to the file mode
- * occurs.
- */
- public int chmod(String path, int mode);
- }
}
diff --git a/src/net/java/sip/communicator/impl/configuration/JdbcConfigService.java b/src/net/java/sip/communicator/impl/configuration/JdbcConfigService.java
index 7ba362e..c9c9c3c 100644
--- a/src/net/java/sip/communicator/impl/configuration/JdbcConfigService.java
+++ b/src/net/java/sip/communicator/impl/configuration/JdbcConfigService.java
@@ -595,6 +595,35 @@ public final class JdbcConfigService
* (non-Javadoc)
*
* @see
+ * org.jitsi.service.configuration.ConfigurationService#getDouble(java.lang
+ * .String, double)
+ */
+ @Override
+ public double getDouble(String propertyName, double defaultValue)
+ {
+ Object value = this.getProperty(propertyName);
+ if (value == null || "".equals(value.toString()))
+ {
+ return defaultValue;
+ }
+
+ try
+ {
+ return Double.parseDouble(value.toString());
+ }
+ catch (NumberFormatException ex)
+ {
+ logger.error(String.format(
+ "'%s' for property %s not a double, returning default (%s)",
+ value, propertyName, defaultValue), ex);
+ return defaultValue;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
* org.jitsi.service.configuration.ConfigurationService#getLong(java.lang
* .String, long)
*/
diff --git a/src/net/java/sip/communicator/impl/dns/ConfigurableDnssecResolver.java b/src/net/java/sip/communicator/impl/dns/ConfigurableDnssecResolver.java
index af8d465..1b23af4 100644
--- a/src/net/java/sip/communicator/impl/dns/ConfigurableDnssecResolver.java
+++ b/src/net/java/sip/communicator/impl/dns/ConfigurableDnssecResolver.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,379 +15,457 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.dns;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.util.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.service.dns.*;
-import net.java.sip.communicator.service.notification.*;
-import net.java.sip.communicator.util.Logger;
-import net.java.sip.communicator.plugin.desktoputil.*;
-
-import org.jitsi.service.configuration.*;
-import org.jitsi.service.resources.*;
-import org.jitsi.util.*;
-import org.xbill.DNS.*;
-
-/**
- * Resolver that wraps a DNSSEC capable resolver and handles validation
- * failures according to the user's settings.
- *
- * @author Ingo Bauersachs
- */
-public class ConfigurableDnssecResolver
- extends UnboundResolver
-{
- private final static Logger logger
- = Logger.getLogger(ConfigurableDnssecResolver.class);
-
- /**
- * Name of the property that defines the default DNSSEC validation
- * behavior.
- */
- public final static String PNAME_DNSSEC_VALIDATION_MODE
- = "net.java.sip.communicator.util.dns.DNSSEC_VALIDATION_MODE";
-
- /**
- * Default value of {@link #PNAME_DNSSEC_VALIDATION_MODE}
- */
- public final static String PNAME_BASE_DNSSEC_PIN
- = "net.java.sip.communicator.util.dns.pin";
-
- final static String EVENT_TYPE = "DNSSEC_NOTIFICATION";
-
- private ConfigurationService config
- = DnsUtilActivator.getConfigurationService();
- private ResourceManagementService R
- = DnsUtilActivator.getResources();
- private Map<String, Date> lastNotifications
- = new HashMap<String, Date>();
-
- /**
- * Creates a new instance of this class. Tries to use the system's
- * default forwarders.
- */
- public ConfigurableDnssecResolver()
- {
- super();
- reset();
- Lookup.setDefaultResolver(this);
-
- DnsUtilActivator.getNotificationService().
- registerDefaultNotificationForEvent(
- ConfigurableDnssecResolver.EVENT_TYPE,
- NotificationAction.ACTION_POPUP_MESSAGE,
- null, null);
- }
-
- /**
- * Inspects a DNS answer message and handles validation results according to
- * the user's preferences.
- *
- * @throws DnssecRuntimeException when the validation failed and the user
- * did not choose to ignore it.
- */
- @Override
- protected void validateMessage(SecureMessage msg)
- throws DnssecRuntimeException
- {
- //---------------------------------------------------------------------
- // || 1 | 2 | 3 | 4 | 5
- //---------------------------------------------------------------------
- // Sec. | Bog. || Ign. | Sec.Only | Sec.Or.Unsig | Warn.Bog | WarnAll
- //---------------------------------------------------------------------
- //a) 1 | 0 || ok | ok | ok | ok | ok
- //b) 0 | 1 || ok | nok | nok | ask | ask
- //c) 0 | 0 || ok | nok | ok | ok | ask
- //---------------------------------------------------------------------
-
- String fqdn = msg.getQuestion().getName().toString();
- String type = Type.string(msg.getQuestion().getType());
- String propName = createPropNameUnsigned(fqdn, type);
- SecureResolveMode defaultAction = Enum.valueOf(SecureResolveMode.class,
- config.getString(
- PNAME_DNSSEC_VALIDATION_MODE,
- SecureResolveMode.WarnIfBogus.name()
- )
- );
- SecureResolveMode pinned = Enum.valueOf(SecureResolveMode.class,
- config.getString(
- propName,
- defaultAction.name()
- )
- );
-
- //create default entry
- if(pinned == defaultAction)
- config.setProperty(propName, pinned.name());
-
- //check domain policy
-
- //[abc]1, a[2-5]
- if(pinned == SecureResolveMode.IgnoreDnssec || msg.isSecure())
- return;
-
- if(
- //b2, c2
- (pinned == SecureResolveMode.SecureOnly && !msg.isSecure())
- ||
- //b3
- (pinned == SecureResolveMode.SecureOrUnsigned && msg.isBogus())
- )
- {
- String text = getExceptionMessage(msg);
- Date last = lastNotifications.get(text);
- if(last == null
- //wait at least 5 minutes before showing the same info again
- || last.before(new Date(new Date().getTime() - 1000*60*5)))
- {
- DnsUtilActivator.getNotificationService().fireNotification(
- EVENT_TYPE,
- R.getI18NString("util.dns.INSECURE_ANSWER_TITLE"),
- text,
- null);
- lastNotifications.put(text, new Date());
- }
- throw new DnssecRuntimeException(text);
- }
-
- //c3
- if(pinned == SecureResolveMode.SecureOrUnsigned && !msg.isBogus())
- return;
-
- //c4
- if(pinned == SecureResolveMode.WarnIfBogus && !msg.isBogus())
- return;
-
- //b4, b5, c5
- String reason = msg.isBogus()
- ? R.getI18NString("util.dns.DNSSEC_ADVANCED_REASON_BOGUS",
- new String[]{fqdn, msg.getBogusReason()})
- : R.getI18NString("util.dns.DNSSEC_ADVANCED_REASON_UNSIGNED",
- new String[]{type, fqdn});
- DnssecDialog dlg = new DnssecDialog(fqdn, reason);
- dlg.setVisible(true);
- DnssecDialogResult result = dlg.getResult();
- switch(result)
- {
- case Accept:
- break;
- case Deny:
- throw new DnssecRuntimeException(getExceptionMessage(msg));
- case AlwaysAccept:
- if(msg.isBogus())
- config.setProperty(propName,
- SecureResolveMode.IgnoreDnssec.name());
- else
- config.setProperty(propName,
- SecureResolveMode.WarnIfBogus.name());
- break;
- case AlwaysDeny:
- config.setProperty(propName, SecureResolveMode.SecureOnly);
- throw new DnssecRuntimeException(getExceptionMessage(msg));
- }
- }
-
- /**
- * Defines the return code from the DNSSEC verification dialog.
- */
- private enum DnssecDialogResult
- {
- /** The DNS result shall be accepted. */
- Accept,
- /** The result shall be rejected. */
- Deny,
- /** The result shall be accepted permanently. */
- AlwaysAccept,
- /**
- * The result shall be rejected automatically unless it is valid
- * according to DNSSEC.
- */
- AlwaysDeny
- }
-
- /**
- * Dialog to ask and warn the user if he wants to continue to accept an
- * invalid dnssec result.
- */
- private class DnssecDialog extends SIPCommDialog implements ActionListener
- {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- //UI controls
- private JPanel pnlAdvanced;
- private JPanel pnlStandard;
- private final String domain;
- private final String reason;
- private JButton cmdAck;
- private JButton cmdShowDetails;
-
- //state
- private DnssecDialogResult result = DnssecDialogResult.Deny;
-
- /**
- * Creates a new instance of this class.
- * @param domain The FQDN of the domain that failed.
- * @param reason String describing why the validation failed.
- */
- public DnssecDialog(String domain, String reason)
- {
- super(false);
- setModal(true);
- this.domain = domain;
- this.reason = reason;
- initComponents();
- }
-
- /**
- * Creates the UI controls
- */
- private void initComponents()
- {
- setLayout(new BorderLayout(15, 15));
- setTitle(R.getI18NString("util.dns.INSECURE_ANSWER_TITLE"));
-
- // warning text
- JLabel imgWarning =
- new JLabel(R.getImage("service.gui.icons.WARNING_ICON"));
- imgWarning.setBorder(BorderFactory
- .createEmptyBorder(10, 10, 10, 10));
- add(imgWarning, BorderLayout.WEST);
- JLabel lblWarning = new JLabel(
- R.getI18NString("util.dns.DNSSEC_WARNING", new String[]{
- R.getSettingsString("service.gui.APPLICATION_NAME"),
- domain
- })
- );
- add(lblWarning, BorderLayout.CENTER);
-
- //standard panel (deny option)
- cmdAck = new JButton(R.getI18NString("service.gui.OK"));
- cmdAck.addActionListener(this);
-
- cmdShowDetails = new JButton(
- R.getI18NString("util.dns.DNSSEC_ADVANCED_OPTIONS"));
- cmdShowDetails.addActionListener(this);
-
- pnlStandard = new TransparentPanel(new BorderLayout());
- pnlStandard.setBorder(BorderFactory
- .createEmptyBorder(10, 10, 10, 10));
- pnlStandard.add(cmdShowDetails, BorderLayout.WEST);
- pnlStandard.add(cmdAck, BorderLayout.EAST);
- add(pnlStandard, BorderLayout.SOUTH);
-
- //advanced panel
- pnlAdvanced = new TransparentPanel(new BorderLayout());
- JPanel pnlAdvancedButtons = new TransparentPanel(
- new FlowLayout(FlowLayout.RIGHT));
- pnlAdvancedButtons.setBorder(BorderFactory
- .createEmptyBorder(10, 10, 10, 10));
- pnlAdvanced.add(pnlAdvancedButtons, BorderLayout.EAST);
- for(DnssecDialogResult r : DnssecDialogResult.values())
- {
- JButton cmd = new JButton(R.getI18NString(
- "net.java.sip.communicator.util.dns."
- + "ConfigurableDnssecResolver$DnssecDialogResult."
- + r.name()));
- cmd.setActionCommand(r.name());
- cmd.addActionListener(this);
- pnlAdvancedButtons.add(cmd);
- }
- JLabel lblReason = new JLabel(reason);
- lblReason.setBorder(BorderFactory
- .createEmptyBorder(10, 10, 10, 10));
- pnlAdvanced.add(lblReason, BorderLayout.NORTH);
- }
-
- /**
- * Handles the events coming from the buttons.
- */
- public void actionPerformed(ActionEvent e)
- {
- if(e.getSource() == cmdAck)
- {
- result = DnssecDialogResult.Deny;
- dispose();
- }
- else if(e.getSource() == cmdShowDetails)
- {
- getContentPane().remove(pnlStandard);
- add(pnlAdvanced, BorderLayout.SOUTH);
- pack();
- }
- else
- {
- result = Enum.valueOf(DnssecDialogResult.class,
- e.getActionCommand());
- dispose();
- }
- }
-
- /**
- * Gets the option that user has chosen.
- * @return the option that user has chosen.
- */
- public DnssecDialogResult getResult()
- {
- return result;
- }
- }
-
- private String getExceptionMessage(SecureMessage msg)
- {
- return msg.getBogusReason() == null
- ? R.getI18NString(
- "util.dns.INSECURE_ANSWER_MESSAGE_NO_REASON",
- new String[]{msg.getQuestion().getName().toString()}
- )
- : R.getI18NString(
- "util.dns.INSECURE_ANSWER_MESSAGE_REASON",
- new String[]{msg.getQuestion().getName().toString(),
- //TODO parse bogus reason text and translate
- msg.getBogusReason()}
- );
- }
-
- private String createPropNameUnsigned(String fqdn, String type)
- {
- return PNAME_BASE_DNSSEC_PIN + "." + fqdn.replace(".", "__");
- }
-
- /**
- * Reloads the configuration of forwarders and trust anchors.
- */
- @Override
- public void reset()
- {
- String forwarders = DnsUtilActivator.getConfigurationService()
- .getString(DnsUtilActivator.PNAME_DNSSEC_NAMESERVERS);
- if(!StringUtils.isNullOrEmpty(forwarders, true))
- {
- if(logger.isTraceEnabled())
- {
- logger.trace("Setting DNSSEC forwarders to: "
- + Arrays.toString(forwarders.split(",")));
- }
- super.setForwarders(forwarders.split(","));
- }
-
- for(int i = 1;;i++)
- {
- String anchor = DnsUtilActivator.getResources().getSettingsString(
- "net.java.sip.communicator.util.dns.DS_ROOT." + i);
- if(anchor == null)
- break;
- clearTrustAnchors();
- addTrustAnchor(anchor);
- if(logger.isTraceEnabled())
- logger.trace("Loaded trust anchor " + anchor);
- }
- }
-}
+package net.java.sip.communicator.impl.dns;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.List;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.service.dns.*;
+import net.java.sip.communicator.service.notification.*;
+import net.java.sip.communicator.util.Logger;
+import net.java.sip.communicator.plugin.desktoputil.*;
+
+import org.jitsi.dnssec.validator.ValidatingResolver;
+import org.jitsi.service.configuration.*;
+import org.jitsi.service.resources.*;
+import org.jitsi.util.*;
+import org.xbill.DNS.*;
+
+/**
+ * Resolver that wraps a DNSSEC capable resolver and handles validation
+ * failures according to the user's settings.
+ *
+ * @author Ingo Bauersachs
+ */
+public class ConfigurableDnssecResolver
+ extends ValidatingResolver
+ implements CustomResolver
+{
+ private final static Logger logger
+ = Logger.getLogger(ConfigurableDnssecResolver.class);
+
+ /**
+ * Name of the property that defines the default DNSSEC validation
+ * behavior.
+ */
+ public final static String PNAME_DNSSEC_VALIDATION_MODE
+ = "net.java.sip.communicator.util.dns.DNSSEC_VALIDATION_MODE";
+
+ /**
+ * Default value of {@link #PNAME_DNSSEC_VALIDATION_MODE}
+ */
+ public final static String PNAME_BASE_DNSSEC_PIN
+ = "net.java.sip.communicator.util.dns.pin";
+
+ final static String EVENT_TYPE = "DNSSEC_NOTIFICATION";
+
+ private ConfigurationService config
+ = DnsUtilActivator.getConfigurationService();
+ private ResourceManagementService R
+ = DnsUtilActivator.getResources();
+ private Map<String, Date> lastNotifications
+ = new HashMap<String, Date>();
+
+ private ExtendedResolver headResolver;
+
+ /**
+ * Creates a new instance of this class. Tries to use the system's
+ * default forwarders.
+ */
+ public ConfigurableDnssecResolver(ExtendedResolver headResolver)
+ {
+ super(headResolver);
+
+ List<String> propNames
+ = config.getPropertyNamesByPrefix("org.jitsi.dnssec", false);
+ Properties config = new Properties();
+ for (String propName : propNames)
+ {
+ String value = config.getProperty(propName);
+ if (!StringUtils.isNullOrEmpty(value))
+ {
+ config.put(propName, value);
+ }
+ }
+
+ try
+ {
+ super.init(config);
+ }
+ catch (IOException e)
+ {
+ logger.error("Extended dnssec properties contained an error", e);
+ }
+
+ this.headResolver = headResolver;
+ reset();
+ Lookup.setDefaultResolver(this);
+
+ DnsUtilActivator.getNotificationService().
+ registerDefaultNotificationForEvent(
+ ConfigurableDnssecResolver.EVENT_TYPE,
+ NotificationAction.ACTION_POPUP_MESSAGE,
+ null, null);
+ }
+
+ /**
+ * Inspects a DNS answer message and handles validation results according to
+ * the user's preferences.
+ *
+ * @throws DnssecRuntimeException when the validation failed and the user
+ * did not choose to ignore it.
+ */
+ @Override
+ public Message send(Message query)
+ throws DnssecRuntimeException, IOException
+ {
+ //---------------------------------------------------------------------
+ // || 1 | 2 | 3 | 4 | 5
+ //---------------------------------------------------------------------
+ // Sec. | Bog. || Ign. | Sec.Only | Sec.Or.Unsig | Warn.Bog | WarnAll
+ //---------------------------------------------------------------------
+ //a) 1 | 0 || ok | ok | ok | ok | ok
+ //b) 0 | 1 || ok | nok | nok | ask | ask
+ //c) 0 | 0 || ok | nok | ok | ok | ask
+ //---------------------------------------------------------------------
+
+ SecureMessage msg = new SecureMessage(super.send(query));
+ String fqdn = msg.getQuestion().getName().toString();
+ String type = Type.string(msg.getQuestion().getType());
+ String propName = createPropNameUnsigned(fqdn, type);
+ SecureResolveMode defaultAction = Enum.valueOf(SecureResolveMode.class,
+ config.getString(
+ PNAME_DNSSEC_VALIDATION_MODE,
+ SecureResolveMode.WarnIfBogus.name()
+ )
+ );
+ SecureResolveMode pinned = Enum.valueOf(SecureResolveMode.class,
+ config.getString(
+ propName,
+ defaultAction.name()
+ )
+ );
+
+ //create default entry
+ if(pinned == defaultAction)
+ config.setProperty(propName, pinned.name());
+
+ //check domain policy
+
+ //[abc]1, a[2-5]
+ if(pinned == SecureResolveMode.IgnoreDnssec || msg.isSecure())
+ return msg;
+
+ if(
+ //b2, c2
+ (pinned == SecureResolveMode.SecureOnly && !msg.isSecure())
+ ||
+ //b3
+ (pinned == SecureResolveMode.SecureOrUnsigned && msg.isBogus())
+ )
+ {
+ String text = getExceptionMessage(msg);
+ Date last = lastNotifications.get(text);
+ if(last == null
+ //wait at least 5 minutes before showing the same info again
+ || last.before(new Date(new Date().getTime() - 1000*60*5)))
+ {
+ DnsUtilActivator.getNotificationService().fireNotification(
+ EVENT_TYPE,
+ R.getI18NString("util.dns.INSECURE_ANSWER_TITLE"),
+ text,
+ null);
+ lastNotifications.put(text, new Date());
+ }
+
+ throw new DnssecRuntimeException(text);
+ }
+
+ //c3
+ if(pinned == SecureResolveMode.SecureOrUnsigned && !msg.isBogus())
+ return msg;
+
+ //c4
+ if(pinned == SecureResolveMode.WarnIfBogus && !msg.isBogus())
+ return msg;
+
+ //b4, b5, c5
+ String reason = msg.isBogus()
+ ? R.getI18NString("util.dns.DNSSEC_ADVANCED_REASON_BOGUS",
+ new String[]{fqdn, msg.getBogusReason()})
+ : R.getI18NString("util.dns.DNSSEC_ADVANCED_REASON_UNSIGNED",
+ new String[]{type, fqdn});
+ DnssecDialog dlg = new DnssecDialog(fqdn, reason);
+ dlg.setVisible(true);
+ DnssecDialogResult result = dlg.getResult();
+ switch(result)
+ {
+ case Accept:
+ break;
+ case Deny:
+ throw new DnssecRuntimeException(getExceptionMessage(msg));
+ case AlwaysAccept:
+ if(msg.isBogus())
+ config.setProperty(propName,
+ SecureResolveMode.IgnoreDnssec.name());
+ else
+ config.setProperty(propName,
+ SecureResolveMode.WarnIfBogus.name());
+ break;
+ case AlwaysDeny:
+ config.setProperty(propName, SecureResolveMode.SecureOnly);
+ throw new DnssecRuntimeException(getExceptionMessage(msg));
+ }
+
+ return msg;
+ }
+
+ /**
+ * Defines the return code from the DNSSEC verification dialog.
+ */
+ private enum DnssecDialogResult
+ {
+ /** The DNS result shall be accepted. */
+ Accept,
+ /** The result shall be rejected. */
+ Deny,
+ /** The result shall be accepted permanently. */
+ AlwaysAccept,
+ /**
+ * The result shall be rejected automatically unless it is valid
+ * according to DNSSEC.
+ */
+ AlwaysDeny
+ }
+
+ /**
+ * Dialog to ask and warn the user if he wants to continue to accept an
+ * invalid dnssec result.
+ */
+ private class DnssecDialog extends SIPCommDialog implements ActionListener
+ {
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ //UI controls
+ private JPanel pnlAdvanced;
+ private JPanel pnlStandard;
+ private final String domain;
+ private final String reason;
+ private JButton cmdAck;
+ private JButton cmdShowDetails;
+
+ //state
+ private DnssecDialogResult result = DnssecDialogResult.Deny;
+
+ /**
+ * Creates a new instance of this class.
+ * @param domain The FQDN of the domain that failed.
+ * @param reason String describing why the validation failed.
+ */
+ public DnssecDialog(String domain, String reason)
+ {
+ super(false);
+ setModal(true);
+ this.domain = domain;
+ this.reason = reason;
+ initComponents();
+ }
+
+ /**
+ * Creates the UI controls
+ */
+ private void initComponents()
+ {
+ setLayout(new BorderLayout(15, 15));
+ setTitle(R.getI18NString("util.dns.INSECURE_ANSWER_TITLE"));
+
+ // warning text
+ JLabel imgWarning =
+ new JLabel(R.getImage("service.gui.icons.WARNING_ICON"));
+ imgWarning.setBorder(BorderFactory
+ .createEmptyBorder(10, 10, 10, 10));
+ add(imgWarning, BorderLayout.WEST);
+ JLabel lblWarning = new JLabel(
+ R.getI18NString("util.dns.DNSSEC_WARNING", new String[]{
+ R.getSettingsString("service.gui.APPLICATION_NAME"),
+ domain
+ })
+ );
+ add(lblWarning, BorderLayout.CENTER);
+
+ //standard panel (deny option)
+ cmdAck = new JButton(R.getI18NString("service.gui.OK"));
+ cmdAck.addActionListener(this);
+
+ cmdShowDetails = new JButton(
+ R.getI18NString("util.dns.DNSSEC_ADVANCED_OPTIONS"));
+ cmdShowDetails.addActionListener(this);
+
+ pnlStandard = new TransparentPanel(new BorderLayout());
+ pnlStandard.setBorder(BorderFactory
+ .createEmptyBorder(10, 10, 10, 10));
+ pnlStandard.add(cmdShowDetails, BorderLayout.WEST);
+ pnlStandard.add(cmdAck, BorderLayout.EAST);
+ add(pnlStandard, BorderLayout.SOUTH);
+
+ //advanced panel
+ pnlAdvanced = new TransparentPanel(new BorderLayout());
+ JPanel pnlAdvancedButtons = new TransparentPanel(
+ new FlowLayout(FlowLayout.RIGHT));
+ pnlAdvancedButtons.setBorder(BorderFactory
+ .createEmptyBorder(10, 10, 10, 10));
+ pnlAdvanced.add(pnlAdvancedButtons, BorderLayout.EAST);
+ for(DnssecDialogResult r : DnssecDialogResult.values())
+ {
+ JButton cmd = new JButton(R.getI18NString(
+ "net.java.sip.communicator.util.dns."
+ + "ConfigurableDnssecResolver$DnssecDialogResult."
+ + r.name()));
+ cmd.setActionCommand(r.name());
+ cmd.addActionListener(this);
+ pnlAdvancedButtons.add(cmd);
+ }
+ JLabel lblReason = new JLabel(reason);
+ lblReason.setBorder(BorderFactory
+ .createEmptyBorder(10, 10, 10, 10));
+ pnlAdvanced.add(lblReason, BorderLayout.NORTH);
+ }
+
+ /**
+ * Handles the events coming from the buttons.
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ if(e.getSource() == cmdAck)
+ {
+ result = DnssecDialogResult.Deny;
+ dispose();
+ }
+ else if(e.getSource() == cmdShowDetails)
+ {
+ getContentPane().remove(pnlStandard);
+ add(pnlAdvanced, BorderLayout.SOUTH);
+ pack();
+ }
+ else
+ {
+ result = Enum.valueOf(DnssecDialogResult.class,
+ e.getActionCommand());
+ dispose();
+ }
+ }
+
+ /**
+ * Gets the option that user has chosen.
+ * @return the option that user has chosen.
+ */
+ public DnssecDialogResult getResult()
+ {
+ return result;
+ }
+ }
+
+ private String getExceptionMessage(SecureMessage msg)
+ {
+ return msg.getBogusReason() == null
+ ? R.getI18NString(
+ "util.dns.INSECURE_ANSWER_MESSAGE_NO_REASON",
+ new String[]{msg.getQuestion().getName().toString()}
+ )
+ : R.getI18NString(
+ "util.dns.INSECURE_ANSWER_MESSAGE_REASON",
+ new String[]{msg.getQuestion().getName().toString(),
+ //TODO parse bogus reason text and translate
+ msg.getBogusReason()}
+ );
+ }
+
+ private String createPropNameUnsigned(String fqdn, String type)
+ {
+ return PNAME_BASE_DNSSEC_PIN + "." + fqdn.replace(".", "__");
+ }
+
+ /**
+ * Reloads the configuration of forwarders and trust anchors.
+ */
+ @Override
+ public void reset()
+ {
+ String forwarders = DnsUtilActivator.getConfigurationService()
+ .getString(DnsUtilActivator.PNAME_DNSSEC_NAMESERVERS);
+ if(!StringUtils.isNullOrEmpty(forwarders, true))
+ {
+ if(logger.isTraceEnabled())
+ {
+ logger.trace("Setting DNSSEC forwarders to: " + forwarders);
+ }
+
+ synchronized (Lookup.class)
+ {
+ Lookup.refreshDefault();
+ String[] fwds = forwarders.split(",");
+ Resolver[] rs = headResolver.getResolvers();
+ for (Resolver r : rs)
+ {
+ headResolver.deleteResolver(r);
+ }
+
+ for (String fwd : fwds)
+ {
+ try
+ {
+ SimpleResolver sr = new SimpleResolver(fwd);
+
+ // these properties are normally set by the
+ // ValidatingResolver in the constructor
+ sr.setEDNS(0, 0, ExtendedFlags.DO, null);
+ sr.setIgnoreTruncation(false);
+ headResolver.addResolver(sr);
+ }
+ catch (UnknownHostException e)
+ {
+ logger.error("Invalid forwarder, ignoring", e);
+ }
+ }
+
+ Lookup.setDefaultResolver(this);
+ }
+ }
+
+ StringBuilder sb = new StringBuilder();
+ for(int i = 1;;i++)
+ {
+ String anchor = DnsUtilActivator.getResources().getSettingsString(
+ "net.java.sip.communicator.util.dns.DS_ROOT." + i);
+ if(anchor == null)
+ {
+ break;
+ }
+
+ sb.append(anchor);
+ sb.append('\n');
+ }
+
+ try
+ {
+ super.loadTrustAnchors(new ByteArrayInputStream(
+ sb.toString().getBytes("ASCII")));
+ }
+ catch (IOException e)
+ {
+ logger.error("Could not load the trust anchors", e);
+ }
+
+ if(logger.isTraceEnabled())
+ logger.trace("Loaded trust anchors " + sb.toString());
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/dns/DnsUtilActivator.java b/src/net/java/sip/communicator/impl/dns/DnsUtilActivator.java
index e8b2e7d..4fc828c 100644
--- a/src/net/java/sip/communicator/impl/dns/DnsUtilActivator.java
+++ b/src/net/java/sip/communicator/impl/dns/DnsUtilActivator.java
@@ -150,7 +150,7 @@ public class DnsUtilActivator
{
bundleContext.registerService(
CustomResolver.class.getName(),
- new ConfigurableDnssecResolver(),
+ new ConfigurableDnssecResolver(new ExtendedResolver()),
null);
logger.info("DnssecResolver ... [REGISTERED]");
}
diff --git a/src/net/java/sip/communicator/impl/dns/SecureMessage.java b/src/net/java/sip/communicator/impl/dns/SecureMessage.java
index 7fe9b68..15f77b0 100644
--- a/src/net/java/sip/communicator/impl/dns/SecureMessage.java
+++ b/src/net/java/sip/communicator/impl/dns/SecureMessage.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,90 +15,97 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.dns;
-
-import java.io.*;
-
-import org.xbill.DNS.*;
-
-/**
- * DNS Message that adds DNSSEC validation information.
- *
- * @author Ingo Bauersachs
- */
-public class SecureMessage
- extends Message
-{
- private boolean secure;
- private boolean bogus;
- private String bogusReason;
-
- /**
- * Creates a new instance of this class based on data received from an
- * Unbound resolve.
- *
- * @param msg The answer of the Unbound resolver.
- * @throws IOException
- */
- public SecureMessage(UnboundResult msg) throws IOException
- {
- super(msg.answerPacket);
- secure = msg.secure;
- bogus = msg.bogus;
- bogusReason = msg.whyBogus;
- }
-
- /**
- * Indicates whether the answer is secure.
- * @return True, if the result is validated securely.
- */
- public boolean isSecure()
- {
- return secure;
- }
-
- /**
- * Indicates if there was a validation failure.
- *
- * @return If the result was not secure (secure == false), and this result
- * is due to a security failure, bogus is true.
- */
- public boolean isBogus()
- {
- return bogus;
- }
-
- /**
- * If the result is bogus this contains a string that describes the failure.
- *
- * @return string that describes the failure.
- */
- public String getBogusReason()
- {
- return bogusReason;
- }
-
- /**
- * Converts the Message to a String. The fields secure, bogus and whyBogus
- * are append as a comment.
- */
- @Override
- public String toString()
- {
- StringBuilder s = new StringBuilder(super.toString());
- s.append('\n');
- s.append(";; Secure: ");
- s.append(secure);
- s.append('\n');
- s.append(";; Bogus: ");
- s.append(bogus);
- s.append('\n');
- if(bogus)
- {
- s.append(";; Reason: ");
- s.append(bogusReason);
- s.append('\n');
- }
- return s.toString();
- }
-}
+package net.java.sip.communicator.impl.dns;
+
+import java.io.*;
+
+import org.jitsi.dnssec.validator.*;
+import org.xbill.DNS.*;
+
+/**
+ * DNS Message that adds DNSSEC validation information.
+ *
+ * @author Ingo Bauersachs
+ */
+public class SecureMessage
+ extends Message
+{
+ private boolean secure;
+ private boolean bogus;
+ private String bogusReason;
+
+ /**
+ * Creates a new instance of this class based on data received from a
+ * dnssecjava resolve.
+ *
+ * @param msg The answer of the dnssecjava resolver.
+ * @throws IOException
+ */
+ public SecureMessage(Message msg) throws IOException
+ {
+ super(msg.toWire());
+ secure = msg.getHeader().getFlag(Flags.AD);
+ bogus = !secure && msg.getRcode() == Rcode.SERVFAIL;
+ for (RRset set : msg.getSectionRRsets(Section.ADDITIONAL)) {
+ if (set.getName().equals(Name.root) && set.getType() == Type.TXT
+ && set.getDClass() == ValidatingResolver.VALIDATION_REASON_QCLASS)
+ {
+ bogusReason = ((TXTRecord)set.first()).getStrings().get(0).toString();
+ }
+ }
+ }
+
+ /**
+ * Indicates whether the answer is secure.
+ * @return True, if the result is validated securely.
+ */
+ public boolean isSecure()
+ {
+ return secure;
+ }
+
+ /**
+ * Indicates if there was a validation failure.
+ *
+ * @return If the result was not secure (secure == false), and this result
+ * is due to a security failure, bogus is true.
+ */
+ public boolean isBogus()
+ {
+ return bogus;
+ }
+
+ /**
+ * If the result is bogus this contains a string that describes the failure.
+ *
+ * @return string that describes the failure.
+ */
+ public String getBogusReason()
+ {
+ return bogusReason;
+ }
+
+ /**
+ * Converts the Message to a String. The fields secure, bogus and whyBogus
+ * are append as a comment.
+ */
+ @Override
+ public String toString()
+ {
+ StringBuilder s = new StringBuilder(super.toString());
+ s.append('\n');
+ s.append(";; Secure: ");
+ s.append(secure);
+ s.append('\n');
+ s.append(";; Bogus: ");
+ s.append(bogus);
+ s.append('\n');
+ if(bogus)
+ {
+ s.append(";; Reason: ");
+ s.append(bogusReason);
+ s.append('\n');
+ }
+ return s.toString();
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/dns/SecureResolveMode.java b/src/net/java/sip/communicator/impl/dns/SecureResolveMode.java
index 8c99836..b74f1c6 100644
--- a/src/net/java/sip/communicator/impl/dns/SecureResolveMode.java
+++ b/src/net/java/sip/communicator/impl/dns/SecureResolveMode.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,40 +15,40 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.dns;
-
-/**
- * Defines how DNSSEC validation errors should be handled.
- *
- * @author Ingo Bauersachs
- */
-public enum SecureResolveMode
-{
- /**
- * Any DNSSEC data is completely ignored.
- */
- IgnoreDnssec,
-
- /**
- * The result of a query is only returned if it validated successfully.
- */
- SecureOnly,
-
- /**
- * The result of a query is returned if it validated successfully or when
- * the zone is unsigned.
- */
- SecureOrUnsigned,
-
- /**
- * If the result of a query is bogus (manipulated, incorrect), the user is
- * to be asked how to proceed.
- */
- WarnIfBogus,
-
- /**
- * If the result of a query is bogus (manipulated, incorrect) or if the zone
- * is unsigned, the user is to be asked how to proceed.
- */
- WarnIfBogusOrUnsigned
-}
+package net.java.sip.communicator.impl.dns;
+
+/**
+ * Defines how DNSSEC validation errors should be handled.
+ *
+ * @author Ingo Bauersachs
+ */
+public enum SecureResolveMode
+{
+ /**
+ * Any DNSSEC data is completely ignored.
+ */
+ IgnoreDnssec,
+
+ /**
+ * The result of a query is only returned if it validated successfully.
+ */
+ SecureOnly,
+
+ /**
+ * The result of a query is returned if it validated successfully or when
+ * the zone is unsigned.
+ */
+ SecureOrUnsigned,
+
+ /**
+ * If the result of a query is bogus (manipulated, incorrect), the user is
+ * to be asked how to proceed.
+ */
+ WarnIfBogus,
+
+ /**
+ * If the result of a query is bogus (manipulated, incorrect) or if the zone
+ * is unsigned, the user is to be asked how to proceed.
+ */
+ WarnIfBogusOrUnsigned
+}
diff --git a/src/net/java/sip/communicator/impl/dns/UnboundApi.java b/src/net/java/sip/communicator/impl/dns/UnboundApi.java
deleted file mode 100644
index 6f35a8b..0000000
--- a/src/net/java/sip/communicator/impl/dns/UnboundApi.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.dns;
-
-/**
- * Wrapper for the JUnbound JNI wrapper.
- * <p>
- * The JavaDoc of these methods is directly copied from libunbound, licensed as
- * follows:
- * <p>
- * Copyright (c) 2007, NLnet Labs. All rights reserved.
- *
- * This software is open source.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the NLNET LABS nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Ingo Bauersachs
- */
-public class UnboundApi
-{
- private static boolean isAvailable;
- private static final Object syncRoot = new Object();
-
- static
- {
- tryLoadUnbound();
- }
-
- /**
- * Attempts to load the Unbound native library. When successful,
- * {@link #isAvailable()} returns true.
- */
- public static void tryLoadUnbound()
- {
- synchronized(syncRoot)
- {
- try
- {
- System.loadLibrary("junbound");
- isAvailable = true;
- }
- catch(UnsatisfiedLinkError e)
- {
- isAvailable = false;
- }
- }
- }
-
- /**
- * Indicates whether the Unbound library is loaded.
- * @return True when the JNI wrapper could be loaded, false otherwise.
- */
- public static boolean isAvailable()
- {
- return isAvailable;
- }
-
- /**
- * Set debug verbosity for the context. Output is directed to stderr. Higher
- * debug level gives more output.
- *
- * @param context context.
- * @param level The debug level.
- */
- public static native void setDebugLevel(long context, int level);
-
- /**
- * Create a resolving and validation context.
- * @return a new context. default initialization. returns NULL on error.
- */
- public static native long createContext();
-
- /**
- * Destroy a validation context and free all its resources. Outstanding
- * async queries are killed and callbacks are not called for them.
- *
- * @param context context to delete
- */
- public static native void deleteContext(long context);
-
- /**
- * Set machine to forward DNS queries to, the caching resolver to use.
- * <p>
- * IP4 or IP6 address. Forwards all DNS requests to that machine, which is
- * expected to run a recursive resolver. If the proxy is not DNSSEC-capable,
- * validation may fail. Can be called several times, in that case the
- * addresses are used as backup servers.
- *
- * @param context context. At this time it is only possible to set
- * configuration before the first resolve is done.
- * @param server address, IP4 or IP6 in string format. If the server is
- * NULL, forwarding is disabled.
- */
- public static native void setForwarder(long context, String server);
-
- /**
- * Add a trust anchor to the given context.
- * <p>
- * The trust anchor is a string, on one line, that holds a valid DNSKEY or
- * DS RR.
- *
- * @param context context. At this time it is only possible to add trusted
- * keys before the first resolve is done.
- * @param anchor string, with zone-format RR on one line. [domainname] [TTL
- * optional] [type] [class optional] [rdata contents]
- */
- public static native void addTrustAnchor(long context, String anchor);
-
- /**
- * Perform resolution and validation of the target name.
- *
- * @param context context. The context is finalized, and can no longer
- * accept config changes.
- * @param name domain name in text format (a zero terminated text string).
- * @param rrtype type of RR in host order, 1 is A (address).
- * @param rrclass class of RR in host order, 1 is IN (for internet).
- * @return the result data is returned in a newly allocated result
- * structure. May be NULL on return, return value is set to an error
- * in that case (out of memory).
- * @throws UnboundException when an error occurred.
- */
- public static native UnboundResult resolve(long context, String name,
- int rrtype, int rrclass) throws UnboundException;
-
- /**
- * Perform resolution and validation of the target name.
- * <p>
- * Asynchronous, after a while, the callback will be called with your data
- * and the result.
- *
- * @param context context. If no thread or process has been created yet to
- * perform the work in the background, it is created now. The
- * context is finalized, and can no longer accept config changes.
- * @param name domain name in text format (a string).
- * @param rrtype type of RR in host order, 1 is A.
- * @param rrclass class of RR in host order, 1 is IN (for internet).
- * @param data this data is your own data (you can pass null), and is passed
- * on to the callback function.
- * @param cb this is called on completion of the resolution.
- * @return an identifier number is returned for the query as it is in
- * progress. It can be used to cancel the query.
- * @throws UnboundException when an error occurred.
- */
- public static native int resolveAsync(long context, String name,
- int rrtype, int rrclass, Object data, UnboundCallback cb)
- throws UnboundException;
-
- /**
- * Cancel an async query in progress. Its callback will not be called.
- *
- * @param context context.
- * @param asyncId which query to cancel.
- * @throws UnboundException This routine can error if the async_id passed
- * does not exist or has already been delivered. If another
- * thread is processing results at the same time, the result may
- * be delivered at the same time and the cancel fails with an
- * error. Also the cancel can fail due to a system error, no
- * memory or socket failures.
- */
- public static native void cancelAsync(long context, int asyncId)
- throws UnboundException;
-
- /**
- * Convert error value to a human readable string.
- *
- * @param code error code from one of the Unbound functions.
- * @return text string of the error code.
- */
- public static native String errorCodeToString(int code);
-
- /**
- * Wait for a context to finish with results. Call this routine to continue
- * processing results from the validating resolver. After the wait, there
- * are no more outstanding asynchronous queries.
- *
- * @param context context.
- * @throws UnboundException when an error occurred.
- */
- public static native void processAsync(long context)
- throws UnboundException;
-
- /**
- * Interface for the async resolve callback.
- */
- public interface UnboundCallback
- {
- /**
- * Called on completion of the async resolution.
- *
- * @param data the same object as passed to
- * {@link UnboundApi#resolveAsync(long, String, int, int,
- * Object, UnboundCallback)}
- * @param err 0 when a result has been found, an Unbound error code
- * otherwise
- * @param result a newly allocated result structure. The result may be
- * null, in that case err is set.
- */
- public void UnboundResolveCallback(Object data, int err,
- UnboundResult result);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/dns/UnboundResolver.java b/src/net/java/sip/communicator/impl/dns/UnboundResolver.java
deleted file mode 100644
index 309e58e..0000000
--- a/src/net/java/sip/communicator/impl/dns/UnboundResolver.java
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.dns;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import java.util.concurrent.*;
-
-import net.java.sip.communicator.service.dns.*;
-import net.java.sip.communicator.util.*;
-
-import org.xbill.DNS.*;
-
-/**
- * Implementation of the {@link Resolver} interface, wrapping the native NLnet
- * Labs Unbound resolver. Only the basic methods for queries are supported.
- *
- * @author Ingo Bauersachs
- */
-public class UnboundResolver
- implements CustomResolver
-{
- private final static Logger logger =
- Logger.getLogger(UnboundResolver.class);
-
- /**
- * Helper class to synchronize on asynchronous queries.
- */
- private static class CallbackData
- {
- /**
- * The resolver consumer that wishes to be informed when the request
- * completed.
- */
- ResolverListener listener;
-
- /**
- * The unbound session context.
- */
- long context;
-
- /**
- * The ID of the unbound async query.
- */
- int asyncId;
-
- /**
- * Java synchronization on top of unbound.
- */
- CountDownLatch sync = new CountDownLatch(1);
- }
-
- /**
- * Timeout for DNS queries.
- */
- private int timeout = 10000;
-
- /**
- * The recursive DNS servers answering our queries.
- */
- private String[] forwarders;
-
- /**
- * DNSSEC trust anchors for signed zones (usually for the root zone).
- */
- private List<String> trustAnchors = new LinkedList<String>();
-
- /**
- * Pool that executes our queries.
- */
- private ExecutorService threadPool;
-
- /**
- * Creates a new instance of this class.
- */
- public UnboundResolver()
- {
- threadPool = Executors.newCachedThreadPool();
- }
-
- /**
- * Sets a list of forwarders to use instead of the system default.
- *
- * @param forwarders list of servers to use for our queries.
- */
- public void setForwarders(String[] forwarders)
- {
- this.forwarders = forwarders;
- }
-
- /**
- * Clears any existing trust anchors previously added.
- */
- public void clearTrustAnchors()
- {
- trustAnchors.clear();
- }
-
- /**
- * Adds a DNSSEC trust anchor validation of the DNSKEYs.
- *
- * @param anchor trust anchor in the form of
- * "'zone' IN DS 'key tag' 'algorithm' 'digest type' 'digest'"
- */
- public void addTrustAnchor(String anchor)
- {
- trustAnchors.add(anchor);
- }
-
- /**
- * {@inheritDoc}
- */
- public SecureMessage send(final Message query) throws IOException
- {
- Future<SecureMessage> future = threadPool.submit(
- new Callable<SecureMessage>()
- {
- public SecureMessage call() throws Exception
- {
- if(logger.isDebugEnabled())
- logger.debug(query);
-
- SecureMessage secureMessage = null;
- final long context = prepareContext();
- try
- {
- UnboundResult result = UnboundApi.resolve(
- context,
- query.getQuestion().getName().toString(),
- query.getQuestion().getType(),
- query.getQuestion().getDClass()
- );
- secureMessage = new SecureMessage(result);
- validateMessage(secureMessage);
- }
- finally
- {
- UnboundApi.deleteContext(context);
- if(logger.isDebugEnabled() && secureMessage != null)
- logger.debug(secureMessage);
- }
-
- return secureMessage;
- }
- });
- try
- {
- return future.get(timeout, TimeUnit.SECONDS);
- }
- catch (InterruptedException e)
- {
- logger.error(e);
- throw new IOException(e.getMessage());
- }
- catch (ExecutionException e)
- {
- if(e.getCause() instanceof DnssecRuntimeException)
- throw new DnssecRuntimeException(e.getCause().getMessage());
- logger.error(e);
- throw new IOException(e.getMessage());
- }
- catch (TimeoutException e)
- {
- throw new SocketTimeoutException(e.getMessage());
- }
- }
-
- /**
- * Method to allow overriders to inspect the message. This class'
- * implementation does nothing.
- *
- * @param msg The message to inspect.
- * @throws DnssecRuntimeException if the inspector does not want the code to
- * continue normal processing of the answer.
- */
- protected void validateMessage(SecureMessage msg)
- throws DnssecRuntimeException
- {
- }
-
- /**
- * Prepares a unbound session context initialized with forwarders and trust
- * anchors.
- *
- * @return The context id
- */
- private long prepareContext()
- {
- final long context = UnboundApi.createContext();
- if(logger.isTraceEnabled())
- UnboundApi.setDebugLevel(context, 100);
- for(String fwd : forwarders == null
- ? ResolverConfig.getCurrentConfig().servers()
- : forwarders)
- {
- fwd = fwd.trim();
- if(NetworkUtils.isValidIPAddress(fwd))
- {
- if(fwd.startsWith("["))
- fwd = fwd.substring(1, fwd.length() - 1);
- UnboundApi.setForwarder(context, fwd);
- }
- }
- for(String anchor : trustAnchors)
- {
- UnboundApi.addTrustAnchor(context, anchor);
- }
- return context;
- }
-
- /**
- * Cleans up an Unbound session context.
- *
- * @param cbData The helper object of the asynchronous call.
- * @param cancelAsync Whether an outstanding asynchronous unbound query
- * should be canceled.
- */
- private static synchronized void deleteContext(CallbackData cbData,
- boolean cancelAsync)
- {
- if(cbData.context == 0)
- return;
-
- if(cancelAsync)
- {
- try
- {
- UnboundApi.cancelAsync(cbData.context, cbData.asyncId);
- }
- catch (UnboundException ignore)
- {}
- }
- UnboundApi.deleteContext(cbData.context);
- cbData.context = 0;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.xbill.DNS.Resolver#sendAsync(org.xbill.DNS.Message,
- * org.xbill.DNS.ResolverListener)
- */
- public CallbackData sendAsync(Message query, ResolverListener listener)
- {
- if(listener == null)
- throw new IllegalArgumentException("listener cannot be null");
-
- final long context = prepareContext();
- final CallbackData cbData = new CallbackData();
- cbData.listener = listener;
- cbData.context = context;
- int asyncId;
- try
- {
- asyncId = UnboundApi.resolveAsync(
- context,
- query.getQuestion().getName().toString(),
- query.getQuestion().getType(),
- query.getQuestion().getDClass(),
- cbData,
- new UnboundApi.UnboundCallback()
- {
- public void UnboundResolveCallback(Object data, int err,
- UnboundResult result)
- {
- CallbackData cbData = (CallbackData)data;
- deleteContext(cbData, false);
-
- ResolverListener l = cbData.listener;
- if(err == 0)
- {
- try
- {
- l.receiveMessage(data,
- new SecureMessage(result));
- }
- catch (IOException e)
- {
- l.handleException(data, e);
- }
- }
- else
- l.handleException(data,
- new Exception(
- UnboundApi.errorCodeToString(err)));
-
- cbData.sync.countDown();
- }
- }
- );
- }
- catch (UnboundException e)
- {
- listener.handleException(null, e);
- return null;
- }
- cbData.asyncId = asyncId;
- threadPool.execute(new Runnable()
- {
- public void run()
- {
- try
- {
- UnboundApi.processAsync(context);
- }
- catch(UnboundException ex)
- {
- cbData.listener.handleException(this, ex);
- deleteContext(cbData, false);
- cbData.sync.countDown();
- }
- }
- });
- return cbData;
- }
-
- /**
- * Not supported.
- * @throws UnsupportedOperationException
- */
- public void setEDNS(int level)
- {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Not supported.
- * @throws UnsupportedOperationException
- */
- @SuppressWarnings("rawtypes")
- public void setEDNS(int level, int payloadSize, int flags, List options)
- {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Not supported.
- * @throws UnsupportedOperationException
- */
- public void setIgnoreTruncation(boolean flag)
- {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Not supported.
- * @throws UnsupportedOperationException
- */
- public void setPort(int port)
- {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Not supported.
- * @throws UnsupportedOperationException
- */
- public void setTCP(boolean flag)
- {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Not supported.
- * @throws UnsupportedOperationException
- */
- public void setTSIGKey(TSIG key)
- {
- throw new UnsupportedOperationException();
- }
-
- /* (non-Javadoc)
- * @see org.xbill.DNS.Resolver#setTimeout(int)
- */
- public void setTimeout(int secs)
- {
- timeout = secs * 1000;
- }
-
- /* (non-Javadoc)
- * @see org.xbill.DNS.Resolver#setTimeout(int, int)
- */
- public void setTimeout(int secs, int msecs)
- {
- timeout = secs * 1000 + msecs;
- }
-
- /**
- * Does nothing.
- */
- public void reset()
- {
- }
-}
diff --git a/src/net/java/sip/communicator/impl/dns/UnboundResult.java b/src/net/java/sip/communicator/impl/dns/UnboundResult.java
deleted file mode 100644
index 85167d0..0000000
--- a/src/net/java/sip/communicator/impl/dns/UnboundResult.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.dns;
-
-/**
- * Class that contains the answer to query processed by the native Unbound
- * resolver. Corresponds to the <a
- * href="http://unbound.net/documentation/doxygen/structub__result.html"
- * >ub_result</a> data structure.
- *
- * The fields {@link #data} and {@link #canonname} are not filled.
- * <p>
- * The JavaDoc of these fields is directly copied from libunbound, licensed as
- * follows:
- * <p>
- * Copyright (c) 2007, NLnet Labs. All rights reserved.
- *
- * This software is open source.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the NLNET LABS nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * @author Ingo Bauersachs
- */
-public class UnboundResult
-{
- /**
- * The original question, name text string.
- */
- String qname;
-
- /**
- * the type asked for
- */
- int qtype;
-
- /**
- * the type asked for
- */
- int qclass;
-
-
- /**
- * a list of network order DNS rdata items, terminated with a NULL pointer,
- * so that data[0] is the first result entry, data[1] the second, and the
- * last entry is NULL.
- */
- byte[][] data;
-
- /**
- * canonical name for the result (the final cname).
- */
- String canonname;
-
- /**
- * DNS RCODE for the result.
- */
- int rcode;
-
- /**
- * The DNS answer packet.
- */
- byte[] answerPacket;
-
-
- /**
- * If there is any data, this is true.
- */
- boolean haveData;
-
- /**
- * If there was no data, and the domain did not exist, this is true.
- */
- boolean nxDomain;
-
- /**
- * True, if the result is validated securely.
- */
- boolean secure;
-
- /**
- * If the result was not secure ({@link #secure} == false), and this result
- * is due to a security failure, bogus is true.
- */
- boolean bogus;
-
- /**
- * If the result is bogus this contains a string (zero terminated) that
- * describes the failure.
- */
- String whyBogus;
-}
diff --git a/src/net/java/sip/communicator/impl/dns/dns.manifest.mf b/src/net/java/sip/communicator/impl/dns/dns.manifest.mf
index 331eba1..33174b5 100644
--- a/src/net/java/sip/communicator/impl/dns/dns.manifest.mf
+++ b/src/net/java/sip/communicator/impl/dns/dns.manifest.mf
@@ -8,6 +8,8 @@ Import-Package: org.jitsi.util,
org.osgi.framework,
net.java.sip.communicator.util,
net.java.sip.communicator.plugin.desktoputil,
+ org.jitsi.dnssec,
+ org.jitsi.dnssec.validator,
org.jitsi.service.resources,
org.jitsi.service.fileaccess,
net.java.sip.communicator.service.resources,
diff --git a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsEntryImpl.java b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsEntryImpl.java
index d4d2ed5..cf42720 100644
--- a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsEntryImpl.java
+++ b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsEntryImpl.java
@@ -43,20 +43,14 @@ public class GoogleContactsEntryImpl
/**
* Google Talk protocol type.
*/
- private static final String YAHOO_PROTOCOL =
- "http://schemas.google.com/g/2005#YAHOO";
-
- /**
- * Google Talk protocol type.
- */
private static final String AIM_PROTOCOL =
"http://schemas.google.com/g/2005#AIM";
/**
* Google Talk protocol type.
*/
- private static final String MSN_PROTOCOL =
- "http://schemas.google.com/g/2005#MSN";
+ private static final String SKYPE_PROTOCOL =
+ "http://schemas.google.com/g/2005#SKYPE";
/**
* Google Talk protocol type.
@@ -432,17 +426,13 @@ public class GoogleContactsEntryImpl
{
proto = GoogleContactsEntry.IMProtocol.GOOGLETALK;
}
- else if(protocol.equals(YAHOO_PROTOCOL))
- {
- proto = GoogleContactsEntry.IMProtocol.YAHOO;
- }
else if(protocol.equals(AIM_PROTOCOL))
{
proto = GoogleContactsEntry.IMProtocol.AIM;
}
- else if(protocol.equals(MSN_PROTOCOL))
+ else if(protocol.equals(SKYPE_PROTOCOL))
{
- proto = GoogleContactsEntry.IMProtocol.MSN;
+ proto = GoogleContactsEntry.IMProtocol.SKYPE;
}
else if(protocol.equals(ICQ_PROTOCOL))
{
diff --git a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsQuery.java b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsQuery.java
index d33e4da..66ea7ad 100644
--- a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsQuery.java
+++ b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsQuery.java
@@ -279,14 +279,11 @@ public class GoogleContactsQuery
case ICQ:
imSubCat = ContactDetail.SubCategory.ICQ;
break;
- case YAHOO:
- imSubCat = ContactDetail.SubCategory.Yahoo;
- break;
case JABBER:
imSubCat = ContactDetail.SubCategory.Jabber;
break;
- case MSN:
- imSubCat = ContactDetail.SubCategory.MSN;
+ case SKYPE:
+ imSubCat = ContactDetail.SubCategory.Skype;
break;
case GOOGLETALK:
imSubCat = ContactDetail.SubCategory.GoogleTalk;
@@ -357,12 +354,6 @@ public class GoogleContactsQuery
OperationSetBasicTelephony.class,
ProtocolNames.JABBER);
break;
- case YAHOO:
- supportedOpSets.add(OperationSetBasicInstantMessaging.class);
- preferredProtocols.put(
- OperationSetBasicInstantMessaging.class,
- ProtocolNames.YAHOO);
- break;
default:
break;
}
diff --git a/src/net/java/sip/communicator/impl/gui/UIServiceImpl.java b/src/net/java/sip/communicator/impl/gui/UIServiceImpl.java
index 2e8735f..db2eac9 100644
--- a/src/net/java/sip/communicator/impl/gui/UIServiceImpl.java
+++ b/src/net/java/sip/communicator/impl/gui/UIServiceImpl.java
@@ -74,7 +74,8 @@ public class UIServiceImpl
implements UIService,
ShutdownService,
ServiceListener,
- PropertyChangeListener
+ PropertyChangeListener,
+ UINotificationListener
{
/**
* The <tt>Logger</tt> used by the <tt>UIServiceImpl</tt> class and its
@@ -140,6 +141,7 @@ public class UIServiceImpl
*/
public UIServiceImpl()
{
+ UINotificationManager.addNotificationListener(this);
}
/**
@@ -197,8 +199,12 @@ public class UIServiceImpl
}
}
- if(ConfigurationUtils.isApplicationVisible())
+ if(ConfigurationUtils.isApplicationVisible()
+ || Boolean.getBoolean("disable-tray")
+ || ConfigurationUtils.isMinimizeInsteadOfHide())
+ {
mainFrame.setFrameVisible(true);
+ }
SwingUtilities.invokeLater(new RunLoginGui());
@@ -428,36 +434,16 @@ public class UIServiceImpl
}
/**
- * Implements {@link UIService#setExitOnMainWindowClose}. Sets the boolean
- * property which indicates whether the application should be exited when
- * the main application window is closed.
- *
- * @param exitOnMainWindowClose <tt>true</tt> if closing the main
- * application window should also be exiting the application; otherwise,
- * <tt>false</tt>
- */
- public void setExitOnMainWindowClose(boolean exitOnMainWindowClose)
- {
- mainFrame.setDefaultCloseOperation(
- exitOnMainWindowClose
- ? JFrame.DISPOSE_ON_CLOSE
- : JFrame.HIDE_ON_CLOSE);
- }
-
- /**
- * Implements {@link UIService#getExitOnMainWindowClose()}. Gets the boolean
- * property which indicates whether the application should be exited when
- * the main application window is closed.
- *
- * @return determines whether the UI impl would exit the application when
- * the main application window is closed.
+ * Called from the systray service when a tray has been initialized and
+ * hiding (instead of minimizing or exiting) is possible). If hiding is
+ * possible and the option to minimize is not selected, the application
+ * gets hidden on clicking 'X'.
+ *
+ * @param true if a tray icon was loaded.
*/
- public boolean getExitOnMainWindowClose()
+ public void setMainWindowCanHide(boolean canHide)
{
- return
- (mainFrame != null)
- && (mainFrame.getDefaultCloseOperation()
- == JFrame.DISPOSE_ON_CLOSE);
+ mainFrame.updateCloseAction(canHide);
}
/**
@@ -1642,4 +1628,41 @@ public class UIServiceImpl
ChatRoomAutoOpenConfigDialog.showChatRoomAutoOpenConfigDialog(
pps, chatRoomId);
}
+
+ /**
+ * Counts the number of unread notifications and forwards the sum to the
+ * systray service.
+ */
+ @Override
+ public void notificationReceived(UINotification notification)
+ {
+ forwardNotificationCount();
+ }
+
+ /**
+ * Counts the number of unread notifications and forwards the sum to the
+ * systray service.
+ */
+ @Override
+ public void notificationCleared(UINotification notification)
+ {
+ forwardNotificationCount();
+ }
+
+ private void forwardNotificationCount()
+ {
+ int count = 0;
+ for (UINotificationGroup g : UINotificationManager
+ .getNotificationGroups())
+ {
+ Iterator<UINotification> it =
+ UINotificationManager.getUnreadNotifications(g);
+ while (it.hasNext())
+ {
+ count += it.next().getUnreadObjects();
+ }
+ }
+
+ GuiActivator.getSystrayService().setNotificationCount(count);
+ }
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
index a8ee80a..b450efe 100644
--- a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
+++ b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
@@ -334,13 +334,9 @@ public class MainFrame
*/
private void init()
{
- setDefaultCloseOperation(
- GuiActivator.getUIService().getExitOnMainWindowClose()
- ? JFrame.DISPOSE_ON_CLOSE
- : JFrame.HIDE_ON_CLOSE);
-
+ // at startup, we cannot hide yet
+ updateCloseAction(false);
registerKeyActions();
-
JComponent northPanel = createTopComponent();
this.setJMenuBar(menu);
@@ -394,6 +390,30 @@ public class MainFrame
}
}
+ /**
+ * If hiding is possible and the option to minimize is not selected, the
+ * application gets hidden on clicking 'X'.
+ *
+ * @param true if hiding is possible, i.e. a tray icon is loaded
+ */
+ public void updateCloseAction(boolean canHide)
+ {
+ if (ConfigurationUtils.isMinimizeInsteadOfHide())
+ {
+ logger.info("Updating close action: DO_NOTHING_ON_CLOSE");
+ setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+ }
+ else
+ {
+ logger.info("Updating close action: " + (canHide
+ ? "HIDE_ON_CLOSE"
+ : "DISPOSE_ON_CLOSE"));
+ setDefaultCloseOperation(canHide
+ ? JFrame.HIDE_ON_CLOSE
+ : JFrame.DISPOSE_ON_CLOSE);
+ }
+ }
+
private Component createButtonPanel()
{
boolean isCallButtonEnabled = false;
@@ -1885,7 +1905,8 @@ public class MainFrame
*/
protected void windowClosed(WindowEvent event)
{
- if(GuiActivator.getUIService().getExitOnMainWindowClose())
+ if(getDefaultCloseOperation() == JFrame.EXIT_ON_CLOSE ||
+ getDefaultCloseOperation() == JFrame.DISPOSE_ON_CLOSE)
{
try
{
@@ -1919,9 +1940,17 @@ public class MainFrame
// On Mac systems the application is not quited on window close, so we
// don't need to warn the user.
- if (!GuiActivator.getUIService().getExitOnMainWindowClose()
- && !OSUtils.IS_MAC)
+ if (OSUtils.IS_MAC)
{
+ return;
+ }
+
+ switch (getDefaultCloseOperation())
+ {
+ case JFrame.EXIT_ON_CLOSE:
+ case JFrame.DISPOSE_ON_CLOSE:
+ return;
+ case JFrame.HIDE_ON_CLOSE:
SwingUtilities.invokeLater(new Runnable()
{
public void run()
@@ -1940,8 +1969,11 @@ public class MainFrame
}
}
});
-
ConfigurationUtils.setApplicationVisible(false);
+ break;
+ case JFrame.DO_NOTHING_ON_CLOSE:
+ this.minimize();
+ break;
}
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/UINotification.java b/src/net/java/sip/communicator/impl/gui/main/UINotification.java
index fbfb6da..4304907 100644
--- a/src/net/java/sip/communicator/impl/gui/main/UINotification.java
+++ b/src/net/java/sip/communicator/impl/gui/main/UINotification.java
@@ -17,6 +17,8 @@
*/
package net.java.sip.communicator.impl.gui.main;
+import java.util.Objects;
+
/**
* The <tt>UINotification</tt> class represents a notification received in the
* user interface. This could be a missed call, voicemail, email notification or
@@ -172,4 +174,10 @@ public class UINotification
return true;
}
+
+ @Override
+ public int hashCode()
+ {
+ return Objects.hash(notificationName, parentGroup);
+ }
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/UINotificationGroup.java b/src/net/java/sip/communicator/impl/gui/main/UINotificationGroup.java
index a2e3673..fb14645 100644
--- a/src/net/java/sip/communicator/impl/gui/main/UINotificationGroup.java
+++ b/src/net/java/sip/communicator/impl/gui/main/UINotificationGroup.java
@@ -99,7 +99,12 @@ public class UINotificationGroup
{
synchronized (unreadNotifications)
{
+ List<UINotification> copy = new ArrayList<>(unreadNotifications);
unreadNotifications.clear();
+ for (UINotification n : copy)
+ {
+ UINotificationManager.fireClearedEvent(n);
+ }
}
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/UINotificationListener.java b/src/net/java/sip/communicator/impl/gui/main/UINotificationListener.java
index fc5568d..932d96c 100644
--- a/src/net/java/sip/communicator/impl/gui/main/UINotificationListener.java
+++ b/src/net/java/sip/communicator/impl/gui/main/UINotificationListener.java
@@ -32,4 +32,11 @@ public interface UINotificationListener
* @param notification the notification that was received
*/
public void notificationReceived(UINotification notification);
+
+ /**
+ * Indicates that a notification has been cleared.
+ *
+ * @param notification the notification that was cleared.
+ */
+ public void notificationCleared(UINotification notification);
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/UINotificationManager.java b/src/net/java/sip/communicator/impl/gui/main/UINotificationManager.java
index b6001f7..2d42233 100644
--- a/src/net/java/sip/communicator/impl/gui/main/UINotificationManager.java
+++ b/src/net/java/sip/communicator/impl/gui/main/UINotificationManager.java
@@ -150,4 +150,23 @@ public class UINotificationManager
listeners.next().notificationReceived(notification);
}
}
+
+
+ /**
+ * Notifies interested <tt>UINotificationListener</tt> that a
+ * notification has been cleared.
+ *
+ * @param notification the cleared notification
+ */
+ static void fireClearedEvent(UINotification notification)
+ {
+ synchronized (notificationListeners)
+ {
+ Iterator<UINotificationListener> listeners
+ = notificationListeners.iterator();
+
+ while (listeners.hasNext())
+ listeners.next().notificationCleared(notification);
+ }
+ }
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/account/AccountsConfigurationPanel.java b/src/net/java/sip/communicator/impl/gui/main/account/AccountsConfigurationPanel.java
index 9511310..a85ffc3 100644
--- a/src/net/java/sip/communicator/impl/gui/main/account/AccountsConfigurationPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/account/AccountsConfigurationPanel.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,278 +15,278 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.gui.main.account;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.beans.*;
-import java.util.List;
-
-import javax.swing.*;
-import javax.swing.event.*;
-
-import net.java.sip.communicator.impl.gui.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.account.*;
-
-import org.jitsi.service.configuration.*;
-import org.jitsi.service.resources.*;
-
-/**
- * The <tt>AccountsConfigurationPanel</tt> is the panel containing the accounts
- * list and according buttons shown in the options form.
- *
- * @author Yana Stamcheva
- * @author Lubomir Marinov
- */
-public class AccountsConfigurationPanel
- extends TransparentPanel
- implements ActionListener,
- ListSelectionListener,
- PropertyChangeListener
-{
- private final AccountList accountList;
-
- private final JButton newButton =
- new JButton(GuiActivator.getResources().getI18NString(
- "service.gui.ADD"));
-
- private final JButton editButton =
- new JButton(GuiActivator.getResources().getI18NString(
- "service.gui.EDIT"));
-
- private final JButton removeButton =
- new JButton(GuiActivator.getResources().getI18NString(
- "service.gui.DELETE"));
-
- /**
- * Creates and initializes this account configuration panel.
- */
- public AccountsConfigurationPanel()
- {
- super(new BorderLayout());
-
- accountList = new AccountList(this);
-
- /*
- * It seems that we can only delete one account at a time because our
- * confirmation dialog asks for one account.
- */
- accountList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-
- this.setPreferredSize(new Dimension(500, 400));
-
- JScrollPane accountListPane = new JScrollPane();
-
- accountListPane.getViewport().add(accountList);
- accountListPane.getVerticalScrollBar().setUnitIncrement(30);
-
- this.add(accountListPane, BorderLayout.CENTER);
-
- JPanel buttonsPanel =
- new TransparentPanel(new FlowLayout(FlowLayout.RIGHT));
-
- newButton.addActionListener(this);
- editButton.addActionListener(this);
- removeButton.addActionListener(this);
-
- this.newButton.setMnemonic(GuiActivator.getResources().getI18nMnemonic(
- "service.gui.ADD"));
- this.editButton
- .setMnemonic(GuiActivator.getResources().getI18nMnemonic(
- "service.gui.EDIT"));
- this.removeButton
- .setMnemonic(GuiActivator.getResources().getI18nMnemonic(
- "service.gui.DELETE"));
-
- buttonsPanel.add(newButton);
-
- buttonsPanel.add(editButton);
-
- buttonsPanel.add(removeButton);
-
- this.add(buttonsPanel, BorderLayout.SOUTH);
-
- accountList.addListSelectionListener(this);
- accountList.addPropertyChangeListener(
- AccountList.ACCOUNT_STATE_CHANGED, this);
- updateButtons();
- }
-
- /**
- * Handles the <tt>ActionEvent</tt> triggered when user clicks on on the
- * buttons. Shows the account registration wizard when user clicks on "New".
- *
- * @param evt the action event that has just occurred.
- */
- public void actionPerformed(ActionEvent evt)
- {
- Object sourceButton = evt.getSource();
-
- if (sourceButton.equals(newButton))
- {
- NewAccountDialog.showNewAccountDialog();
- }
- else if (sourceButton.equals(removeButton))
- {
- Account account = accountList.getSelectedAccount();
-
- if (account == null)
- return;
-
- AccountID accountID = account.getAccountID();
-
- ProtocolProviderFactory providerFactory =
- AccountUtils.getProtocolProviderFactory(
- accountID.getProtocolName());
-
- if (providerFactory != null)
- {
- int result = JOptionPane.showConfirmDialog(
- this,
- GuiActivator.getResources()
- .getI18NString("service.gui.REMOVE_ACCOUNT_MESSAGE"),
- GuiActivator.getResources().getI18NString(
- "service.gui.REMOVE_ACCOUNT"),
- JOptionPane.YES_NO_OPTION);
-
- if (result == JOptionPane.YES_OPTION)
- {
- ConfigurationService configService
- = GuiActivator.getConfigurationService();
- String prefix
- = "net.java.sip.communicator.impl.gui.accounts";
- List<String> accounts
- = configService.getPropertyNamesByPrefix(prefix, true);
-
- for (String accountRootPropName : accounts)
- {
- String accountUID
- = configService.getString(accountRootPropName);
-
- if (accountUID.equals(accountID.getAccountUniqueID()))
- {
- configService.setProperty(accountRootPropName, null);
- break;
- }
- }
- boolean isUninstalled
- = providerFactory.uninstallAccount(accountID);
-
- if (isUninstalled)
- {
- accountList.ensureAccountRemoved(accountID);
-
- // Notify the corresponding wizard that the account
- // would be removed.
- AccountRegWizardContainerImpl wizardContainer
- = (AccountRegWizardContainerImpl) GuiActivator
- .getUIService().getAccountRegWizardContainer();
-
- ProtocolProviderService protocolProvider =
- account.getProtocolProvider();
- AccountRegistrationWizard wizard =
- wizardContainer.getProtocolWizard(protocolProvider);
-
- if (wizard != null)
- wizard.accountRemoved(protocolProvider);
- }
- }
- }
- }
- else if (sourceButton.equals(editButton))
- {
- Account account = accountList.getSelectedAccount();
-
- if (account == null)
- return;
-
- AccountRegWizardContainerImpl wizard =
- (AccountRegWizardContainerImpl) GuiActivator.getUIService()
- .getAccountRegWizardContainer();
-
- AccountRegistrationWizard protocolWizard =
- wizard.getProtocolWizard(account.getProtocolProvider());
-
- ResourceManagementService resources = GuiActivator.getResources();
- if (protocolWizard != null)
- {
- wizard.setTitle(resources.getI18NString(
- "service.gui.ACCOUNT_REGISTRATION_WIZARD"));
-
- wizard.modifyAccount(account.getProtocolProvider());
- wizard.showDialog(false);
- }
- else
- {
- // There is no wizard for this account - just show an error
- // dialog:
- String title = resources.getI18NString("service.gui.ERROR");
- String message =
- resources.getI18NString("service.gui.EDIT_NOT_SUPPORTED");
- ErrorDialog dialog = new ErrorDialog(null, title, message);
- dialog.setVisible(true);
- }
- }
- }
-
- /**
- * Returns the edit button.
- *
- * @return the edit button
- */
- public JButton getEditButton()
- {
- return editButton;
- }
-
- /**
- * Updates enabled states of the buttons of this
- * <tt>AccountsConfigurationPanel</tt> to reflect their applicability to the
- * current selection in <tt>accountList</tt>.
- */
- private void updateButtons()
- {
- if(!SwingUtilities.isEventDispatchThread())
- {
- SwingUtilities.invokeLater(new Runnable()
- {
- public void run()
- {
- updateButtons();
- }
- });
- return;
- }
-
- Account account = accountList.getSelectedAccount();
- boolean enabled = (account != null);
-
- editButton.setEnabled(enabled && account.isEnabled());
- removeButton.setEnabled(enabled);
- }
-
- /**
- * Implements ListSelectionListener#valueChanged(ListSelectionEvent).
- * @param e the <tt>ListSelectionEvent</tt> that notified us
- */
- public void valueChanged(ListSelectionEvent e)
- {
- if (!e.getValueIsAdjusting())
- updateButtons();
- }
-
- /**
- * This method gets called when a property is changed.
- *
- * @param evt A PropertyChangeEvent object describing the event source
- * and the property that has changed.
- */
- public void propertyChange(PropertyChangeEvent evt)
- {
- // update buttons whenever an account changes its state
- updateButtons();
- }
-}
+package net.java.sip.communicator.impl.gui.main.account;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.beans.*;
+import java.util.List;
+
+import javax.swing.*;
+import javax.swing.event.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.account.*;
+
+import org.jitsi.service.configuration.*;
+import org.jitsi.service.resources.*;
+
+/**
+ * The <tt>AccountsConfigurationPanel</tt> is the panel containing the accounts
+ * list and according buttons shown in the options form.
+ *
+ * @author Yana Stamcheva
+ * @author Lubomir Marinov
+ */
+public class AccountsConfigurationPanel
+ extends TransparentPanel
+ implements ActionListener,
+ ListSelectionListener,
+ PropertyChangeListener
+{
+ private final AccountList accountList;
+
+ private final JButton newButton =
+ new JButton(GuiActivator.getResources().getI18NString(
+ "service.gui.ADD"));
+
+ private final JButton editButton =
+ new JButton(GuiActivator.getResources().getI18NString(
+ "service.gui.EDIT"));
+
+ private final JButton removeButton =
+ new JButton(GuiActivator.getResources().getI18NString(
+ "service.gui.DELETE"));
+
+ /**
+ * Creates and initializes this account configuration panel.
+ */
+ public AccountsConfigurationPanel()
+ {
+ super(new BorderLayout());
+
+ accountList = new AccountList(this);
+
+ /*
+ * It seems that we can only delete one account at a time because our
+ * confirmation dialog asks for one account.
+ */
+ accountList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+
+ this.setPreferredSize(new Dimension(500, 400));
+
+ JScrollPane accountListPane = new JScrollPane();
+
+ accountListPane.getViewport().add(accountList);
+ accountListPane.getVerticalScrollBar().setUnitIncrement(30);
+
+ this.add(accountListPane, BorderLayout.CENTER);
+
+ JPanel buttonsPanel =
+ new TransparentPanel(new FlowLayout(FlowLayout.RIGHT));
+
+ newButton.addActionListener(this);
+ editButton.addActionListener(this);
+ removeButton.addActionListener(this);
+
+ this.newButton.setMnemonic(GuiActivator.getResources().getI18nMnemonic(
+ "service.gui.ADD"));
+ this.editButton
+ .setMnemonic(GuiActivator.getResources().getI18nMnemonic(
+ "service.gui.EDIT"));
+ this.removeButton
+ .setMnemonic(GuiActivator.getResources().getI18nMnemonic(
+ "service.gui.DELETE"));
+
+ buttonsPanel.add(newButton);
+
+ buttonsPanel.add(editButton);
+
+ buttonsPanel.add(removeButton);
+
+ this.add(buttonsPanel, BorderLayout.SOUTH);
+
+ accountList.addListSelectionListener(this);
+ accountList.addPropertyChangeListener(
+ AccountList.ACCOUNT_STATE_CHANGED, this);
+ updateButtons();
+ }
+
+ /**
+ * Handles the <tt>ActionEvent</tt> triggered when user clicks on on the
+ * buttons. Shows the account registration wizard when user clicks on "New".
+ *
+ * @param evt the action event that has just occurred.
+ */
+ public void actionPerformed(ActionEvent evt)
+ {
+ Object sourceButton = evt.getSource();
+
+ if (sourceButton.equals(newButton))
+ {
+ NewAccountDialog.showNewAccountDialog();
+ }
+ else if (sourceButton.equals(removeButton))
+ {
+ Account account = accountList.getSelectedAccount();
+
+ if (account == null)
+ return;
+
+ AccountID accountID = account.getAccountID();
+
+ ProtocolProviderFactory providerFactory =
+ AccountUtils.getProtocolProviderFactory(
+ accountID.getProtocolName());
+
+ if (providerFactory != null)
+ {
+ int result = JOptionPane.showConfirmDialog(
+ this,
+ GuiActivator.getResources()
+ .getI18NString("service.gui.REMOVE_ACCOUNT_MESSAGE"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.REMOVE_ACCOUNT"),
+ JOptionPane.YES_NO_OPTION);
+
+ if (result == JOptionPane.YES_OPTION)
+ {
+ ConfigurationService configService
+ = GuiActivator.getConfigurationService();
+ String prefix
+ = "net.java.sip.communicator.impl.gui.accounts";
+ List<String> accounts
+ = configService.getPropertyNamesByPrefix(prefix, true);
+
+ for (String accountRootPropName : accounts)
+ {
+ String accountUID
+ = configService.getString(accountRootPropName);
+
+ if (accountUID.equals(accountID.getAccountUniqueID()))
+ {
+ configService.setProperty(accountRootPropName, null);
+ break;
+ }
+ }
+ boolean isUninstalled
+ = providerFactory.uninstallAccount(accountID);
+
+ if (isUninstalled)
+ {
+ accountList.ensureAccountRemoved(accountID);
+
+ // Notify the corresponding wizard that the account
+ // would be removed.
+ AccountRegWizardContainerImpl wizardContainer
+ = (AccountRegWizardContainerImpl) GuiActivator
+ .getUIService().getAccountRegWizardContainer();
+
+ ProtocolProviderService protocolProvider =
+ account.getProtocolProvider();
+ AccountRegistrationWizard wizard =
+ wizardContainer.getProtocolWizard(protocolProvider);
+
+ if (wizard != null)
+ wizard.accountRemoved(protocolProvider);
+ }
+ }
+ }
+ }
+ else if (sourceButton.equals(editButton))
+ {
+ Account account = accountList.getSelectedAccount();
+
+ if (account == null)
+ return;
+
+ AccountRegWizardContainerImpl wizard =
+ (AccountRegWizardContainerImpl) GuiActivator.getUIService()
+ .getAccountRegWizardContainer();
+
+ AccountRegistrationWizard protocolWizard =
+ wizard.getProtocolWizard(account.getProtocolProvider());
+
+ ResourceManagementService resources = GuiActivator.getResources();
+ if (protocolWizard != null)
+ {
+ wizard.setTitle(resources.getI18NString(
+ "service.gui.ACCOUNT_REGISTRATION_WIZARD"));
+
+ wizard.modifyAccount(account.getProtocolProvider());
+ wizard.showDialog(false);
+ }
+ else
+ {
+ // There is no wizard for this account - just show an error
+ // dialog:
+ String title = resources.getI18NString("service.gui.ERROR");
+ String message =
+ resources.getI18NString("service.gui.EDIT_NOT_SUPPORTED");
+ ErrorDialog dialog = new ErrorDialog(null, title, message);
+ dialog.setVisible(true);
+ }
+ }
+ }
+
+ /**
+ * Returns the edit button.
+ *
+ * @return the edit button
+ */
+ public JButton getEditButton()
+ {
+ return editButton;
+ }
+
+ /**
+ * Updates enabled states of the buttons of this
+ * <tt>AccountsConfigurationPanel</tt> to reflect their applicability to the
+ * current selection in <tt>accountList</tt>.
+ */
+ private void updateButtons()
+ {
+ if(!SwingUtilities.isEventDispatchThread())
+ {
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ updateButtons();
+ }
+ });
+ return;
+ }
+
+ Account account = accountList.getSelectedAccount();
+ boolean enabled = (account != null);
+
+ editButton.setEnabled(enabled && account.isEnabled());
+ removeButton.setEnabled(enabled);
+ }
+
+ /**
+ * Implements ListSelectionListener#valueChanged(ListSelectionEvent).
+ * @param e the <tt>ListSelectionEvent</tt> that notified us
+ */
+ public void valueChanged(ListSelectionEvent e)
+ {
+ if (!e.getValueIsAdjusting())
+ updateButtons();
+ }
+
+ /**
+ * This method gets called when a property is changed.
+ *
+ * @param evt A PropertyChangeEvent object describing the event source
+ * and the property that has changed.
+ */
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ // update buttons whenever an account changes its state
+ updateButtons();
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallDialog.java b/src/net/java/sip/communicator/impl/gui/main/call/CallDialog.java
index 697a3fc..de63f79 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/CallDialog.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/CallDialog.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,619 +15,619 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.gui.main.call;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.impl.gui.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
-
-/**
- * The dialog created for a given call.
- *
- * @author Yana Stamcheva
- * @author Adam Netocny
- * @author Lyubomir Marinov
- */
-public class CallDialog
- extends SIPCommFrame
- implements CallContainer,
- CallTitleListener
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * Enabling force minimized mode will always open call dialog minimized.
- * The call dialog still can be shown, but by default it will be minimized.
- */
- private static final String FORCE_MINIMIZED_MODE
- = "net.java.sip.communicator.impl.gui.main.call.FORCE_MINIMIZED_MODE";
-
- /**
- * Finds a <tt>Container</tt> which is an ancestor of a specific
- * <tt>Component</tt>, has a set <tt>preferredSize</tt> and is closest to
- * the specified <tt>Component</tt> up the ancestor hierarchy.
- *
- * @param component the <tt>Component</tt> whose ancestor hierarchy is to be
- * searched upwards
- * @return a <tt>Container</tt>, if any, which is an ancestor of the
- * specified <tt>component</tt>, has a set <tt>preferredSize</tt> and is
- * closest to the specified <tt>component</tt> up the ancestor hierarchy
- */
- private static Container findClosestAncestorWithSetPreferredSize(
- Component component)
- {
- if ((component instanceof Container) && component.isPreferredSizeSet())
- return (Container) component;
- else
- {
- Container parent;
-
- while ((parent = component.getParent()) != null)
- {
- if (parent.isPreferredSizeSet())
- return parent;
- else
- component = parent;
- }
- return null;
- }
- }
-
- /**
- * The panel, where all call components are added.
- */
- private CallPanel callPanel;
-
- private final WindowStateListener windowStateListener
- = new WindowStateListener()
- {
- public void windowStateChanged(WindowEvent ev)
- {
- switch (ev.getID())
- {
- case WindowEvent.WINDOW_DEACTIVATED:
- case WindowEvent.WINDOW_ICONIFIED:
- case WindowEvent.WINDOW_LOST_FOCUS:
- setFullScreen(false);
- break;
- }
- }
- };
-
- /**
- * Creates a <tt>CallDialog</tt> by specifying the underlying call panel.
- */
- public CallDialog()
- {
- super(true, false);
-
- setMinimumSize(new Dimension(360, 300));
- }
-
- /**
- * Adds a call panel.
- *
- * @param callPanel the call panel to add to this dialog
- */
- public void addCallPanel(CallPanel callPanel)
- {
- this.callPanel = callPanel;
-
- getContentPane().add(callPanel);
-
- callPanel.addCallTitleListener(this);
- setTitle(callPanel.getCallTitle());
-
- if (!isVisible())
- {
- pack();
-
- // checks whether we need to open the call dialog in minimized mode
- if(GuiActivator.getConfigurationService()
- .getBoolean(FORCE_MINIMIZED_MODE, false))
- {
- setState(ICONIFIED);
- }
- setVisible(true);
- }
- }
-
- /**
- * Called when the title of the given <tt>CallPanel</tt> changes.
- *
- * @param callPanel the <tt>CallPanel</tt>, which title has changed
- */
- public void callTitleChanged(CallPanel callPanel)
- {
- if (this.callPanel.equals(callPanel))
- setTitle(callPanel.getCallTitle());
- }
-
- /**
- * {@inheritDoc}
- *
- * Hang ups the call/telephony conference depicted by this
- * <tt>CallDialog</tt> on close.
- */
- @Override
- protected void close(boolean escape)
- {
- if (escape)
- {
- /*
- * In full-screen mode, ESC does not close this CallDialog but exits
- * from full-screen to windowed mode.
- */
- if (isFullScreen())
- {
- setFullScreen(false);
- return;
- }
- }
- else
- {
- /*
- * If the window has been closed by clicking the X button or
- * pressing the key combination corresponding to the same button we
- * close the window first and then perform all hang up operations.
- */
-
- callPanel.disposeCallInfoFrame();
- // We hide the window here. It will be disposed when the call has
- // been ended.
- setVisible(false);
- }
-
- // Then perform hang up operations.
- callPanel.actionPerformedOnHangupButton(escape);
- }
-
- /**
- * {@inheritDoc}
- *
- * The delay implemented by <tt>CallDialog</tt> is 5 seconds.
- */
- public void close(final CallPanel callPanel, boolean delay)
- {
- if (this.callPanel.equals(callPanel))
- {
- if (delay)
- {
- Timer timer
- = new Timer(
- 5000,
- new ActionListener()
- {
- public void actionPerformed(ActionEvent ev)
- {
- dispose();
- }
- });
-
- timer.setRepeats(false);
- timer.start();
- }
- else
- {
- dispose();
- }
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * <tt>CallDialog</tt> prepares the <tt>CallPanel</tt> it contains for
- * garbage collection.
- */
- @Override
- public void dispose()
- {
- super.dispose();
-
- /*
- * Technically, CallManager adds/removes the callPanel to/from this
- * instance. It may want to just move it to another CallContainer so it
- * does not sound right that we are disposing of it. But we do not have
- * such a case at this time so try to reduce the risk of memory leaks.
- */
- if (this.callPanel != null)
- {
- callPanel.disposeCallInfoFrame();
- callPanel.dispose();
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * Attempts to adjust the size of this <tt>Frame</tt> as requested in the
- * AWT event dispatching thread.
- * <p>
- * The method may be executed on the AWT event dispatching thread only
- * because whoever is making the decision to request an adjustment of the
- * Frame size in relation to a AWT Component should be analyzing that same
- * Component in the AWT event dispatching thread only.
- * </p>
- *
- * @throws RuntimeException if the method is not called on the AWT event
- * dispatching thread
- */
- public void ensureSize(Component component, int width, int height)
- {
- CallManager.assertIsEventDispatchingThread();
-
- Frame frame = CallPeerRendererUtils.getFrame(component);
-
- if (frame == null)
- return;
- else if ((frame.getExtendedState() & Frame.MAXIMIZED_BOTH)
- == Frame.MAXIMIZED_BOTH)
- {
- /*
- * Forcing the size of a Component which is displayed in a maximized
- * window does not sound like anything we want to do.
- */
- return;
- }
- else if (frame.equals(
- frame.getGraphicsConfiguration().getDevice()
- .getFullScreenWindow()))
- {
- /*
- * Forcing the size of a Component which is displayed in a
- * full-screen window does not sound like anything we want to do.
- */
- return;
- }
- else if (!frame.equals(this))
- {
- /* This Frame will try to adjust only its own size. */
- return;
- }
- else if ((component.getHeight() >= height)
- && (component.getWidth() >= width))
- {
- /*
- * We will only enlarge the frame size. If the component has already
- * been given at least what it is requesting, do not enlarge the
- * frame size because the whole calculation is prone to inaccuracy.
- */
- return;
- }
- else
- {
- /*
- * If there is no callPanel, it is unlikely that this CallDialog
- * will be asked to ensureSize. Anyway, support the scenario just in
- * case. In light of the absence of a callPanel to guide this
- * CallDialog about the preferred size, we do not have much of a
- * choice but to trust the method arguments.
- */
- if (callPanel != null)
- {
- /*
- * If there is a callPanel, we are likely to get a much better
- * estimation about the preferred size by asking the callPanel
- * rather than by trusting the method arguments. For example,
- * the visual Component displaying the video streaming from the
- * local user/peer to the remote peer(s) will think that its
- * preferred size is the one to base this Frame's size on but
- * that may be misleading because the local video may not be
- * displayed with its preferred size even if this Frame's size
- * will accommodate it.
- */
- /*
- * Just asking the callPanel about its preferredSize would've
- * been terrificly great. Unfortunately, that is presently
- * futile because the callPanel may have a preferredSize while
- * we are still required to display visual Components displaying
- * video in their non-scaled size. The same goes for any
- * Container which is an ancestor of the specified component.
- */
- Container ancestor
- = findClosestAncestorWithSetPreferredSize(component);
-
- if (ancestor == null)
- ancestor = callPanel;
- /*
- * If the ancestor has a forced preferredSize, its LayoutManager
- * may be able to give a good enough estimation.
- */
- if (ancestor.isPreferredSizeSet())
- {
- LayoutManager ancestorLayout = ancestor.getLayout();
-
- if (ancestorLayout != null)
- {
- Dimension preferredLayoutSize
- = ancestorLayout.preferredLayoutSize(ancestor);
-
- if (preferredLayoutSize != null)
- {
- component = ancestor;
- width = preferredLayoutSize.width;
- height = preferredLayoutSize.height;
- }
- }
- }
- else
- {
- /*
- * If the ancestor doesn't have a preferredSize forced, then
- * we may think that it will calculate an appropriate
- * preferredSize itself.
- */
- Dimension prefSize = ancestor.getPreferredSize();
-
- if (prefSize != null)
- {
- component = ancestor;
- width = prefSize.width;
- height = prefSize.height;
- }
- }
- }
-
- /*
- * If the component (which may be an ancestor of the Component
- * specified as an argument to the ensureSize method at this point)
- * has not been given a size, we will make a mistake if we try to
- * use it for the purposes of determining how much this Frame is to
- * be enlarged.
- */
- Dimension componentSize = component.getSize();
-
- if ((componentSize.width < 1) || (componentSize.height < 1))
- return;
-
- Dimension frameSize = frame.getSize();
- int newFrameWidth = frameSize.width + width - componentSize.width;
- int newFrameHeight
- = frameSize.height + height - componentSize.height;
-
- // Respect the minimum size.
- Dimension minSize = frame.getMinimumSize();
-
- if (newFrameWidth < minSize.width)
- newFrameWidth = minSize.width;
- if (newFrameHeight < minSize.height)
- newFrameHeight = minSize.height;
-
- // Don't get bigger than the screen.
- Rectangle screenBounds
- = frame.getGraphicsConfiguration().getBounds();
-
- if (newFrameWidth > screenBounds.width)
- newFrameWidth = screenBounds.width;
- if (newFrameHeight > screenBounds.height)
- newFrameHeight = screenBounds.height;
-
- /*
- * If we're going to make too small a change, don't even bother.
- * Besides, we don't want some weird recursive resizing.
- * Additionally, do not reduce the Frame size.
- */
- boolean changeWidth = ((newFrameWidth - frameSize.width) > 1);
- boolean changeHeight = ((newFrameHeight - frameSize.height) > 1);
-
- if (changeWidth || changeHeight)
- {
- if (!changeWidth)
- newFrameWidth = frameSize.width;
- else if (!changeHeight)
- newFrameHeight = frameSize.height;
-
- /*
- * The latest requirement with respect to the behavior upon
- * resizing is to center the Frame.
- */
- int newFrameX
- = screenBounds.x
- + (screenBounds.width - newFrameWidth) / 2;
- int newFrameY
- = screenBounds.y
- + (screenBounds.height - newFrameHeight) / 2;
-
- // Do not let the top left go out of the screen.
- if (newFrameX < screenBounds.x)
- newFrameX = screenBounds.x;
- if (newFrameY < screenBounds.y)
- newFrameY = screenBounds.y;
-
- frame.setBounds(
- newFrameX, newFrameY,
- newFrameWidth, newFrameHeight);
-
- /*
- * Make sure that the component which originally requested the
- * update to the size of the frame realizes the change as soon
- * as possible; otherwise, it may request yet another update.
- */
- if (frame.isDisplayable())
- {
- if (frame.isValid())
- frame.doLayout();
- else
- frame.validate();
- frame.repaint();
- }
- else
- frame.doLayout();
- }
- }
- }
-
- /**
- * Returns the frame of the call window.
- *
- * @return the frame of the call window
- */
- public JFrame getFrame()
- {
- return this;
- }
-
- /**
- * Overrides getMinimumSize and checks the minimum size that
- * is needed to display buttons and use it for minimum size if
- * needed.
- * @return minimum size.
- */
- @Override
- public Dimension getMinimumSize()
- {
- Dimension minSize = super.getMinimumSize();
-
- if(callPanel != null)
- {
- int minButtonWidth = callPanel.getMinimumButtonWidth();
-
- if(minButtonWidth > minSize.getWidth())
- minSize = new Dimension(minButtonWidth, 300);
- }
-
- return minSize;
- }
-
- /**
- * Indicates if the given <tt>callPanel</tt> is currently visible.
- *
- * @param callPanel the <tt>CallPanel</tt>, for which we verify
- * @return <tt>true</tt> if the given call container is visible in this
- * call window, otherwise - <tt>false</tt>
- */
- public boolean isCallVisible(CallPanel callPanel)
- {
- return this.callPanel.equals(callPanel) ? isVisible() : false;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isFullScreen()
- {
- return isFullScreen(getFrame());
- }
-
- /**
- * Determines whether a specific <tt>Window</tt> is displayed in full-screen
- * mode.
- *
- * @param window the <tt>Window</tt> to be checked whether it is displayed
- * in full-screen mode
- * @return <tt>true</tt> if the specified <tt>window</tt> is displayed in
- * full-screen mode; otherwise, <tt>false</tt>
- */
- public static boolean isFullScreen(Window window)
- {
- GraphicsConfiguration graphicsConfiguration
- = window.getGraphicsConfiguration();
-
- if (graphicsConfiguration != null)
- {
- GraphicsDevice device = graphicsConfiguration.getDevice();
-
- if (device != null)
- return window.equals(device.getFullScreenWindow());
- }
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setFullScreen(boolean fullScreen)
- {
- GraphicsConfiguration graphicsConfiguration
- = getGraphicsConfiguration();
-
- if (graphicsConfiguration != null)
- {
- GraphicsDevice device = graphicsConfiguration.getDevice();
-
- if (device != null)
- {
- boolean thisIsFullScreen = equals(device.getFullScreenWindow());
- boolean firePropertyChange = false;
- boolean setVisible = isVisible();
-
- try
- {
- if (fullScreen)
- {
- if (!thisIsFullScreen)
- {
- /*
- * XXX The setUndecorated method will only work if
- * this Window is not displayable.
- */
- windowDispose();
- setUndecorated(true);
-
- device.setFullScreenWindow(this);
- firePropertyChange = true;
- }
- }
- else if (thisIsFullScreen)
- {
- /*
- * XXX The setUndecorated method will only work if this
- * Window is not displayable.
- */
- windowDispose();
- setUndecorated(false);
-
- device.setFullScreenWindow(null);
- firePropertyChange = true;
- }
-
- if (firePropertyChange)
- {
- if (fullScreen)
- {
- addWindowStateListener(windowStateListener);
-
- /*
- * If full-screen mode, a black background is the
- * most common.
- */
- getContentPane().setBackground(Color.BLACK);
- }
- else
- {
- removeWindowStateListener(windowStateListener);
-
- /*
- * In windowed mode, a system-defined background is
- * the most common.
- */
- getContentPane().setBackground(null);
- }
-
- firePropertyChange(
- PROP_FULL_SCREEN,
- thisIsFullScreen,
- fullScreen);
- }
- }
- finally
- {
- /*
- * Regardless of whether this Window successfully entered or
- * exited full-screen mode, make sure that remains visible.
- */
- if (setVisible)
- setVisible(true);
- }
- }
- }
- }
-}
+package net.java.sip.communicator.impl.gui.main.call;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.plugin.desktoputil.*;
+
+/**
+ * The dialog created for a given call.
+ *
+ * @author Yana Stamcheva
+ * @author Adam Netocny
+ * @author Lyubomir Marinov
+ */
+public class CallDialog
+ extends SIPCommFrame
+ implements CallContainer,
+ CallTitleListener
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * Enabling force minimized mode will always open call dialog minimized.
+ * The call dialog still can be shown, but by default it will be minimized.
+ */
+ private static final String FORCE_MINIMIZED_MODE
+ = "net.java.sip.communicator.impl.gui.main.call.FORCE_MINIMIZED_MODE";
+
+ /**
+ * Finds a <tt>Container</tt> which is an ancestor of a specific
+ * <tt>Component</tt>, has a set <tt>preferredSize</tt> and is closest to
+ * the specified <tt>Component</tt> up the ancestor hierarchy.
+ *
+ * @param component the <tt>Component</tt> whose ancestor hierarchy is to be
+ * searched upwards
+ * @return a <tt>Container</tt>, if any, which is an ancestor of the
+ * specified <tt>component</tt>, has a set <tt>preferredSize</tt> and is
+ * closest to the specified <tt>component</tt> up the ancestor hierarchy
+ */
+ private static Container findClosestAncestorWithSetPreferredSize(
+ Component component)
+ {
+ if ((component instanceof Container) && component.isPreferredSizeSet())
+ return (Container) component;
+ else
+ {
+ Container parent;
+
+ while ((parent = component.getParent()) != null)
+ {
+ if (parent.isPreferredSizeSet())
+ return parent;
+ else
+ component = parent;
+ }
+ return null;
+ }
+ }
+
+ /**
+ * The panel, where all call components are added.
+ */
+ private CallPanel callPanel;
+
+ private final WindowStateListener windowStateListener
+ = new WindowStateListener()
+ {
+ public void windowStateChanged(WindowEvent ev)
+ {
+ switch (ev.getID())
+ {
+ case WindowEvent.WINDOW_DEACTIVATED:
+ case WindowEvent.WINDOW_ICONIFIED:
+ case WindowEvent.WINDOW_LOST_FOCUS:
+ setFullScreen(false);
+ break;
+ }
+ }
+ };
+
+ /**
+ * Creates a <tt>CallDialog</tt> by specifying the underlying call panel.
+ */
+ public CallDialog()
+ {
+ super(true, false);
+
+ setMinimumSize(new Dimension(360, 300));
+ }
+
+ /**
+ * Adds a call panel.
+ *
+ * @param callPanel the call panel to add to this dialog
+ */
+ public void addCallPanel(CallPanel callPanel)
+ {
+ this.callPanel = callPanel;
+
+ getContentPane().add(callPanel);
+
+ callPanel.addCallTitleListener(this);
+ setTitle(callPanel.getCallTitle());
+
+ if (!isVisible())
+ {
+ pack();
+
+ // checks whether we need to open the call dialog in minimized mode
+ if(GuiActivator.getConfigurationService()
+ .getBoolean(FORCE_MINIMIZED_MODE, false))
+ {
+ setState(ICONIFIED);
+ }
+ setVisible(true);
+ }
+ }
+
+ /**
+ * Called when the title of the given <tt>CallPanel</tt> changes.
+ *
+ * @param callPanel the <tt>CallPanel</tt>, which title has changed
+ */
+ public void callTitleChanged(CallPanel callPanel)
+ {
+ if (this.callPanel.equals(callPanel))
+ setTitle(callPanel.getCallTitle());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Hang ups the call/telephony conference depicted by this
+ * <tt>CallDialog</tt> on close.
+ */
+ @Override
+ protected void close(boolean escape)
+ {
+ if (escape)
+ {
+ /*
+ * In full-screen mode, ESC does not close this CallDialog but exits
+ * from full-screen to windowed mode.
+ */
+ if (isFullScreen())
+ {
+ setFullScreen(false);
+ return;
+ }
+ }
+ else
+ {
+ /*
+ * If the window has been closed by clicking the X button or
+ * pressing the key combination corresponding to the same button we
+ * close the window first and then perform all hang up operations.
+ */
+
+ callPanel.disposeCallInfoFrame();
+ // We hide the window here. It will be disposed when the call has
+ // been ended.
+ setVisible(false);
+ }
+
+ // Then perform hang up operations.
+ callPanel.actionPerformedOnHangupButton(escape);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * The delay implemented by <tt>CallDialog</tt> is 5 seconds.
+ */
+ public void close(final CallPanel callPanel, boolean delay)
+ {
+ if (this.callPanel.equals(callPanel))
+ {
+ if (delay)
+ {
+ Timer timer
+ = new Timer(
+ 5000,
+ new ActionListener()
+ {
+ public void actionPerformed(ActionEvent ev)
+ {
+ dispose();
+ }
+ });
+
+ timer.setRepeats(false);
+ timer.start();
+ }
+ else
+ {
+ dispose();
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <tt>CallDialog</tt> prepares the <tt>CallPanel</tt> it contains for
+ * garbage collection.
+ */
+ @Override
+ public void dispose()
+ {
+ super.dispose();
+
+ /*
+ * Technically, CallManager adds/removes the callPanel to/from this
+ * instance. It may want to just move it to another CallContainer so it
+ * does not sound right that we are disposing of it. But we do not have
+ * such a case at this time so try to reduce the risk of memory leaks.
+ */
+ if (this.callPanel != null)
+ {
+ callPanel.disposeCallInfoFrame();
+ callPanel.dispose();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Attempts to adjust the size of this <tt>Frame</tt> as requested in the
+ * AWT event dispatching thread.
+ * <p>
+ * The method may be executed on the AWT event dispatching thread only
+ * because whoever is making the decision to request an adjustment of the
+ * Frame size in relation to a AWT Component should be analyzing that same
+ * Component in the AWT event dispatching thread only.
+ * </p>
+ *
+ * @throws RuntimeException if the method is not called on the AWT event
+ * dispatching thread
+ */
+ public void ensureSize(Component component, int width, int height)
+ {
+ CallManager.assertIsEventDispatchingThread();
+
+ Frame frame = CallPeerRendererUtils.getFrame(component);
+
+ if (frame == null)
+ return;
+ else if ((frame.getExtendedState() & Frame.MAXIMIZED_BOTH)
+ == Frame.MAXIMIZED_BOTH)
+ {
+ /*
+ * Forcing the size of a Component which is displayed in a maximized
+ * window does not sound like anything we want to do.
+ */
+ return;
+ }
+ else if (frame.equals(
+ frame.getGraphicsConfiguration().getDevice()
+ .getFullScreenWindow()))
+ {
+ /*
+ * Forcing the size of a Component which is displayed in a
+ * full-screen window does not sound like anything we want to do.
+ */
+ return;
+ }
+ else if (!frame.equals(this))
+ {
+ /* This Frame will try to adjust only its own size. */
+ return;
+ }
+ else if ((component.getHeight() >= height)
+ && (component.getWidth() >= width))
+ {
+ /*
+ * We will only enlarge the frame size. If the component has already
+ * been given at least what it is requesting, do not enlarge the
+ * frame size because the whole calculation is prone to inaccuracy.
+ */
+ return;
+ }
+ else
+ {
+ /*
+ * If there is no callPanel, it is unlikely that this CallDialog
+ * will be asked to ensureSize. Anyway, support the scenario just in
+ * case. In light of the absence of a callPanel to guide this
+ * CallDialog about the preferred size, we do not have much of a
+ * choice but to trust the method arguments.
+ */
+ if (callPanel != null)
+ {
+ /*
+ * If there is a callPanel, we are likely to get a much better
+ * estimation about the preferred size by asking the callPanel
+ * rather than by trusting the method arguments. For example,
+ * the visual Component displaying the video streaming from the
+ * local user/peer to the remote peer(s) will think that its
+ * preferred size is the one to base this Frame's size on but
+ * that may be misleading because the local video may not be
+ * displayed with its preferred size even if this Frame's size
+ * will accommodate it.
+ */
+ /*
+ * Just asking the callPanel about its preferredSize would've
+ * been terrificly great. Unfortunately, that is presently
+ * futile because the callPanel may have a preferredSize while
+ * we are still required to display visual Components displaying
+ * video in their non-scaled size. The same goes for any
+ * Container which is an ancestor of the specified component.
+ */
+ Container ancestor
+ = findClosestAncestorWithSetPreferredSize(component);
+
+ if (ancestor == null)
+ ancestor = callPanel;
+ /*
+ * If the ancestor has a forced preferredSize, its LayoutManager
+ * may be able to give a good enough estimation.
+ */
+ if (ancestor.isPreferredSizeSet())
+ {
+ LayoutManager ancestorLayout = ancestor.getLayout();
+
+ if (ancestorLayout != null)
+ {
+ Dimension preferredLayoutSize
+ = ancestorLayout.preferredLayoutSize(ancestor);
+
+ if (preferredLayoutSize != null)
+ {
+ component = ancestor;
+ width = preferredLayoutSize.width;
+ height = preferredLayoutSize.height;
+ }
+ }
+ }
+ else
+ {
+ /*
+ * If the ancestor doesn't have a preferredSize forced, then
+ * we may think that it will calculate an appropriate
+ * preferredSize itself.
+ */
+ Dimension prefSize = ancestor.getPreferredSize();
+
+ if (prefSize != null)
+ {
+ component = ancestor;
+ width = prefSize.width;
+ height = prefSize.height;
+ }
+ }
+ }
+
+ /*
+ * If the component (which may be an ancestor of the Component
+ * specified as an argument to the ensureSize method at this point)
+ * has not been given a size, we will make a mistake if we try to
+ * use it for the purposes of determining how much this Frame is to
+ * be enlarged.
+ */
+ Dimension componentSize = component.getSize();
+
+ if ((componentSize.width < 1) || (componentSize.height < 1))
+ return;
+
+ Dimension frameSize = frame.getSize();
+ int newFrameWidth = frameSize.width + width - componentSize.width;
+ int newFrameHeight
+ = frameSize.height + height - componentSize.height;
+
+ // Respect the minimum size.
+ Dimension minSize = frame.getMinimumSize();
+
+ if (newFrameWidth < minSize.width)
+ newFrameWidth = minSize.width;
+ if (newFrameHeight < minSize.height)
+ newFrameHeight = minSize.height;
+
+ // Don't get bigger than the screen.
+ Rectangle screenBounds
+ = frame.getGraphicsConfiguration().getBounds();
+
+ if (newFrameWidth > screenBounds.width)
+ newFrameWidth = screenBounds.width;
+ if (newFrameHeight > screenBounds.height)
+ newFrameHeight = screenBounds.height;
+
+ /*
+ * If we're going to make too small a change, don't even bother.
+ * Besides, we don't want some weird recursive resizing.
+ * Additionally, do not reduce the Frame size.
+ */
+ boolean changeWidth = ((newFrameWidth - frameSize.width) > 1);
+ boolean changeHeight = ((newFrameHeight - frameSize.height) > 1);
+
+ if (changeWidth || changeHeight)
+ {
+ if (!changeWidth)
+ newFrameWidth = frameSize.width;
+ else if (!changeHeight)
+ newFrameHeight = frameSize.height;
+
+ /*
+ * The latest requirement with respect to the behavior upon
+ * resizing is to center the Frame.
+ */
+ int newFrameX
+ = screenBounds.x
+ + (screenBounds.width - newFrameWidth) / 2;
+ int newFrameY
+ = screenBounds.y
+ + (screenBounds.height - newFrameHeight) / 2;
+
+ // Do not let the top left go out of the screen.
+ if (newFrameX < screenBounds.x)
+ newFrameX = screenBounds.x;
+ if (newFrameY < screenBounds.y)
+ newFrameY = screenBounds.y;
+
+ frame.setBounds(
+ newFrameX, newFrameY,
+ newFrameWidth, newFrameHeight);
+
+ /*
+ * Make sure that the component which originally requested the
+ * update to the size of the frame realizes the change as soon
+ * as possible; otherwise, it may request yet another update.
+ */
+ if (frame.isDisplayable())
+ {
+ if (frame.isValid())
+ frame.doLayout();
+ else
+ frame.validate();
+ frame.repaint();
+ }
+ else
+ frame.doLayout();
+ }
+ }
+ }
+
+ /**
+ * Returns the frame of the call window.
+ *
+ * @return the frame of the call window
+ */
+ public JFrame getFrame()
+ {
+ return this;
+ }
+
+ /**
+ * Overrides getMinimumSize and checks the minimum size that
+ * is needed to display buttons and use it for minimum size if
+ * needed.
+ * @return minimum size.
+ */
+ @Override
+ public Dimension getMinimumSize()
+ {
+ Dimension minSize = super.getMinimumSize();
+
+ if(callPanel != null)
+ {
+ int minButtonWidth = callPanel.getMinimumButtonWidth();
+
+ if(minButtonWidth > minSize.getWidth())
+ minSize = new Dimension(minButtonWidth, 300);
+ }
+
+ return minSize;
+ }
+
+ /**
+ * Indicates if the given <tt>callPanel</tt> is currently visible.
+ *
+ * @param callPanel the <tt>CallPanel</tt>, for which we verify
+ * @return <tt>true</tt> if the given call container is visible in this
+ * call window, otherwise - <tt>false</tt>
+ */
+ public boolean isCallVisible(CallPanel callPanel)
+ {
+ return this.callPanel.equals(callPanel) ? isVisible() : false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isFullScreen()
+ {
+ return isFullScreen(getFrame());
+ }
+
+ /**
+ * Determines whether a specific <tt>Window</tt> is displayed in full-screen
+ * mode.
+ *
+ * @param window the <tt>Window</tt> to be checked whether it is displayed
+ * in full-screen mode
+ * @return <tt>true</tt> if the specified <tt>window</tt> is displayed in
+ * full-screen mode; otherwise, <tt>false</tt>
+ */
+ public static boolean isFullScreen(Window window)
+ {
+ GraphicsConfiguration graphicsConfiguration
+ = window.getGraphicsConfiguration();
+
+ if (graphicsConfiguration != null)
+ {
+ GraphicsDevice device = graphicsConfiguration.getDevice();
+
+ if (device != null)
+ return window.equals(device.getFullScreenWindow());
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setFullScreen(boolean fullScreen)
+ {
+ GraphicsConfiguration graphicsConfiguration
+ = getGraphicsConfiguration();
+
+ if (graphicsConfiguration != null)
+ {
+ GraphicsDevice device = graphicsConfiguration.getDevice();
+
+ if (device != null)
+ {
+ boolean thisIsFullScreen = equals(device.getFullScreenWindow());
+ boolean firePropertyChange = false;
+ boolean setVisible = isVisible();
+
+ try
+ {
+ if (fullScreen)
+ {
+ if (!thisIsFullScreen)
+ {
+ /*
+ * XXX The setUndecorated method will only work if
+ * this Window is not displayable.
+ */
+ windowDispose();
+ setUndecorated(true);
+
+ device.setFullScreenWindow(this);
+ firePropertyChange = true;
+ }
+ }
+ else if (thisIsFullScreen)
+ {
+ /*
+ * XXX The setUndecorated method will only work if this
+ * Window is not displayable.
+ */
+ windowDispose();
+ setUndecorated(false);
+
+ device.setFullScreenWindow(null);
+ firePropertyChange = true;
+ }
+
+ if (firePropertyChange)
+ {
+ if (fullScreen)
+ {
+ addWindowStateListener(windowStateListener);
+
+ /*
+ * If full-screen mode, a black background is the
+ * most common.
+ */
+ getContentPane().setBackground(Color.BLACK);
+ }
+ else
+ {
+ removeWindowStateListener(windowStateListener);
+
+ /*
+ * In windowed mode, a system-defined background is
+ * the most common.
+ */
+ getContentPane().setBackground(null);
+ }
+
+ firePropertyChange(
+ PROP_FULL_SCREEN,
+ thisIsFullScreen,
+ fullScreen);
+ }
+ }
+ finally
+ {
+ /*
+ * Regardless of whether this Window successfully entered or
+ * exited full-screen mode, make sure that remains visible.
+ */
+ if (setVisible)
+ setVisible(true);
+ }
+ }
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java b/src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java
index 095b3dd..d1c0a42 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java
@@ -130,6 +130,14 @@ public class CallHistoryButton
}
/**
+ * Does nothing because this class causes the clearing.
+ */
+ @Override
+ public void notificationCleared(UINotification notification)
+ {
+ }
+
+ /**
* Sets the history view.
*/
private void setHistoryView()
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallInfoFrame.java b/src/net/java/sip/communicator/impl/gui/main/call/CallInfoFrame.java
index ad8f6fd..872e861 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/CallInfoFrame.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/CallInfoFrame.java
@@ -34,6 +34,7 @@ import net.java.sip.communicator.util.*;
import org.ice4j.ice.*;
import org.jitsi.service.neomedia.*;
+import org.jitsi.service.neomedia.stats.*;
import org.jitsi.service.resources.*;
import org.jitsi.util.*;
@@ -469,7 +470,7 @@ public class CallInfoFrame
StringBuffer stringBuffer,
MediaType mediaType)
{
- MediaStreamStats mediaStreamStats
+ MediaStreamStats2 mediaStreamStats
= mediaStream.getMediaStreamStats();
if(mediaStreamStats == null)
@@ -624,18 +625,19 @@ public class CallInfoFrame
resources.getI18NString(
"service.gui.callinfo.BANDWITH"),
"&darr; "
- + (int) mediaStreamStats.getDownloadRateKiloBitPerSec()
+ + (int) mediaStreamStats.getReceiveStats().getBitrate()/1024
+ " Kbps "
+ " &uarr; "
- + (int) mediaStreamStats.getUploadRateKiloBitPerSec()
+ + (int) mediaStreamStats.getSendStats().getBitrate()/1024
+ " Kbps"));
stringBuffer.append(
getLineString(
resources.getI18NString("service.gui.callinfo.LOSS_RATE"),
- "&darr; " + (int) mediaStreamStats.getDownloadPercentLoss()
+ "&darr;"
+ + (int) (mediaStreamStats.getReceiveStats().getLossRate() * 100)
+ "% &uarr; "
- + (int) mediaStreamStats.getUploadPercentLoss()
+ + (int) (mediaStreamStats.getSendStats().getLossRate() * 100)
+ "%"));
stringBuffer.append(
getLineString(
@@ -668,21 +670,23 @@ public class CallInfoFrame
+ mediaStreamStats.getPacketQueueCountPackets() + "/"
+ mediaStreamStats.getPacketQueueSize() + " packets"));
- long rttMs = mediaStreamStats.getRttMs();
- if(rttMs != -1)
+ long sendRttMs = mediaStreamStats.getSendStats().getRtt();
+ long recvRttMs = mediaStreamStats.getReceiveStats().getRtt();
+ if(recvRttMs != -1 || sendRttMs != -1)
{
stringBuffer.append(
getLineString(resources.getI18NString(
"service.gui.callinfo.RTT"),
- rttMs + " ms"));
+ (recvRttMs != -1 ? "&darr; " + recvRttMs + " ms" : "") +
+ (sendRttMs != -1 ? "&uarr; " + sendRttMs + " ms" : "")));
}
stringBuffer.append(
getLineString(resources.getI18NString(
"service.gui.callinfo.JITTER"),
- "&darr; " + (int) mediaStreamStats.getDownloadJitterMs()
+ "&darr; " + (int) mediaStreamStats.getReceiveStats().getJitter()
+ " ms &uarr; "
- + (int) mediaStreamStats.getUploadJitterMs() + " ms"));
+ + (int) mediaStreamStats.getSendStats().getJitter() + " ms"));
}
/**
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallTransferHandler.java b/src/net/java/sip/communicator/impl/gui/main/call/CallTransferHandler.java
index 54f48ee..6235e1c 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/CallTransferHandler.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/CallTransferHandler.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,276 +15,276 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.gui.main.call;
-
-import java.awt.datatransfer.*;
-import java.awt.im.*;
-import java.io.*;
-import java.util.*;
-
-import javax.swing.*;
-
-import org.jitsi.service.resources.*;
-
-import net.java.sip.communicator.impl.gui.*;
-import net.java.sip.communicator.impl.gui.main.contactlist.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * A <tt>TransferHandler</tt> that handles dropping of <tt>UIContact</tt>s or
- * <tt>String</tt> addresses on a <tt>CallConference</tt>. Dropping such data on
- * the <tt>CallDialog</tt> will turn a one-to-one <tt>Call</tt> into a telephony
- * conference.
- *
- * @author Yana Stamcheva
- */
-public class CallTransferHandler
- extends ExtendedTransferHandler
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * The data flavor used when transferring <tt>UIContact</tt>s.
- */
- protected static final DataFlavor uiContactDataFlavor
- = new DataFlavor(UIContact.class, "UIContact");
-
- /**
- * The logger.
- */
- private static final Logger logger
- = Logger.getLogger(CallTransferHandler.class);
-
- /**
- * The <tt>CallConference</tt> into which the dropped callees are to be
- * invited.
- */
- private final CallConference callConference;
-
- /**
- * Initializes a new <tt>CallTransferHandler</tt> instance which is to
- * invite dropped callees to a telephony conference specified by a specific
- * <tt>Call</tt> which participates in it.
- *
- * @param call the <tt>Call</tt> which specifies the telephony conference to
- * which dropped callees are to be invited
- */
- public CallTransferHandler(Call call)
- {
- this(call.getConference());
- }
-
- /**
- * Initializes a new <tt>CallTransferHandler</tt> instance which is to
- * invite dropped callees to a specific <tt>CallConference</tt>.
- *
- * @param callConference the <tt>CallConference</tt> to which dropped
- * callees are to be invited
- */
- public CallTransferHandler(CallConference callConference)
- {
- this.callConference = callConference;
- }
-
- /**
- * Indicates whether a component will accept an import of the given
- * set of data flavors prior to actually attempting to import it. We return
- * <tt>true</tt> to indicate that the transfer with at least one of the
- * given flavors would work and <tt>false</tt> to reject the transfer.
- * <p>
- * @param comp component
- * @param flavor the data formats available
- * @return true if the data can be inserted into the component, false
- * otherwise
- * @throws NullPointerException if <code>support</code> is {@code null}
- */
- @Override
- public boolean canImport(JComponent comp, DataFlavor[] flavor)
- {
- for (DataFlavor f : flavor)
- {
- if (f.equals(DataFlavor.stringFlavor)
- || f.equals(uiContactDataFlavor))
- {
- return (comp instanceof JPanel);
- }
- }
- return false;
- }
-
- /**
- * Handles transfers to the chat panel from the clip board or a
- * DND drop operation. The <tt>Transferable</tt> parameter contains the
- * data that needs to be imported.
- * <p>
- * @param comp the component to receive the transfer;
- * @param t the data to import
- * @return true if the data was inserted into the component and false
- * otherwise
- */
- @Override
- public boolean importData(JComponent comp, Transferable t)
- {
- String callee = null;
- ProtocolProviderService provider = null;
-
- if (t.isDataFlavorSupported(uiContactDataFlavor))
- {
- Object o = null;
-
- try
- {
- o = t.getTransferData(uiContactDataFlavor);
- }
- catch (UnsupportedFlavorException e)
- {
- if (logger.isDebugEnabled())
- logger.debug("Failed to drop meta contact.", e);
- }
- catch (IOException e)
- {
- if (logger.isDebugEnabled())
- logger.debug("Failed to drop meta contact.", e);
- }
-
- if (o instanceof ContactNode)
- {
- UIContact uiContact = ((ContactNode) o).getContactDescriptor();
- Iterator<UIContactDetail> contactDetails
- = uiContact
- .getContactDetailsForOperationSet(
- OperationSetBasicTelephony.class)
- .iterator();
-
- while (contactDetails.hasNext())
- {
- UIContactDetail detail = contactDetails.next();
- ProtocolProviderService detailProvider
- = detail.getPreferredProtocolProvider(
- OperationSetBasicTelephony.class);
-
- if (detailProvider != null)
- {
- /*
- * Currently for videobridge conferences we only support
- * adding contacts via the account with the videobridge
- */
- if (callConference.isJitsiVideobridge())
- {
- for (Call call : callConference.getCalls())
- {
- if (detailProvider == call.getProtocolProvider())
- {
- callee = detail.getAddress();
- provider = detailProvider;
- break;
- }
- }
- }
- else
- {
- callee = detail.getAddress();
- provider = detailProvider;
- break;
- }
- }
- }
-
- if (callee == null)
- {
- /*
- * It turns out that the error message to be reported would
- * like to display information about the account which could
- * not add the dropped callee to the telephony conference.
- * Unfortunately, a telephony conference may have multiple
- * accounts involved. Anyway, choose the first account
- * involved in the telephony conference.
- */
- ProtocolProviderService callProvider
- = callConference.getCalls().get(0)
- .getProtocolProvider();
-
- ResourceManagementService resources
- = GuiActivator.getResources();
- AccountID accountID = callProvider.getAccountID();
-
- new ErrorDialog(null,
- resources.getI18NString("service.gui.ERROR"),
- resources.getI18NString(
- "service.gui.CALL_NOT_SUPPORTING_PARTICIPANT",
- new String[]
- {
- accountID.getService(),
- accountID.getUserID(),
- uiContact.getDisplayName()
- }))
- .showDialog();
- }
- }
- }
- else if (t.isDataFlavorSupported(DataFlavor.stringFlavor))
- {
- InputContext inputContext = comp.getInputContext();
-
- if (inputContext != null)
- inputContext.endComposition();
-
- try
- {
- BufferedReader reader
- = new BufferedReader(
- DataFlavor.stringFlavor.getReaderForText(t));
-
- try
- {
- String line;
- StringBuilder calleeBuilder = new StringBuilder();
-
- while ((line = reader.readLine()) != null)
- calleeBuilder.append(line);
-
- callee = calleeBuilder.toString();
- /*
- * The value of the local variable provider will be null
- * because we have a String only and hence we have no
- * associated ProtocolProviderService.
- * CallManager.inviteToConferenceCall will accept it.
- */
- }
- finally
- {
- reader.close();
- }
- }
- catch (UnsupportedFlavorException e)
- {
- if (logger.isDebugEnabled())
- logger.debug("Failed to drop string.", e);
- }
- catch (IOException e)
- {
- if (logger.isDebugEnabled())
- logger.debug("Failed to drop string.", e);
- }
- }
-
- if (callee == null)
- return false;
- else
- {
- Map<ProtocolProviderService, List<String>> callees
- = new HashMap<ProtocolProviderService, List<String>>();
-
- callees.put(provider, Arrays.asList(callee));
- CallManager.inviteToConferenceCall(callees, callConference);
-
- return true;
- }
- }
-}
+package net.java.sip.communicator.impl.gui.main.call;
+
+import java.awt.datatransfer.*;
+import java.awt.im.*;
+import java.io.*;
+import java.util.*;
+
+import javax.swing.*;
+
+import org.jitsi.service.resources.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.contactlist.*;
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * A <tt>TransferHandler</tt> that handles dropping of <tt>UIContact</tt>s or
+ * <tt>String</tt> addresses on a <tt>CallConference</tt>. Dropping such data on
+ * the <tt>CallDialog</tt> will turn a one-to-one <tt>Call</tt> into a telephony
+ * conference.
+ *
+ * @author Yana Stamcheva
+ */
+public class CallTransferHandler
+ extends ExtendedTransferHandler
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * The data flavor used when transferring <tt>UIContact</tt>s.
+ */
+ protected static final DataFlavor uiContactDataFlavor
+ = new DataFlavor(UIContact.class, "UIContact");
+
+ /**
+ * The logger.
+ */
+ private static final Logger logger
+ = Logger.getLogger(CallTransferHandler.class);
+
+ /**
+ * The <tt>CallConference</tt> into which the dropped callees are to be
+ * invited.
+ */
+ private final CallConference callConference;
+
+ /**
+ * Initializes a new <tt>CallTransferHandler</tt> instance which is to
+ * invite dropped callees to a telephony conference specified by a specific
+ * <tt>Call</tt> which participates in it.
+ *
+ * @param call the <tt>Call</tt> which specifies the telephony conference to
+ * which dropped callees are to be invited
+ */
+ public CallTransferHandler(Call call)
+ {
+ this(call.getConference());
+ }
+
+ /**
+ * Initializes a new <tt>CallTransferHandler</tt> instance which is to
+ * invite dropped callees to a specific <tt>CallConference</tt>.
+ *
+ * @param callConference the <tt>CallConference</tt> to which dropped
+ * callees are to be invited
+ */
+ public CallTransferHandler(CallConference callConference)
+ {
+ this.callConference = callConference;
+ }
+
+ /**
+ * Indicates whether a component will accept an import of the given
+ * set of data flavors prior to actually attempting to import it. We return
+ * <tt>true</tt> to indicate that the transfer with at least one of the
+ * given flavors would work and <tt>false</tt> to reject the transfer.
+ * <p>
+ * @param comp component
+ * @param flavor the data formats available
+ * @return true if the data can be inserted into the component, false
+ * otherwise
+ * @throws NullPointerException if <code>support</code> is {@code null}
+ */
+ @Override
+ public boolean canImport(JComponent comp, DataFlavor[] flavor)
+ {
+ for (DataFlavor f : flavor)
+ {
+ if (f.equals(DataFlavor.stringFlavor)
+ || f.equals(uiContactDataFlavor))
+ {
+ return (comp instanceof JPanel);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Handles transfers to the chat panel from the clip board or a
+ * DND drop operation. The <tt>Transferable</tt> parameter contains the
+ * data that needs to be imported.
+ * <p>
+ * @param comp the component to receive the transfer;
+ * @param t the data to import
+ * @return true if the data was inserted into the component and false
+ * otherwise
+ */
+ @Override
+ public boolean importData(JComponent comp, Transferable t)
+ {
+ String callee = null;
+ ProtocolProviderService provider = null;
+
+ if (t.isDataFlavorSupported(uiContactDataFlavor))
+ {
+ Object o = null;
+
+ try
+ {
+ o = t.getTransferData(uiContactDataFlavor);
+ }
+ catch (UnsupportedFlavorException e)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Failed to drop meta contact.", e);
+ }
+ catch (IOException e)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Failed to drop meta contact.", e);
+ }
+
+ if (o instanceof ContactNode)
+ {
+ UIContact uiContact = ((ContactNode) o).getContactDescriptor();
+ Iterator<UIContactDetail> contactDetails
+ = uiContact
+ .getContactDetailsForOperationSet(
+ OperationSetBasicTelephony.class)
+ .iterator();
+
+ while (contactDetails.hasNext())
+ {
+ UIContactDetail detail = contactDetails.next();
+ ProtocolProviderService detailProvider
+ = detail.getPreferredProtocolProvider(
+ OperationSetBasicTelephony.class);
+
+ if (detailProvider != null)
+ {
+ /*
+ * Currently for videobridge conferences we only support
+ * adding contacts via the account with the videobridge
+ */
+ if (callConference.isJitsiVideobridge())
+ {
+ for (Call call : callConference.getCalls())
+ {
+ if (detailProvider == call.getProtocolProvider())
+ {
+ callee = detail.getAddress();
+ provider = detailProvider;
+ break;
+ }
+ }
+ }
+ else
+ {
+ callee = detail.getAddress();
+ provider = detailProvider;
+ break;
+ }
+ }
+ }
+
+ if (callee == null)
+ {
+ /*
+ * It turns out that the error message to be reported would
+ * like to display information about the account which could
+ * not add the dropped callee to the telephony conference.
+ * Unfortunately, a telephony conference may have multiple
+ * accounts involved. Anyway, choose the first account
+ * involved in the telephony conference.
+ */
+ ProtocolProviderService callProvider
+ = callConference.getCalls().get(0)
+ .getProtocolProvider();
+
+ ResourceManagementService resources
+ = GuiActivator.getResources();
+ AccountID accountID = callProvider.getAccountID();
+
+ new ErrorDialog(null,
+ resources.getI18NString("service.gui.ERROR"),
+ resources.getI18NString(
+ "service.gui.CALL_NOT_SUPPORTING_PARTICIPANT",
+ new String[]
+ {
+ accountID.getService(),
+ accountID.getUserID(),
+ uiContact.getDisplayName()
+ }))
+ .showDialog();
+ }
+ }
+ }
+ else if (t.isDataFlavorSupported(DataFlavor.stringFlavor))
+ {
+ InputContext inputContext = comp.getInputContext();
+
+ if (inputContext != null)
+ inputContext.endComposition();
+
+ try
+ {
+ BufferedReader reader
+ = new BufferedReader(
+ DataFlavor.stringFlavor.getReaderForText(t));
+
+ try
+ {
+ String line;
+ StringBuilder calleeBuilder = new StringBuilder();
+
+ while ((line = reader.readLine()) != null)
+ calleeBuilder.append(line);
+
+ callee = calleeBuilder.toString();
+ /*
+ * The value of the local variable provider will be null
+ * because we have a String only and hence we have no
+ * associated ProtocolProviderService.
+ * CallManager.inviteToConferenceCall will accept it.
+ */
+ }
+ finally
+ {
+ reader.close();
+ }
+ }
+ catch (UnsupportedFlavorException e)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Failed to drop string.", e);
+ }
+ catch (IOException e)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Failed to drop string.", e);
+ }
+ }
+
+ if (callee == null)
+ return false;
+ else
+ {
+ Map<ProtocolProviderService, List<String>> callees
+ = new HashMap<ProtocolProviderService, List<String>>();
+
+ callees.put(provider, Arrays.asList(callee));
+ CallManager.inviteToConferenceCall(callees, callConference);
+
+ return true;
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/FullScreenLayout.java b/src/net/java/sip/communicator/impl/gui/main/call/FullScreenLayout.java
index 3e823ba..c56a415 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/FullScreenLayout.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/FullScreenLayout.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,176 +15,176 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.gui.main.call;
-
-import java.awt.*;
-import java.util.*;
-import java.util.List;
-
-/**
- * Implements a <tt>LayoutManager</tt> for the full-screen <tt>Call</tt>
- * display.
- *
- * @author Lyubomir Marinov
- */
-public class FullScreenLayout
- implements LayoutManager
-{
- public static final String CENTER = "CENTER";
-
- public static final String SOUTH = "SOUTH";
-
- private Component center;
-
- /**
- * The indicator which determines whether {@link #south} is to be laid out
- * on top of {@link #center} i.e. as an overlay.
- */
- private final boolean overlay;
-
- private Component south;
-
- /**
- * The vertical gap between the center and the south components.
- */
- private int yGap = 0;
-
- /**
- * Initializes a new <tt>FullScreenLayout</tt> instance.
- *
- * @param overlay <tt>true</tt> to lay out the <tt>Component</tt> at
- * {@link #SOUTH} on top of the <tt>Component</tt> at {@link #CENTER} i.e as
- * an overlay; otherwise, <tt>false</tt>
- * @oaram yGap the gap betwen the center and the south component
- */
- public FullScreenLayout(boolean overlay, int yGap)
- {
- this.overlay = overlay;
- this.yGap = yGap;
- }
-
- /**
- * Adds the given component to this layout.
- *
- * @param name the name of the constraint (CENTER or SOUTH)
- * @param comp the component to add to this layout
- */
- public void addLayoutComponent(String name, Component comp)
- {
- if (CENTER.equals(name))
- center = comp;
- else if (SOUTH.equals(name))
- south = comp;
- }
-
- /**
- * Gets a <tt>List</tt> of the <tt>Component</tt>s to be laid out by this
- * <tt>LayoutManager</tt> i.e. the non-<tt>null</tt> of {@link #center}
- * and {@link #south}.
- *
- * @return a <tt>List</tt> of the <tt>Component</tt>s to be laid out by this
- * <tt>LayoutManager</tt>
- */
- private List<Component> getLayoutComponents()
- {
- List<Component> layoutComponents = new ArrayList<Component>(2);
-
- if (center != null)
- layoutComponents.add(center);
- if (south != null)
- layoutComponents.add(south);
- return layoutComponents;
- }
-
- /**
- * Lays out the components added in the given parent container
- *
- * @param parent the parent container to lay out
- */
- public void layoutContainer(Container parent)
- {
- int southWidth;
- int southHeight;
-
- if (south == null)
- {
- southWidth = southHeight = 0;
- }
- else
- {
- Dimension southSize = south.getPreferredSize();
-
- southWidth = southSize.width;
- southHeight = southSize.height;
- }
-
- Dimension parentSize = parent.getSize();
-
- if (center != null)
- {
- /*
- * If the Component at the SOUTH is not to be shown as an overlay,
- * make room for it bellow the Component at the CENTER.
- */
- int yOffset = overlay ? 0 : southHeight + yGap;
-
- center.setBounds(
- 0,
- 0,
- parentSize.width,
- parentSize.height - yOffset);
- }
- if (south != null)
- {
- south.setBounds(
- (parentSize.width - southWidth) / 2,
- parentSize.height - southHeight,
- southWidth,
- southHeight);
- }
- }
-
- public Dimension minimumLayoutSize(Container parent)
- {
- List<Component> components = getLayoutComponents();
- Dimension size = new Dimension(0, 0);
-
- for (Component component : components)
- {
- Dimension componentSize = component.getMinimumSize();
-
- size.width = Math.max(size.width, componentSize.width);
- if (overlay)
- size.height = Math.max(size.height, componentSize.height);
- else
- size.height += componentSize.height;
- }
- return size;
- }
-
- public Dimension preferredLayoutSize(Container parent)
- {
- List<Component> components = getLayoutComponents();
- Dimension size = new Dimension(0, 0);
-
- for (Component component : components)
- {
- Dimension componentSize = component.getPreferredSize();
-
- size.width = Math.max(size.width, componentSize.width);
- if (overlay)
- size.height = Math.max(size.height, componentSize.height);
- else
- size.height += componentSize.height;
- }
- return size;
- }
-
- public void removeLayoutComponent(Component comp)
- {
- if (comp.equals(center))
- center = null;
- else if (comp.equals(south))
- south = null;
- }
-}
+package net.java.sip.communicator.impl.gui.main.call;
+
+import java.awt.*;
+import java.util.*;
+import java.util.List;
+
+/**
+ * Implements a <tt>LayoutManager</tt> for the full-screen <tt>Call</tt>
+ * display.
+ *
+ * @author Lyubomir Marinov
+ */
+public class FullScreenLayout
+ implements LayoutManager
+{
+ public static final String CENTER = "CENTER";
+
+ public static final String SOUTH = "SOUTH";
+
+ private Component center;
+
+ /**
+ * The indicator which determines whether {@link #south} is to be laid out
+ * on top of {@link #center} i.e. as an overlay.
+ */
+ private final boolean overlay;
+
+ private Component south;
+
+ /**
+ * The vertical gap between the center and the south components.
+ */
+ private int yGap = 0;
+
+ /**
+ * Initializes a new <tt>FullScreenLayout</tt> instance.
+ *
+ * @param overlay <tt>true</tt> to lay out the <tt>Component</tt> at
+ * {@link #SOUTH} on top of the <tt>Component</tt> at {@link #CENTER} i.e as
+ * an overlay; otherwise, <tt>false</tt>
+ * @oaram yGap the gap betwen the center and the south component
+ */
+ public FullScreenLayout(boolean overlay, int yGap)
+ {
+ this.overlay = overlay;
+ this.yGap = yGap;
+ }
+
+ /**
+ * Adds the given component to this layout.
+ *
+ * @param name the name of the constraint (CENTER or SOUTH)
+ * @param comp the component to add to this layout
+ */
+ public void addLayoutComponent(String name, Component comp)
+ {
+ if (CENTER.equals(name))
+ center = comp;
+ else if (SOUTH.equals(name))
+ south = comp;
+ }
+
+ /**
+ * Gets a <tt>List</tt> of the <tt>Component</tt>s to be laid out by this
+ * <tt>LayoutManager</tt> i.e. the non-<tt>null</tt> of {@link #center}
+ * and {@link #south}.
+ *
+ * @return a <tt>List</tt> of the <tt>Component</tt>s to be laid out by this
+ * <tt>LayoutManager</tt>
+ */
+ private List<Component> getLayoutComponents()
+ {
+ List<Component> layoutComponents = new ArrayList<Component>(2);
+
+ if (center != null)
+ layoutComponents.add(center);
+ if (south != null)
+ layoutComponents.add(south);
+ return layoutComponents;
+ }
+
+ /**
+ * Lays out the components added in the given parent container
+ *
+ * @param parent the parent container to lay out
+ */
+ public void layoutContainer(Container parent)
+ {
+ int southWidth;
+ int southHeight;
+
+ if (south == null)
+ {
+ southWidth = southHeight = 0;
+ }
+ else
+ {
+ Dimension southSize = south.getPreferredSize();
+
+ southWidth = southSize.width;
+ southHeight = southSize.height;
+ }
+
+ Dimension parentSize = parent.getSize();
+
+ if (center != null)
+ {
+ /*
+ * If the Component at the SOUTH is not to be shown as an overlay,
+ * make room for it bellow the Component at the CENTER.
+ */
+ int yOffset = overlay ? 0 : southHeight + yGap;
+
+ center.setBounds(
+ 0,
+ 0,
+ parentSize.width,
+ parentSize.height - yOffset);
+ }
+ if (south != null)
+ {
+ south.setBounds(
+ (parentSize.width - southWidth) / 2,
+ parentSize.height - southHeight,
+ southWidth,
+ southHeight);
+ }
+ }
+
+ public Dimension minimumLayoutSize(Container parent)
+ {
+ List<Component> components = getLayoutComponents();
+ Dimension size = new Dimension(0, 0);
+
+ for (Component component : components)
+ {
+ Dimension componentSize = component.getMinimumSize();
+
+ size.width = Math.max(size.width, componentSize.width);
+ if (overlay)
+ size.height = Math.max(size.height, componentSize.height);
+ else
+ size.height += componentSize.height;
+ }
+ return size;
+ }
+
+ public Dimension preferredLayoutSize(Container parent)
+ {
+ List<Component> components = getLayoutComponents();
+ Dimension size = new Dimension(0, 0);
+
+ for (Component component : components)
+ {
+ Dimension componentSize = component.getPreferredSize();
+
+ size.width = Math.max(size.width, componentSize.width);
+ if (overlay)
+ size.height = Math.max(size.height, componentSize.height);
+ else
+ size.height += componentSize.height;
+ }
+ return size;
+ }
+
+ public void removeLayoutComponent(Component comp)
+ {
+ if (comp.equals(center))
+ center = null;
+ else if (comp.equals(south))
+ south = null;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/PreCallDialog.java b/src/net/java/sip/communicator/impl/gui/main/call/PreCallDialog.java
index 76c4139..0d6206a 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/PreCallDialog.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/PreCallDialog.java
@@ -256,8 +256,12 @@ public abstract class PreCallDialog
receivedCallWindow.setAlwaysOnTop(true);
+ // Register the JFrame so the dialog window is able to get dragged
+ // across the screen
+ ComponentMover.registerComponent(receivedCallWindow);
+
// prevents dialog window to get unwanted key events and when going
- // on top on linux, it steals focus and if we are accidently
+ // on top on linux, it steals focus and if we are accidentally
// writing something and pressing enter a call get answered
receivedCallWindow.setFocusableWindowState(false);
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/SecurityPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/SecurityPanel.java
index 2e2ed5b..b49e0a3 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/SecurityPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/SecurityPanel.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,117 +15,117 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.gui.main.call;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.skin.*;
-
-import org.jitsi.service.neomedia.*;
-
-/**
- * Base class for security panels that show encryption specific UI controls.
- *
- * @author Ingo Bauersachs
- */
-public abstract class SecurityPanel<T extends SrtpControl>
- extends FadeInBalloonPanel
- implements Skinnable
-{
- /**
- * The currently used security control.
- */
- protected T securityControl;
-
- /**
- * Create security panel using the security control.
- * @param securityControl
- */
- public SecurityPanel(T securityControl)
- {
- this.securityControl = securityControl;
- }
-
- /**
- * The currently used security control.
- * @return
- */
- public T getSecurityControl()
- {
- return securityControl;
- }
-
- /**
- * The currently used security control.
- * @return
- */
- public void setSecurityControl(T securityControl)
- {
- this.securityControl = securityControl;
- }
-
- /**
- * Creates the security panel depending on the concrete implementation of
- * the passed security controller.
- *
- * @param srtpControl the security controller that provides the information
- * to be shown on the UI
- * @return An instance of a {@link SecurityPanel} for the security
- * controller or an {@link TransparentPanel} if the controller is
- * unknown or does not have any controls to show.
- */
- public static SecurityPanel<?> create(
- SwingCallPeerRenderer peerRenderer,
- CallPeer callPeer,
- SrtpControl srtpControl)
- {
- if(srtpControl instanceof ZrtpControl)
- {
- return
- new ZrtpSecurityPanel(
- peerRenderer,
- callPeer,
- (ZrtpControl) srtpControl);
- }
- else
- {
- return
- new SecurityPanel<SrtpControl>(srtpControl)
- {
- public void loadSkin() {}
-
- @Override
- public void securityOn(CallPeerSecurityOnEvent evt) {}
-
- @Override
- public void securityOff(CallPeerSecurityOffEvent evt) {}
-
- @Override
- public void securityTimeout(
- CallPeerSecurityTimeoutEvent evt) {}
- };
- }
- }
-
- /**
- * Indicates that the security is turned on.
- *
- * @param evt details about the event that caused this message.
- */
- public abstract void securityOn(CallPeerSecurityOnEvent evt);
-
- /**
- * Indicates that the security is turned off.
- *
- * @param evt details about the event that caused this message.
- */
- public abstract void securityOff(CallPeerSecurityOffEvent evt);
-
- /**
- * Indicates that the security is timeouted, is not supported by the
- * other end.
- * @param evt Details about the event that caused this message.
- */
- public abstract void securityTimeout(CallPeerSecurityTimeoutEvent evt);
-}
+package net.java.sip.communicator.impl.gui.main.call;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.util.skin.*;
+
+import org.jitsi.service.neomedia.*;
+
+/**
+ * Base class for security panels that show encryption specific UI controls.
+ *
+ * @author Ingo Bauersachs
+ */
+public abstract class SecurityPanel<T extends SrtpControl>
+ extends FadeInBalloonPanel
+ implements Skinnable
+{
+ /**
+ * The currently used security control.
+ */
+ protected T securityControl;
+
+ /**
+ * Create security panel using the security control.
+ * @param securityControl
+ */
+ public SecurityPanel(T securityControl)
+ {
+ this.securityControl = securityControl;
+ }
+
+ /**
+ * The currently used security control.
+ * @return
+ */
+ public T getSecurityControl()
+ {
+ return securityControl;
+ }
+
+ /**
+ * The currently used security control.
+ * @return
+ */
+ public void setSecurityControl(T securityControl)
+ {
+ this.securityControl = securityControl;
+ }
+
+ /**
+ * Creates the security panel depending on the concrete implementation of
+ * the passed security controller.
+ *
+ * @param srtpControl the security controller that provides the information
+ * to be shown on the UI
+ * @return An instance of a {@link SecurityPanel} for the security
+ * controller or an {@link TransparentPanel} if the controller is
+ * unknown or does not have any controls to show.
+ */
+ public static SecurityPanel<?> create(
+ SwingCallPeerRenderer peerRenderer,
+ CallPeer callPeer,
+ SrtpControl srtpControl)
+ {
+ if(srtpControl instanceof ZrtpControl)
+ {
+ return
+ new ZrtpSecurityPanel(
+ peerRenderer,
+ callPeer,
+ (ZrtpControl) srtpControl);
+ }
+ else
+ {
+ return
+ new SecurityPanel<SrtpControl>(srtpControl)
+ {
+ public void loadSkin() {}
+
+ @Override
+ public void securityOn(CallPeerSecurityOnEvent evt) {}
+
+ @Override
+ public void securityOff(CallPeerSecurityOffEvent evt) {}
+
+ @Override
+ public void securityTimeout(
+ CallPeerSecurityTimeoutEvent evt) {}
+ };
+ }
+ }
+
+ /**
+ * Indicates that the security is turned on.
+ *
+ * @param evt details about the event that caused this message.
+ */
+ public abstract void securityOn(CallPeerSecurityOnEvent evt);
+
+ /**
+ * Indicates that the security is turned off.
+ *
+ * @param evt details about the event that caused this message.
+ */
+ public abstract void securityOff(CallPeerSecurityOffEvent evt);
+
+ /**
+ * Indicates that the security is timeouted, is not supported by the
+ * other end.
+ * @param evt Details about the event that caused this message.
+ */
+ public abstract void securityTimeout(CallPeerSecurityTimeoutEvent evt);
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/TransferCallDialog.java b/src/net/java/sip/communicator/impl/gui/main/call/TransferCallDialog.java
index f2f2bd2..982738b 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/TransferCallDialog.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/TransferCallDialog.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,140 +15,140 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.gui.main.call;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.util.*;
-
-import net.java.sip.communicator.impl.gui.*;
-import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
-import net.java.sip.communicator.impl.gui.utils.*;
-import net.java.sip.communicator.service.contactsource.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * Represents a <tt>Dialog</tt> which allows specifying the target contact
- * address of a transfer-call operation.
- *
- * @author Yana Stamcheva
- */
-public class TransferCallDialog
- extends OneChoiceInviteDialog
-{
- /**
- * The peer to transfer.
- */
- private final CallPeer transferPeer;
-
- /**
- * Creates a <tt>TransferCallDialog</tt> by specifying the peer to transfer
- * @param peer the peer to transfer
- */
- public TransferCallDialog(final CallPeer peer)
- {
- super(GuiActivator.getResources()
- .getI18NString("service.gui.TRANSFER_CALL_TITLE"));
-
- this.transferPeer = peer;
-
- this.initContactListData(peer.getProtocolProvider());
-
- this.setInfoText(GuiActivator.getResources()
- .getI18NString("service.gui.TRANSFER_CALL_MSG"));
- this.setOkButtonText(GuiActivator.getResources()
- .getI18NString("service.gui.TRANSFER"));
-
- this.setMinimumSize(new Dimension(300, 300));
-
- addOkButtonListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- UIContact uiContact = getSelectedContact();
-
- if (uiContact != null)
- {
- transferToContact(uiContact);
- }
-
- setVisible(false);
- dispose();
- }
- });
- addCancelButtonListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- setVisible(false);
- dispose();
- }
- });
- }
-
- /**
- * Initializes contact list sources.
- */
- private void initContactSources()
- {
- DemuxContactSourceService demuxCSService
- = GuiActivator.getDemuxContactSourceService();
-
- // If the DemuxContactSourceService isn't registered we use the default
- // contact source set.
- if (demuxCSService == null)
- return;
-
- Iterator<UIContactSource> sourcesIter
- = new ArrayList<UIContactSource>(
- contactList.getContactSources()).iterator();
-
- contactList.removeAllContactSources();
-
- while (sourcesIter.hasNext())
- {
- ContactSourceService contactSource
- = sourcesIter.next().getContactSourceService();
-
- contactList.addContactSource(
- demuxCSService.createDemuxContactSource(contactSource));
- }
- }
-
- /**
- * Initializes the left contact list with the contacts that could be added
- * to the current chat session.
- *
- * @param protocolProvider the protocol provider from which to initialize
- * the contact list data
- */
- private void initContactListData(ProtocolProviderService protocolProvider)
- {
- initContactSources();
-
- contactList.addContactSource(
- new ProtocolContactSourceServiceImpl(
- protocolProvider, OperationSetBasicTelephony.class));
- contactList.addContactSource(
- new StringContactSourceServiceImpl(
- protocolProvider, OperationSetBasicTelephony.class));
-
- contactList.applyDefaultFilter();
- }
-
- /**
- * Transfer the transfer peer to the given <tt>UIContact</tt>.
- *
- * @param uiContact the contact to transfer to
- */
- private void transferToContact(UIContact uiContact)
- {
- UIContactDetail contactDetail = uiContact
- .getDefaultContactDetail(
- OperationSetBasicTelephony.class);
-
- CallManager.transferCall( transferPeer,
- contactDetail.getAddress());
- }
-}
+package net.java.sip.communicator.impl.gui.main.call;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
+import net.java.sip.communicator.impl.gui.utils.*;
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * Represents a <tt>Dialog</tt> which allows specifying the target contact
+ * address of a transfer-call operation.
+ *
+ * @author Yana Stamcheva
+ */
+public class TransferCallDialog
+ extends OneChoiceInviteDialog
+{
+ /**
+ * The peer to transfer.
+ */
+ private final CallPeer transferPeer;
+
+ /**
+ * Creates a <tt>TransferCallDialog</tt> by specifying the peer to transfer
+ * @param peer the peer to transfer
+ */
+ public TransferCallDialog(final CallPeer peer)
+ {
+ super(GuiActivator.getResources()
+ .getI18NString("service.gui.TRANSFER_CALL_TITLE"));
+
+ this.transferPeer = peer;
+
+ this.initContactListData(peer.getProtocolProvider());
+
+ this.setInfoText(GuiActivator.getResources()
+ .getI18NString("service.gui.TRANSFER_CALL_MSG"));
+ this.setOkButtonText(GuiActivator.getResources()
+ .getI18NString("service.gui.TRANSFER"));
+
+ this.setMinimumSize(new Dimension(300, 300));
+
+ addOkButtonListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ UIContact uiContact = getSelectedContact();
+
+ if (uiContact != null)
+ {
+ transferToContact(uiContact);
+ }
+
+ setVisible(false);
+ dispose();
+ }
+ });
+ addCancelButtonListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ setVisible(false);
+ dispose();
+ }
+ });
+ }
+
+ /**
+ * Initializes contact list sources.
+ */
+ private void initContactSources()
+ {
+ DemuxContactSourceService demuxCSService
+ = GuiActivator.getDemuxContactSourceService();
+
+ // If the DemuxContactSourceService isn't registered we use the default
+ // contact source set.
+ if (demuxCSService == null)
+ return;
+
+ Iterator<UIContactSource> sourcesIter
+ = new ArrayList<UIContactSource>(
+ contactList.getContactSources()).iterator();
+
+ contactList.removeAllContactSources();
+
+ while (sourcesIter.hasNext())
+ {
+ ContactSourceService contactSource
+ = sourcesIter.next().getContactSourceService();
+
+ contactList.addContactSource(
+ demuxCSService.createDemuxContactSource(contactSource));
+ }
+ }
+
+ /**
+ * Initializes the left contact list with the contacts that could be added
+ * to the current chat session.
+ *
+ * @param protocolProvider the protocol provider from which to initialize
+ * the contact list data
+ */
+ private void initContactListData(ProtocolProviderService protocolProvider)
+ {
+ initContactSources();
+
+ contactList.addContactSource(
+ new ProtocolContactSourceServiceImpl(
+ protocolProvider, OperationSetBasicTelephony.class));
+ contactList.addContactSource(
+ new StringContactSourceServiceImpl(
+ protocolProvider, OperationSetBasicTelephony.class));
+
+ contactList.applyDefaultFilter();
+ }
+
+ /**
+ * Transfer the transfer peer to the given <tt>UIContact</tt>.
+ *
+ * @param uiContact the contact to transfer to
+ */
+ private void transferToContact(UIContact uiContact)
+ {
+ UIContactDetail contactDetail = uiContact
+ .getDefaultContactDetail(
+ OperationSetBasicTelephony.class);
+
+ CallManager.transferCall( transferPeer,
+ contactDetail.getAddress());
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java
index 80eedc6..bb32858 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,570 +15,570 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.gui.main.call.conference;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.util.*;
-import java.util.List;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.impl.gui.*;
-import net.java.sip.communicator.impl.gui.main.call.*;
-import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
-import net.java.sip.communicator.impl.gui.utils.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.service.contactsource.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * The invite dialog is the one shown when the user clicks on the conference
- * button in the chat toolbar.
- *
- * @author Yana Stamcheva
- * @author Lyubomir Marinov
- */
-public class ConferenceInviteDialog
- extends InviteDialog
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * The account selector box.
- */
- private final JComboBox accountSelectorBox = new JComboBox();
-
- /**
- * The last selected account.
- */
- private Object lastSelectedAccount;
-
- /**
- * The telephony conference into which this instance is to invite
- * participants.
- */
- private final CallConference conference;
-
- /**
- * The current provider contact source.
- */
- private ContactSourceService currentProviderContactSource;
-
- /**
- * The current string contact source.
- */
- private ContactSourceService currentStringContactSource;
-
- /**
- * The previously selected protocol provider, with which this dialog has
- * been instantiated.
- */
- private ProtocolProviderService preselectedProtocolProvider;
-
- /**
- * Indicates whether this conference invite dialog is associated with a
- * Jitsi Videobridge invite.
- */
- private final boolean isJitsiVideobridge;
-
- /**
- * Initializes a new <tt>ConferenceInviteDialog</tt> instance which is to
- * invite contacts/participants in a specific telephony conference.
- *
- * @param conference the telephony conference in which the new instance is
- * to invite contacts/participants
- */
- public ConferenceInviteDialog(
- CallConference conference,
- ProtocolProviderService preselectedProvider,
- List<ProtocolProviderService> protocolProviders,
- final boolean isJitsiVideobridge)
- {
- // Set the correct dialog title depending if we're going to create a
- // video bridge conference call
- super((isJitsiVideobridge
- ? GuiActivator.getResources()
- .getI18NString("service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE")
- : GuiActivator.getResources()
- .getI18NString("service.gui.INVITE_CONTACT_TO_CALL")),
- false);
-
- this.conference = conference;
- this.preselectedProtocolProvider = preselectedProvider;
- this.isJitsiVideobridge = isJitsiVideobridge;
-
- if (preselectedProtocolProvider == null)
- initAccountSelectorPanel(protocolProviders);
-
- // init the list, as we check whether features are supported
- // it may take some time if we have too much contacts
- SwingUtilities.invokeLater(new Runnable()
- {
- public void run()
- {
- initContactSources();
-
- // Initialize the list of contacts to select from.
- if (preselectedProtocolProvider != null)
- initContactListData(preselectedProtocolProvider);
- else
- initContactListData(
- (ProtocolProviderService) accountSelectorBox
- .getSelectedItem());
- }
- });
-
- this.addInviteButtonListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- Collection<UIContact> selectedContacts
- = destContactList.getContacts(null);
-
- if (selectedContacts != null && selectedContacts.size() > 0)
- {
- if (preselectedProtocolProvider == null)
- preselectedProtocolProvider
- = (ProtocolProviderService) accountSelectorBox
- .getSelectedItem();
-
- if (isJitsiVideobridge)
- inviteJitsiVideobridgeContacts( preselectedProtocolProvider,
- selectedContacts);
- else
- inviteContacts(selectedContacts);
-
- // Store the last used account in order to pre-select it
- // next time.
- ConfigurationUtils.setLastCallConferenceProvider(
- preselectedProtocolProvider);
-
- dispose();
- }
- else
- {
- // TODO: The underlying invite dialog should show a message
- // to the user that she should select at least two contacts
- // in order to create a conference.
- }
- }
- });
-
- this.addCancelButtonListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- dispose();
- }
- });
- }
-
- /**
- * Constructs the <tt>ConferenceInviteDialog</tt>.
- */
- public ConferenceInviteDialog()
- {
- this(null, null, null, false);
- }
-
- /**
- * Creates an instance of <tt>ConferenceInviteDialog</tt> by specifying an
- * already created conference. To use when inviting contacts to an existing
- * conference is needed.
- *
- * @param conference the existing <tt>CallConference</tt>
- */
- public ConferenceInviteDialog(CallConference conference)
- {
- this(conference, null, null, false);
- }
-
- /**
- * Creates an instance of <tt>ConferenceInviteDialog</tt> by specifying an
- * already created conference. To use when inviting contacts to an existing
- * conference is needed.
- *
- * @param conference the existing <tt>CallConference</tt>
- */
- public ConferenceInviteDialog(
- CallConference conference,
- ProtocolProviderService preselectedProtocolProvider,
- boolean isJitsiVideobridge)
- {
- this(conference, preselectedProtocolProvider, null, isJitsiVideobridge);
- }
-
- /**
- * Creates an instance of <tt>ConferenceInviteDialog</tt> by specifying a
- * preselected protocol provider to be used and if this is an invite for
- * a video bridge conference.
- *
- * @param protocolProviders the protocol providers list
- * @param isJitsiVideobridge <tt>true</tt> if this dialog should create a
- * conference through a Jitsi Videobridge; otherwise, <tt>false</tt>
- */
- public ConferenceInviteDialog(
- List<ProtocolProviderService> protocolProviders,
- boolean isJitsiVideobridge)
- {
- this(null, null, protocolProviders, isJitsiVideobridge);
- }
-
- /**
- * Creates an instance of <tt>ConferenceInviteDialog</tt> by specifying a
- * preselected protocol provider to be used and if this is an invite for
- * a video bridge conference.
- *
- * @param selectedConfProvider the preselected protocol provider
- * @param isJitsiVideobridge <tt>true</tt> if this dialog should create a
- * conference through a Jitsi Videobridge; otherwise, <tt>false</tt>
- */
- public ConferenceInviteDialog(
- ProtocolProviderService selectedConfProvider,
- boolean isJitsiVideobridge)
- {
- this(null, selectedConfProvider, null, isJitsiVideobridge);
- }
-
- /**
- * Initializes the account selector panel.
- *
- * @param protocolProviders the list of protocol providers we'd like to
- * show in the account selector box
- */
- private void initAccountSelectorPanel(
- List<ProtocolProviderService> protocolProviders)
- {
- JLabel accountSelectorLabel = new JLabel(
- GuiActivator.getResources().getI18NString("service.gui.CALL_VIA"));
-
- TransparentPanel accountSelectorPanel
- = new TransparentPanel(new BorderLayout());
-
- accountSelectorPanel.setBorder(
- BorderFactory.createEmptyBorder(5, 5, 5, 5));
- accountSelectorPanel.add(accountSelectorLabel, BorderLayout.WEST);
- accountSelectorPanel.add(accountSelectorBox, BorderLayout.CENTER);
-
- // Initialize the account selector box.
- if (protocolProviders != null && protocolProviders.size() > 0)
- this.initAccountListData(protocolProviders);
- else
- this.initAccountListData();
-
- this.accountSelectorBox.setRenderer(new DefaultListCellRenderer()
- {
- private static final long serialVersionUID = 0L;
-
- @Override
- public Component getListCellRendererComponent(JList list,
- Object value, int index, boolean isSelected,
- boolean cellHasFocus)
- {
- ProtocolProviderService protocolProvider
- = (ProtocolProviderService) value;
-
- if (protocolProvider != null)
- {
- this.setText(
- protocolProvider.getAccountID().getDisplayName());
- this.setIcon(
- ImageLoader.getAccountStatusImage(protocolProvider));
- }
-
- return this;
- }
- });
-
- this.accountSelectorBox.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- Object accountSelectorBoxSelectedItem
- = accountSelectorBox.getSelectedItem();
-
- if (lastSelectedAccount == null
- || !lastSelectedAccount
- .equals(accountSelectorBoxSelectedItem))
- {
- lastSelectedAccount = accountSelectorBoxSelectedItem;
-
- initContactListData(
- (ProtocolProviderService) accountSelectorBox
- .getSelectedItem());
-
- if (isJitsiVideobridge)
- destContactList.removeAll();
- }
- }
- });
-
- this.getContentPane().add(accountSelectorPanel, BorderLayout.NORTH);
- }
-
- /**
- * Initializes the account selector box with the given list of
- * <tt>ProtocolProviderService</tt>-s.
- *
- * @param protocolProviders the list of <tt>ProtocolProviderService</tt>-s
- * we'd like to show in the account selector box
- */
- private void initAccountListData(
- List<ProtocolProviderService> protocolProviders)
- {
- Iterator<ProtocolProviderService> providersIter
- = protocolProviders.iterator();
-
- while (providersIter.hasNext())
- {
- ProtocolProviderService protocolProvider
- = providersIter.next();
-
- accountSelectorBox.addItem(protocolProvider);
- }
-
- if (accountSelectorBox.getItemCount() > 0)
- accountSelectorBox.setSelectedIndex(0);
- }
-
- /**
- * Initializes the account list.
- */
- private void initAccountListData()
- {
- Iterator<ProtocolProviderService> protocolProviders
- = GuiActivator.getUIService().getMainFrame().getProtocolProviders();
-
- while(protocolProviders.hasNext())
- {
- ProtocolProviderService protocolProvider
- = protocolProviders.next();
- OperationSet opSet
- = protocolProvider.getOperationSet(
- OperationSetTelephonyConferencing.class);
-
- if ((opSet != null) && protocolProvider.isRegistered())
- accountSelectorBox.addItem(protocolProvider);
- }
-
- // Try to select the last used account if available.
- ProtocolProviderService pps
- = ConfigurationUtils.getLastCallConferenceProvider();
-
- if (pps == null && conference != null)
- {
- /*
- * Pick up the first account from the ones participating in the
- * associated telephony conference which supports
- * OperationSetTelephonyConferencing.
- */
- for (Call call : conference.getCalls())
- {
- ProtocolProviderService callPps = call.getProtocolProvider();
-
- if (callPps.getOperationSet(
- OperationSetTelephonyConferencing.class)
- != null)
- {
- pps = callPps;
- break;
- }
- }
- }
-
- if (pps != null)
- accountSelectorBox.setSelectedItem(pps);
- else if (accountSelectorBox.getItemCount() > 0)
- accountSelectorBox.setSelectedIndex(0);
- }
-
- /**
- * Initializes contact list sources.
- */
- private void initContactSources()
- {
- DemuxContactSourceService demuxCSService
- = GuiActivator.getDemuxContactSourceService();
-
- // If the DemuxContactSourceService isn't registered we use the default
- // contact source set.
- if (demuxCSService == null)
- return;
-
- Iterator<UIContactSource> sourcesIter
- = new ArrayList<UIContactSource>(
- srcContactList.getContactSources()).iterator();
-
- srcContactList.removeAllContactSources();
-
- while (sourcesIter.hasNext())
- {
- ContactSourceService contactSource
- = sourcesIter.next().getContactSourceService();
-
- srcContactList.addContactSource(
- demuxCSService.createDemuxContactSource(contactSource));
- }
- }
-
- /**
- * Initializes the left contact list with the contacts that could be added
- * to the current chat session.
- * @param protocolProvider the protocol provider from which to initialize
- * the contact list data
- */
- private void initContactListData(ProtocolProviderService protocolProvider)
- {
- this.setCurrentProvider(protocolProvider);
-
- Iterator<UIContactSource> sourcesIter
- = new ArrayList<UIContactSource>(
- srcContactList.getContactSources()).iterator();
-
- while (sourcesIter.hasNext())
- {
- ContactSourceService contactSource
- = sourcesIter.next().getContactSourceService();
-
- if (contactSource instanceof ProtocolAwareContactSourceService)
- {
- ((ProtocolAwareContactSourceService) contactSource)
- .setPreferredProtocolProvider(
- OperationSetBasicTelephony.class, protocolProvider);
- }
- }
-
- srcContactList.removeContactSource(currentProviderContactSource);
- srcContactList.removeContactSource(currentStringContactSource);
-
- currentProviderContactSource
- = new ProtocolContactSourceServiceImpl(
- protocolProvider,
- OperationSetBasicTelephony.class);
- currentStringContactSource
- = new StringContactSourceServiceImpl(
- protocolProvider,
- OperationSetBasicTelephony.class);
-
- srcContactList.addContactSource(currentProviderContactSource);
- srcContactList.addContactSource(currentStringContactSource);
-
- srcContactList.applyDefaultFilter();
- }
-
- /**
- * Invites the contacts to the chat conference.
- *
- * @param contacts the list of contacts to invite
- */
- private void inviteContacts(Collection<UIContact> contacts)
- {
- ProtocolProviderService selectedProvider;
- Map<ProtocolProviderService, List<String>> selectedProviderCallees
- = new HashMap<ProtocolProviderService, List<String>>();
- List<String> callees;
-
- Iterator<UIContact> contactsIter = contacts.iterator();
-
- while (contactsIter.hasNext())
- {
- UIContact uiContact = contactsIter.next();
-
- Iterator<UIContactDetail> contactDetailsIter = uiContact
- .getContactDetailsForOperationSet(
- OperationSetBasicTelephony.class).iterator();
-
- // We invite the first protocol contact that corresponds to the
- // invite provider.
- if (contactDetailsIter.hasNext())
- {
- UIContactDetail inviteDetail = contactDetailsIter.next();
- selectedProvider = inviteDetail
- .getPreferredProtocolProvider(
- OperationSetBasicTelephony.class);
-
- if (selectedProvider == null)
- {
- selectedProvider
- = (ProtocolProviderService)
- accountSelectorBox.getSelectedItem();
- }
-
- if(selectedProvider != null
- && selectedProviderCallees.get(selectedProvider) != null)
- {
- callees = selectedProviderCallees.get(selectedProvider);
- }
- else
- {
- callees = new ArrayList<String>();
- }
-
- callees.add(inviteDetail.getAddress());
- selectedProviderCallees.put(selectedProvider, callees);
- }
- }
-
- if(conference != null)
- {
- CallManager.inviteToConferenceCall(
- selectedProviderCallees,
- conference);
- }
- else
- {
- CallManager.createConferenceCall(selectedProviderCallees);
- }
- }
-
- /**
- * Invites the contacts to the chat conference.
- *
- * @param contacts the list of contacts to invite
- */
- private void inviteJitsiVideobridgeContacts(
- ProtocolProviderService preselectedProvider,
- Collection<UIContact> contacts)
- {
- List<String> callees = new ArrayList<String>();
-
- Iterator<UIContact> contactsIter = contacts.iterator();
-
- while (contactsIter.hasNext())
- {
- UIContact uiContact = contactsIter.next();
-
- Iterator<UIContactDetail> contactDetailsIter = uiContact
- .getContactDetailsForOperationSet(
- OperationSetBasicTelephony.class).iterator();
-
- // We invite the first protocol contact that corresponds to the
- // invite provider.
- if (contactDetailsIter.hasNext())
- {
- UIContactDetail inviteDetail = contactDetailsIter.next();
-
- callees.add(inviteDetail.getAddress());
- }
- }
-
- if(conference != null)
- {
- CallManager.inviteToJitsiVideobridgeConfCall(
- callees.toArray(new String[callees.size()]),
- conference.getCalls().get(0));
- }
- else
- {
- CallManager.createJitsiVideobridgeConfCall(
- preselectedProvider,
- callees.toArray(new String[callees.size()]));
- }
- }
-}
+package net.java.sip.communicator.impl.gui.main.call.conference;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.util.List;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.call.*;
+import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
+import net.java.sip.communicator.impl.gui.utils.*;
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * The invite dialog is the one shown when the user clicks on the conference
+ * button in the chat toolbar.
+ *
+ * @author Yana Stamcheva
+ * @author Lyubomir Marinov
+ */
+public class ConferenceInviteDialog
+ extends InviteDialog
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * The account selector box.
+ */
+ private final JComboBox accountSelectorBox = new JComboBox();
+
+ /**
+ * The last selected account.
+ */
+ private Object lastSelectedAccount;
+
+ /**
+ * The telephony conference into which this instance is to invite
+ * participants.
+ */
+ private final CallConference conference;
+
+ /**
+ * The current provider contact source.
+ */
+ private ContactSourceService currentProviderContactSource;
+
+ /**
+ * The current string contact source.
+ */
+ private ContactSourceService currentStringContactSource;
+
+ /**
+ * The previously selected protocol provider, with which this dialog has
+ * been instantiated.
+ */
+ private ProtocolProviderService preselectedProtocolProvider;
+
+ /**
+ * Indicates whether this conference invite dialog is associated with a
+ * Jitsi Videobridge invite.
+ */
+ private final boolean isJitsiVideobridge;
+
+ /**
+ * Initializes a new <tt>ConferenceInviteDialog</tt> instance which is to
+ * invite contacts/participants in a specific telephony conference.
+ *
+ * @param conference the telephony conference in which the new instance is
+ * to invite contacts/participants
+ */
+ public ConferenceInviteDialog(
+ CallConference conference,
+ ProtocolProviderService preselectedProvider,
+ List<ProtocolProviderService> protocolProviders,
+ final boolean isJitsiVideobridge)
+ {
+ // Set the correct dialog title depending if we're going to create a
+ // video bridge conference call
+ super((isJitsiVideobridge
+ ? GuiActivator.getResources()
+ .getI18NString("service.gui.INVITE_CONTACT_TO_VIDEO_BRIDGE")
+ : GuiActivator.getResources()
+ .getI18NString("service.gui.INVITE_CONTACT_TO_CALL")),
+ false);
+
+ this.conference = conference;
+ this.preselectedProtocolProvider = preselectedProvider;
+ this.isJitsiVideobridge = isJitsiVideobridge;
+
+ if (preselectedProtocolProvider == null)
+ initAccountSelectorPanel(protocolProviders);
+
+ // init the list, as we check whether features are supported
+ // it may take some time if we have too much contacts
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ initContactSources();
+
+ // Initialize the list of contacts to select from.
+ if (preselectedProtocolProvider != null)
+ initContactListData(preselectedProtocolProvider);
+ else
+ initContactListData(
+ (ProtocolProviderService) accountSelectorBox
+ .getSelectedItem());
+ }
+ });
+
+ this.addInviteButtonListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ Collection<UIContact> selectedContacts
+ = destContactList.getContacts(null);
+
+ if (selectedContacts != null && selectedContacts.size() > 0)
+ {
+ if (preselectedProtocolProvider == null)
+ preselectedProtocolProvider
+ = (ProtocolProviderService) accountSelectorBox
+ .getSelectedItem();
+
+ if (isJitsiVideobridge)
+ inviteJitsiVideobridgeContacts( preselectedProtocolProvider,
+ selectedContacts);
+ else
+ inviteContacts(selectedContacts);
+
+ // Store the last used account in order to pre-select it
+ // next time.
+ ConfigurationUtils.setLastCallConferenceProvider(
+ preselectedProtocolProvider);
+
+ dispose();
+ }
+ else
+ {
+ // TODO: The underlying invite dialog should show a message
+ // to the user that she should select at least two contacts
+ // in order to create a conference.
+ }
+ }
+ });
+
+ this.addCancelButtonListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ dispose();
+ }
+ });
+ }
+
+ /**
+ * Constructs the <tt>ConferenceInviteDialog</tt>.
+ */
+ public ConferenceInviteDialog()
+ {
+ this(null, null, null, false);
+ }
+
+ /**
+ * Creates an instance of <tt>ConferenceInviteDialog</tt> by specifying an
+ * already created conference. To use when inviting contacts to an existing
+ * conference is needed.
+ *
+ * @param conference the existing <tt>CallConference</tt>
+ */
+ public ConferenceInviteDialog(CallConference conference)
+ {
+ this(conference, null, null, false);
+ }
+
+ /**
+ * Creates an instance of <tt>ConferenceInviteDialog</tt> by specifying an
+ * already created conference. To use when inviting contacts to an existing
+ * conference is needed.
+ *
+ * @param conference the existing <tt>CallConference</tt>
+ */
+ public ConferenceInviteDialog(
+ CallConference conference,
+ ProtocolProviderService preselectedProtocolProvider,
+ boolean isJitsiVideobridge)
+ {
+ this(conference, preselectedProtocolProvider, null, isJitsiVideobridge);
+ }
+
+ /**
+ * Creates an instance of <tt>ConferenceInviteDialog</tt> by specifying a
+ * preselected protocol provider to be used and if this is an invite for
+ * a video bridge conference.
+ *
+ * @param protocolProviders the protocol providers list
+ * @param isJitsiVideobridge <tt>true</tt> if this dialog should create a
+ * conference through a Jitsi Videobridge; otherwise, <tt>false</tt>
+ */
+ public ConferenceInviteDialog(
+ List<ProtocolProviderService> protocolProviders,
+ boolean isJitsiVideobridge)
+ {
+ this(null, null, protocolProviders, isJitsiVideobridge);
+ }
+
+ /**
+ * Creates an instance of <tt>ConferenceInviteDialog</tt> by specifying a
+ * preselected protocol provider to be used and if this is an invite for
+ * a video bridge conference.
+ *
+ * @param selectedConfProvider the preselected protocol provider
+ * @param isJitsiVideobridge <tt>true</tt> if this dialog should create a
+ * conference through a Jitsi Videobridge; otherwise, <tt>false</tt>
+ */
+ public ConferenceInviteDialog(
+ ProtocolProviderService selectedConfProvider,
+ boolean isJitsiVideobridge)
+ {
+ this(null, selectedConfProvider, null, isJitsiVideobridge);
+ }
+
+ /**
+ * Initializes the account selector panel.
+ *
+ * @param protocolProviders the list of protocol providers we'd like to
+ * show in the account selector box
+ */
+ private void initAccountSelectorPanel(
+ List<ProtocolProviderService> protocolProviders)
+ {
+ JLabel accountSelectorLabel = new JLabel(
+ GuiActivator.getResources().getI18NString("service.gui.CALL_VIA"));
+
+ TransparentPanel accountSelectorPanel
+ = new TransparentPanel(new BorderLayout());
+
+ accountSelectorPanel.setBorder(
+ BorderFactory.createEmptyBorder(5, 5, 5, 5));
+ accountSelectorPanel.add(accountSelectorLabel, BorderLayout.WEST);
+ accountSelectorPanel.add(accountSelectorBox, BorderLayout.CENTER);
+
+ // Initialize the account selector box.
+ if (protocolProviders != null && protocolProviders.size() > 0)
+ this.initAccountListData(protocolProviders);
+ else
+ this.initAccountListData();
+
+ this.accountSelectorBox.setRenderer(new DefaultListCellRenderer()
+ {
+ private static final long serialVersionUID = 0L;
+
+ @Override
+ public Component getListCellRendererComponent(JList list,
+ Object value, int index, boolean isSelected,
+ boolean cellHasFocus)
+ {
+ ProtocolProviderService protocolProvider
+ = (ProtocolProviderService) value;
+
+ if (protocolProvider != null)
+ {
+ this.setText(
+ protocolProvider.getAccountID().getDisplayName());
+ this.setIcon(
+ ImageLoader.getAccountStatusImage(protocolProvider));
+ }
+
+ return this;
+ }
+ });
+
+ this.accountSelectorBox.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ Object accountSelectorBoxSelectedItem
+ = accountSelectorBox.getSelectedItem();
+
+ if (lastSelectedAccount == null
+ || !lastSelectedAccount
+ .equals(accountSelectorBoxSelectedItem))
+ {
+ lastSelectedAccount = accountSelectorBoxSelectedItem;
+
+ initContactListData(
+ (ProtocolProviderService) accountSelectorBox
+ .getSelectedItem());
+
+ if (isJitsiVideobridge)
+ destContactList.removeAll();
+ }
+ }
+ });
+
+ this.getContentPane().add(accountSelectorPanel, BorderLayout.NORTH);
+ }
+
+ /**
+ * Initializes the account selector box with the given list of
+ * <tt>ProtocolProviderService</tt>-s.
+ *
+ * @param protocolProviders the list of <tt>ProtocolProviderService</tt>-s
+ * we'd like to show in the account selector box
+ */
+ private void initAccountListData(
+ List<ProtocolProviderService> protocolProviders)
+ {
+ Iterator<ProtocolProviderService> providersIter
+ = protocolProviders.iterator();
+
+ while (providersIter.hasNext())
+ {
+ ProtocolProviderService protocolProvider
+ = providersIter.next();
+
+ accountSelectorBox.addItem(protocolProvider);
+ }
+
+ if (accountSelectorBox.getItemCount() > 0)
+ accountSelectorBox.setSelectedIndex(0);
+ }
+
+ /**
+ * Initializes the account list.
+ */
+ private void initAccountListData()
+ {
+ Iterator<ProtocolProviderService> protocolProviders
+ = GuiActivator.getUIService().getMainFrame().getProtocolProviders();
+
+ while(protocolProviders.hasNext())
+ {
+ ProtocolProviderService protocolProvider
+ = protocolProviders.next();
+ OperationSet opSet
+ = protocolProvider.getOperationSet(
+ OperationSetTelephonyConferencing.class);
+
+ if ((opSet != null) && protocolProvider.isRegistered())
+ accountSelectorBox.addItem(protocolProvider);
+ }
+
+ // Try to select the last used account if available.
+ ProtocolProviderService pps
+ = ConfigurationUtils.getLastCallConferenceProvider();
+
+ if (pps == null && conference != null)
+ {
+ /*
+ * Pick up the first account from the ones participating in the
+ * associated telephony conference which supports
+ * OperationSetTelephonyConferencing.
+ */
+ for (Call call : conference.getCalls())
+ {
+ ProtocolProviderService callPps = call.getProtocolProvider();
+
+ if (callPps.getOperationSet(
+ OperationSetTelephonyConferencing.class)
+ != null)
+ {
+ pps = callPps;
+ break;
+ }
+ }
+ }
+
+ if (pps != null)
+ accountSelectorBox.setSelectedItem(pps);
+ else if (accountSelectorBox.getItemCount() > 0)
+ accountSelectorBox.setSelectedIndex(0);
+ }
+
+ /**
+ * Initializes contact list sources.
+ */
+ private void initContactSources()
+ {
+ DemuxContactSourceService demuxCSService
+ = GuiActivator.getDemuxContactSourceService();
+
+ // If the DemuxContactSourceService isn't registered we use the default
+ // contact source set.
+ if (demuxCSService == null)
+ return;
+
+ Iterator<UIContactSource> sourcesIter
+ = new ArrayList<UIContactSource>(
+ srcContactList.getContactSources()).iterator();
+
+ srcContactList.removeAllContactSources();
+
+ while (sourcesIter.hasNext())
+ {
+ ContactSourceService contactSource
+ = sourcesIter.next().getContactSourceService();
+
+ srcContactList.addContactSource(
+ demuxCSService.createDemuxContactSource(contactSource));
+ }
+ }
+
+ /**
+ * Initializes the left contact list with the contacts that could be added
+ * to the current chat session.
+ * @param protocolProvider the protocol provider from which to initialize
+ * the contact list data
+ */
+ private void initContactListData(ProtocolProviderService protocolProvider)
+ {
+ this.setCurrentProvider(protocolProvider);
+
+ Iterator<UIContactSource> sourcesIter
+ = new ArrayList<UIContactSource>(
+ srcContactList.getContactSources()).iterator();
+
+ while (sourcesIter.hasNext())
+ {
+ ContactSourceService contactSource
+ = sourcesIter.next().getContactSourceService();
+
+ if (contactSource instanceof ProtocolAwareContactSourceService)
+ {
+ ((ProtocolAwareContactSourceService) contactSource)
+ .setPreferredProtocolProvider(
+ OperationSetBasicTelephony.class, protocolProvider);
+ }
+ }
+
+ srcContactList.removeContactSource(currentProviderContactSource);
+ srcContactList.removeContactSource(currentStringContactSource);
+
+ currentProviderContactSource
+ = new ProtocolContactSourceServiceImpl(
+ protocolProvider,
+ OperationSetBasicTelephony.class);
+ currentStringContactSource
+ = new StringContactSourceServiceImpl(
+ protocolProvider,
+ OperationSetBasicTelephony.class);
+
+ srcContactList.addContactSource(currentProviderContactSource);
+ srcContactList.addContactSource(currentStringContactSource);
+
+ srcContactList.applyDefaultFilter();
+ }
+
+ /**
+ * Invites the contacts to the chat conference.
+ *
+ * @param contacts the list of contacts to invite
+ */
+ private void inviteContacts(Collection<UIContact> contacts)
+ {
+ ProtocolProviderService selectedProvider;
+ Map<ProtocolProviderService, List<String>> selectedProviderCallees
+ = new HashMap<ProtocolProviderService, List<String>>();
+ List<String> callees;
+
+ Iterator<UIContact> contactsIter = contacts.iterator();
+
+ while (contactsIter.hasNext())
+ {
+ UIContact uiContact = contactsIter.next();
+
+ Iterator<UIContactDetail> contactDetailsIter = uiContact
+ .getContactDetailsForOperationSet(
+ OperationSetBasicTelephony.class).iterator();
+
+ // We invite the first protocol contact that corresponds to the
+ // invite provider.
+ if (contactDetailsIter.hasNext())
+ {
+ UIContactDetail inviteDetail = contactDetailsIter.next();
+ selectedProvider = inviteDetail
+ .getPreferredProtocolProvider(
+ OperationSetBasicTelephony.class);
+
+ if (selectedProvider == null)
+ {
+ selectedProvider
+ = (ProtocolProviderService)
+ accountSelectorBox.getSelectedItem();
+ }
+
+ if(selectedProvider != null
+ && selectedProviderCallees.get(selectedProvider) != null)
+ {
+ callees = selectedProviderCallees.get(selectedProvider);
+ }
+ else
+ {
+ callees = new ArrayList<String>();
+ }
+
+ callees.add(inviteDetail.getAddress());
+ selectedProviderCallees.put(selectedProvider, callees);
+ }
+ }
+
+ if(conference != null)
+ {
+ CallManager.inviteToConferenceCall(
+ selectedProviderCallees,
+ conference);
+ }
+ else
+ {
+ CallManager.createConferenceCall(selectedProviderCallees);
+ }
+ }
+
+ /**
+ * Invites the contacts to the chat conference.
+ *
+ * @param contacts the list of contacts to invite
+ */
+ private void inviteJitsiVideobridgeContacts(
+ ProtocolProviderService preselectedProvider,
+ Collection<UIContact> contacts)
+ {
+ List<String> callees = new ArrayList<String>();
+
+ Iterator<UIContact> contactsIter = contacts.iterator();
+
+ while (contactsIter.hasNext())
+ {
+ UIContact uiContact = contactsIter.next();
+
+ Iterator<UIContactDetail> contactDetailsIter = uiContact
+ .getContactDetailsForOperationSet(
+ OperationSetBasicTelephony.class).iterator();
+
+ // We invite the first protocol contact that corresponds to the
+ // invite provider.
+ if (contactDetailsIter.hasNext())
+ {
+ UIContactDetail inviteDetail = contactDetailsIter.next();
+
+ callees.add(inviteDetail.getAddress());
+ }
+ }
+
+ if(conference != null)
+ {
+ CallManager.inviteToJitsiVideobridgeConfCall(
+ callees.toArray(new String[callees.size()]),
+ conference.getCalls().get(0));
+ }
+ else
+ {
+ CallManager.createJitsiVideobridgeConfCall(
+ preselectedProvider,
+ callees.toArray(new String[callees.size()]));
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/conference/VideoConferenceCallPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/conference/VideoConferenceCallPanel.java
index 0dd6ef5..07c653d 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/conference/VideoConferenceCallPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/conference/VideoConferenceCallPanel.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,1395 +15,1395 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.gui.main.call.conference;
-
-import java.awt.*;
-import java.util.*;
-import java.util.List;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.impl.gui.main.call.*;
-import net.java.sip.communicator.impl.gui.utils.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.plugin.desktoputil.TransparentPanel;
-
-import org.jitsi.util.swing.*;
-
-/**
- * Extends <tt>BasicConferenceCallPanel</tt> to implement a user interface
- * <tt>Component</tt> which depicts a <tt>CallConference</tt> with audio and
- * video and is contained in a <tt>CallPanel</tt>.
- *
- * @author Yana Stamcheva
- * @author Lyubomir Marinov
- */
-public class VideoConferenceCallPanel
- extends BasicConferenceCallPanel
-{
- /**
- * The <tt>Logger</tt> used by the <tt>VideoConferenceCallPanel</tt> class
- * and its instances for logging output.
- */
- private static final Logger logger
- = Logger.getLogger(VideoConferenceCallPanel.class);
-
- /**
- * The compile-time flag which indicates whether each video displayed by
- * <tt>VideoConferenceCallPanel</tt> is to be depicted with an associated
- * tool bar showing information and controls related to the (local or
- * remote) peer sending the respective video.
- */
- private static final boolean SHOW_TOOLBARS = true;
-
- /**
- * The facility which aids this instance with the video-related information.
- */
- private final UIVideoHandler2 uiVideoHandler;
-
- /**
- * The <tt>Observer</tt> which listens to {@link #uiVideoHandler} about
- * changes in the video-related information.
- */
- private final Observer uiVideoHandlerObserver
- = new Observer()
- {
- public void update(Observable o, Object arg)
- {
- updateViewFromModel();
- }
- };
-
- /**
- * The <tt>VideoContainer</tt> which occupies this whole <tt>Component</tt>
- * and arranges the visual <tt>Component</tt>s displaying the video
- * streaming between the local peer/user and the remote peer(s).
- */
- private final VideoContainer videoContainer;
-
- /**
- * The set of visual <tt>Component</tt>s displaying video streaming between
- * the local peer/user and the remote peers which are depicted by this
- * instance.
- */
- private final Set<Component> videos = new HashSet<Component>();
-
- /**
- * The thumbnail container.
- */
- private final ThumbnailConferenceCallPanel thumbnailContainer;
-
- private final JPanel thumbnailPanel;
-
- /**
- * Initializes a new <tt>VideoConferenceCallPanel</tt> instance which is to
- * be used by a specific <tt>CallPanel</tt> to depict a specific
- * <tt>CallConference</tt>. The new instance will depict both the
- * audio-related and the video-related information.
- *
- * @param callPanel the <tt>CallPanel</tt> which will use the new instance
- * to depict the specified <tt>CallConference</tt>.
- * @param callConference the <tt>CallConference</tt> to be depicted by the
- * new instance
- * @param uiVideoHandler the utility which is to aid the new instance in
- * dealing with the video-related information
- */
- public VideoConferenceCallPanel(
- CallPanel callPanel,
- CallConference callConference,
- UIVideoHandler2 uiVideoHandler)
- {
- super(callPanel, callConference);
-
- this.uiVideoHandler = uiVideoHandler;
-
- thumbnailPanel = new JPanel(new BorderLayout());
- thumbnailContainer
- = new ThumbnailConferenceCallPanel( callPanel,
- callConference,
- uiVideoHandler);
-
- videoContainer = createVideoContainer();
-
- /*
- * Our user interface hierarchy has been initialized so we are ready to
- * begin receiving events warranting updates of this view from its
- * model.
- */
- uiVideoHandler.addObserver(uiVideoHandlerObserver);
-
- /*
- * Notify the super that this instance has completed its initialization
- * and the view that it implements is ready to be updated from the
- * model.
- */
- initializeComplete();
- }
-
- private void addConferenceMemberContainers(
- ConferenceParticipantContainer cpc)
- {
- List<ConferenceParticipantContainer> cmcs
- = cpc.conferenceMemberContainers;
-
- if ((cmcs != null) && !cmcs.isEmpty())
- {
- for (ConferenceParticipantContainer cmc : cmcs)
- {
- if (!cmc.toBeRemoved)
- {
- videoContainer.add(
- cmc.getComponent(),
- VideoLayout.CENTER_REMOTE);
- }
- }
- }
- }
-
- private Component createDefaultPhotoPanel(Call call)
- {
- OperationSetServerStoredAccountInfo accountInfo
- = call.getProtocolProvider().getOperationSet(
- OperationSetServerStoredAccountInfo.class);
- ImageIcon photoLabelIcon = null;
-
- if (accountInfo != null)
- {
- byte[] accountImage = AccountInfoUtils.getImage(accountInfo);
-
- // do not set empty images
- if ((accountImage != null) && (accountImage.length > 0))
- photoLabelIcon = new ImageIcon(accountImage);
- }
- if (photoLabelIcon == null)
- {
- photoLabelIcon
- = new ImageIcon(
- ImageLoader.getImage(ImageLoader.DEFAULT_USER_PHOTO));
- }
-
- return createDefaultPhotoPanel(photoLabelIcon);
- }
-
- private Component createDefaultPhotoPanel(CallPeer callPeer)
- {
- byte[] peerImage = CallManager.getPeerImage(callPeer);
- ImageIcon photoLabelIcon
- = (peerImage == null)
- ? new ImageIcon(
- ImageLoader.getImage(ImageLoader.DEFAULT_USER_PHOTO))
- : new ImageIcon(peerImage);
-
- return createDefaultPhotoPanel(photoLabelIcon);
- }
-
- private Component createDefaultPhotoPanel(ConferenceMember conferenceMember)
- {
- return
- createDefaultPhotoPanel(
- new ImageIcon(
- ImageLoader.getImage(
- ImageLoader.DEFAULT_USER_PHOTO)));
- }
-
- /**
- * Creates a new <tt>Component</tt> which is to display a specific
- * <tt>ImageIcon</tt> representing the photo of a participant in a call.
- *
- * @param photoLabelIcon the <tt>ImageIcon</tt> which represents the photo
- * of a participant in a call and which is to be displayed by the new
- * <tt>Component</tt>
- * @return a new <tt>Component</tt> which displays the specified
- * <tt>photoLabelIcon</tt>
- */
- private Component createDefaultPhotoPanel(ImageIcon photoLabelIcon)
- {
- JLabel photoLabel = new JLabel();
-
- photoLabel.setIcon(photoLabelIcon);
-
- @SuppressWarnings("serial")
- JPanel photoPanel
- = new TransparentPanel(new GridBagLayout())
- {
- /**
- * @{inheritDoc}
- */
- @Override
- public void paintComponent(Graphics g)
- {
- super.paintComponent(g);
-
- g = g.create();
- try
- {
- AntialiasingManager.activateAntialiasing(g);
-
- g.setColor(Color.GRAY);
- g.fillRoundRect(
- 0, 0, this.getWidth(), this.getHeight(),
- 6, 6);
- }
- finally
- {
- g.dispose();
- }
- }
- };
-
- photoPanel.setPreferredSize(new Dimension(320, 240));
-
- GridBagConstraints photoPanelConstraints = new GridBagConstraints();
-
- photoPanelConstraints.anchor = GridBagConstraints.CENTER;
- photoPanelConstraints.fill = GridBagConstraints.NONE;
- photoPanel.add(photoLabel, photoPanelConstraints);
-
- return photoPanel;
- }
-
- /**
- * Initializes a new <tt>VideoContainer</tt> instance which is to contain
- * the visual/video <tt>Component</tt>s of the telephony conference depicted
- * by this instance.
- */
- private VideoContainer createVideoContainer()
- {
- VideoContainer videoContainer = new VideoContainer(null, true);
-
- thumbnailPanel.setBackground(Color.DARK_GRAY);
- thumbnailPanel.add(thumbnailContainer, BorderLayout.NORTH);
-
- add(thumbnailPanel, BorderLayout.EAST);
- add(videoContainer, BorderLayout.CENTER);
-
- return videoContainer;
- }
-
- /**
- * Shows/hides the participants thumbnails list.
- *
- * @param show <tt>true</tt> to show the participants list, <tt>false</tt>
- * to hide it
- */
- public void showThumbnailsList(boolean show)
- {
- thumbnailPanel.setVisible(show);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void dispose()
- {
- try
- {
- uiVideoHandler.deleteObserver(uiVideoHandlerObserver);
- }
- finally
- {
- super.dispose();
- }
- }
-
- /**
- * Determines whether a specific <tt>ConferenceMember</tt> represents the
- * same conference participant as a specific <tt>CallPeer</tt>. If the
- * specified <tt>conferenceMember</tt> is <tt>null</tt>, returns
- * <tt>true</tt>. Otherwise, determines whether the addresses of the
- * specified <tt>conferenceMember</tt> and the specified <tt>callPeer</tt>
- * identify one and the same entity.
- *
- * @param conferenceMember the <tt>ConferenceMember</tt> to be checked
- * whether is represents the same conference participant as the specified
- * <tt>callPeer</tt>. If it is <tt>null</tt>, <tt>true</tt> is returned.
- * @param callPeer the <tt>CallPeer</tt> to be checked whether it represents
- * the same conference participant as the specified
- * <tt>conferenceMember</tt>
- * @return <tt>true</tt> if the specified <tt>conferenceMember</tt> and the
- * specified <tt>callPeer</tt> represent the same conference participant or
- * the specified <tt>conferenceMember</tt> is <tt>null</tt>; otherwise,
- * <tt>false</tt>
- */
- private boolean isConferenceMemberCallPeer(
- ConferenceMember conferenceMember,
- CallPeer callPeer)
- {
- return
- (conferenceMember == null)
- ? true
- : CallManager.addressesAreEqual(
- conferenceMember.getAddress(),
- callPeer.getAddress());
- }
-
- /**
- * Determines whether a specific <tt>ConferenceMember</tt> represents the
- * local peer/user. Since this instance depicts a whole telephony
- * conference, the local peer/user may be participating with multiple
- * <tt>Call</tt>s in it. The <tt>Call</tt>s may be through different
- * (local) accounts. That's why the implementation determines whether the
- * address of the specified <tt>conferenceMember</tt> identifies the address
- * of a (local) accounts involved in the telephony conference depicted by
- * this instance.
- *
- * @param conferenceMember the <tt>ConferenceMember</tt> to be checked
- * whether it represents the local peer/user
- * @return <tt>true</tt> if the specified <tt>conferenceMember</tt>
- * represents the local peer/user; otherwise, <tt>false</tt>
- */
- private boolean isConferenceMemberLocalUser(
- ConferenceMember conferenceMember)
- {
- String address = conferenceMember.getAddress();
-
- for (Call call : callConference.getCalls())
- {
- if (CallManager.addressesAreEqual(
- address,
- call.getProtocolProvider().getAccountID()
- .getAccountAddress()))
- {
- return true;
- }
- }
- return false;
- }
-
- private void removeConferenceMemberContainers(
- ConferenceParticipantContainer cpc,
- boolean all)
- {
- List<ConferenceParticipantContainer> cmcs
- = cpc.conferenceMemberContainers;
-
- if ((cmcs != null) && !cmcs.isEmpty())
- {
- Iterator<ConferenceParticipantContainer> i = cmcs.iterator();
-
- while (i.hasNext())
- {
- ConferenceParticipantContainer cmc = i.next();
-
- if (all || cmc.toBeRemoved)
- {
- i.remove();
-
- videoContainer.remove(cmc.getComponent());
- cmc.dispose();
- }
- }
- }
- }
-
- /**
- * Updates the <tt>ConferenceParticipantContainer</tt>s which depict the
- * <tt>ConferenceMember</tt>s of the <tt>CallPeer</tt> depicted by a
- * specific <tt>ConferenceParticipantContainer</tt>.
- *
- * @param cpc the <tt>ConferenceParticipantContainer</tt> which depicts the
- * <tt>CallPeer</tt> whose <tt>ConferenceMember</tt>s are to be depicted
- * @param videos the visual <tt>Component</tt>s displaying video streaming
- * from the remote peer (represented by <tt>cpc</tt>) to the local peer/user
- * @param videoTelephony the <tt>OperationSetVideoTelephony</tt> which
- * retrieved the specified <tt>videos</tt> from the <tt>CallPeer</tt>
- * depicted by <tt>cpc</tt>. While the <tt>CallPeer</tt> could be queried
- * for it, such a query would waste more resources at run time given that
- * the invoker has it already.
- */
- private void updateConferenceMemberContainers(
- ConferenceParticipantContainer cpc,
- List<Component> videos,
- OperationSetVideoTelephony videoTelephony)
- {
- CallPeer callPeer = (CallPeer) cpc.getParticipant();
- List<ConferenceParticipantContainer> cmcs
- = cpc.conferenceMemberContainers;
-
- /*
- * Invalidate all conferenceMemberContainers. Then validate which of
- * them are to remain and which of them are to really be removed
- * later on.
- */
- if (cmcs != null)
- {
- for (ConferenceParticipantContainer cmc : cmcs)
- cmc.toBeRemoved = true;
- }
-
- /*
- * Depict the remote videos. They may or may not be associated with
- * ConferenceMembers so the ConferenceMembers which have no
- * associated videos will be depicted afterwards.
- */
- if (videos != null)
- {
- Component video = cpc.getVideo();
-
- for (Component conferenceMemberVideo : videos)
- {
- /*
- * One of the remote videos is already used to depict the
- * callPeer.
- */
- if (conferenceMemberVideo == video)
- continue;
-
- boolean addNewConferenceParticipantContainer = true;
- ConferenceMember conferenceMember
- = videoTelephony.getConferenceMember(
- callPeer,
- conferenceMemberVideo);
-
- if (cmcs == null)
- {
- cmcs = new LinkedList<ConferenceParticipantContainer>();
- cpc.conferenceMemberContainers = cmcs;
- }
- else
- {
- for (ConferenceParticipantContainer cmc : cmcs)
- {
- Object cmcParticipant = cmc.getParticipant();
-
- if (conferenceMember == null)
- {
- if (cmcParticipant == callPeer)
- {
- Component cmcVideo = cmc.getVideo();
-
- if (cmcVideo == null)
- {
- cmc.setVideo(conferenceMemberVideo);
- cmc.toBeRemoved = false;
- addNewConferenceParticipantContainer
- = false;
- break;
- }
- else if (cmcVideo == conferenceMemberVideo)
- {
- cmc.toBeRemoved = false;
- addNewConferenceParticipantContainer
- = false;
- break;
- }
- }
- }
- else if (cmcParticipant == conferenceMember)
- {
- cmc.setVideo(conferenceMemberVideo);
- cmc.toBeRemoved = false;
- addNewConferenceParticipantContainer = false;
- break;
- }
- }
- }
-
- if (addNewConferenceParticipantContainer)
- {
- ConferenceParticipantContainer cmc
- = (conferenceMember == null)
- ? new ConferenceParticipantContainer(
- callPeer,
- conferenceMemberVideo)
- : new ConferenceParticipantContainer(
- conferenceMember,
- conferenceMemberVideo);
-
- cmcs.add(cmc);
- }
- }
- }
-
- /*
- * Depict the ConferenceMembers which have not been depicted yet.
- * They have no associated videos.
- */
- List<ConferenceMember> conferenceMembers
- = callPeer.getConferenceMembers();
-
- if (!conferenceMembers.isEmpty())
- {
- if (cmcs == null)
- {
- cmcs = new LinkedList<ConferenceParticipantContainer>();
- cpc.conferenceMemberContainers = cmcs;
- }
- for (ConferenceMember conferenceMember : conferenceMembers)
- {
- /*
- * If the callPeer reports itself as a ConferenceMember, then
- * we've already depicted it with cpc.
- */
- if (isConferenceMemberCallPeer(conferenceMember, callPeer))
- continue;
- /*
- * If the callPeer reports the local peer/user as a
- * ConferenceMember, then we've already depicted it.
- */
- if (isConferenceMemberLocalUser(conferenceMember))
- continue;
-
- boolean addNewConferenceParticipantContainer = true;
-
- for (ConferenceParticipantContainer cmc : cmcs)
- {
- if (cmc.getParticipant() == conferenceMember)
- {
- /*
- * It is possible to have a ConferenceMember who is
- * sending video but we just do not have the SSRC of
- * that video to associate the video with the
- * ConferenceMember. In such a case, we may be depicting
- * the ConferenceMember twice: once with video without a
- * ConferenceMember and once with a ConferenceMember
- * without video. This will surely be the case at the
- * time of this writing with non-focus participants in a
- * telephony conference hosted on a Jitsi Videobridge.
- * Such a display is undesirable. If the
- * conferenceMember is known to send video, we will not
- * display it until we associated it with a video. This
- * way, if a ConferenceMember is not sending video, we
- * will depict it and we can be sure that no video
- * without a ConferenceMember association will be
- * depicting it a second time.
- */
- if (cmc.toBeRemoved
- && !conferenceMember
- .getVideoStatus()
- .allowsSending())
- {
- cmc.setVideo(null);
- cmc.toBeRemoved = false;
- }
- addNewConferenceParticipantContainer = false;
- break;
- }
- }
-
- if (addNewConferenceParticipantContainer)
- {
- ConferenceParticipantContainer cmc
- = new ConferenceParticipantContainer(
- conferenceMember,
- null);
-
- cmcs.add(cmc);
- }
- }
- }
-
- if ((cmcs != null) && !cmcs.isEmpty())
- {
- removeConferenceMemberContainers(cpc, false);
- /*
- * If cpc is already added to the user interface hierarchy of this
- * instance, then it was there before the update procedure and it
- * was determined to be appropriate to continue to depict its model.
- * Consequently, its Component will be neither added to (because it
- * was already added) nor removed from the user interface hierarchy
- * of this instance. That's why we have make sure that the
- * Components of its conferenceMemberContainers are also added to
- * the user interface.
- */
- if (UIVideoHandler2.isAncestor(this, cpc.getComponent()))
- addConferenceMemberContainers(cpc);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected ConferenceCallPeerRenderer updateViewFromModel(
- ConferenceCallPeerRenderer callPeerPanel,
- CallPeer callPeer)
- {
- if (callPeer == null)
- {
- /*
- * The local peer/user will be represented by a Call which has a
- * CallPeer who provides local video. However, if the user has
- * selected to hide the local video, the local peer/user will not be
- * represented at all.
- */
- Component video = null;
-
- if (uiVideoHandler.isLocalVideoVisible())
- {
- for (Call aCall : callConference.getCalls())
- {
- Iterator<? extends CallPeer> callPeerIter
- = aCall.getCallPeers();
- OperationSetVideoTelephony videoTelephony
- = aCall.getProtocolProvider().getOperationSet(
- OperationSetVideoTelephony.class);
-
- while (callPeerIter.hasNext())
- {
- callPeer = callPeerIter.next();
-
- if (videoTelephony != null)
- {
- try
- {
- video
- = videoTelephony.getLocalVisualComponent(
- callPeer);
- }
- catch (OperationFailedException ofe)
- {
- logger.error(
- "Failed to retrieve the local video"
- + " for display",
- ofe);
- }
- if (video != null)
- break;
- }
- }
- if (video != null)
- break;
- }
- }
-
- if (callPeer == null)
- callPeerPanel = null;
- else
- {
- Call call = callPeer.getCall();
-
- if (callPeerPanel instanceof ConferenceParticipantContainer)
- {
- ConferenceParticipantContainer cpc
- = (ConferenceParticipantContainer) callPeerPanel;
-
- if (cpc.getParticipant() == call)
- cpc.setVideo(video);
- else
- callPeerPanel = null;
- }
- else
- callPeerPanel = null;
- if (callPeerPanel == null)
- {
- callPeerPanel
- = new ConferenceParticipantContainer(call, video);
- }
- }
- }
- else
- {
- /*
- * The specified callPeer will be represented by one of its remote
- * videos which is not associated with a ConferenceMember or is
- * associated with a ConferenceMember representing the callPeer
- * itself.
- */
- OperationSetVideoTelephony videoTelephony
- = callPeer.getProtocolProvider().getOperationSet(
- OperationSetVideoTelephony.class);
- List<Component> videos = null;
- Component video = null;
-
- if (videoTelephony != null)
- {
- videos = videoTelephony.getVisualComponents(callPeer);
- if ((videos != null) && !videos.isEmpty())
- {
- for (Component aVideo : videos)
- {
- ConferenceMember conferenceMember
- = videoTelephony.getConferenceMember(
- callPeer,
- aVideo);
-
- if (isConferenceMemberCallPeer(
- conferenceMember,
- callPeer))
- {
- video = aVideo;
- break;
- }
- }
- }
- }
-
- ConferenceParticipantContainer cpc = null;
-
- if (callPeerPanel instanceof ConferenceParticipantContainer)
- {
- cpc = (ConferenceParticipantContainer) callPeerPanel;
- if (cpc.getParticipant() == callPeer)
- cpc.setVideo(video);
- else
- cpc = null;
- }
- if (cpc == null)
- cpc = new ConferenceParticipantContainer(callPeer, video);
- callPeerPanel = cpc;
-
- // Update the conferenceMemberContainers of the cpc.
- updateConferenceMemberContainers(cpc, videos, videoTelephony);
- }
- return callPeerPanel;
- }
-
- /**
- * {@inheritDoc}
- *
- * If {@link #SHOW_TOOLBARS} is <tt>false</tt>, disables the use of
- * <tt>ConferenceParticipantContainer</tt>. A reason for such a value of
- * <tt>SHOW_TOOLBARS</tt> may be that the functionality implemented in the
- * model may not fully support mapping of visual <tt>Component</tt>s
- * displaying video to telephony conference participants (e.g. in telephony
- * conferences utilizing the Jitsi Videobridge server-side technology). In
- * such a case displays the videos only, does not map videos to participants
- * and does not display participants who do not have videos.
- */
- @Override
- protected void updateViewFromModelInEventDispatchThread()
- {
- if (SHOW_TOOLBARS)
- {
- super.updateViewFromModelInEventDispatchThread();
- return;
- }
-
- /*
- * Determine the set of visual Components displaying video streaming
- * between the local peer/user and the remote peers which are to be
- * depicted by this instance.
- */
- Component localVideo = null;
- Set<Component> videos = new HashSet<Component>();
-
- for (Call call : callConference.getCalls())
- {
- OperationSetVideoTelephony videoTelephony
- = call.getProtocolProvider().getOperationSet(
- OperationSetVideoTelephony.class);
-
- if (videoTelephony == null)
- continue;
-
- Iterator<? extends CallPeer> callPeerIter = call.getCallPeers();
-
- while (callPeerIter.hasNext())
- {
- CallPeer callPeer = callPeerIter.next();
-
- /*
- * TODO VideoConferenceCallPanel respects
- * UIVideoHandler2.isLocalVideoVisible() in order to react to
- * the associated button at the bottom of the CallPanel.
- * However, it does not add a close button on top of the local
- * video in contrast to OneToOneCallPeerPanel. Overall, the
- * result is questionable.
- */
- if (uiVideoHandler.isLocalVideoVisible()
- && (localVideo == null))
- {
- try
- {
- localVideo
- = videoTelephony.getLocalVisualComponent(callPeer);
- }
- catch (OperationFailedException ofe)
- {
- /*
- * We'll just try to get the local video through another
- * CallPeer then.
- */
- }
- if (localVideo != null)
- videos.add(localVideo);
- }
-
- List<Component> callPeerRemoteVideos
- = videoTelephony.getVisualComponents(callPeer);
-
- videos.addAll(callPeerRemoteVideos);
- }
- }
-
- /*
- * Remove the Components of this view which are no longer present in the
- * model.
- */
- Iterator<Component> thisVideoIter = this.videos.iterator();
-
- while (thisVideoIter.hasNext())
- {
- Component thisVideo = thisVideoIter.next();
-
- if (!videos.contains(thisVideo))
- {
- thisVideoIter.remove();
- videoContainer.remove(thisVideo);
- }
-
- /*
- * If a video is known to be depicted by this view and is still
- * present in the model, then we could remove it from the set of
- * videos present in the model in order to prevent going through the
- * procedure of adding it to this view. However, we choose to play
- * on the safe side.
- */
- }
-
- /*
- * Add the Components of the model which are not depicted by this view.
- */
- for (Component video : videos)
- {
- if (!UIVideoHandler2.isAncestor(videoContainer, video))
- {
- this.videos.add(video);
- videoContainer.add(
- video,
- (video == localVideo)
- ? VideoLayout.LOCAL
- : VideoLayout.CENTER_REMOTE);
- }
- }
- }
-
- @Override
- protected void viewForModelAdded(
- ConferenceCallPeerRenderer callPeerPanel,
- CallPeer callPeer)
- {
- videoContainer.add(
- callPeerPanel.getComponent(),
- VideoLayout.CENTER_REMOTE);
- if ((callPeer != null)
- && (callPeerPanel instanceof ConferenceParticipantContainer))
- {
- addConferenceMemberContainers(
- (ConferenceParticipantContainer) callPeerPanel);
- }
- }
-
- @Override
- protected void viewForModelRemoved(
- ConferenceCallPeerRenderer callPeerPanel,
- CallPeer callPeer)
- {
- videoContainer.remove(callPeerPanel.getComponent());
- if ((callPeer != null)
- && (callPeerPanel instanceof ConferenceParticipantContainer))
- {
- removeConferenceMemberContainers(
- (ConferenceParticipantContainer) callPeerPanel,
- true);
- }
- }
-
- /**
- * Implements an AWT <tt>Component</tt> which contains the user interface
- * elements depicting a specific participant in the telephony conference
- * depicted by a <tt>VideoConferenceCallPanel</tt>.
- */
- private class ConferenceParticipantContainer
- extends TransparentPanel
- implements ConferenceCallPeerRenderer
- {
- /**
- * The list of <tt>ConferenceParticipantContainer</tt>s which represent
- * the <tt>ConferenceMember</tt>s of the participant represented by this
- * instance. Since a <tt>CallPeer</tt> may send the local peer/user
- * multiple videos without providing a way to associate a
- * ConferenceMember with each one of them, the list may contain
- * <tt>ConferenceParticipantContainer</tt>s which do not represent a
- * specific <tt>ConferenceMember</tt> instance but rather a video sent
- * by a <tt>CallPeer</tt> to the local peer/user which looks like (in
- * the terms of <tt>VideoConferenceCallPanel) a member of a conference
- * organized by the <tt>CallPeer</tt> in question.
- * <p>
- * Implements a state which is private to
- * <tt>VideoConferenceCallPanel</tt> and is of no concern to
- * <tt>ConferenceParticipantContainer</tt>.
- * </p>
- */
- List<ConferenceParticipantContainer> conferenceMemberContainers;
-
- /**
- * The indicator which determines whether this instance is to be removed
- * because it has become out-of-date, obsolete, unnecessary.
- * <p>
- * Implements a state which is private to
- * <tt>VideoConferenceCallPanel</tt> and is of no concern to
- * <tt>ConferenceParticipantContainer</tt>.
- * </p>
- */
- boolean toBeRemoved;
-
- /**
- * The <tt>BasicConferenceParticipantPanel</tt> which is displayed at
- * the bottom of this instance, bellow the {@link #video} (i.e.
- * {@link #videoContainer}) and is referred to as the tool bar.
- */
- private final BasicConferenceParticipantPanel<?> toolBar;
-
- /**
- * The visual <tt>Component</tt>, if any, displaying video which is
- * depicted by this instance.
- */
- private Component video;
-
- /**
- * The <tt>VideoContainer</tt> which lays out the video depicted by this
- * instance i.e. {@link #video}.
- */
- private final VideoContainer videoContainer;
-
- /**
- * The <tt>CallPeer</tt> associated with this container, if it has been
- * created to represent a <tt>CallPeer</tt>.
- */
- private CallPeer callPeer;
-
- /**
- * The <tt>conferenceMember</tt> associated with this container, if it
- * has been created to represent a <tt>conferenceMember</tt>.
- */
- private ConferenceMember conferenceMember;
-
- /**
- * Indicates that this container contains information for the local
- * user.
- */
- private boolean isLocalUser;
-
- /**
- * Initializes a new <tt>ConferenceParticipantContainer</tt> instance
- * which is to depict the local peer/user.
- *
- * @param call a <tt>Call</tt> which is to provide information about the
- * local peer/user
- * @param video the visual <tt>Component</tt>, if any, displaying the
- * video streaming from the local peer/user to the remote peer(s)
- */
- public ConferenceParticipantContainer(Call call, Component video)
- {
- this(
- createDefaultPhotoPanel(call),
- video,
- new ConferencePeerPanel(
- VideoConferenceCallPanel.this,
- call,
- true),
- null, null, true);
- }
-
- public ConferenceParticipantContainer(
- CallPeer callPeer,
- Component video)
- {
- this( createDefaultPhotoPanel(callPeer),
- video,
- new ConferencePeerPanel(
- VideoConferenceCallPanel.this,
- callPeer,
- true),
- callPeer, null, false);
- }
-
- private ConferenceParticipantContainer(
- Component noVideo,
- Component video,
- BasicConferenceParticipantPanel<?> toolBar,
- CallPeer callPeer,
- ConferenceMember conferenceMember,
- boolean isLocalUser)
- {
- super(new BorderLayout());
-
- this.callPeer = callPeer;
- this.conferenceMember = conferenceMember;
- this.isLocalUser = isLocalUser;
-
- videoContainer = new VideoContainer(noVideo, false);
- add(videoContainer, BorderLayout.CENTER);
-
- this.toolBar = toolBar;
- if (this.toolBar != null)
- add(this.toolBar, BorderLayout.SOUTH);
-
- if (video != null)
- {
- setVideo(video);
- }
- else
- setVisible(false);
- }
-
- public ConferenceParticipantContainer(
- ConferenceMember conferenceMember,
- Component video)
- {
- this(
- createDefaultPhotoPanel(conferenceMember),
- video,
- new ConferenceMemberPanel(
- VideoConferenceCallPanel.this,
- conferenceMember,
- true),
- null, conferenceMember, false);
- }
-
- public void dispose()
- {
- ConferenceCallPeerRenderer delegate
- = getConferenceCallPeerRendererDelegate();
-
- if (delegate != null)
- delegate.dispose();
-
- // Dispose of the conferenceMemberContainers if any.
- /*
- * XXX The field conferenceMemberContainers implements a state
- * private to VideoConferenceCallPanel which the latter makes sure
- * to access on the AWT event dispatching thread only. Since we are
- * going out of our way here to help VideoConferenceCallPanel,
- * ensure that the mentioned synchronization rule is not violated.
- */
- CallManager.assertIsEventDispatchingThread();
- if (conferenceMemberContainers != null)
- {
- for (ConferenceParticipantContainer cmc
- : conferenceMemberContainers)
- {
- cmc.dispose();
- }
- }
- }
-
- public CallPanel getCallPanel()
- {
- return getCallRenderer().getCallContainer();
- }
-
- public SwingCallRenderer getCallRenderer()
- {
- return VideoConferenceCallPanel.this;
- }
-
- public Component getComponent()
- {
- return this;
- }
-
- private ConferenceCallPeerRenderer
- getConferenceCallPeerRendererDelegate()
- {
- return
- (toolBar instanceof ConferenceCallPeerRenderer)
- ? (ConferenceCallPeerRenderer) toolBar
- : null;
- }
-
- /**
- * Gets the conference participant depicted by this instance.
- *
- * @return the conference participant depicted by this instance
- */
- public Object getParticipant()
- {
- return (toolBar == null) ? null : toolBar.getParticipant();
- }
-
- public Component getVideo()
- {
- return video;
- }
-
- /**
- * {@inheritDoc}
- *
- * Delegates to the <tt>toolBar</tt>, if the latter implements
- * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
- * container only. Otherwise, returns <tt>false</tt>.
- */
- public boolean isLocalVideoVisible()
- {
- ConferenceCallPeerRenderer delegate
- = getConferenceCallPeerRendererDelegate();
-
- return (delegate == null) ? false : delegate.isLocalVideoVisible();
- }
-
- /**
- * {@inheritDoc}
- *
- * Delegates to the <tt>toolBar</tt>, if the latter implements
- * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
- * container only.
- */
- public void printDTMFTone(char dtmfChar)
- {
- ConferenceCallPeerRenderer delegate
- = getConferenceCallPeerRendererDelegate();
-
- if (delegate != null)
- delegate.printDTMFTone(dtmfChar);
- }
-
- /**
- * {@inheritDoc}
- *
- * Delegates to the <tt>toolBar</tt>, if the latter implements
- * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
- * container only.
- */
- public void securityNegotiationStarted(
- CallPeerSecurityNegotiationStartedEvent ev)
- {
- ConferenceCallPeerRenderer delegate
- = getConferenceCallPeerRendererDelegate();
-
- if (delegate != null)
- delegate.securityNegotiationStarted(ev);
- }
-
- /**
- * {@inheritDoc}
- *
- * Delegates to the <tt>toolBar</tt>, if the latter implements
- * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
- * container only.
- */
- public void securityOff(CallPeerSecurityOffEvent ev)
- {
- ConferenceCallPeerRenderer delegate
- = getConferenceCallPeerRendererDelegate();
-
- if (delegate != null)
- delegate.securityOff(ev);
- }
-
- /**
- * {@inheritDoc}
- *
- * Delegates to the <tt>toolBar</tt>, if the latter implements
- * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
- * container only.
- */
- public void securityOn(CallPeerSecurityOnEvent ev)
- {
- ConferenceCallPeerRenderer delegate
- = getConferenceCallPeerRendererDelegate();
-
- if (delegate != null)
- delegate.securityOn(ev);
- }
-
- /**
- * {@inheritDoc}
- *
- * Delegates to the <tt>toolBar</tt>, if the latter implements
- * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
- * container only.
- */
- public void securityPending()
- {
- ConferenceCallPeerRenderer delegate
- = getConferenceCallPeerRendererDelegate();
-
- if (delegate != null)
- delegate.securityPending();
- }
-
- /**
- * {@inheritDoc}
- *
- * Delegates to the <tt>toolBar</tt>, if the latter implements
- * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
- * container only.
- */
- public void securityTimeout(CallPeerSecurityTimeoutEvent ev)
- {
- ConferenceCallPeerRenderer delegate
- = getConferenceCallPeerRendererDelegate();
-
- if (delegate != null)
- delegate.securityTimeout(ev);
- }
-
- /**
- * {@inheritDoc}
- *
- * Delegates to the <tt>toolBar</tt>, if the latter implements
- * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
- * container only.
- */
- public void setErrorReason(String reason)
- {
- ConferenceCallPeerRenderer delegate
- = getConferenceCallPeerRendererDelegate();
-
- if (delegate != null)
- delegate.setErrorReason(reason);
- }
-
- /**
- * {@inheritDoc}
- *
- * Delegates to the <tt>toolBar</tt>, if the latter implements
- * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
- * container only.
- */
- public void setLocalVideoVisible(boolean visible)
- {
- ConferenceCallPeerRenderer delegate
- = getConferenceCallPeerRendererDelegate();
-
- if (delegate != null)
- delegate.setLocalVideoVisible(visible);
- }
-
- /**
- * {@inheritDoc}
- *
- * Delegates to the <tt>toolBar</tt>, if the latter implements
- * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
- * container only.
- */
- public void setMute(boolean mute)
- {
- ConferenceCallPeerRenderer delegate
- = getConferenceCallPeerRendererDelegate();
-
- if (delegate != null)
- delegate.setMute(mute);
- }
-
- /**
- * {@inheritDoc}
- *
- * Delegates to the <tt>toolBar</tt>, if the latter implements
- * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
- * container only.
- */
- public void setOnHold(boolean onHold)
- {
- ConferenceCallPeerRenderer delegate
- = getConferenceCallPeerRendererDelegate();
-
- if (delegate != null)
- delegate.setOnHold(onHold);
- }
-
- /**
- * {@inheritDoc}
- *
- * Delegates to the <tt>toolBar</tt>, if the latter implements
- * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
- * container only.
- */
- public void setPeerImage(byte[] image)
- {
- ConferenceCallPeerRenderer delegate
- = getConferenceCallPeerRendererDelegate();
-
- if (delegate != null)
- delegate.setPeerImage(image);
- }
-
- /**
- * {@inheritDoc}
- *
- * Delegates to the <tt>toolBar</tt>, if the latter implements
- * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
- * container only.
- */
- public void setPeerName(String name)
- {
- ConferenceCallPeerRenderer delegate
- = getConferenceCallPeerRendererDelegate();
-
- if (delegate != null)
- delegate.setPeerName(name);
- }
-
- /**
- * {@inheritDoc}
- *
- * Delegates to the <tt>toolBar</tt>, if the latter implements
- * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
- * container only.
- */
- public void setPeerState(
- CallPeerState oldState,
- CallPeerState newState,
- String stateString)
- {
- ConferenceCallPeerRenderer delegate
- = getConferenceCallPeerRendererDelegate();
-
- if (delegate != null)
- delegate.setPeerState(oldState, newState, stateString);
- }
-
- /**
- * {@inheritDoc}
- *
- * Delegates to the <tt>toolBar</tt>, if the latter implements
- * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
- * container only.
- */
- public void setSecurityPanelVisible(boolean visible)
- {
- ConferenceCallPeerRenderer delegate
- = getConferenceCallPeerRendererDelegate();
-
- if (delegate != null)
- delegate.setSecurityPanelVisible(visible);
- }
-
- /**
- * Sets the visual <tt>Component</tt> displaying the video associated
- * with the participant depicted by this instance.
- *
- * @param video the visual <tt>Component</tt> displaying video which is
- * to be associated with the participant depicted by this instance
- */
- void setVideo(Component video)
- {
- if (this.video != video)
- {
- if (this.video != null)
- videoContainer.remove(this.video);
-
- this.video = video;
-
- if (this.video != null)
- {
- setVisible(true);
- videoContainer.add(this.video, VideoLayout.CENTER_REMOTE);
- }
- else
- setVisible(false);
-
- // Update thumbnails container according to video status.
- if (thumbnailContainer != null)
- {
- if (conferenceMember != null)
- thumbnailContainer
- .updateThumbnail(conferenceMember, (video != null));
- else if (callPeer != null)
- thumbnailContainer
- .updateThumbnail(callPeer, (video != null));
- else if (isLocalUser)
- thumbnailContainer
- .updateThumbnail((video != null));
- }
- }
- }
- }
-}
+package net.java.sip.communicator.impl.gui.main.call.conference;
+
+import java.awt.*;
+import java.util.*;
+import java.util.List;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.impl.gui.main.call.*;
+import net.java.sip.communicator.impl.gui.utils.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.util.*;
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.plugin.desktoputil.TransparentPanel;
+
+import org.jitsi.util.swing.*;
+
+/**
+ * Extends <tt>BasicConferenceCallPanel</tt> to implement a user interface
+ * <tt>Component</tt> which depicts a <tt>CallConference</tt> with audio and
+ * video and is contained in a <tt>CallPanel</tt>.
+ *
+ * @author Yana Stamcheva
+ * @author Lyubomir Marinov
+ */
+public class VideoConferenceCallPanel
+ extends BasicConferenceCallPanel
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>VideoConferenceCallPanel</tt> class
+ * and its instances for logging output.
+ */
+ private static final Logger logger
+ = Logger.getLogger(VideoConferenceCallPanel.class);
+
+ /**
+ * The compile-time flag which indicates whether each video displayed by
+ * <tt>VideoConferenceCallPanel</tt> is to be depicted with an associated
+ * tool bar showing information and controls related to the (local or
+ * remote) peer sending the respective video.
+ */
+ private static final boolean SHOW_TOOLBARS = true;
+
+ /**
+ * The facility which aids this instance with the video-related information.
+ */
+ private final UIVideoHandler2 uiVideoHandler;
+
+ /**
+ * The <tt>Observer</tt> which listens to {@link #uiVideoHandler} about
+ * changes in the video-related information.
+ */
+ private final Observer uiVideoHandlerObserver
+ = new Observer()
+ {
+ public void update(Observable o, Object arg)
+ {
+ updateViewFromModel();
+ }
+ };
+
+ /**
+ * The <tt>VideoContainer</tt> which occupies this whole <tt>Component</tt>
+ * and arranges the visual <tt>Component</tt>s displaying the video
+ * streaming between the local peer/user and the remote peer(s).
+ */
+ private final VideoContainer videoContainer;
+
+ /**
+ * The set of visual <tt>Component</tt>s displaying video streaming between
+ * the local peer/user and the remote peers which are depicted by this
+ * instance.
+ */
+ private final Set<Component> videos = new HashSet<Component>();
+
+ /**
+ * The thumbnail container.
+ */
+ private final ThumbnailConferenceCallPanel thumbnailContainer;
+
+ private final JPanel thumbnailPanel;
+
+ /**
+ * Initializes a new <tt>VideoConferenceCallPanel</tt> instance which is to
+ * be used by a specific <tt>CallPanel</tt> to depict a specific
+ * <tt>CallConference</tt>. The new instance will depict both the
+ * audio-related and the video-related information.
+ *
+ * @param callPanel the <tt>CallPanel</tt> which will use the new instance
+ * to depict the specified <tt>CallConference</tt>.
+ * @param callConference the <tt>CallConference</tt> to be depicted by the
+ * new instance
+ * @param uiVideoHandler the utility which is to aid the new instance in
+ * dealing with the video-related information
+ */
+ public VideoConferenceCallPanel(
+ CallPanel callPanel,
+ CallConference callConference,
+ UIVideoHandler2 uiVideoHandler)
+ {
+ super(callPanel, callConference);
+
+ this.uiVideoHandler = uiVideoHandler;
+
+ thumbnailPanel = new JPanel(new BorderLayout());
+ thumbnailContainer
+ = new ThumbnailConferenceCallPanel( callPanel,
+ callConference,
+ uiVideoHandler);
+
+ videoContainer = createVideoContainer();
+
+ /*
+ * Our user interface hierarchy has been initialized so we are ready to
+ * begin receiving events warranting updates of this view from its
+ * model.
+ */
+ uiVideoHandler.addObserver(uiVideoHandlerObserver);
+
+ /*
+ * Notify the super that this instance has completed its initialization
+ * and the view that it implements is ready to be updated from the
+ * model.
+ */
+ initializeComplete();
+ }
+
+ private void addConferenceMemberContainers(
+ ConferenceParticipantContainer cpc)
+ {
+ List<ConferenceParticipantContainer> cmcs
+ = cpc.conferenceMemberContainers;
+
+ if ((cmcs != null) && !cmcs.isEmpty())
+ {
+ for (ConferenceParticipantContainer cmc : cmcs)
+ {
+ if (!cmc.toBeRemoved)
+ {
+ videoContainer.add(
+ cmc.getComponent(),
+ VideoLayout.CENTER_REMOTE);
+ }
+ }
+ }
+ }
+
+ private Component createDefaultPhotoPanel(Call call)
+ {
+ OperationSetServerStoredAccountInfo accountInfo
+ = call.getProtocolProvider().getOperationSet(
+ OperationSetServerStoredAccountInfo.class);
+ ImageIcon photoLabelIcon = null;
+
+ if (accountInfo != null)
+ {
+ byte[] accountImage = AccountInfoUtils.getImage(accountInfo);
+
+ // do not set empty images
+ if ((accountImage != null) && (accountImage.length > 0))
+ photoLabelIcon = new ImageIcon(accountImage);
+ }
+ if (photoLabelIcon == null)
+ {
+ photoLabelIcon
+ = new ImageIcon(
+ ImageLoader.getImage(ImageLoader.DEFAULT_USER_PHOTO));
+ }
+
+ return createDefaultPhotoPanel(photoLabelIcon);
+ }
+
+ private Component createDefaultPhotoPanel(CallPeer callPeer)
+ {
+ byte[] peerImage = CallManager.getPeerImage(callPeer);
+ ImageIcon photoLabelIcon
+ = (peerImage == null)
+ ? new ImageIcon(
+ ImageLoader.getImage(ImageLoader.DEFAULT_USER_PHOTO))
+ : new ImageIcon(peerImage);
+
+ return createDefaultPhotoPanel(photoLabelIcon);
+ }
+
+ private Component createDefaultPhotoPanel(ConferenceMember conferenceMember)
+ {
+ return
+ createDefaultPhotoPanel(
+ new ImageIcon(
+ ImageLoader.getImage(
+ ImageLoader.DEFAULT_USER_PHOTO)));
+ }
+
+ /**
+ * Creates a new <tt>Component</tt> which is to display a specific
+ * <tt>ImageIcon</tt> representing the photo of a participant in a call.
+ *
+ * @param photoLabelIcon the <tt>ImageIcon</tt> which represents the photo
+ * of a participant in a call and which is to be displayed by the new
+ * <tt>Component</tt>
+ * @return a new <tt>Component</tt> which displays the specified
+ * <tt>photoLabelIcon</tt>
+ */
+ private Component createDefaultPhotoPanel(ImageIcon photoLabelIcon)
+ {
+ JLabel photoLabel = new JLabel();
+
+ photoLabel.setIcon(photoLabelIcon);
+
+ @SuppressWarnings("serial")
+ JPanel photoPanel
+ = new TransparentPanel(new GridBagLayout())
+ {
+ /**
+ * @{inheritDoc}
+ */
+ @Override
+ public void paintComponent(Graphics g)
+ {
+ super.paintComponent(g);
+
+ g = g.create();
+ try
+ {
+ AntialiasingManager.activateAntialiasing(g);
+
+ g.setColor(Color.GRAY);
+ g.fillRoundRect(
+ 0, 0, this.getWidth(), this.getHeight(),
+ 6, 6);
+ }
+ finally
+ {
+ g.dispose();
+ }
+ }
+ };
+
+ photoPanel.setPreferredSize(new Dimension(320, 240));
+
+ GridBagConstraints photoPanelConstraints = new GridBagConstraints();
+
+ photoPanelConstraints.anchor = GridBagConstraints.CENTER;
+ photoPanelConstraints.fill = GridBagConstraints.NONE;
+ photoPanel.add(photoLabel, photoPanelConstraints);
+
+ return photoPanel;
+ }
+
+ /**
+ * Initializes a new <tt>VideoContainer</tt> instance which is to contain
+ * the visual/video <tt>Component</tt>s of the telephony conference depicted
+ * by this instance.
+ */
+ private VideoContainer createVideoContainer()
+ {
+ VideoContainer videoContainer = new VideoContainer(null, true);
+
+ thumbnailPanel.setBackground(Color.DARK_GRAY);
+ thumbnailPanel.add(thumbnailContainer, BorderLayout.NORTH);
+
+ add(thumbnailPanel, BorderLayout.EAST);
+ add(videoContainer, BorderLayout.CENTER);
+
+ return videoContainer;
+ }
+
+ /**
+ * Shows/hides the participants thumbnails list.
+ *
+ * @param show <tt>true</tt> to show the participants list, <tt>false</tt>
+ * to hide it
+ */
+ public void showThumbnailsList(boolean show)
+ {
+ thumbnailPanel.setVisible(show);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void dispose()
+ {
+ try
+ {
+ uiVideoHandler.deleteObserver(uiVideoHandlerObserver);
+ }
+ finally
+ {
+ super.dispose();
+ }
+ }
+
+ /**
+ * Determines whether a specific <tt>ConferenceMember</tt> represents the
+ * same conference participant as a specific <tt>CallPeer</tt>. If the
+ * specified <tt>conferenceMember</tt> is <tt>null</tt>, returns
+ * <tt>true</tt>. Otherwise, determines whether the addresses of the
+ * specified <tt>conferenceMember</tt> and the specified <tt>callPeer</tt>
+ * identify one and the same entity.
+ *
+ * @param conferenceMember the <tt>ConferenceMember</tt> to be checked
+ * whether is represents the same conference participant as the specified
+ * <tt>callPeer</tt>. If it is <tt>null</tt>, <tt>true</tt> is returned.
+ * @param callPeer the <tt>CallPeer</tt> to be checked whether it represents
+ * the same conference participant as the specified
+ * <tt>conferenceMember</tt>
+ * @return <tt>true</tt> if the specified <tt>conferenceMember</tt> and the
+ * specified <tt>callPeer</tt> represent the same conference participant or
+ * the specified <tt>conferenceMember</tt> is <tt>null</tt>; otherwise,
+ * <tt>false</tt>
+ */
+ private boolean isConferenceMemberCallPeer(
+ ConferenceMember conferenceMember,
+ CallPeer callPeer)
+ {
+ return
+ (conferenceMember == null)
+ ? true
+ : CallManager.addressesAreEqual(
+ conferenceMember.getAddress(),
+ callPeer.getAddress());
+ }
+
+ /**
+ * Determines whether a specific <tt>ConferenceMember</tt> represents the
+ * local peer/user. Since this instance depicts a whole telephony
+ * conference, the local peer/user may be participating with multiple
+ * <tt>Call</tt>s in it. The <tt>Call</tt>s may be through different
+ * (local) accounts. That's why the implementation determines whether the
+ * address of the specified <tt>conferenceMember</tt> identifies the address
+ * of a (local) accounts involved in the telephony conference depicted by
+ * this instance.
+ *
+ * @param conferenceMember the <tt>ConferenceMember</tt> to be checked
+ * whether it represents the local peer/user
+ * @return <tt>true</tt> if the specified <tt>conferenceMember</tt>
+ * represents the local peer/user; otherwise, <tt>false</tt>
+ */
+ private boolean isConferenceMemberLocalUser(
+ ConferenceMember conferenceMember)
+ {
+ String address = conferenceMember.getAddress();
+
+ for (Call call : callConference.getCalls())
+ {
+ if (CallManager.addressesAreEqual(
+ address,
+ call.getProtocolProvider().getAccountID()
+ .getAccountAddress()))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void removeConferenceMemberContainers(
+ ConferenceParticipantContainer cpc,
+ boolean all)
+ {
+ List<ConferenceParticipantContainer> cmcs
+ = cpc.conferenceMemberContainers;
+
+ if ((cmcs != null) && !cmcs.isEmpty())
+ {
+ Iterator<ConferenceParticipantContainer> i = cmcs.iterator();
+
+ while (i.hasNext())
+ {
+ ConferenceParticipantContainer cmc = i.next();
+
+ if (all || cmc.toBeRemoved)
+ {
+ i.remove();
+
+ videoContainer.remove(cmc.getComponent());
+ cmc.dispose();
+ }
+ }
+ }
+ }
+
+ /**
+ * Updates the <tt>ConferenceParticipantContainer</tt>s which depict the
+ * <tt>ConferenceMember</tt>s of the <tt>CallPeer</tt> depicted by a
+ * specific <tt>ConferenceParticipantContainer</tt>.
+ *
+ * @param cpc the <tt>ConferenceParticipantContainer</tt> which depicts the
+ * <tt>CallPeer</tt> whose <tt>ConferenceMember</tt>s are to be depicted
+ * @param videos the visual <tt>Component</tt>s displaying video streaming
+ * from the remote peer (represented by <tt>cpc</tt>) to the local peer/user
+ * @param videoTelephony the <tt>OperationSetVideoTelephony</tt> which
+ * retrieved the specified <tt>videos</tt> from the <tt>CallPeer</tt>
+ * depicted by <tt>cpc</tt>. While the <tt>CallPeer</tt> could be queried
+ * for it, such a query would waste more resources at run time given that
+ * the invoker has it already.
+ */
+ private void updateConferenceMemberContainers(
+ ConferenceParticipantContainer cpc,
+ List<Component> videos,
+ OperationSetVideoTelephony videoTelephony)
+ {
+ CallPeer callPeer = (CallPeer) cpc.getParticipant();
+ List<ConferenceParticipantContainer> cmcs
+ = cpc.conferenceMemberContainers;
+
+ /*
+ * Invalidate all conferenceMemberContainers. Then validate which of
+ * them are to remain and which of them are to really be removed
+ * later on.
+ */
+ if (cmcs != null)
+ {
+ for (ConferenceParticipantContainer cmc : cmcs)
+ cmc.toBeRemoved = true;
+ }
+
+ /*
+ * Depict the remote videos. They may or may not be associated with
+ * ConferenceMembers so the ConferenceMembers which have no
+ * associated videos will be depicted afterwards.
+ */
+ if (videos != null)
+ {
+ Component video = cpc.getVideo();
+
+ for (Component conferenceMemberVideo : videos)
+ {
+ /*
+ * One of the remote videos is already used to depict the
+ * callPeer.
+ */
+ if (conferenceMemberVideo == video)
+ continue;
+
+ boolean addNewConferenceParticipantContainer = true;
+ ConferenceMember conferenceMember
+ = videoTelephony.getConferenceMember(
+ callPeer,
+ conferenceMemberVideo);
+
+ if (cmcs == null)
+ {
+ cmcs = new LinkedList<ConferenceParticipantContainer>();
+ cpc.conferenceMemberContainers = cmcs;
+ }
+ else
+ {
+ for (ConferenceParticipantContainer cmc : cmcs)
+ {
+ Object cmcParticipant = cmc.getParticipant();
+
+ if (conferenceMember == null)
+ {
+ if (cmcParticipant == callPeer)
+ {
+ Component cmcVideo = cmc.getVideo();
+
+ if (cmcVideo == null)
+ {
+ cmc.setVideo(conferenceMemberVideo);
+ cmc.toBeRemoved = false;
+ addNewConferenceParticipantContainer
+ = false;
+ break;
+ }
+ else if (cmcVideo == conferenceMemberVideo)
+ {
+ cmc.toBeRemoved = false;
+ addNewConferenceParticipantContainer
+ = false;
+ break;
+ }
+ }
+ }
+ else if (cmcParticipant == conferenceMember)
+ {
+ cmc.setVideo(conferenceMemberVideo);
+ cmc.toBeRemoved = false;
+ addNewConferenceParticipantContainer = false;
+ break;
+ }
+ }
+ }
+
+ if (addNewConferenceParticipantContainer)
+ {
+ ConferenceParticipantContainer cmc
+ = (conferenceMember == null)
+ ? new ConferenceParticipantContainer(
+ callPeer,
+ conferenceMemberVideo)
+ : new ConferenceParticipantContainer(
+ conferenceMember,
+ conferenceMemberVideo);
+
+ cmcs.add(cmc);
+ }
+ }
+ }
+
+ /*
+ * Depict the ConferenceMembers which have not been depicted yet.
+ * They have no associated videos.
+ */
+ List<ConferenceMember> conferenceMembers
+ = callPeer.getConferenceMembers();
+
+ if (!conferenceMembers.isEmpty())
+ {
+ if (cmcs == null)
+ {
+ cmcs = new LinkedList<ConferenceParticipantContainer>();
+ cpc.conferenceMemberContainers = cmcs;
+ }
+ for (ConferenceMember conferenceMember : conferenceMembers)
+ {
+ /*
+ * If the callPeer reports itself as a ConferenceMember, then
+ * we've already depicted it with cpc.
+ */
+ if (isConferenceMemberCallPeer(conferenceMember, callPeer))
+ continue;
+ /*
+ * If the callPeer reports the local peer/user as a
+ * ConferenceMember, then we've already depicted it.
+ */
+ if (isConferenceMemberLocalUser(conferenceMember))
+ continue;
+
+ boolean addNewConferenceParticipantContainer = true;
+
+ for (ConferenceParticipantContainer cmc : cmcs)
+ {
+ if (cmc.getParticipant() == conferenceMember)
+ {
+ /*
+ * It is possible to have a ConferenceMember who is
+ * sending video but we just do not have the SSRC of
+ * that video to associate the video with the
+ * ConferenceMember. In such a case, we may be depicting
+ * the ConferenceMember twice: once with video without a
+ * ConferenceMember and once with a ConferenceMember
+ * without video. This will surely be the case at the
+ * time of this writing with non-focus participants in a
+ * telephony conference hosted on a Jitsi Videobridge.
+ * Such a display is undesirable. If the
+ * conferenceMember is known to send video, we will not
+ * display it until we associated it with a video. This
+ * way, if a ConferenceMember is not sending video, we
+ * will depict it and we can be sure that no video
+ * without a ConferenceMember association will be
+ * depicting it a second time.
+ */
+ if (cmc.toBeRemoved
+ && !conferenceMember
+ .getVideoStatus()
+ .allowsSending())
+ {
+ cmc.setVideo(null);
+ cmc.toBeRemoved = false;
+ }
+ addNewConferenceParticipantContainer = false;
+ break;
+ }
+ }
+
+ if (addNewConferenceParticipantContainer)
+ {
+ ConferenceParticipantContainer cmc
+ = new ConferenceParticipantContainer(
+ conferenceMember,
+ null);
+
+ cmcs.add(cmc);
+ }
+ }
+ }
+
+ if ((cmcs != null) && !cmcs.isEmpty())
+ {
+ removeConferenceMemberContainers(cpc, false);
+ /*
+ * If cpc is already added to the user interface hierarchy of this
+ * instance, then it was there before the update procedure and it
+ * was determined to be appropriate to continue to depict its model.
+ * Consequently, its Component will be neither added to (because it
+ * was already added) nor removed from the user interface hierarchy
+ * of this instance. That's why we have make sure that the
+ * Components of its conferenceMemberContainers are also added to
+ * the user interface.
+ */
+ if (UIVideoHandler2.isAncestor(this, cpc.getComponent()))
+ addConferenceMemberContainers(cpc);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected ConferenceCallPeerRenderer updateViewFromModel(
+ ConferenceCallPeerRenderer callPeerPanel,
+ CallPeer callPeer)
+ {
+ if (callPeer == null)
+ {
+ /*
+ * The local peer/user will be represented by a Call which has a
+ * CallPeer who provides local video. However, if the user has
+ * selected to hide the local video, the local peer/user will not be
+ * represented at all.
+ */
+ Component video = null;
+
+ if (uiVideoHandler.isLocalVideoVisible())
+ {
+ for (Call aCall : callConference.getCalls())
+ {
+ Iterator<? extends CallPeer> callPeerIter
+ = aCall.getCallPeers();
+ OperationSetVideoTelephony videoTelephony
+ = aCall.getProtocolProvider().getOperationSet(
+ OperationSetVideoTelephony.class);
+
+ while (callPeerIter.hasNext())
+ {
+ callPeer = callPeerIter.next();
+
+ if (videoTelephony != null)
+ {
+ try
+ {
+ video
+ = videoTelephony.getLocalVisualComponent(
+ callPeer);
+ }
+ catch (OperationFailedException ofe)
+ {
+ logger.error(
+ "Failed to retrieve the local video"
+ + " for display",
+ ofe);
+ }
+ if (video != null)
+ break;
+ }
+ }
+ if (video != null)
+ break;
+ }
+ }
+
+ if (callPeer == null)
+ callPeerPanel = null;
+ else
+ {
+ Call call = callPeer.getCall();
+
+ if (callPeerPanel instanceof ConferenceParticipantContainer)
+ {
+ ConferenceParticipantContainer cpc
+ = (ConferenceParticipantContainer) callPeerPanel;
+
+ if (cpc.getParticipant() == call)
+ cpc.setVideo(video);
+ else
+ callPeerPanel = null;
+ }
+ else
+ callPeerPanel = null;
+ if (callPeerPanel == null)
+ {
+ callPeerPanel
+ = new ConferenceParticipantContainer(call, video);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * The specified callPeer will be represented by one of its remote
+ * videos which is not associated with a ConferenceMember or is
+ * associated with a ConferenceMember representing the callPeer
+ * itself.
+ */
+ OperationSetVideoTelephony videoTelephony
+ = callPeer.getProtocolProvider().getOperationSet(
+ OperationSetVideoTelephony.class);
+ List<Component> videos = null;
+ Component video = null;
+
+ if (videoTelephony != null)
+ {
+ videos = videoTelephony.getVisualComponents(callPeer);
+ if ((videos != null) && !videos.isEmpty())
+ {
+ for (Component aVideo : videos)
+ {
+ ConferenceMember conferenceMember
+ = videoTelephony.getConferenceMember(
+ callPeer,
+ aVideo);
+
+ if (isConferenceMemberCallPeer(
+ conferenceMember,
+ callPeer))
+ {
+ video = aVideo;
+ break;
+ }
+ }
+ }
+ }
+
+ ConferenceParticipantContainer cpc = null;
+
+ if (callPeerPanel instanceof ConferenceParticipantContainer)
+ {
+ cpc = (ConferenceParticipantContainer) callPeerPanel;
+ if (cpc.getParticipant() == callPeer)
+ cpc.setVideo(video);
+ else
+ cpc = null;
+ }
+ if (cpc == null)
+ cpc = new ConferenceParticipantContainer(callPeer, video);
+ callPeerPanel = cpc;
+
+ // Update the conferenceMemberContainers of the cpc.
+ updateConferenceMemberContainers(cpc, videos, videoTelephony);
+ }
+ return callPeerPanel;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * If {@link #SHOW_TOOLBARS} is <tt>false</tt>, disables the use of
+ * <tt>ConferenceParticipantContainer</tt>. A reason for such a value of
+ * <tt>SHOW_TOOLBARS</tt> may be that the functionality implemented in the
+ * model may not fully support mapping of visual <tt>Component</tt>s
+ * displaying video to telephony conference participants (e.g. in telephony
+ * conferences utilizing the Jitsi Videobridge server-side technology). In
+ * such a case displays the videos only, does not map videos to participants
+ * and does not display participants who do not have videos.
+ */
+ @Override
+ protected void updateViewFromModelInEventDispatchThread()
+ {
+ if (SHOW_TOOLBARS)
+ {
+ super.updateViewFromModelInEventDispatchThread();
+ return;
+ }
+
+ /*
+ * Determine the set of visual Components displaying video streaming
+ * between the local peer/user and the remote peers which are to be
+ * depicted by this instance.
+ */
+ Component localVideo = null;
+ Set<Component> videos = new HashSet<Component>();
+
+ for (Call call : callConference.getCalls())
+ {
+ OperationSetVideoTelephony videoTelephony
+ = call.getProtocolProvider().getOperationSet(
+ OperationSetVideoTelephony.class);
+
+ if (videoTelephony == null)
+ continue;
+
+ Iterator<? extends CallPeer> callPeerIter = call.getCallPeers();
+
+ while (callPeerIter.hasNext())
+ {
+ CallPeer callPeer = callPeerIter.next();
+
+ /*
+ * TODO VideoConferenceCallPanel respects
+ * UIVideoHandler2.isLocalVideoVisible() in order to react to
+ * the associated button at the bottom of the CallPanel.
+ * However, it does not add a close button on top of the local
+ * video in contrast to OneToOneCallPeerPanel. Overall, the
+ * result is questionable.
+ */
+ if (uiVideoHandler.isLocalVideoVisible()
+ && (localVideo == null))
+ {
+ try
+ {
+ localVideo
+ = videoTelephony.getLocalVisualComponent(callPeer);
+ }
+ catch (OperationFailedException ofe)
+ {
+ /*
+ * We'll just try to get the local video through another
+ * CallPeer then.
+ */
+ }
+ if (localVideo != null)
+ videos.add(localVideo);
+ }
+
+ List<Component> callPeerRemoteVideos
+ = videoTelephony.getVisualComponents(callPeer);
+
+ videos.addAll(callPeerRemoteVideos);
+ }
+ }
+
+ /*
+ * Remove the Components of this view which are no longer present in the
+ * model.
+ */
+ Iterator<Component> thisVideoIter = this.videos.iterator();
+
+ while (thisVideoIter.hasNext())
+ {
+ Component thisVideo = thisVideoIter.next();
+
+ if (!videos.contains(thisVideo))
+ {
+ thisVideoIter.remove();
+ videoContainer.remove(thisVideo);
+ }
+
+ /*
+ * If a video is known to be depicted by this view and is still
+ * present in the model, then we could remove it from the set of
+ * videos present in the model in order to prevent going through the
+ * procedure of adding it to this view. However, we choose to play
+ * on the safe side.
+ */
+ }
+
+ /*
+ * Add the Components of the model which are not depicted by this view.
+ */
+ for (Component video : videos)
+ {
+ if (!UIVideoHandler2.isAncestor(videoContainer, video))
+ {
+ this.videos.add(video);
+ videoContainer.add(
+ video,
+ (video == localVideo)
+ ? VideoLayout.LOCAL
+ : VideoLayout.CENTER_REMOTE);
+ }
+ }
+ }
+
+ @Override
+ protected void viewForModelAdded(
+ ConferenceCallPeerRenderer callPeerPanel,
+ CallPeer callPeer)
+ {
+ videoContainer.add(
+ callPeerPanel.getComponent(),
+ VideoLayout.CENTER_REMOTE);
+ if ((callPeer != null)
+ && (callPeerPanel instanceof ConferenceParticipantContainer))
+ {
+ addConferenceMemberContainers(
+ (ConferenceParticipantContainer) callPeerPanel);
+ }
+ }
+
+ @Override
+ protected void viewForModelRemoved(
+ ConferenceCallPeerRenderer callPeerPanel,
+ CallPeer callPeer)
+ {
+ videoContainer.remove(callPeerPanel.getComponent());
+ if ((callPeer != null)
+ && (callPeerPanel instanceof ConferenceParticipantContainer))
+ {
+ removeConferenceMemberContainers(
+ (ConferenceParticipantContainer) callPeerPanel,
+ true);
+ }
+ }
+
+ /**
+ * Implements an AWT <tt>Component</tt> which contains the user interface
+ * elements depicting a specific participant in the telephony conference
+ * depicted by a <tt>VideoConferenceCallPanel</tt>.
+ */
+ private class ConferenceParticipantContainer
+ extends TransparentPanel
+ implements ConferenceCallPeerRenderer
+ {
+ /**
+ * The list of <tt>ConferenceParticipantContainer</tt>s which represent
+ * the <tt>ConferenceMember</tt>s of the participant represented by this
+ * instance. Since a <tt>CallPeer</tt> may send the local peer/user
+ * multiple videos without providing a way to associate a
+ * ConferenceMember with each one of them, the list may contain
+ * <tt>ConferenceParticipantContainer</tt>s which do not represent a
+ * specific <tt>ConferenceMember</tt> instance but rather a video sent
+ * by a <tt>CallPeer</tt> to the local peer/user which looks like (in
+ * the terms of <tt>VideoConferenceCallPanel) a member of a conference
+ * organized by the <tt>CallPeer</tt> in question.
+ * <p>
+ * Implements a state which is private to
+ * <tt>VideoConferenceCallPanel</tt> and is of no concern to
+ * <tt>ConferenceParticipantContainer</tt>.
+ * </p>
+ */
+ List<ConferenceParticipantContainer> conferenceMemberContainers;
+
+ /**
+ * The indicator which determines whether this instance is to be removed
+ * because it has become out-of-date, obsolete, unnecessary.
+ * <p>
+ * Implements a state which is private to
+ * <tt>VideoConferenceCallPanel</tt> and is of no concern to
+ * <tt>ConferenceParticipantContainer</tt>.
+ * </p>
+ */
+ boolean toBeRemoved;
+
+ /**
+ * The <tt>BasicConferenceParticipantPanel</tt> which is displayed at
+ * the bottom of this instance, bellow the {@link #video} (i.e.
+ * {@link #videoContainer}) and is referred to as the tool bar.
+ */
+ private final BasicConferenceParticipantPanel<?> toolBar;
+
+ /**
+ * The visual <tt>Component</tt>, if any, displaying video which is
+ * depicted by this instance.
+ */
+ private Component video;
+
+ /**
+ * The <tt>VideoContainer</tt> which lays out the video depicted by this
+ * instance i.e. {@link #video}.
+ */
+ private final VideoContainer videoContainer;
+
+ /**
+ * The <tt>CallPeer</tt> associated with this container, if it has been
+ * created to represent a <tt>CallPeer</tt>.
+ */
+ private CallPeer callPeer;
+
+ /**
+ * The <tt>conferenceMember</tt> associated with this container, if it
+ * has been created to represent a <tt>conferenceMember</tt>.
+ */
+ private ConferenceMember conferenceMember;
+
+ /**
+ * Indicates that this container contains information for the local
+ * user.
+ */
+ private boolean isLocalUser;
+
+ /**
+ * Initializes a new <tt>ConferenceParticipantContainer</tt> instance
+ * which is to depict the local peer/user.
+ *
+ * @param call a <tt>Call</tt> which is to provide information about the
+ * local peer/user
+ * @param video the visual <tt>Component</tt>, if any, displaying the
+ * video streaming from the local peer/user to the remote peer(s)
+ */
+ public ConferenceParticipantContainer(Call call, Component video)
+ {
+ this(
+ createDefaultPhotoPanel(call),
+ video,
+ new ConferencePeerPanel(
+ VideoConferenceCallPanel.this,
+ call,
+ true),
+ null, null, true);
+ }
+
+ public ConferenceParticipantContainer(
+ CallPeer callPeer,
+ Component video)
+ {
+ this( createDefaultPhotoPanel(callPeer),
+ video,
+ new ConferencePeerPanel(
+ VideoConferenceCallPanel.this,
+ callPeer,
+ true),
+ callPeer, null, false);
+ }
+
+ private ConferenceParticipantContainer(
+ Component noVideo,
+ Component video,
+ BasicConferenceParticipantPanel<?> toolBar,
+ CallPeer callPeer,
+ ConferenceMember conferenceMember,
+ boolean isLocalUser)
+ {
+ super(new BorderLayout());
+
+ this.callPeer = callPeer;
+ this.conferenceMember = conferenceMember;
+ this.isLocalUser = isLocalUser;
+
+ videoContainer = new VideoContainer(noVideo, false);
+ add(videoContainer, BorderLayout.CENTER);
+
+ this.toolBar = toolBar;
+ if (this.toolBar != null)
+ add(this.toolBar, BorderLayout.SOUTH);
+
+ if (video != null)
+ {
+ setVideo(video);
+ }
+ else
+ setVisible(false);
+ }
+
+ public ConferenceParticipantContainer(
+ ConferenceMember conferenceMember,
+ Component video)
+ {
+ this(
+ createDefaultPhotoPanel(conferenceMember),
+ video,
+ new ConferenceMemberPanel(
+ VideoConferenceCallPanel.this,
+ conferenceMember,
+ true),
+ null, conferenceMember, false);
+ }
+
+ public void dispose()
+ {
+ ConferenceCallPeerRenderer delegate
+ = getConferenceCallPeerRendererDelegate();
+
+ if (delegate != null)
+ delegate.dispose();
+
+ // Dispose of the conferenceMemberContainers if any.
+ /*
+ * XXX The field conferenceMemberContainers implements a state
+ * private to VideoConferenceCallPanel which the latter makes sure
+ * to access on the AWT event dispatching thread only. Since we are
+ * going out of our way here to help VideoConferenceCallPanel,
+ * ensure that the mentioned synchronization rule is not violated.
+ */
+ CallManager.assertIsEventDispatchingThread();
+ if (conferenceMemberContainers != null)
+ {
+ for (ConferenceParticipantContainer cmc
+ : conferenceMemberContainers)
+ {
+ cmc.dispose();
+ }
+ }
+ }
+
+ public CallPanel getCallPanel()
+ {
+ return getCallRenderer().getCallContainer();
+ }
+
+ public SwingCallRenderer getCallRenderer()
+ {
+ return VideoConferenceCallPanel.this;
+ }
+
+ public Component getComponent()
+ {
+ return this;
+ }
+
+ private ConferenceCallPeerRenderer
+ getConferenceCallPeerRendererDelegate()
+ {
+ return
+ (toolBar instanceof ConferenceCallPeerRenderer)
+ ? (ConferenceCallPeerRenderer) toolBar
+ : null;
+ }
+
+ /**
+ * Gets the conference participant depicted by this instance.
+ *
+ * @return the conference participant depicted by this instance
+ */
+ public Object getParticipant()
+ {
+ return (toolBar == null) ? null : toolBar.getParticipant();
+ }
+
+ public Component getVideo()
+ {
+ return video;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Delegates to the <tt>toolBar</tt>, if the latter implements
+ * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
+ * container only. Otherwise, returns <tt>false</tt>.
+ */
+ public boolean isLocalVideoVisible()
+ {
+ ConferenceCallPeerRenderer delegate
+ = getConferenceCallPeerRendererDelegate();
+
+ return (delegate == null) ? false : delegate.isLocalVideoVisible();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Delegates to the <tt>toolBar</tt>, if the latter implements
+ * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
+ * container only.
+ */
+ public void printDTMFTone(char dtmfChar)
+ {
+ ConferenceCallPeerRenderer delegate
+ = getConferenceCallPeerRendererDelegate();
+
+ if (delegate != null)
+ delegate.printDTMFTone(dtmfChar);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Delegates to the <tt>toolBar</tt>, if the latter implements
+ * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
+ * container only.
+ */
+ public void securityNegotiationStarted(
+ CallPeerSecurityNegotiationStartedEvent ev)
+ {
+ ConferenceCallPeerRenderer delegate
+ = getConferenceCallPeerRendererDelegate();
+
+ if (delegate != null)
+ delegate.securityNegotiationStarted(ev);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Delegates to the <tt>toolBar</tt>, if the latter implements
+ * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
+ * container only.
+ */
+ public void securityOff(CallPeerSecurityOffEvent ev)
+ {
+ ConferenceCallPeerRenderer delegate
+ = getConferenceCallPeerRendererDelegate();
+
+ if (delegate != null)
+ delegate.securityOff(ev);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Delegates to the <tt>toolBar</tt>, if the latter implements
+ * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
+ * container only.
+ */
+ public void securityOn(CallPeerSecurityOnEvent ev)
+ {
+ ConferenceCallPeerRenderer delegate
+ = getConferenceCallPeerRendererDelegate();
+
+ if (delegate != null)
+ delegate.securityOn(ev);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Delegates to the <tt>toolBar</tt>, if the latter implements
+ * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
+ * container only.
+ */
+ public void securityPending()
+ {
+ ConferenceCallPeerRenderer delegate
+ = getConferenceCallPeerRendererDelegate();
+
+ if (delegate != null)
+ delegate.securityPending();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Delegates to the <tt>toolBar</tt>, if the latter implements
+ * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
+ * container only.
+ */
+ public void securityTimeout(CallPeerSecurityTimeoutEvent ev)
+ {
+ ConferenceCallPeerRenderer delegate
+ = getConferenceCallPeerRendererDelegate();
+
+ if (delegate != null)
+ delegate.securityTimeout(ev);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Delegates to the <tt>toolBar</tt>, if the latter implements
+ * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
+ * container only.
+ */
+ public void setErrorReason(String reason)
+ {
+ ConferenceCallPeerRenderer delegate
+ = getConferenceCallPeerRendererDelegate();
+
+ if (delegate != null)
+ delegate.setErrorReason(reason);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Delegates to the <tt>toolBar</tt>, if the latter implements
+ * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
+ * container only.
+ */
+ public void setLocalVideoVisible(boolean visible)
+ {
+ ConferenceCallPeerRenderer delegate
+ = getConferenceCallPeerRendererDelegate();
+
+ if (delegate != null)
+ delegate.setLocalVideoVisible(visible);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Delegates to the <tt>toolBar</tt>, if the latter implements
+ * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
+ * container only.
+ */
+ public void setMute(boolean mute)
+ {
+ ConferenceCallPeerRenderer delegate
+ = getConferenceCallPeerRendererDelegate();
+
+ if (delegate != null)
+ delegate.setMute(mute);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Delegates to the <tt>toolBar</tt>, if the latter implements
+ * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
+ * container only.
+ */
+ public void setOnHold(boolean onHold)
+ {
+ ConferenceCallPeerRenderer delegate
+ = getConferenceCallPeerRendererDelegate();
+
+ if (delegate != null)
+ delegate.setOnHold(onHold);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Delegates to the <tt>toolBar</tt>, if the latter implements
+ * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
+ * container only.
+ */
+ public void setPeerImage(byte[] image)
+ {
+ ConferenceCallPeerRenderer delegate
+ = getConferenceCallPeerRendererDelegate();
+
+ if (delegate != null)
+ delegate.setPeerImage(image);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Delegates to the <tt>toolBar</tt>, if the latter implements
+ * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
+ * container only.
+ */
+ public void setPeerName(String name)
+ {
+ ConferenceCallPeerRenderer delegate
+ = getConferenceCallPeerRendererDelegate();
+
+ if (delegate != null)
+ delegate.setPeerName(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Delegates to the <tt>toolBar</tt>, if the latter implements
+ * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
+ * container only.
+ */
+ public void setPeerState(
+ CallPeerState oldState,
+ CallPeerState newState,
+ String stateString)
+ {
+ ConferenceCallPeerRenderer delegate
+ = getConferenceCallPeerRendererDelegate();
+
+ if (delegate != null)
+ delegate.setPeerState(oldState, newState, stateString);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Delegates to the <tt>toolBar</tt>, if the latter implements
+ * <tt>ConferenceCallPeerRenderer</tt>, because this instance is a
+ * container only.
+ */
+ public void setSecurityPanelVisible(boolean visible)
+ {
+ ConferenceCallPeerRenderer delegate
+ = getConferenceCallPeerRendererDelegate();
+
+ if (delegate != null)
+ delegate.setSecurityPanelVisible(visible);
+ }
+
+ /**
+ * Sets the visual <tt>Component</tt> displaying the video associated
+ * with the participant depicted by this instance.
+ *
+ * @param video the visual <tt>Component</tt> displaying video which is
+ * to be associated with the participant depicted by this instance
+ */
+ void setVideo(Component video)
+ {
+ if (this.video != video)
+ {
+ if (this.video != null)
+ videoContainer.remove(this.video);
+
+ this.video = video;
+
+ if (this.video != null)
+ {
+ setVisible(true);
+ videoContainer.add(this.video, VideoLayout.CENTER_REMOTE);
+ }
+ else
+ setVisible(false);
+
+ // Update thumbnails container according to video status.
+ if (thumbnailContainer != null)
+ {
+ if (conferenceMember != null)
+ thumbnailContainer
+ .updateThumbnail(conferenceMember, (video != null));
+ else if (callPeer != null)
+ thumbnailContainer
+ .updateThumbnail(callPeer, (video != null));
+ else if (isLocalUser)
+ thumbnailContainer
+ .updateThumbnail((video != null));
+ }
+ }
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java
index 127e28b..0283e25 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java
@@ -790,8 +790,6 @@ public class ChatConversationPanel
*/
public void correctMessage(final ChatMessage chatMessage)
{
- lastMessageUID = chatMessage.getMessageUID();
-
if (!SwingUtilities.isEventDispatchThread())
{
SwingUtilities.invokeLater(new Runnable()
@@ -805,6 +803,11 @@ public class ChatConversationPanel
}
String correctedUID = chatMessage.getCorrectedMessageUID();
+ if (correctedUID != null && correctedUID.equals(lastMessageUID))
+ {
+ lastMessageUID = chatMessage.getMessageUID();
+ }
+
Element root = document.getDefaultRootElement();
Element correctedMsgElement
= document.getElement(root,
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatSessionChangeListener.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatSessionChangeListener.java
index 0b96069..1e6127e 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatSessionChangeListener.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatSessionChangeListener.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,32 +15,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.gui.main.chat;
-
-/**
- * Listens for changes in {@link ChatSession}.
- * @author George Politis
- */
-public interface ChatSessionChangeListener
-{
- /**
- * The icon representing the ChatTransport has changed.
- */
- public static final int ICON_UPDATED = 1;
-
- /**
- * Called when the current {@link ChatTransport} has
- * changed.
- *
- * @param chatSession the {@link ChatSession} it's current
- * {@link ChatTransport} has changed
- */
- public void currentChatTransportChanged(ChatSession chatSession);
-
- /**
- * When a property of the chatTransport has changed.
- * @param eventID the event id representing the property of the transport
- * that has changed.
- */
- public void currentChatTransportUpdated(int eventID);
-}
+package net.java.sip.communicator.impl.gui.main.chat;
+
+/**
+ * Listens for changes in {@link ChatSession}.
+ * @author George Politis
+ */
+public interface ChatSessionChangeListener
+{
+ /**
+ * The icon representing the ChatTransport has changed.
+ */
+ public static final int ICON_UPDATED = 1;
+
+ /**
+ * Called when the current {@link ChatTransport} has
+ * changed.
+ *
+ * @param chatSession the {@link ChatSession} it's current
+ * {@link ChatTransport} has changed
+ */
+ public void currentChatTransportChanged(ChatSession chatSession);
+
+ /**
+ * When a property of the chatTransport has changed.
+ * @param eventID the event id representing the property of the transport
+ * that has changed.
+ */
+ public void currentChatTransportUpdated(int eventID);
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatContactListModel.java b/src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatContactListModel.java
index d42ecfb..acf36bf 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatContactListModel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatContactListModel.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,235 +15,235 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.gui.main.chat.conference;
-
-import java.util.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.impl.gui.main.chat.*;
-import net.java.sip.communicator.service.muc.*;
-import net.java.sip.communicator.service.protocol.event.*;
-
-/**
- * Implements an <tt>AbstractListModel</tt> which represents a member list of
- * <tt>ChatContact</tt>s. The primary purpose of the implementation is to sort
- * the <tt>ChatContact</tt>s according to their member roles and in alphabetical
- * order according to their names.
- *
- * @author Lyubomir Marinov
- */
-public class ChatContactListModel
- extends AbstractListModel
- implements ChatRoomMemberPropertyChangeListener
-{
-
- /**
- * The backing store of this <tt>AbstractListModel</tt> listing the
- * <tt>ChatContact</tt>s.
- */
- private final List<ChatContact<?>> chatContacts
- = new ArrayList<ChatContact<?>>();
-
- /**
- * Current chat session.
- */
- private ChatSession chatSession;
-
- /**
- * The implementation of the sorting rules - the <tt>ChatContact</tt>s are
- * first sorted according to their roles in decreasing order of their
- * privileges and then they are sorted according to their names in
- * alphabetical order.
- */
- private final Comparator<ChatContact<?>> sorter
- = new Comparator<ChatContact<?>>()
- {
- public int compare(ChatContact<?> chatContact0, ChatContact<?> chatContact1)
- {
- /*
- * Place ChatMembers with more privileges at the beginning of
- * the list.
- */
- if (chatContact0 instanceof ConferenceChatContact)
- {
- if (chatContact1 instanceof ConferenceChatContact)
- {
- int role0
- = ((ConferenceChatContact) chatContact0).getRole()
- .getRoleIndex();
- int role1
- = ((ConferenceChatContact) chatContact1).getRole()
- .getRoleIndex();
-
- if (role0 > role1)
- return -1;
- else if (role0 < role1)
- return 1;
- }
- else
- return -1;
- }
- else if (chatContact1 instanceof ConferenceChatContact)
- return 1;
-
- /* By default, sort the ChatContacts in alphabetical order. */
- return
- chatContact0.getName().compareToIgnoreCase(
- chatContact1.getName());
- }
- };
-
- /**
- * Creates the model.
- * @param chatSession The current model chat session.
- */
- public ChatContactListModel(ChatSession chatSession)
- {
- this.chatSession = chatSession;
-
- // when something like rename on a member change update the UI to
- // reflect it
- Object descriptor = chatSession.getDescriptor();
-
- if(descriptor instanceof ChatRoomWrapper)
- {
- ((ChatRoomWrapper) descriptor)
- .getChatRoom().addMemberPropertyChangeListener(this);
- }
- }
-
- /**
- * Listens for property change in chat room members.
- * @param ev the event
- */
- public void chatRoomPropertyChanged(ChatRoomMemberPropertyChangeEvent ev)
- {
- // Translate into
- // ListDataListener.contentsChanged.
- int chatContactCount = chatContacts.size();
-
- for (int i = 0; i < chatContactCount; i++)
- {
- ChatContact<?> chatContact = chatContacts.get(i);
-
- if(chatContact.getDescriptor().equals(ev.getSourceChatRoomMember()))
- {
- fireContentsChanged(chatContact, i, i);
- /*
- * TODO Can ev.sourceChatRoomMember
- * equal more than one chatContacts
- * element? If it cannot, it will be
- * more efficient to break here.
- */
- }
- }
- }
-
- /**
- * Adds a specific <tt>ChatContact</tt> to this <tt>AbstractListModel</tt>
- * implementation and preserves the sorting it applies.
- *
- * @param chatContact a <tt>ChatContact</tt> to be added to this
- * <tt>AbstractListModel</tt>
- */
- public void addElement(ChatContact<?> chatContact)
- {
- if (chatContact == null)
- throw new IllegalArgumentException("chatContact");
-
- int index = -1;
-
- synchronized(chatContacts)
- {
- int chatContactCount = chatContacts.size();
-
- for (int i = 0; i < chatContactCount; i++)
- {
- ChatContact<?> containedChatContact = chatContacts.get(i);
-
- // We don't want duplicates.
- if (chatContact.equals(containedChatContact))
- return;
- if ((index == -1)
- && (sorter.compare(containedChatContact, chatContact) > 0))
- {
- index = i;
- // Continue in order to prevent duplicates.
- }
- }
- if (index == -1)
- index = chatContactCount;
-
- chatContacts.add(index, chatContact);
- }
- fireIntervalAdded(this, index, index);
- }
-
- /* Implements ListModel#getElementAt(int). */
- public ChatContact<?> getElementAt(int index)
- {
- synchronized(chatContacts)
- {
- return chatContacts.get(index);
- }
- }
-
- /* Implements ListModel#getSize(). */
- public int getSize()
- {
- synchronized(chatContacts)
- {
- return chatContacts.size();
- }
- }
-
- /**
- * Removes a specific <tt>ChatContact</tt> from this
- * <tt>AbstractListModel</tt> implementation.
- *
- * @param chatContact a <tt>ChatContact</tt> to be removed from this
- * <tt>AbstractListModel</tt> if it's already contained
- */
- public void removeElement(ChatContact<?> chatContact)
- {
- synchronized(chatContacts)
- {
- int index = chatContacts.indexOf(chatContact);
-
- if ((index >= 0) && chatContacts.remove(chatContact))
- fireIntervalRemoved(this, index, index);
- }
- }
-
- /**
- * Removes all the elements from this model.
- */
- public void removeAllElements()
- {
- if (chatContacts == null || chatContacts.size() <= 0)
- return;
-
- synchronized(chatContacts)
- {
- int contactsSize = chatContacts.size();
- chatContacts.clear();
-
- fireIntervalRemoved(this, 0, contactsSize - 1);
- }
- }
-
- /**
- * Runs clean-up.
- */
- public void dispose()
- {
- Object descriptor = chatSession.getDescriptor();
-
- if(descriptor instanceof ChatRoomWrapper)
- {
- ((ChatRoomWrapper) descriptor)
- .getChatRoom().removeMemberPropertyChangeListener(this);
- }
- }
-}
+package net.java.sip.communicator.impl.gui.main.chat.conference;
+
+import java.util.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.impl.gui.main.chat.*;
+import net.java.sip.communicator.service.muc.*;
+import net.java.sip.communicator.service.protocol.event.*;
+
+/**
+ * Implements an <tt>AbstractListModel</tt> which represents a member list of
+ * <tt>ChatContact</tt>s. The primary purpose of the implementation is to sort
+ * the <tt>ChatContact</tt>s according to their member roles and in alphabetical
+ * order according to their names.
+ *
+ * @author Lyubomir Marinov
+ */
+public class ChatContactListModel
+ extends AbstractListModel
+ implements ChatRoomMemberPropertyChangeListener
+{
+
+ /**
+ * The backing store of this <tt>AbstractListModel</tt> listing the
+ * <tt>ChatContact</tt>s.
+ */
+ private final List<ChatContact<?>> chatContacts
+ = new ArrayList<ChatContact<?>>();
+
+ /**
+ * Current chat session.
+ */
+ private ChatSession chatSession;
+
+ /**
+ * The implementation of the sorting rules - the <tt>ChatContact</tt>s are
+ * first sorted according to their roles in decreasing order of their
+ * privileges and then they are sorted according to their names in
+ * alphabetical order.
+ */
+ private final Comparator<ChatContact<?>> sorter
+ = new Comparator<ChatContact<?>>()
+ {
+ public int compare(ChatContact<?> chatContact0, ChatContact<?> chatContact1)
+ {
+ /*
+ * Place ChatMembers with more privileges at the beginning of
+ * the list.
+ */
+ if (chatContact0 instanceof ConferenceChatContact)
+ {
+ if (chatContact1 instanceof ConferenceChatContact)
+ {
+ int role0
+ = ((ConferenceChatContact) chatContact0).getRole()
+ .getRoleIndex();
+ int role1
+ = ((ConferenceChatContact) chatContact1).getRole()
+ .getRoleIndex();
+
+ if (role0 > role1)
+ return -1;
+ else if (role0 < role1)
+ return 1;
+ }
+ else
+ return -1;
+ }
+ else if (chatContact1 instanceof ConferenceChatContact)
+ return 1;
+
+ /* By default, sort the ChatContacts in alphabetical order. */
+ return
+ chatContact0.getName().compareToIgnoreCase(
+ chatContact1.getName());
+ }
+ };
+
+ /**
+ * Creates the model.
+ * @param chatSession The current model chat session.
+ */
+ public ChatContactListModel(ChatSession chatSession)
+ {
+ this.chatSession = chatSession;
+
+ // when something like rename on a member change update the UI to
+ // reflect it
+ Object descriptor = chatSession.getDescriptor();
+
+ if(descriptor instanceof ChatRoomWrapper)
+ {
+ ((ChatRoomWrapper) descriptor)
+ .getChatRoom().addMemberPropertyChangeListener(this);
+ }
+ }
+
+ /**
+ * Listens for property change in chat room members.
+ * @param ev the event
+ */
+ public void chatRoomPropertyChanged(ChatRoomMemberPropertyChangeEvent ev)
+ {
+ // Translate into
+ // ListDataListener.contentsChanged.
+ int chatContactCount = chatContacts.size();
+
+ for (int i = 0; i < chatContactCount; i++)
+ {
+ ChatContact<?> chatContact = chatContacts.get(i);
+
+ if(chatContact.getDescriptor().equals(ev.getSourceChatRoomMember()))
+ {
+ fireContentsChanged(chatContact, i, i);
+ /*
+ * TODO Can ev.sourceChatRoomMember
+ * equal more than one chatContacts
+ * element? If it cannot, it will be
+ * more efficient to break here.
+ */
+ }
+ }
+ }
+
+ /**
+ * Adds a specific <tt>ChatContact</tt> to this <tt>AbstractListModel</tt>
+ * implementation and preserves the sorting it applies.
+ *
+ * @param chatContact a <tt>ChatContact</tt> to be added to this
+ * <tt>AbstractListModel</tt>
+ */
+ public void addElement(ChatContact<?> chatContact)
+ {
+ if (chatContact == null)
+ throw new IllegalArgumentException("chatContact");
+
+ int index = -1;
+
+ synchronized(chatContacts)
+ {
+ int chatContactCount = chatContacts.size();
+
+ for (int i = 0; i < chatContactCount; i++)
+ {
+ ChatContact<?> containedChatContact = chatContacts.get(i);
+
+ // We don't want duplicates.
+ if (chatContact.equals(containedChatContact))
+ return;
+ if ((index == -1)
+ && (sorter.compare(containedChatContact, chatContact) > 0))
+ {
+ index = i;
+ // Continue in order to prevent duplicates.
+ }
+ }
+ if (index == -1)
+ index = chatContactCount;
+
+ chatContacts.add(index, chatContact);
+ }
+ fireIntervalAdded(this, index, index);
+ }
+
+ /* Implements ListModel#getElementAt(int). */
+ public ChatContact<?> getElementAt(int index)
+ {
+ synchronized(chatContacts)
+ {
+ return chatContacts.get(index);
+ }
+ }
+
+ /* Implements ListModel#getSize(). */
+ public int getSize()
+ {
+ synchronized(chatContacts)
+ {
+ return chatContacts.size();
+ }
+ }
+
+ /**
+ * Removes a specific <tt>ChatContact</tt> from this
+ * <tt>AbstractListModel</tt> implementation.
+ *
+ * @param chatContact a <tt>ChatContact</tt> to be removed from this
+ * <tt>AbstractListModel</tt> if it's already contained
+ */
+ public void removeElement(ChatContact<?> chatContact)
+ {
+ synchronized(chatContacts)
+ {
+ int index = chatContacts.indexOf(chatContact);
+
+ if ((index >= 0) && chatContacts.remove(chatContact))
+ fireIntervalRemoved(this, index, index);
+ }
+ }
+
+ /**
+ * Removes all the elements from this model.
+ */
+ public void removeAllElements()
+ {
+ if (chatContacts == null || chatContacts.size() <= 0)
+ return;
+
+ synchronized(chatContacts)
+ {
+ int contactsSize = chatContacts.size();
+ chatContacts.clear();
+
+ fireIntervalRemoved(this, 0, contactsSize - 1);
+ }
+ }
+
+ /**
+ * Runs clean-up.
+ */
+ public void dispose()
+ {
+ Object descriptor = chatSession.getDescriptor();
+
+ if(descriptor instanceof ChatRoomWrapper)
+ {
+ ((ChatRoomWrapper) descriptor)
+ .getChatRoom().removeMemberPropertyChangeListener(this);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java b/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java
index 58a1db4..89ceb48 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,1390 +15,1390 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.gui.main.chat.conference;
-
-import java.util.*;
-import java.util.concurrent.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.impl.gui.*;
-import net.java.sip.communicator.impl.gui.main.chat.*;
-import net.java.sip.communicator.impl.gui.main.chat.history.*;
-import net.java.sip.communicator.impl.gui.main.chatroomslist.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.muc.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.service.protocol.globalstatus.*;
-import net.java.sip.communicator.util.*;
-import net.java.sip.communicator.util.Logger;
-
-import org.jdesktop.swingworker.SwingWorker;
-import org.jitsi.util.*;
-import org.osgi.framework.*;
-
-/**
- * The <tt>ConferenceChatManager</tt> is the one that manages both chat room and
- * ad-hoc chat rooms invitations.
- *
- * @author Yana Stamcheva
- * @author Lubomir Marinov
- * @author Valentin Martinet
- * @author Hristo Terezov
- */
-public class ConferenceChatManager
- implements ChatRoomMessageListener,
- ChatRoomInvitationListener,
- ChatRoomInvitationRejectionListener,
- AdHocChatRoomMessageListener,
- AdHocChatRoomInvitationListener,
- AdHocChatRoomInvitationRejectionListener,
- LocalUserChatRoomPresenceListener,
- LocalUserAdHocChatRoomPresenceListener,
- ServiceListener, ChatRoomLocalUserRoleListener
-{
- /**
- * The object used for logging.
- */
- private static final Logger logger
- = Logger.getLogger(ConferenceChatManager.class);
-
- /**
- * Maps each history window to a <tt>ChatRoomWrapper</tt>.
- */
- private final Hashtable<ChatRoomWrapper, HistoryWindow> chatRoomHistory =
- new Hashtable<ChatRoomWrapper, HistoryWindow>();
-
- /**
- * The list of ad-hoc chat rooms.
- */
- private final AdHocChatRoomList adHocChatRoomList = new AdHocChatRoomList();
-
- /**
- * A list of all <tt>AdHocChatRoomListChangeListener</tt>-s.
- */
- private final Vector<AdHocChatRoomListChangeListener>
- adHoclistChangeListeners = new Vector<AdHocChatRoomListChangeListener>();
-
- /**
- * Creates an instance of <tt>ConferenceChatManager</tt>.
- */
- public ConferenceChatManager()
- {
- // Loads the chat rooms list in a separate thread.
- new Thread()
- {
- @Override
- public void run()
- {
- adHocChatRoomList.loadList();
- }
- }.start();
-
- GuiActivator.bundleContext.addServiceListener(this);
-
- }
-
- /**
- * Returns all chat room providers currently contained in the ad-hoc chat
- * room list.
- *
- * @return all chat room providers currently contained in the ad-hoc chat
- * room list.
- */
- public AdHocChatRoomList getAdHocChatRoomList()
- {
- return adHocChatRoomList;
- }
-
- /**
- * Handles <tt>ChatRoomInvitationReceivedEvent</tt>-s.
- */
- public void invitationReceived(ChatRoomInvitationReceivedEvent evt)
- {
- InvitationReceivedDialog dialog
- = new InvitationReceivedDialog(
- this,
- evt.getSourceOperationSet(),
- evt.getInvitation());
-
- dialog.setVisible(true);
- }
-
- public void invitationRejected(ChatRoomInvitationRejectedEvent evt) {}
-
- /**
- * Implements the <tt>ChatRoomMessageListener.messageDelivered</tt> method.
- * <br>
- * Shows the message in the conversation area and clears the write message
- * area.
- * @param evt the <tt>ChatRoomMessageDeliveredEvent</tt> that notified us
- * that the message was delivered to its destination
- */
- public void messageDelivered(ChatRoomMessageDeliveredEvent evt)
- {
- ChatRoom sourceChatRoom = (ChatRoom) evt.getSource();
-
- if (logger.isTraceEnabled())
- logger.trace(
- "MESSAGE DELIVERED to chat room: " + sourceChatRoom.getName());
-
- ChatPanel chatPanel = GuiActivator.getUIService().getChatWindowManager()
- .getMultiChat(sourceChatRoom, false);
-
- if(chatPanel != null)
- {
- String messageType;
-
- switch (evt.getEventType())
- {
- case ChatRoomMessageDeliveredEvent.CONVERSATION_MESSAGE_DELIVERED:
- messageType = Chat.OUTGOING_MESSAGE;
- break;
- case ChatRoomMessageDeliveredEvent.ACTION_MESSAGE_DELIVERED:
- messageType = Chat.ACTION_MESSAGE;
- break;
- default:
- messageType = null;
- break;
- }
-
- Message msg = evt.getMessage();
-
- chatPanel.addMessage(
- sourceChatRoom.getUserNickname(),
- null,
- evt.getTimestamp(),
- messageType,
- msg.getContent(),
- msg.getContentType(),
- msg.getMessageUID(),
- null);
- }
- }
-
- /**
- * Implements the <tt>ChatRoomMessageListener.messageReceived</tt> method.
- * <br>
- * Obtains the corresponding <tt>ChatPanel</tt> and process the message
- * there.
- * @param evt the <tt>ChatRoomMessageReceivedEvent</tt> that notified us
- * that a message has been received
- */
- public void messageReceived(ChatRoomMessageReceivedEvent evt)
- {
- ChatRoom sourceChatRoom = evt.getSourceChatRoom();
- ChatRoomMember sourceMember = evt.getSourceChatRoomMember();
-
- String messageType = null;
-
- switch (evt.getEventType())
- {
- case ChatRoomMessageReceivedEvent.CONVERSATION_MESSAGE_RECEIVED:
- messageType = Chat.INCOMING_MESSAGE;
- break;
- case ChatRoomMessageReceivedEvent.SYSTEM_MESSAGE_RECEIVED:
- messageType = Chat.SYSTEM_MESSAGE;
- break;
- case ChatRoomMessageReceivedEvent.ACTION_MESSAGE_RECEIVED:
- messageType = Chat.ACTION_MESSAGE;
- break;
- }
-
- if (logger.isTraceEnabled())
- logger.trace("MESSAGE RECEIVED from contact: "
- + sourceMember.getContactAddress());
-
- Message message = evt.getMessage();
-
- ChatPanel chatPanel = null;
-
- ChatWindowManager chatWindowManager
- = GuiActivator.getUIService().getChatWindowManager();
-
- boolean createWindow = false;
- String autoOpenConfig
- = MUCService.getChatRoomAutoOpenOption(
- sourceChatRoom.getParentProvider(),
- sourceChatRoom.getIdentifier());
- if(autoOpenConfig == null)
- autoOpenConfig = MUCService.DEFAULT_AUTO_OPEN_BEHAVIOUR;
-
- if(autoOpenConfig.equals(MUCService.OPEN_ON_ACTIVITY)
- || (autoOpenConfig.equals(MUCService.OPEN_ON_MESSAGE)
- && !evt.isHistoryMessage())
- || evt.isImportantMessage())
- createWindow = true;
-
- if(sourceChatRoom.isSystem())
- {
- ChatRoomProviderWrapper serverWrapper
- = GuiActivator.getMUCService().findServerWrapperFromProvider(
- sourceChatRoom.getParentProvider());
-
- chatPanel = chatWindowManager.getMultiChat(
- serverWrapper.getSystemRoomWrapper(), createWindow);
- }
- else
- {
- chatPanel = chatWindowManager.getMultiChat(
- sourceChatRoom, createWindow, message.getMessageUID());
- }
-
- if(chatPanel == null)
- return;
-
- String messageContent = message.getContent();
-
- if (evt.isHistoryMessage())
- {
- Date timeStamp = chatPanel.getChatConversationPanel()
- .getLastIncomingMsgTimestamp();
- Collection<Object> c =
- chatPanel.getChatSession().getHistoryBeforeDate(
- new Date(
- timeStamp.equals(new Date(0))
- ? System.currentTimeMillis() - 10000
- : timeStamp.getTime()
- ), 20);
- if (c.size() > 0)
- {
- boolean isPresent = false;
- for (Object o : c)
- {
- if (o instanceof ChatRoomMessageDeliveredEvent)
- {
- ChatRoomMessageDeliveredEvent ev =
- (ChatRoomMessageDeliveredEvent) o;
- if (evt.getTimestamp() != null
- && evt.getTimestamp().equals(ev.getTimestamp()))
- {
- isPresent = true;
- break;
- }
- }
- else if(o instanceof ChatRoomMessageReceivedEvent)
- {
- ChatRoomMessageReceivedEvent ev =
- (ChatRoomMessageReceivedEvent) o;
- if (evt.getTimestamp() != null
- && evt.getTimestamp().equals(ev.getTimestamp()))
- {
- isPresent = true;
- break;
- }
- }
-
- Message m2 = evt.getMessage();
-
- if(m2 != null
- && m2.getContent().equals(messageContent))
- {
- isPresent = true;
- break;
- }
- }
-
- if (isPresent)
- return;
- }
- }
-
- chatPanel.addMessage(
- sourceMember.getName(),
- null,
- evt.getTimestamp(),
- messageType,
- messageContent,
- message.getContentType(),
- message.getMessageUID(),
- null);
-
- if(createWindow)
- chatWindowManager.openChat(chatPanel, false);
- }
-
- /**
- * Implements the <tt>ChatRoomMessageListener.messageDeliveryFailed</tt>
- * method.
- * <br>
- * In the conversation area shows an error message, explaining the problem.
- * @param evt the <tt>ChatRoomMessageDeliveryFailedEvent</tt> that notified
- * us of a delivery failure
- */
- public void messageDeliveryFailed(ChatRoomMessageDeliveryFailedEvent evt)
- {
- ChatRoom sourceChatRoom = evt.getSourceChatRoom();
-
- String errorMsg = null;
-
- /*
- * FIXME ChatRoomMessageDeliveryFailedEvent#getSource() is not a Message
- * instance at the time of this writing and the attempt "(Message)
- * evt.getSource()" seems to be to get the message which failed to be
- * delivered. I'm not sure it's
- * ChatRoomMessageDeliveryFailedEvent#getMessage() but since it's the
- * only message I can get out of ChatRoomMessageDeliveryFailedEvent, I'm
- * using it.
- */
- Message sourceMessage = evt.getMessage();
-
- ChatRoomMember destMember = evt.getDestinationChatRoomMember();
-
- if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.OFFLINE_MESSAGES_NOT_SUPPORTED)
- {
- errorMsg = GuiActivator.getResources().getI18NString(
- "service.gui.MSG_DELIVERY_NOT_SUPPORTED",
- new String[]{destMember.getName()});
- }
- else if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.NETWORK_FAILURE)
- {
- errorMsg = GuiActivator.getResources()
- .getI18NString("service.gui.MSG_NOT_DELIVERED");
- }
- else if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.PROVIDER_NOT_REGISTERED)
- {
- errorMsg = GuiActivator.getResources().getI18NString(
- "service.gui.MSG_SEND_CONNECTION_PROBLEM");
- }
- else if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.INTERNAL_ERROR)
- {
- errorMsg = GuiActivator.getResources().getI18NString(
- "service.gui.MSG_DELIVERY_INTERNAL_ERROR");
- }
- else if (evt.getErrorCode()
- == ChatRoomMessageDeliveryFailedEvent.FORBIDDEN)
- {
- errorMsg = GuiActivator.getResources().getI18NString(
- "service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN");
- }
- else if (evt.getErrorCode()
- == ChatRoomMessageDeliveryFailedEvent.UNSUPPORTED_OPERATION)
- {
- errorMsg =
- GuiActivator.getResources().getI18NString(
- "service.gui.MSG_DELIVERY_UNSUPPORTED_OPERATION");
- }
- else
- {
- errorMsg = GuiActivator.getResources().getI18NString(
- "service.gui.MSG_DELIVERY_UNKNOWN_ERROR");
- }
-
- String reason = evt.getReason();
- if (reason != null)
- errorMsg += " " + GuiActivator.getResources().getI18NString(
- "service.gui.ERROR_WAS",
- new String[]{reason});
-
- ChatWindowManager chatWindowManager
- = GuiActivator.getUIService().getChatWindowManager();
- ChatPanel chatPanel
- = chatWindowManager.getMultiChat(sourceChatRoom, true);
-
- chatPanel.addMessage(
- destMember != null ? destMember.getName()
- : sourceChatRoom.getName(),
- new Date(),
- Chat.OUTGOING_MESSAGE,
- sourceMessage.getContent(),
- sourceMessage.getContentType());
-
- chatPanel.addErrorMessage(
- destMember != null ? destMember.getName()
- : sourceChatRoom.getName(),
- errorMsg);
-
- chatWindowManager.openChat(chatPanel, false);
- }
-
- /**
- * Implements the
- * <tt>LocalUserAdHocChatRoomPresenceListener.localUserPresenceChanged</tt>
- * method
- *
- * @param evt the <tt>LocalUserAdHocChatRoomPresenceChangeEvent</tt> that
- * notified us of a presence change
- */
- public void localUserAdHocPresenceChanged(
- LocalUserAdHocChatRoomPresenceChangeEvent evt)
- {
- AdHocChatRoom sourceAdHocChatRoom = evt.getAdHocChatRoom();
- AdHocChatRoomWrapper adHocChatRoomWrapper
- = adHocChatRoomList
- .findChatRoomWrapperFromAdHocChatRoom(sourceAdHocChatRoom);
-
- String eventType = evt.getEventType();
-
- if (LocalUserAdHocChatRoomPresenceChangeEvent
- .LOCAL_USER_JOINED.equals(eventType))
- {
- if(adHocChatRoomWrapper != null)
- {
- this.fireAdHocChatRoomListChangedEvent(
- adHocChatRoomWrapper,
- AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_CHANGED);
-
- ChatWindowManager chatWindowManager
- = GuiActivator.getUIService().getChatWindowManager();
- ChatPanel chatPanel
- = chatWindowManager
- .getMultiChat(adHocChatRoomWrapper, true);
-
- // Check if we have already opened a chat window for this chat
- // wrapper and load the real chat room corresponding to the
- // wrapper.
- if(chatPanel.isShown())
- ((AdHocConferenceChatSession) chatPanel.getChatSession())
- .loadChatRoom(sourceAdHocChatRoom);
- else
- chatWindowManager.openChat(chatPanel, true);
- }
-
- sourceAdHocChatRoom.addMessageListener(this);
- }
- else if (evt.getEventType().equals(
- LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOIN_FAILED))
- {
- GuiActivator.getAlertUIService().showAlertPopup(
- GuiActivator.getResources().getI18NString("service.gui.ERROR"),
- GuiActivator.getResources().getI18NString(
- "service.gui.FAILED_TO_JOIN_CHAT_ROOM",
- new String[]{sourceAdHocChatRoom.getName()})
- + evt.getReason());
- }
- else if (LocalUserAdHocChatRoomPresenceChangeEvent
- .LOCAL_USER_LEFT.equals(eventType)
- || LocalUserAdHocChatRoomPresenceChangeEvent
- .LOCAL_USER_DROPPED.equals(eventType))
- {
- this.closeAdHocChatRoom(adHocChatRoomWrapper);
-
- // Need to refresh the chat room's list in order to change
- // the state of the chat room to offline.
- fireAdHocChatRoomListChangedEvent(
- adHocChatRoomWrapper,
- AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_CHANGED);
-
- sourceAdHocChatRoom.removeMessageListener(this);
- }
- }
-
- /**
- * Implements the
- * <tt>LocalUserChatRoomPresenceListener.localUserPresenceChanged</tt>
- * method.
- * @param evt the <tt>LocalUserChatRoomPresenceChangeEvent</tt> that
- * notified us
- */
- public void localUserPresenceChanged(
- final LocalUserChatRoomPresenceChangeEvent evt)
- {
- if(!SwingUtilities.isEventDispatchThread())
- {
- SwingUtilities.invokeLater(new Runnable()
- {
- @Override
- public void run()
- {
- localUserPresenceChanged(evt);
- }
- });
- return;
- }
-
- ChatRoom sourceChatRoom = evt.getChatRoom();
- ChatRoomWrapper chatRoomWrapper
- = GuiActivator.getMUCService().findChatRoomWrapperFromChatRoom(
- sourceChatRoom);
-
- String eventType = evt.getEventType();
-
- if (LocalUserChatRoomPresenceChangeEvent
- .LOCAL_USER_JOINED.equals(eventType))
- {
- if(chatRoomWrapper != null)
- {
- GuiActivator.getMUCService().fireChatRoomListChangedEvent(
- chatRoomWrapper,
- ChatRoomListChangeEvent.CHAT_ROOM_CHANGED);
-
- boolean createWindow = false;
-
- String autoOpenConfig
- = MUCService.getChatRoomAutoOpenOption(
- sourceChatRoom.getParentProvider(),
- sourceChatRoom.getIdentifier());
-
- if(autoOpenConfig != null
- && autoOpenConfig.equals(MUCService.OPEN_ON_ACTIVITY))
- createWindow = true;
-
- ChatWindowManager chatWindowManager
- = GuiActivator.getUIService().getChatWindowManager();
- ChatPanel chatPanel
- = chatWindowManager.getMultiChat(
- chatRoomWrapper, createWindow);
-
- if(chatPanel != null)
- {
- chatPanel.setChatIcon(
- chatPanel.getChatSession().getChatStatusIcon());
-
- // Check if we have already opened a chat window for this chat
- // wrapper and load the real chat room corresponding to the
- // wrapper.
- if(chatPanel.isShown())
- {
- ((ConferenceChatSession) chatPanel.getChatSession())
- .loadChatRoom(sourceChatRoom);
- }
- else
- {
- chatWindowManager.openChat(chatPanel, true);
- }
- }
- }
-
- if (sourceChatRoom.isSystem())
- {
- ChatRoomProviderWrapper serverWrapper
- = GuiActivator.getMUCService()
- .findServerWrapperFromProvider(
- sourceChatRoom.getParentProvider());
-
- serverWrapper.setSystemRoom(sourceChatRoom);
- }
-
- sourceChatRoom.addMessageListener(this);
- sourceChatRoom.addLocalUserRoleListener(this);
- }
- else if (LocalUserChatRoomPresenceChangeEvent
- .LOCAL_USER_JOIN_FAILED.equals(eventType))
- {
- GuiActivator.getAlertUIService().showAlertPopup(
- GuiActivator.getResources().getI18NString("service.gui.ERROR"),
- GuiActivator.getResources().getI18NString(
- "service.gui.FAILED_TO_JOIN_CHAT_ROOM",
- new String[]{sourceChatRoom.getName()})
- + evt.getReason());
- }
- else if (LocalUserChatRoomPresenceChangeEvent
- .LOCAL_USER_LEFT.equals(eventType)
- || LocalUserChatRoomPresenceChangeEvent
- .LOCAL_USER_KICKED.equals(eventType)
- || LocalUserChatRoomPresenceChangeEvent
- .LOCAL_USER_DROPPED.equals(eventType))
- {
- if(chatRoomWrapper != null)
- {
- if(StringUtils.isNullOrEmpty(evt.getReason()))
- {
- GuiActivator.getUIService()
- .closeChatRoomWindow(chatRoomWrapper);
- }
- else
- {
- // send some system messages informing for the
- // reason of leaving
- ChatWindowManager chatWindowManager
- = GuiActivator.getUIService().getChatWindowManager();
-
- ChatPanel chatPanel = chatWindowManager.getMultiChat(
- sourceChatRoom, false);
-
- if(chatPanel != null)
- {
- chatPanel.addMessage(
- sourceChatRoom.getName(),
- null,
- new Date(),
- Chat.SYSTEM_MESSAGE,
- evt.getReason(),
- OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE,
- null,
- null);
-
- // print and the alternate address
- if(!StringUtils.isNullOrEmpty(
- evt.getAlternateAddress()))
- {
- chatPanel.addMessage(
- sourceChatRoom.getName(),
- null,
- new Date(),
- Chat.SYSTEM_MESSAGE,
- GuiActivator.getResources().getI18NString(
- "service.gui.CHAT_ROOM_ALTERNATE_ADDRESS",
- new String[]{evt.getAlternateAddress()}),
- OperationSetBasicInstantMessaging
- .DEFAULT_MIME_TYPE,
- null,
- null);
- }
- }
- }
-
- // Need to refresh the chat room's list in order to change
- // the state of the chat room to offline.
-
- GuiActivator.getMUCService().fireChatRoomListChangedEvent(
- chatRoomWrapper,
- ChatRoomListChangeEvent.CHAT_ROOM_CHANGED);
- }
-
- sourceChatRoom.removeMessageListener(this);
- sourceChatRoom.removelocalUserRoleListener(this);
- }
- }
-
-
- /**
- * Called to accept an incoming invitation. Adds the invitation chat room
- * to the list of chat rooms and joins it.
- *
- * @param invitation the invitation to accept
- * @param multiUserChatOpSet the operation set for chat conferencing
- * @throws OperationFailedException if the accept fails
- */
- public void acceptInvitation(
- AdHocChatRoomInvitation invitation,
- OperationSetAdHocMultiUserChat multiUserChatOpSet)
- throws OperationFailedException
- {
- AdHocChatRoom chatRoom = invitation.getTargetAdHocChatRoom();
-
- chatRoom.join();
- }
-
- /**
- * Rejects the given invitation with the specified reason.
- *
- * @param multiUserChatAdHocOpSet the operation set to use for rejecting the
- * invitation
- * @param invitation the invitation to reject
- * @param reason the reason for the rejection
- */
- public void rejectInvitation(
- OperationSetAdHocMultiUserChat multiUserChatAdHocOpSet,
- AdHocChatRoomInvitation invitation,
- String reason)
- {
- multiUserChatAdHocOpSet.rejectInvitation(invitation, reason);
- }
-
- /**
- * Creates an ad-hoc chat room, by specifying the ad-hoc chat room name, the
- * parent protocol provider and eventually, the contacts invited to
- * participate in this ad-hoc chat room.
- *
- * @param protocolProvider the parent protocol provider.
- * @param contacts the contacts invited when creating the chat room.
- * @param reason the reason for this invitation
- * @return the <tt>AdHocChatRoomWrapper</tt> corresponding to the created
- * ad hoc chat room
- */
- public AdHocChatRoomWrapper createAdHocChatRoom(
- ProtocolProviderService protocolProvider,
- Collection<String> contacts,
- String reason)
- {
- AdHocChatRoomWrapper chatRoomWrapper = null;
-
- OperationSetAdHocMultiUserChat groupChatOpSet
- = protocolProvider
- .getOperationSet(OperationSetAdHocMultiUserChat.class);
-
- // If there's no group chat operation set we have nothing to do here.
- if (groupChatOpSet == null)
- return null;
-
- AdHocChatRoom chatRoom = null;
-
- try
- {
- java.util.List<String> members = new LinkedList<String>();
-
- for(String address : contacts)
- members.add(address);
-
- chatRoom = groupChatOpSet.createAdHocChatRoom(
- "chatroom-" + new Date().getTime(), members, reason);
- }
- catch (OperationFailedException ex)
- {
- new ErrorDialog(
- GuiActivator.getUIService().getMainFrame(),
- GuiActivator.getResources().getI18NString("service.gui.ERROR"),
- GuiActivator.getResources().getI18NString(
- "service.gui.CREATE_CHAT_ROOM_ERROR",
- new String[]{protocolProvider.getProtocolDisplayName()}),
- ex)
- .showDialog();
- }
- catch (OperationNotSupportedException ex)
- {
- new ErrorDialog(
- GuiActivator.getUIService().getMainFrame(),
- GuiActivator.getResources().getI18NString("service.gui.ERROR"),
- GuiActivator.getResources().getI18NString(
- "service.gui.CREATE_CHAT_ROOM_ERROR",
- new String[]{protocolProvider.getProtocolDisplayName()}),
- ex)
- .showDialog();
- }
-
- if(chatRoom != null)
- {
- AdHocChatRoomProviderWrapper parentProvider
- = adHocChatRoomList.findServerWrapperFromProvider(
- protocolProvider);
-
- chatRoomWrapper = new AdHocChatRoomWrapper(
- parentProvider, chatRoom);
- parentProvider.addAdHocChatRoom(chatRoomWrapper);
- adHocChatRoomList.addAdHocChatRoom(chatRoomWrapper);
-
- fireAdHocChatRoomListChangedEvent(
- chatRoomWrapper,
- AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_ADDED);
- }
-
- return chatRoomWrapper;
- }
-
- /**
- * Joins the given ad-hoc chat room
- *
- * @param chatRoomWrapper
- */
- public void joinChatRoom(AdHocChatRoomWrapper chatRoomWrapper)
- {
- AdHocChatRoom chatRoom = chatRoomWrapper.getAdHocChatRoom();
-
- if(chatRoom == null)
- {
- new ErrorDialog(
- GuiActivator.getUIService().getMainFrame(),
- GuiActivator.getResources().getI18NString("service.gui.WARNING"),
- GuiActivator.getResources().getI18NString(
- "service.gui.CHAT_ROOM_NOT_CONNECTED",
- new String[]{chatRoomWrapper.getAdHocChatRoomName()}))
- .showDialog();
-
- return;
- }
-
- new JoinAdHocChatRoomTask(chatRoomWrapper).execute();
- }
-
- /**
- * Removes the given chat room from the UI.
- *
- * @param chatRoomWrapper the chat room to remove.
- */
- public void removeChatRoom(ChatRoomWrapper chatRoomWrapper)
- {
- ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
-
- if (chatRoom != null)
- leaveChatRoom(chatRoomWrapper);
-
- GuiActivator.getUIService().closeChatRoomWindow(chatRoomWrapper);
-
- GuiActivator.getMUCService().removeChatRoom(chatRoomWrapper);
-
- }
-
- /**
- * Joins the given chat room and manages all the exceptions that could
- * occur during the join process.
- *
- * @param chatRoom the chat room to join
- */
- public void joinChatRoom(AdHocChatRoom chatRoom)
- {
- AdHocChatRoomWrapper chatRoomWrapper
- = adHocChatRoomList.findChatRoomWrapperFromAdHocChatRoom(chatRoom);
-
- if(chatRoomWrapper == null)
- {
- AdHocChatRoomProviderWrapper parentProvider
- = adHocChatRoomList.findServerWrapperFromProvider(
- chatRoom.getParentProvider());
-
- chatRoomWrapper =
- new AdHocChatRoomWrapper(parentProvider, chatRoom);
-
- adHocChatRoomList.addAdHocChatRoom(chatRoomWrapper);
-
- fireAdHocChatRoomListChangedEvent(
- chatRoomWrapper,
- AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_ADDED);
- }
-
- this.joinChatRoom(chatRoomWrapper);
-
- ChatWindowManager chatWindowManager
- = GuiActivator.getUIService().getChatWindowManager();
-
- chatWindowManager
- .openChat(
- chatWindowManager.getMultiChat(chatRoomWrapper, true),
- true);
- }
-
- /**
- * Leaves the given <tt>ChatRoom</tt>.
- *
- * @param chatRoomWrapper the <tt>ChatRoom</tt> to leave.
- */
- public void leaveChatRoom(ChatRoomWrapper chatRoomWrapper)
- {
- ChatRoomWrapper leavedRoomWrapped
- = GuiActivator.getMUCService().leaveChatRoom(chatRoomWrapper);
- if(leavedRoomWrapped != null)
- GuiActivator.getUIService().closeChatRoomWindow(leavedRoomWrapped);
- }
-
- /**
- * Leaves the given <tt>ChatRoom</tt>.
- *
- * @param chatRoomWrapper the <tt>ChatRoom</tt> to leave.
- */
- public void leaveChatRoom(AdHocChatRoomWrapper chatRoomWrapper)
- {
- AdHocChatRoom chatRoom = chatRoomWrapper.getAdHocChatRoom();
-
- if (chatRoom != null)
- {
- chatRoom.leave();
- }
- else
- {
- new ErrorDialog(
- GuiActivator.getUIService().getMainFrame(),
- GuiActivator.getResources().getI18NString("service.gui.WARNING"),
- GuiActivator.getResources().getI18NString(
- "service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED"))
- .showDialog();
- }
- }
-
- /**
- * Checks if there's an open history window for the given chat room.
- *
- * @param chatRoomWrapper the chat room wrapper to check for
- * @return TRUE if there's an opened history window for the given chat room,
- * FALSE otherwise.
- */
- public boolean containsHistoryWindowForChatRoom(
- ChatRoomWrapper chatRoomWrapper)
- {
- return chatRoomHistory.containsKey(chatRoomWrapper);
- }
-
- /**
- * Returns the history window for the given chat room.
- *
- * @param chatRoomWrapper the chat room wrapper to search for
- * @return the history window for the given chat room
- */
- public HistoryWindow getHistoryWindowForChatRoom(
- ChatRoomWrapper chatRoomWrapper)
- {
- return chatRoomHistory.get(chatRoomWrapper);
- }
-
- /**
- * Adds a history window for a given chat room in the table of opened
- * history windows.
- *
- * @param chatRoomWrapper the chat room wrapper to add
- * @param historyWindow the history window to add
- */
- public void addHistoryWindowForChatRoom(ChatRoomWrapper chatRoomWrapper,
- HistoryWindow historyWindow)
- {
- chatRoomHistory.put(chatRoomWrapper, historyWindow);
- }
-
- /**
- * Removes the history window for the given chat room.
- *
- * @param chatRoomWrapper the chat room wrapper to remove the history window
- */
- public void removeHistoryWindowForChatRoom(ChatRoomWrapper chatRoomWrapper)
- {
- chatRoomHistory.remove(chatRoomWrapper);
- }
-
- /**
- * Adds the given <tt>AdHocChatRoomListChangeListener</tt> that will listen
- * for all changes of the chat room list data model.
- *
- * @param l the listener to add.
- */
- public void addAdHocChatRoomListChangeListener(
- AdHocChatRoomListChangeListener l)
- {
- synchronized (adHoclistChangeListeners)
- {
- adHoclistChangeListeners.add(l);
- }
- }
-
- /**
- * Removes the given <tt>AdHocChatRoomListChangeListener</tt>.
- *
- * @param l the listener to remove.
- */
- public void removeAdHocChatRoomListChangeListener(
- AdHocChatRoomListChangeListener l)
- {
- synchronized (adHoclistChangeListeners)
- {
- adHoclistChangeListeners.remove(l);
- }
- }
-
- /**
- * Notifies all interested listeners that a change in the chat room list
- * model has occurred.
- * @param adHocChatRoomWrapper the chat room wrapper that identifies the
- * chat room
- * @param eventID the identifier of the event
- */
- private void fireAdHocChatRoomListChangedEvent(
- AdHocChatRoomWrapper adHocChatRoomWrapper,
- int eventID)
- {
- AdHocChatRoomListChangeEvent evt
- = new AdHocChatRoomListChangeEvent(adHocChatRoomWrapper, eventID);
-
- for (AdHocChatRoomListChangeListener l : adHoclistChangeListeners)
- {
- l.contentChanged(evt);
- }
- }
-
-
- /**
- * Closes the chat corresponding to the given ad-hoc chat room wrapper, if
- * such exists.
- *
- * @param chatRoomWrapper the ad-hoc chat room wrapper for which we search a
- * chat to close.
- */
- private void closeAdHocChatRoom(AdHocChatRoomWrapper chatRoomWrapper)
- {
- ChatWindowManager chatWindowManager
- = GuiActivator.getUIService().getChatWindowManager();
- ChatPanel chatPanel
- = chatWindowManager.getMultiChat(chatRoomWrapper, false);
-
- if (chatPanel != null)
- chatWindowManager.closeChat(chatPanel);
- }
-
- /**
- * Handles <tt>ServiceEvent</tt>s triggered by adding or removing a
- * ProtocolProviderService. Updates the list of available chat rooms and
- * chat room servers.
- *
- * @param event The event to handle.
- */
- public void serviceChanged(ServiceEvent event)
- {
- // if the event is caused by a bundle being stopped, we don't want to
- // know
- if (event.getServiceReference().getBundle().getState()
- == Bundle.STOPPING)
- return;
-
- Object service = GuiActivator.bundleContext.getService(event
- .getServiceReference());
-
- // we don't care if the source service is not a protocol provider
- if (!(service instanceof ProtocolProviderService))
- return;
-
- ProtocolProviderService protocolProvider
- = (ProtocolProviderService) service;
-
-
- Object multiUserChatAdHocOpSet
- = protocolProvider
- .getOperationSet(OperationSetAdHocMultiUserChat.class);
-
- if (multiUserChatAdHocOpSet != null)
- {
- if (event.getType() == ServiceEvent.REGISTERED)
- {
- adHocChatRoomList.addChatProvider(protocolProvider);
- }
- else if (event.getType() == ServiceEvent.UNREGISTERING)
- {
- adHocChatRoomList.removeChatProvider(protocolProvider);
- }
- }
- }
-
- /**
- * Joins an ad-hoc chat room in an asynchronous way.
- */
- private static class JoinAdHocChatRoomTask
- extends SwingWorker<String, Object>
- {
- private static final String SUCCESS = "Success";
-
- private static final String AUTHENTICATION_FAILED
- = "AuthenticationFailed";
-
- private static final String REGISTRATION_REQUIRED
- = "RegistrationRequired";
-
- private static final String PROVIDER_NOT_REGISTERED
- = "ProviderNotRegistered";
-
- private static final String SUBSCRIPTION_ALREADY_EXISTS
- = "SubscriptionAlreadyExists";
-
- private static final String UNKNOWN_ERROR
- = "UnknownError";
-
- private final AdHocChatRoomWrapper adHocChatRoomWrapper;
-
- JoinAdHocChatRoomTask(AdHocChatRoomWrapper chatRoomWrapper)
- {
- this.adHocChatRoomWrapper = chatRoomWrapper;
- }
-
- /**
- * @override {@link SwingWorker}{@link #doInBackground()} to perform
- * all asynchronous tasks.
- * @return SUCCESS if success, otherwise the error code
- */
- @Override
- public String doInBackground()
- {
- AdHocChatRoom chatRoom = adHocChatRoomWrapper.getAdHocChatRoom();
-
- try
- {
- chatRoom.join();
-
- return SUCCESS;
- }
- catch (OperationFailedException e)
- {
- if (logger.isTraceEnabled())
- logger.trace("Failed to join ad-hoc chat room: "
- + chatRoom.getName(), e);
-
- switch (e.getErrorCode())
- {
- case OperationFailedException.AUTHENTICATION_FAILED:
- return AUTHENTICATION_FAILED;
- case OperationFailedException.REGISTRATION_REQUIRED:
- return REGISTRATION_REQUIRED;
- case OperationFailedException.PROVIDER_NOT_REGISTERED:
- return PROVIDER_NOT_REGISTERED;
- case OperationFailedException.SUBSCRIPTION_ALREADY_EXISTS:
- return SUBSCRIPTION_ALREADY_EXISTS;
- default:
- return UNKNOWN_ERROR;
- }
- }
- }
-
- /**
- * @override {@link SwingWorker}{@link #done()} to perform UI changes
- * after the ad-hoc chat room join task has finished.
- */
- @Override
- protected void done()
- {
- String returnCode = null;
- try
- {
- returnCode = get();
- }
- catch (InterruptedException ignore)
- {}
- catch (ExecutionException ignore)
- {}
-
- ConfigurationUtils.updateChatRoomStatus(
- adHocChatRoomWrapper.getParentProvider().getProtocolProvider(),
- adHocChatRoomWrapper.getAdHocChatRoomID(),
- GlobalStatusEnum.ONLINE_STATUS);
-
- String errorMessage = null;
- if(PROVIDER_NOT_REGISTERED.equals(returnCode))
- {
- errorMessage
- = GuiActivator.getResources()
- .getI18NString("service.gui.CHAT_ROOM_NOT_CONNECTED",
- new String[]{
- adHocChatRoomWrapper.getAdHocChatRoomName()});
- }
- else if(SUBSCRIPTION_ALREADY_EXISTS.equals(returnCode))
- {
- errorMessage
- = GuiActivator.getResources()
- .getI18NString("service.gui.CHAT_ROOM_ALREADY_JOINED",
- new String[]{
- adHocChatRoomWrapper.getAdHocChatRoomName()});
- }
- else
- {
- errorMessage
- = GuiActivator.getResources()
- .getI18NString("service.gui.FAILED_TO_JOIN_CHAT_ROOM",
- new String[]{
- adHocChatRoomWrapper.getAdHocChatRoomName()});
- }
-
- if (!SUCCESS.equals(returnCode)
- && !AUTHENTICATION_FAILED.equals(returnCode))
- {
- GuiActivator.getAlertUIService().showAlertPopup(
- GuiActivator.getResources().getI18NString(
- "service.gui.ERROR"), errorMessage);
- }
- }
- }
-
-
- /**
- * Indicates that an invitation has been received and opens the invitation
- * dialog to notify the user.
- * @param evt the <tt>AdHocChatRoomInvitationReceivedEvent</tt> that
- * notified us
- */
- public void invitationReceived(AdHocChatRoomInvitationReceivedEvent evt)
- {
- if (logger.isInfoEnabled())
- logger.info("Invitation received: "+evt.toString());
- OperationSetAdHocMultiUserChat multiUserChatOpSet
- = evt.getSourceOperationSet();
-
- InvitationReceivedDialog dialog = new InvitationReceivedDialog(
- this, multiUserChatOpSet, evt.getInvitation());
-
- dialog.setVisible(true);
- }
-
- /**
- * Implements the <tt>AdHocChatRoomMessageListener.messageDelivered</tt>
- * method.
- * <br>
- * Shows the message in the conversation area and clears the write message
- * area.
- * @param evt the <tt>AdHocChatRoomMessageDeliveredEvent</tt> that notified
- * us
- */
- public void messageDelivered(AdHocChatRoomMessageDeliveredEvent evt)
- {
- AdHocChatRoom sourceChatRoom = (AdHocChatRoom) evt.getSource();
-
- if (logger.isInfoEnabled())
- logger.info("MESSAGE DELIVERED to ad-hoc chat room: "
- + sourceChatRoom.getName());
-
- ChatPanel chatPanel
- = GuiActivator
- .getUIService()
- .getChatWindowManager()
- .getMultiChat(sourceChatRoom, false);
-
- if(chatPanel != null)
- {
- String messageType;
- switch (evt.getEventType())
- {
- case AdHocChatRoomMessageDeliveredEvent
- .CONVERSATION_MESSAGE_DELIVERED:
- messageType = Chat.OUTGOING_MESSAGE;
- break;
- case AdHocChatRoomMessageDeliveredEvent.ACTION_MESSAGE_DELIVERED:
- messageType = Chat.ACTION_MESSAGE;
- break;
- default:
- messageType = null;
- }
-
- Message msg = evt.getMessage();
-
- chatPanel
- .addMessage(
- sourceChatRoom
- .getParentProvider().getAccountID().getUserID(),
- null,
- evt.getTimestamp(),
- messageType,
- msg.getContent(),
- msg.getContentType(),
- msg.getMessageUID(),
- null);
- }
- else
- {
- logger.error("chat panel is null, message NOT DELIVERED !");
- }
- }
-
- /**
- * Implements <tt>AdHocChatRoomMessageListener.messageDeliveryFailed</tt>
- * method.
- * <br>
- * In the conversation area shows an error message, explaining the problem.
- * @param evt the <tt>AdHocChatRoomMessageDeliveryFailedEvent</tt> that
- * notified us
- */
- public void messageDeliveryFailed(
- AdHocChatRoomMessageDeliveryFailedEvent evt)
- {
- AdHocChatRoom sourceChatRoom = evt.getSourceChatRoom();
- Message sourceMessage = evt.getMessage();
- Contact destParticipant = evt.getDestinationParticipant();
-
- String errorMsg = null;
- if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.OFFLINE_MESSAGES_NOT_SUPPORTED)
- {
- errorMsg = GuiActivator.getResources().getI18NString(
- "service.gui.MSG_DELIVERY_NOT_SUPPORTED",
- new String[]{destParticipant.getDisplayName()});
- }
- else if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.NETWORK_FAILURE)
- {
- errorMsg = GuiActivator.getResources()
- .getI18NString("service.gui.MSG_NOT_DELIVERED");
- }
- else if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.PROVIDER_NOT_REGISTERED)
- {
- errorMsg = GuiActivator.getResources().getI18NString(
- "service.gui.MSG_SEND_CONNECTION_PROBLEM");
- }
- else if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.INTERNAL_ERROR)
- {
- errorMsg = GuiActivator.getResources().getI18NString(
- "service.gui.MSG_DELIVERY_INTERNAL_ERROR");
- }
- else if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.UNSUPPORTED_OPERATION)
- {
- errorMsg = GuiActivator.getResources().getI18NString(
- "service.gui.MSG_DELIVERY_UNSUPPORTED_OPERATION");
- }
- else
- {
- errorMsg = GuiActivator.getResources().getI18NString(
- "service.gui.MSG_DELIVERY_UNKNOWN_ERROR");
- }
-
- ChatWindowManager chatWindowManager
- = GuiActivator.getUIService().getChatWindowManager();
- ChatPanel chatPanel
- = chatWindowManager.getMultiChat(sourceChatRoom, true);
-
- chatPanel.addMessage(
- destParticipant.getDisplayName(),
- new Date(),
- Chat.OUTGOING_MESSAGE,
- sourceMessage.getContent(),
- sourceMessage.getContentType());
-
- chatPanel.addErrorMessage(
- destParticipant.getDisplayName(),
- errorMsg);
-
- chatWindowManager.openChat(chatPanel, false);
- }
-
- /**
- * Implements the <tt>AdHocChatRoomMessageListener.messageReceived</tt>
- * method.
- * <br>
- * Obtains the corresponding <tt>ChatPanel</tt> and process the message
- * there.
- * @param evt the <tt>AdHocChatRoomMessageReceivedEvent</tt> that notified
- * us
- */
- public void messageReceived(AdHocChatRoomMessageReceivedEvent evt)
- {
- AdHocChatRoom sourceChatRoom = evt.getSourceChatRoom();
- Contact sourceParticipant = evt.getSourceChatRoomParticipant();
-
- String messageType = null;
-
- switch (evt.getEventType())
- {
- case AdHocChatRoomMessageReceivedEvent.CONVERSATION_MESSAGE_RECEIVED:
- messageType = Chat.INCOMING_MESSAGE;
- break;
- case AdHocChatRoomMessageReceivedEvent.SYSTEM_MESSAGE_RECEIVED:
- messageType = Chat.SYSTEM_MESSAGE;
- break;
- case AdHocChatRoomMessageReceivedEvent.ACTION_MESSAGE_RECEIVED:
- messageType = Chat.ACTION_MESSAGE;
- break;
- }
-
- if (logger.isInfoEnabled())
- logger.info("MESSAGE RECEIVED from contact: "
- + sourceParticipant.getAddress());
-
- Message message = evt.getMessage();
-
- ChatWindowManager chatWindowManager
- = GuiActivator.getUIService().getChatWindowManager();
- ChatPanel chatPanel
- = chatWindowManager
- .getMultiChat(sourceChatRoom, true, message.getMessageUID());
-
- String messageContent = message.getContent();
-
- chatPanel.addMessage(
- sourceParticipant.getDisplayName(),
- null,
- evt.getTimestamp(),
- messageType,
- messageContent,
- message.getContentType(),
- message.getMessageUID(),
- null);
-
- chatWindowManager.openChat(chatPanel, false);
- }
-
- public void invitationRejected(AdHocChatRoomInvitationRejectedEvent evt) {}
-
- @Override
- public void localUserRoleChanged(ChatRoomLocalUserRoleChangeEvent evt)
- {
- if(evt.isInitial())
- return;
- ChatRoom sourceChatRoom = evt.getSourceChatRoom();
- ChatRoomWrapper chatRoomWrapper
- = GuiActivator.getMUCService().findChatRoomWrapperFromChatRoom(
- sourceChatRoom);
- ChatWindowManager chatWindowManager
- = GuiActivator.getUIService().getChatWindowManager();
- ChatPanel chatPanel
- = chatWindowManager.getMultiChat(chatRoomWrapper, true);
- chatWindowManager.openChat(chatPanel, true);
- }
-
-}
+package net.java.sip.communicator.impl.gui.main.chat.conference;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+import javax.swing.*;
+import javax.swing.SwingWorker;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.chat.*;
+import net.java.sip.communicator.impl.gui.main.chat.history.*;
+import net.java.sip.communicator.impl.gui.main.chatroomslist.*;
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.muc.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.service.protocol.globalstatus.*;
+import net.java.sip.communicator.util.*;
+import net.java.sip.communicator.util.Logger;
+
+import org.jitsi.util.*;
+import org.osgi.framework.*;
+
+/**
+ * The <tt>ConferenceChatManager</tt> is the one that manages both chat room and
+ * ad-hoc chat rooms invitations.
+ *
+ * @author Yana Stamcheva
+ * @author Lubomir Marinov
+ * @author Valentin Martinet
+ * @author Hristo Terezov
+ */
+public class ConferenceChatManager
+ implements ChatRoomMessageListener,
+ ChatRoomInvitationListener,
+ ChatRoomInvitationRejectionListener,
+ AdHocChatRoomMessageListener,
+ AdHocChatRoomInvitationListener,
+ AdHocChatRoomInvitationRejectionListener,
+ LocalUserChatRoomPresenceListener,
+ LocalUserAdHocChatRoomPresenceListener,
+ ServiceListener, ChatRoomLocalUserRoleListener
+{
+ /**
+ * The object used for logging.
+ */
+ private static final Logger logger
+ = Logger.getLogger(ConferenceChatManager.class);
+
+ /**
+ * Maps each history window to a <tt>ChatRoomWrapper</tt>.
+ */
+ private final Hashtable<ChatRoomWrapper, HistoryWindow> chatRoomHistory =
+ new Hashtable<ChatRoomWrapper, HistoryWindow>();
+
+ /**
+ * The list of ad-hoc chat rooms.
+ */
+ private final AdHocChatRoomList adHocChatRoomList = new AdHocChatRoomList();
+
+ /**
+ * A list of all <tt>AdHocChatRoomListChangeListener</tt>-s.
+ */
+ private final Vector<AdHocChatRoomListChangeListener>
+ adHoclistChangeListeners = new Vector<AdHocChatRoomListChangeListener>();
+
+ /**
+ * Creates an instance of <tt>ConferenceChatManager</tt>.
+ */
+ public ConferenceChatManager()
+ {
+ // Loads the chat rooms list in a separate thread.
+ new Thread()
+ {
+ @Override
+ public void run()
+ {
+ adHocChatRoomList.loadList();
+ }
+ }.start();
+
+ GuiActivator.bundleContext.addServiceListener(this);
+
+ }
+
+ /**
+ * Returns all chat room providers currently contained in the ad-hoc chat
+ * room list.
+ *
+ * @return all chat room providers currently contained in the ad-hoc chat
+ * room list.
+ */
+ public AdHocChatRoomList getAdHocChatRoomList()
+ {
+ return adHocChatRoomList;
+ }
+
+ /**
+ * Handles <tt>ChatRoomInvitationReceivedEvent</tt>-s.
+ */
+ public void invitationReceived(ChatRoomInvitationReceivedEvent evt)
+ {
+ InvitationReceivedDialog dialog
+ = new InvitationReceivedDialog(
+ this,
+ evt.getSourceOperationSet(),
+ evt.getInvitation());
+
+ dialog.setVisible(true);
+ }
+
+ public void invitationRejected(ChatRoomInvitationRejectedEvent evt) {}
+
+ /**
+ * Implements the <tt>ChatRoomMessageListener.messageDelivered</tt> method.
+ * <br>
+ * Shows the message in the conversation area and clears the write message
+ * area.
+ * @param evt the <tt>ChatRoomMessageDeliveredEvent</tt> that notified us
+ * that the message was delivered to its destination
+ */
+ public void messageDelivered(ChatRoomMessageDeliveredEvent evt)
+ {
+ ChatRoom sourceChatRoom = (ChatRoom) evt.getSource();
+
+ if (logger.isTraceEnabled())
+ logger.trace(
+ "MESSAGE DELIVERED to chat room: " + sourceChatRoom.getName());
+
+ ChatPanel chatPanel = GuiActivator.getUIService().getChatWindowManager()
+ .getMultiChat(sourceChatRoom, false);
+
+ if(chatPanel != null)
+ {
+ String messageType;
+
+ switch (evt.getEventType())
+ {
+ case ChatRoomMessageDeliveredEvent.CONVERSATION_MESSAGE_DELIVERED:
+ messageType = Chat.OUTGOING_MESSAGE;
+ break;
+ case ChatRoomMessageDeliveredEvent.ACTION_MESSAGE_DELIVERED:
+ messageType = Chat.ACTION_MESSAGE;
+ break;
+ default:
+ messageType = null;
+ break;
+ }
+
+ Message msg = evt.getMessage();
+
+ chatPanel.addMessage(
+ sourceChatRoom.getUserNickname(),
+ null,
+ evt.getTimestamp(),
+ messageType,
+ msg.getContent(),
+ msg.getContentType(),
+ msg.getMessageUID(),
+ null);
+ }
+ }
+
+ /**
+ * Implements the <tt>ChatRoomMessageListener.messageReceived</tt> method.
+ * <br>
+ * Obtains the corresponding <tt>ChatPanel</tt> and process the message
+ * there.
+ * @param evt the <tt>ChatRoomMessageReceivedEvent</tt> that notified us
+ * that a message has been received
+ */
+ public void messageReceived(ChatRoomMessageReceivedEvent evt)
+ {
+ ChatRoom sourceChatRoom = evt.getSourceChatRoom();
+ ChatRoomMember sourceMember = evt.getSourceChatRoomMember();
+
+ String messageType = null;
+
+ switch (evt.getEventType())
+ {
+ case ChatRoomMessageReceivedEvent.CONVERSATION_MESSAGE_RECEIVED:
+ messageType = Chat.INCOMING_MESSAGE;
+ break;
+ case ChatRoomMessageReceivedEvent.SYSTEM_MESSAGE_RECEIVED:
+ messageType = Chat.SYSTEM_MESSAGE;
+ break;
+ case ChatRoomMessageReceivedEvent.ACTION_MESSAGE_RECEIVED:
+ messageType = Chat.ACTION_MESSAGE;
+ break;
+ }
+
+ if (logger.isTraceEnabled())
+ logger.trace("MESSAGE RECEIVED from contact: "
+ + sourceMember.getContactAddress());
+
+ Message message = evt.getMessage();
+
+ ChatPanel chatPanel = null;
+
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+
+ boolean createWindow = false;
+ String autoOpenConfig
+ = MUCService.getChatRoomAutoOpenOption(
+ sourceChatRoom.getParentProvider(),
+ sourceChatRoom.getIdentifier());
+ if(autoOpenConfig == null)
+ autoOpenConfig = MUCService.DEFAULT_AUTO_OPEN_BEHAVIOUR;
+
+ if(autoOpenConfig.equals(MUCService.OPEN_ON_ACTIVITY)
+ || (autoOpenConfig.equals(MUCService.OPEN_ON_MESSAGE)
+ && !evt.isHistoryMessage())
+ || evt.isImportantMessage())
+ createWindow = true;
+
+ if(sourceChatRoom.isSystem())
+ {
+ ChatRoomProviderWrapper serverWrapper
+ = GuiActivator.getMUCService().findServerWrapperFromProvider(
+ sourceChatRoom.getParentProvider());
+
+ chatPanel = chatWindowManager.getMultiChat(
+ serverWrapper.getSystemRoomWrapper(), createWindow);
+ }
+ else
+ {
+ chatPanel = chatWindowManager.getMultiChat(
+ sourceChatRoom, createWindow, message.getMessageUID());
+ }
+
+ if(chatPanel == null)
+ return;
+
+ String messageContent = message.getContent();
+
+ if (evt.isHistoryMessage())
+ {
+ Date timeStamp = chatPanel.getChatConversationPanel()
+ .getLastIncomingMsgTimestamp();
+ Collection<Object> c =
+ chatPanel.getChatSession().getHistoryBeforeDate(
+ new Date(
+ timeStamp.equals(new Date(0))
+ ? System.currentTimeMillis() - 10000
+ : timeStamp.getTime()
+ ), 20);
+ if (c.size() > 0)
+ {
+ boolean isPresent = false;
+ for (Object o : c)
+ {
+ if (o instanceof ChatRoomMessageDeliveredEvent)
+ {
+ ChatRoomMessageDeliveredEvent ev =
+ (ChatRoomMessageDeliveredEvent) o;
+ if (evt.getTimestamp() != null
+ && evt.getTimestamp().equals(ev.getTimestamp()))
+ {
+ isPresent = true;
+ break;
+ }
+ }
+ else if(o instanceof ChatRoomMessageReceivedEvent)
+ {
+ ChatRoomMessageReceivedEvent ev =
+ (ChatRoomMessageReceivedEvent) o;
+ if (evt.getTimestamp() != null
+ && evt.getTimestamp().equals(ev.getTimestamp()))
+ {
+ isPresent = true;
+ break;
+ }
+ }
+
+ Message m2 = evt.getMessage();
+
+ if(m2 != null
+ && m2.getContent().equals(messageContent))
+ {
+ isPresent = true;
+ break;
+ }
+ }
+
+ if (isPresent)
+ return;
+ }
+ }
+
+ chatPanel.addMessage(
+ sourceMember.getName(),
+ null,
+ evt.getTimestamp(),
+ messageType,
+ messageContent,
+ message.getContentType(),
+ message.getMessageUID(),
+ null);
+
+ if(createWindow)
+ chatWindowManager.openChat(chatPanel, false);
+ }
+
+ /**
+ * Implements the <tt>ChatRoomMessageListener.messageDeliveryFailed</tt>
+ * method.
+ * <br>
+ * In the conversation area shows an error message, explaining the problem.
+ * @param evt the <tt>ChatRoomMessageDeliveryFailedEvent</tt> that notified
+ * us of a delivery failure
+ */
+ public void messageDeliveryFailed(ChatRoomMessageDeliveryFailedEvent evt)
+ {
+ ChatRoom sourceChatRoom = evt.getSourceChatRoom();
+
+ String errorMsg = null;
+
+ /*
+ * FIXME ChatRoomMessageDeliveryFailedEvent#getSource() is not a Message
+ * instance at the time of this writing and the attempt "(Message)
+ * evt.getSource()" seems to be to get the message which failed to be
+ * delivered. I'm not sure it's
+ * ChatRoomMessageDeliveryFailedEvent#getMessage() but since it's the
+ * only message I can get out of ChatRoomMessageDeliveryFailedEvent, I'm
+ * using it.
+ */
+ Message sourceMessage = evt.getMessage();
+
+ ChatRoomMember destMember = evt.getDestinationChatRoomMember();
+
+ if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.OFFLINE_MESSAGES_NOT_SUPPORTED)
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_DELIVERY_NOT_SUPPORTED",
+ new String[]{destMember.getName()});
+ }
+ else if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.NETWORK_FAILURE)
+ {
+ errorMsg = GuiActivator.getResources()
+ .getI18NString("service.gui.MSG_NOT_DELIVERED");
+ }
+ else if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.PROVIDER_NOT_REGISTERED)
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_SEND_CONNECTION_PROBLEM");
+ }
+ else if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.INTERNAL_ERROR)
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_DELIVERY_INTERNAL_ERROR");
+ }
+ else if (evt.getErrorCode()
+ == ChatRoomMessageDeliveryFailedEvent.FORBIDDEN)
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_SEND_MSG_FORBIDDEN");
+ }
+ else if (evt.getErrorCode()
+ == ChatRoomMessageDeliveryFailedEvent.UNSUPPORTED_OPERATION)
+ {
+ errorMsg =
+ GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_DELIVERY_UNSUPPORTED_OPERATION");
+ }
+ else
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_DELIVERY_UNKNOWN_ERROR");
+ }
+
+ String reason = evt.getReason();
+ if (reason != null)
+ errorMsg += " " + GuiActivator.getResources().getI18NString(
+ "service.gui.ERROR_WAS",
+ new String[]{reason});
+
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+ ChatPanel chatPanel
+ = chatWindowManager.getMultiChat(sourceChatRoom, true);
+
+ chatPanel.addMessage(
+ destMember != null ? destMember.getName()
+ : sourceChatRoom.getName(),
+ new Date(),
+ Chat.OUTGOING_MESSAGE,
+ sourceMessage.getContent(),
+ sourceMessage.getContentType());
+
+ chatPanel.addErrorMessage(
+ destMember != null ? destMember.getName()
+ : sourceChatRoom.getName(),
+ errorMsg);
+
+ chatWindowManager.openChat(chatPanel, false);
+ }
+
+ /**
+ * Implements the
+ * <tt>LocalUserAdHocChatRoomPresenceListener.localUserPresenceChanged</tt>
+ * method
+ *
+ * @param evt the <tt>LocalUserAdHocChatRoomPresenceChangeEvent</tt> that
+ * notified us of a presence change
+ */
+ public void localUserAdHocPresenceChanged(
+ LocalUserAdHocChatRoomPresenceChangeEvent evt)
+ {
+ AdHocChatRoom sourceAdHocChatRoom = evt.getAdHocChatRoom();
+ AdHocChatRoomWrapper adHocChatRoomWrapper
+ = adHocChatRoomList
+ .findChatRoomWrapperFromAdHocChatRoom(sourceAdHocChatRoom);
+
+ String eventType = evt.getEventType();
+
+ if (LocalUserAdHocChatRoomPresenceChangeEvent
+ .LOCAL_USER_JOINED.equals(eventType))
+ {
+ if(adHocChatRoomWrapper != null)
+ {
+ this.fireAdHocChatRoomListChangedEvent(
+ adHocChatRoomWrapper,
+ AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_CHANGED);
+
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+ ChatPanel chatPanel
+ = chatWindowManager
+ .getMultiChat(adHocChatRoomWrapper, true);
+
+ // Check if we have already opened a chat window for this chat
+ // wrapper and load the real chat room corresponding to the
+ // wrapper.
+ if(chatPanel.isShown())
+ ((AdHocConferenceChatSession) chatPanel.getChatSession())
+ .loadChatRoom(sourceAdHocChatRoom);
+ else
+ chatWindowManager.openChat(chatPanel, true);
+ }
+
+ sourceAdHocChatRoom.addMessageListener(this);
+ }
+ else if (evt.getEventType().equals(
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOIN_FAILED))
+ {
+ GuiActivator.getAlertUIService().showAlertPopup(
+ GuiActivator.getResources().getI18NString("service.gui.ERROR"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.FAILED_TO_JOIN_CHAT_ROOM",
+ new String[]{sourceAdHocChatRoom.getName()})
+ + evt.getReason());
+ }
+ else if (LocalUserAdHocChatRoomPresenceChangeEvent
+ .LOCAL_USER_LEFT.equals(eventType)
+ || LocalUserAdHocChatRoomPresenceChangeEvent
+ .LOCAL_USER_DROPPED.equals(eventType))
+ {
+ this.closeAdHocChatRoom(adHocChatRoomWrapper);
+
+ // Need to refresh the chat room's list in order to change
+ // the state of the chat room to offline.
+ fireAdHocChatRoomListChangedEvent(
+ adHocChatRoomWrapper,
+ AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_CHANGED);
+
+ sourceAdHocChatRoom.removeMessageListener(this);
+ }
+ }
+
+ /**
+ * Implements the
+ * <tt>LocalUserChatRoomPresenceListener.localUserPresenceChanged</tt>
+ * method.
+ * @param evt the <tt>LocalUserChatRoomPresenceChangeEvent</tt> that
+ * notified us
+ */
+ public void localUserPresenceChanged(
+ final LocalUserChatRoomPresenceChangeEvent evt)
+ {
+ if(!SwingUtilities.isEventDispatchThread())
+ {
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ localUserPresenceChanged(evt);
+ }
+ });
+ return;
+ }
+
+ ChatRoom sourceChatRoom = evt.getChatRoom();
+ ChatRoomWrapper chatRoomWrapper
+ = GuiActivator.getMUCService().findChatRoomWrapperFromChatRoom(
+ sourceChatRoom);
+
+ String eventType = evt.getEventType();
+
+ if (LocalUserChatRoomPresenceChangeEvent
+ .LOCAL_USER_JOINED.equals(eventType))
+ {
+ if(chatRoomWrapper != null)
+ {
+ GuiActivator.getMUCService().fireChatRoomListChangedEvent(
+ chatRoomWrapper,
+ ChatRoomListChangeEvent.CHAT_ROOM_CHANGED);
+
+ boolean createWindow = false;
+
+ String autoOpenConfig
+ = MUCService.getChatRoomAutoOpenOption(
+ sourceChatRoom.getParentProvider(),
+ sourceChatRoom.getIdentifier());
+
+ if(autoOpenConfig != null
+ && autoOpenConfig.equals(MUCService.OPEN_ON_ACTIVITY))
+ createWindow = true;
+
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+ ChatPanel chatPanel
+ = chatWindowManager.getMultiChat(
+ chatRoomWrapper, createWindow);
+
+ if(chatPanel != null)
+ {
+ chatPanel.setChatIcon(
+ chatPanel.getChatSession().getChatStatusIcon());
+
+ // Check if we have already opened a chat window for this chat
+ // wrapper and load the real chat room corresponding to the
+ // wrapper.
+ if(chatPanel.isShown())
+ {
+ ((ConferenceChatSession) chatPanel.getChatSession())
+ .loadChatRoom(sourceChatRoom);
+ }
+ else
+ {
+ chatWindowManager.openChat(chatPanel, true);
+ }
+ }
+ }
+
+ if (sourceChatRoom.isSystem())
+ {
+ ChatRoomProviderWrapper serverWrapper
+ = GuiActivator.getMUCService()
+ .findServerWrapperFromProvider(
+ sourceChatRoom.getParentProvider());
+
+ serverWrapper.setSystemRoom(sourceChatRoom);
+ }
+
+ sourceChatRoom.addMessageListener(this);
+ sourceChatRoom.addLocalUserRoleListener(this);
+ }
+ else if (LocalUserChatRoomPresenceChangeEvent
+ .LOCAL_USER_JOIN_FAILED.equals(eventType))
+ {
+ GuiActivator.getAlertUIService().showAlertPopup(
+ GuiActivator.getResources().getI18NString("service.gui.ERROR"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.FAILED_TO_JOIN_CHAT_ROOM",
+ new String[]{sourceChatRoom.getName()})
+ + evt.getReason());
+ }
+ else if (LocalUserChatRoomPresenceChangeEvent
+ .LOCAL_USER_LEFT.equals(eventType)
+ || LocalUserChatRoomPresenceChangeEvent
+ .LOCAL_USER_KICKED.equals(eventType)
+ || LocalUserChatRoomPresenceChangeEvent
+ .LOCAL_USER_DROPPED.equals(eventType))
+ {
+ if(chatRoomWrapper != null)
+ {
+ if(StringUtils.isNullOrEmpty(evt.getReason()))
+ {
+ GuiActivator.getUIService()
+ .closeChatRoomWindow(chatRoomWrapper);
+ }
+ else
+ {
+ // send some system messages informing for the
+ // reason of leaving
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+
+ ChatPanel chatPanel = chatWindowManager.getMultiChat(
+ sourceChatRoom, false);
+
+ if(chatPanel != null)
+ {
+ chatPanel.addMessage(
+ sourceChatRoom.getName(),
+ null,
+ new Date(),
+ Chat.SYSTEM_MESSAGE,
+ evt.getReason(),
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE,
+ null,
+ null);
+
+ // print and the alternate address
+ if(!StringUtils.isNullOrEmpty(
+ evt.getAlternateAddress()))
+ {
+ chatPanel.addMessage(
+ sourceChatRoom.getName(),
+ null,
+ new Date(),
+ Chat.SYSTEM_MESSAGE,
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_ALTERNATE_ADDRESS",
+ new String[]{evt.getAlternateAddress()}),
+ OperationSetBasicInstantMessaging
+ .DEFAULT_MIME_TYPE,
+ null,
+ null);
+ }
+ }
+ }
+
+ // Need to refresh the chat room's list in order to change
+ // the state of the chat room to offline.
+
+ GuiActivator.getMUCService().fireChatRoomListChangedEvent(
+ chatRoomWrapper,
+ ChatRoomListChangeEvent.CHAT_ROOM_CHANGED);
+ }
+
+ sourceChatRoom.removeMessageListener(this);
+ sourceChatRoom.removelocalUserRoleListener(this);
+ }
+ }
+
+
+ /**
+ * Called to accept an incoming invitation. Adds the invitation chat room
+ * to the list of chat rooms and joins it.
+ *
+ * @param invitation the invitation to accept
+ * @param multiUserChatOpSet the operation set for chat conferencing
+ * @throws OperationFailedException if the accept fails
+ */
+ public void acceptInvitation(
+ AdHocChatRoomInvitation invitation,
+ OperationSetAdHocMultiUserChat multiUserChatOpSet)
+ throws OperationFailedException
+ {
+ AdHocChatRoom chatRoom = invitation.getTargetAdHocChatRoom();
+
+ chatRoom.join();
+ }
+
+ /**
+ * Rejects the given invitation with the specified reason.
+ *
+ * @param multiUserChatAdHocOpSet the operation set to use for rejecting the
+ * invitation
+ * @param invitation the invitation to reject
+ * @param reason the reason for the rejection
+ */
+ public void rejectInvitation(
+ OperationSetAdHocMultiUserChat multiUserChatAdHocOpSet,
+ AdHocChatRoomInvitation invitation,
+ String reason)
+ {
+ multiUserChatAdHocOpSet.rejectInvitation(invitation, reason);
+ }
+
+ /**
+ * Creates an ad-hoc chat room, by specifying the ad-hoc chat room name, the
+ * parent protocol provider and eventually, the contacts invited to
+ * participate in this ad-hoc chat room.
+ *
+ * @param protocolProvider the parent protocol provider.
+ * @param contacts the contacts invited when creating the chat room.
+ * @param reason the reason for this invitation
+ * @return the <tt>AdHocChatRoomWrapper</tt> corresponding to the created
+ * ad hoc chat room
+ */
+ public AdHocChatRoomWrapper createAdHocChatRoom(
+ ProtocolProviderService protocolProvider,
+ Collection<String> contacts,
+ String reason)
+ {
+ AdHocChatRoomWrapper chatRoomWrapper = null;
+
+ OperationSetAdHocMultiUserChat groupChatOpSet
+ = protocolProvider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+
+ // If there's no group chat operation set we have nothing to do here.
+ if (groupChatOpSet == null)
+ return null;
+
+ AdHocChatRoom chatRoom = null;
+
+ try
+ {
+ java.util.List<String> members = new LinkedList<String>();
+
+ for(String address : contacts)
+ members.add(address);
+
+ chatRoom = groupChatOpSet.createAdHocChatRoom(
+ "chatroom-" + new Date().getTime(), members, reason);
+ }
+ catch (OperationFailedException ex)
+ {
+ new ErrorDialog(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.ERROR"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CREATE_CHAT_ROOM_ERROR",
+ new String[]{protocolProvider.getProtocolDisplayName()}),
+ ex)
+ .showDialog();
+ }
+ catch (OperationNotSupportedException ex)
+ {
+ new ErrorDialog(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.ERROR"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CREATE_CHAT_ROOM_ERROR",
+ new String[]{protocolProvider.getProtocolDisplayName()}),
+ ex)
+ .showDialog();
+ }
+
+ if(chatRoom != null)
+ {
+ AdHocChatRoomProviderWrapper parentProvider
+ = adHocChatRoomList.findServerWrapperFromProvider(
+ protocolProvider);
+
+ chatRoomWrapper = new AdHocChatRoomWrapper(
+ parentProvider, chatRoom);
+ parentProvider.addAdHocChatRoom(chatRoomWrapper);
+ adHocChatRoomList.addAdHocChatRoom(chatRoomWrapper);
+
+ fireAdHocChatRoomListChangedEvent(
+ chatRoomWrapper,
+ AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_ADDED);
+ }
+
+ return chatRoomWrapper;
+ }
+
+ /**
+ * Joins the given ad-hoc chat room
+ *
+ * @param chatRoomWrapper
+ */
+ public void joinChatRoom(AdHocChatRoomWrapper chatRoomWrapper)
+ {
+ AdHocChatRoom chatRoom = chatRoomWrapper.getAdHocChatRoom();
+
+ if(chatRoom == null)
+ {
+ new ErrorDialog(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.WARNING"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_NOT_CONNECTED",
+ new String[]{chatRoomWrapper.getAdHocChatRoomName()}))
+ .showDialog();
+
+ return;
+ }
+
+ new JoinAdHocChatRoomTask(chatRoomWrapper).execute();
+ }
+
+ /**
+ * Removes the given chat room from the UI.
+ *
+ * @param chatRoomWrapper the chat room to remove.
+ */
+ public void removeChatRoom(ChatRoomWrapper chatRoomWrapper)
+ {
+ ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
+
+ if (chatRoom != null)
+ leaveChatRoom(chatRoomWrapper);
+
+ GuiActivator.getUIService().closeChatRoomWindow(chatRoomWrapper);
+
+ GuiActivator.getMUCService().removeChatRoom(chatRoomWrapper);
+
+ }
+
+ /**
+ * Joins the given chat room and manages all the exceptions that could
+ * occur during the join process.
+ *
+ * @param chatRoom the chat room to join
+ */
+ public void joinChatRoom(AdHocChatRoom chatRoom)
+ {
+ AdHocChatRoomWrapper chatRoomWrapper
+ = adHocChatRoomList.findChatRoomWrapperFromAdHocChatRoom(chatRoom);
+
+ if(chatRoomWrapper == null)
+ {
+ AdHocChatRoomProviderWrapper parentProvider
+ = adHocChatRoomList.findServerWrapperFromProvider(
+ chatRoom.getParentProvider());
+
+ chatRoomWrapper =
+ new AdHocChatRoomWrapper(parentProvider, chatRoom);
+
+ adHocChatRoomList.addAdHocChatRoom(chatRoomWrapper);
+
+ fireAdHocChatRoomListChangedEvent(
+ chatRoomWrapper,
+ AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_ADDED);
+ }
+
+ this.joinChatRoom(chatRoomWrapper);
+
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+
+ chatWindowManager
+ .openChat(
+ chatWindowManager.getMultiChat(chatRoomWrapper, true),
+ true);
+ }
+
+ /**
+ * Leaves the given <tt>ChatRoom</tt>.
+ *
+ * @param chatRoomWrapper the <tt>ChatRoom</tt> to leave.
+ */
+ public void leaveChatRoom(ChatRoomWrapper chatRoomWrapper)
+ {
+ ChatRoomWrapper leavedRoomWrapped
+ = GuiActivator.getMUCService().leaveChatRoom(chatRoomWrapper);
+ if(leavedRoomWrapped != null)
+ GuiActivator.getUIService().closeChatRoomWindow(leavedRoomWrapped);
+ }
+
+ /**
+ * Leaves the given <tt>ChatRoom</tt>.
+ *
+ * @param chatRoomWrapper the <tt>ChatRoom</tt> to leave.
+ */
+ public void leaveChatRoom(AdHocChatRoomWrapper chatRoomWrapper)
+ {
+ AdHocChatRoom chatRoom = chatRoomWrapper.getAdHocChatRoom();
+
+ if (chatRoom != null)
+ {
+ chatRoom.leave();
+ }
+ else
+ {
+ new ErrorDialog(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.WARNING"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED"))
+ .showDialog();
+ }
+ }
+
+ /**
+ * Checks if there's an open history window for the given chat room.
+ *
+ * @param chatRoomWrapper the chat room wrapper to check for
+ * @return TRUE if there's an opened history window for the given chat room,
+ * FALSE otherwise.
+ */
+ public boolean containsHistoryWindowForChatRoom(
+ ChatRoomWrapper chatRoomWrapper)
+ {
+ return chatRoomHistory.containsKey(chatRoomWrapper);
+ }
+
+ /**
+ * Returns the history window for the given chat room.
+ *
+ * @param chatRoomWrapper the chat room wrapper to search for
+ * @return the history window for the given chat room
+ */
+ public HistoryWindow getHistoryWindowForChatRoom(
+ ChatRoomWrapper chatRoomWrapper)
+ {
+ return chatRoomHistory.get(chatRoomWrapper);
+ }
+
+ /**
+ * Adds a history window for a given chat room in the table of opened
+ * history windows.
+ *
+ * @param chatRoomWrapper the chat room wrapper to add
+ * @param historyWindow the history window to add
+ */
+ public void addHistoryWindowForChatRoom(ChatRoomWrapper chatRoomWrapper,
+ HistoryWindow historyWindow)
+ {
+ chatRoomHistory.put(chatRoomWrapper, historyWindow);
+ }
+
+ /**
+ * Removes the history window for the given chat room.
+ *
+ * @param chatRoomWrapper the chat room wrapper to remove the history window
+ */
+ public void removeHistoryWindowForChatRoom(ChatRoomWrapper chatRoomWrapper)
+ {
+ chatRoomHistory.remove(chatRoomWrapper);
+ }
+
+ /**
+ * Adds the given <tt>AdHocChatRoomListChangeListener</tt> that will listen
+ * for all changes of the chat room list data model.
+ *
+ * @param l the listener to add.
+ */
+ public void addAdHocChatRoomListChangeListener(
+ AdHocChatRoomListChangeListener l)
+ {
+ synchronized (adHoclistChangeListeners)
+ {
+ adHoclistChangeListeners.add(l);
+ }
+ }
+
+ /**
+ * Removes the given <tt>AdHocChatRoomListChangeListener</tt>.
+ *
+ * @param l the listener to remove.
+ */
+ public void removeAdHocChatRoomListChangeListener(
+ AdHocChatRoomListChangeListener l)
+ {
+ synchronized (adHoclistChangeListeners)
+ {
+ adHoclistChangeListeners.remove(l);
+ }
+ }
+
+ /**
+ * Notifies all interested listeners that a change in the chat room list
+ * model has occurred.
+ * @param adHocChatRoomWrapper the chat room wrapper that identifies the
+ * chat room
+ * @param eventID the identifier of the event
+ */
+ private void fireAdHocChatRoomListChangedEvent(
+ AdHocChatRoomWrapper adHocChatRoomWrapper,
+ int eventID)
+ {
+ AdHocChatRoomListChangeEvent evt
+ = new AdHocChatRoomListChangeEvent(adHocChatRoomWrapper, eventID);
+
+ for (AdHocChatRoomListChangeListener l : adHoclistChangeListeners)
+ {
+ l.contentChanged(evt);
+ }
+ }
+
+
+ /**
+ * Closes the chat corresponding to the given ad-hoc chat room wrapper, if
+ * such exists.
+ *
+ * @param chatRoomWrapper the ad-hoc chat room wrapper for which we search a
+ * chat to close.
+ */
+ private void closeAdHocChatRoom(AdHocChatRoomWrapper chatRoomWrapper)
+ {
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+ ChatPanel chatPanel
+ = chatWindowManager.getMultiChat(chatRoomWrapper, false);
+
+ if (chatPanel != null)
+ chatWindowManager.closeChat(chatPanel);
+ }
+
+ /**
+ * Handles <tt>ServiceEvent</tt>s triggered by adding or removing a
+ * ProtocolProviderService. Updates the list of available chat rooms and
+ * chat room servers.
+ *
+ * @param event The event to handle.
+ */
+ public void serviceChanged(ServiceEvent event)
+ {
+ // if the event is caused by a bundle being stopped, we don't want to
+ // know
+ if (event.getServiceReference().getBundle().getState()
+ == Bundle.STOPPING)
+ return;
+
+ Object service = GuiActivator.bundleContext.getService(event
+ .getServiceReference());
+
+ // we don't care if the source service is not a protocol provider
+ if (!(service instanceof ProtocolProviderService))
+ return;
+
+ ProtocolProviderService protocolProvider
+ = (ProtocolProviderService) service;
+
+
+ Object multiUserChatAdHocOpSet
+ = protocolProvider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+
+ if (multiUserChatAdHocOpSet != null)
+ {
+ if (event.getType() == ServiceEvent.REGISTERED)
+ {
+ adHocChatRoomList.addChatProvider(protocolProvider);
+ }
+ else if (event.getType() == ServiceEvent.UNREGISTERING)
+ {
+ adHocChatRoomList.removeChatProvider(protocolProvider);
+ }
+ }
+ }
+
+ /**
+ * Joins an ad-hoc chat room in an asynchronous way.
+ */
+ private static class JoinAdHocChatRoomTask
+ extends SwingWorker<String, Object>
+ {
+ private static final String SUCCESS = "Success";
+
+ private static final String AUTHENTICATION_FAILED
+ = "AuthenticationFailed";
+
+ private static final String REGISTRATION_REQUIRED
+ = "RegistrationRequired";
+
+ private static final String PROVIDER_NOT_REGISTERED
+ = "ProviderNotRegistered";
+
+ private static final String SUBSCRIPTION_ALREADY_EXISTS
+ = "SubscriptionAlreadyExists";
+
+ private static final String UNKNOWN_ERROR
+ = "UnknownError";
+
+ private final AdHocChatRoomWrapper adHocChatRoomWrapper;
+
+ JoinAdHocChatRoomTask(AdHocChatRoomWrapper chatRoomWrapper)
+ {
+ this.adHocChatRoomWrapper = chatRoomWrapper;
+ }
+
+ /**
+ * @override {@link SwingWorker}{@link #doInBackground()} to perform
+ * all asynchronous tasks.
+ * @return SUCCESS if success, otherwise the error code
+ */
+ @Override
+ public String doInBackground()
+ {
+ AdHocChatRoom chatRoom = adHocChatRoomWrapper.getAdHocChatRoom();
+
+ try
+ {
+ chatRoom.join();
+
+ return SUCCESS;
+ }
+ catch (OperationFailedException e)
+ {
+ if (logger.isTraceEnabled())
+ logger.trace("Failed to join ad-hoc chat room: "
+ + chatRoom.getName(), e);
+
+ switch (e.getErrorCode())
+ {
+ case OperationFailedException.AUTHENTICATION_FAILED:
+ return AUTHENTICATION_FAILED;
+ case OperationFailedException.REGISTRATION_REQUIRED:
+ return REGISTRATION_REQUIRED;
+ case OperationFailedException.PROVIDER_NOT_REGISTERED:
+ return PROVIDER_NOT_REGISTERED;
+ case OperationFailedException.SUBSCRIPTION_ALREADY_EXISTS:
+ return SUBSCRIPTION_ALREADY_EXISTS;
+ default:
+ return UNKNOWN_ERROR;
+ }
+ }
+ }
+
+ /**
+ * @override {@link SwingWorker}{@link #done()} to perform UI changes
+ * after the ad-hoc chat room join task has finished.
+ */
+ @Override
+ protected void done()
+ {
+ String returnCode = null;
+ try
+ {
+ returnCode = get();
+ }
+ catch (InterruptedException ignore)
+ {}
+ catch (ExecutionException ignore)
+ {}
+
+ ConfigurationUtils.updateChatRoomStatus(
+ adHocChatRoomWrapper.getParentProvider().getProtocolProvider(),
+ adHocChatRoomWrapper.getAdHocChatRoomID(),
+ GlobalStatusEnum.ONLINE_STATUS);
+
+ String errorMessage = null;
+ if(PROVIDER_NOT_REGISTERED.equals(returnCode))
+ {
+ errorMessage
+ = GuiActivator.getResources()
+ .getI18NString("service.gui.CHAT_ROOM_NOT_CONNECTED",
+ new String[]{
+ adHocChatRoomWrapper.getAdHocChatRoomName()});
+ }
+ else if(SUBSCRIPTION_ALREADY_EXISTS.equals(returnCode))
+ {
+ errorMessage
+ = GuiActivator.getResources()
+ .getI18NString("service.gui.CHAT_ROOM_ALREADY_JOINED",
+ new String[]{
+ adHocChatRoomWrapper.getAdHocChatRoomName()});
+ }
+ else
+ {
+ errorMessage
+ = GuiActivator.getResources()
+ .getI18NString("service.gui.FAILED_TO_JOIN_CHAT_ROOM",
+ new String[]{
+ adHocChatRoomWrapper.getAdHocChatRoomName()});
+ }
+
+ if (!SUCCESS.equals(returnCode)
+ && !AUTHENTICATION_FAILED.equals(returnCode))
+ {
+ GuiActivator.getAlertUIService().showAlertPopup(
+ GuiActivator.getResources().getI18NString(
+ "service.gui.ERROR"), errorMessage);
+ }
+ }
+ }
+
+
+ /**
+ * Indicates that an invitation has been received and opens the invitation
+ * dialog to notify the user.
+ * @param evt the <tt>AdHocChatRoomInvitationReceivedEvent</tt> that
+ * notified us
+ */
+ public void invitationReceived(AdHocChatRoomInvitationReceivedEvent evt)
+ {
+ if (logger.isInfoEnabled())
+ logger.info("Invitation received: "+evt.toString());
+ OperationSetAdHocMultiUserChat multiUserChatOpSet
+ = evt.getSourceOperationSet();
+
+ InvitationReceivedDialog dialog = new InvitationReceivedDialog(
+ this, multiUserChatOpSet, evt.getInvitation());
+
+ dialog.setVisible(true);
+ }
+
+ /**
+ * Implements the <tt>AdHocChatRoomMessageListener.messageDelivered</tt>
+ * method.
+ * <br>
+ * Shows the message in the conversation area and clears the write message
+ * area.
+ * @param evt the <tt>AdHocChatRoomMessageDeliveredEvent</tt> that notified
+ * us
+ */
+ public void messageDelivered(AdHocChatRoomMessageDeliveredEvent evt)
+ {
+ AdHocChatRoom sourceChatRoom = (AdHocChatRoom) evt.getSource();
+
+ if (logger.isInfoEnabled())
+ logger.info("MESSAGE DELIVERED to ad-hoc chat room: "
+ + sourceChatRoom.getName());
+
+ ChatPanel chatPanel
+ = GuiActivator
+ .getUIService()
+ .getChatWindowManager()
+ .getMultiChat(sourceChatRoom, false);
+
+ if(chatPanel != null)
+ {
+ String messageType;
+ switch (evt.getEventType())
+ {
+ case AdHocChatRoomMessageDeliveredEvent
+ .CONVERSATION_MESSAGE_DELIVERED:
+ messageType = Chat.OUTGOING_MESSAGE;
+ break;
+ case AdHocChatRoomMessageDeliveredEvent.ACTION_MESSAGE_DELIVERED:
+ messageType = Chat.ACTION_MESSAGE;
+ break;
+ default:
+ messageType = null;
+ }
+
+ Message msg = evt.getMessage();
+
+ chatPanel
+ .addMessage(
+ sourceChatRoom
+ .getParentProvider().getAccountID().getUserID(),
+ null,
+ evt.getTimestamp(),
+ messageType,
+ msg.getContent(),
+ msg.getContentType(),
+ msg.getMessageUID(),
+ null);
+ }
+ else
+ {
+ logger.error("chat panel is null, message NOT DELIVERED !");
+ }
+ }
+
+ /**
+ * Implements <tt>AdHocChatRoomMessageListener.messageDeliveryFailed</tt>
+ * method.
+ * <br>
+ * In the conversation area shows an error message, explaining the problem.
+ * @param evt the <tt>AdHocChatRoomMessageDeliveryFailedEvent</tt> that
+ * notified us
+ */
+ public void messageDeliveryFailed(
+ AdHocChatRoomMessageDeliveryFailedEvent evt)
+ {
+ AdHocChatRoom sourceChatRoom = evt.getSourceChatRoom();
+ Message sourceMessage = evt.getMessage();
+ Contact destParticipant = evt.getDestinationParticipant();
+
+ String errorMsg = null;
+ if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.OFFLINE_MESSAGES_NOT_SUPPORTED)
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_DELIVERY_NOT_SUPPORTED",
+ new String[]{destParticipant.getDisplayName()});
+ }
+ else if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.NETWORK_FAILURE)
+ {
+ errorMsg = GuiActivator.getResources()
+ .getI18NString("service.gui.MSG_NOT_DELIVERED");
+ }
+ else if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.PROVIDER_NOT_REGISTERED)
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_SEND_CONNECTION_PROBLEM");
+ }
+ else if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.INTERNAL_ERROR)
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_DELIVERY_INTERNAL_ERROR");
+ }
+ else if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.UNSUPPORTED_OPERATION)
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_DELIVERY_UNSUPPORTED_OPERATION");
+ }
+ else
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_DELIVERY_UNKNOWN_ERROR");
+ }
+
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+ ChatPanel chatPanel
+ = chatWindowManager.getMultiChat(sourceChatRoom, true);
+
+ chatPanel.addMessage(
+ destParticipant.getDisplayName(),
+ new Date(),
+ Chat.OUTGOING_MESSAGE,
+ sourceMessage.getContent(),
+ sourceMessage.getContentType());
+
+ chatPanel.addErrorMessage(
+ destParticipant.getDisplayName(),
+ errorMsg);
+
+ chatWindowManager.openChat(chatPanel, false);
+ }
+
+ /**
+ * Implements the <tt>AdHocChatRoomMessageListener.messageReceived</tt>
+ * method.
+ * <br>
+ * Obtains the corresponding <tt>ChatPanel</tt> and process the message
+ * there.
+ * @param evt the <tt>AdHocChatRoomMessageReceivedEvent</tt> that notified
+ * us
+ */
+ public void messageReceived(AdHocChatRoomMessageReceivedEvent evt)
+ {
+ AdHocChatRoom sourceChatRoom = evt.getSourceChatRoom();
+ Contact sourceParticipant = evt.getSourceChatRoomParticipant();
+
+ String messageType = null;
+
+ switch (evt.getEventType())
+ {
+ case AdHocChatRoomMessageReceivedEvent.CONVERSATION_MESSAGE_RECEIVED:
+ messageType = Chat.INCOMING_MESSAGE;
+ break;
+ case AdHocChatRoomMessageReceivedEvent.SYSTEM_MESSAGE_RECEIVED:
+ messageType = Chat.SYSTEM_MESSAGE;
+ break;
+ case AdHocChatRoomMessageReceivedEvent.ACTION_MESSAGE_RECEIVED:
+ messageType = Chat.ACTION_MESSAGE;
+ break;
+ }
+
+ if (logger.isInfoEnabled())
+ logger.info("MESSAGE RECEIVED from contact: "
+ + sourceParticipant.getAddress());
+
+ Message message = evt.getMessage();
+
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+ ChatPanel chatPanel
+ = chatWindowManager
+ .getMultiChat(sourceChatRoom, true, message.getMessageUID());
+
+ String messageContent = message.getContent();
+
+ chatPanel.addMessage(
+ sourceParticipant.getDisplayName(),
+ null,
+ evt.getTimestamp(),
+ messageType,
+ messageContent,
+ message.getContentType(),
+ message.getMessageUID(),
+ null);
+
+ chatWindowManager.openChat(chatPanel, false);
+ }
+
+ public void invitationRejected(AdHocChatRoomInvitationRejectedEvent evt) {}
+
+ @Override
+ public void localUserRoleChanged(ChatRoomLocalUserRoleChangeEvent evt)
+ {
+ if(evt.isInitial())
+ return;
+ ChatRoom sourceChatRoom = evt.getSourceChatRoom();
+ ChatRoomWrapper chatRoomWrapper
+ = GuiActivator.getMUCService().findChatRoomWrapperFromChatRoom(
+ sourceChatRoom);
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+ ChatPanel chatPanel
+ = chatWindowManager.getMultiChat(chatRoomWrapper, true);
+ chatWindowManager.openChat(chatPanel, true);
+ }
+
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/filetransfer/ReceiveFileConversationComponent.java b/src/net/java/sip/communicator/impl/gui/main/chat/filetransfer/ReceiveFileConversationComponent.java
index ef72a89..f5a698b 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/filetransfer/ReceiveFileConversationComponent.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/filetransfer/ReceiveFileConversationComponent.java
@@ -164,6 +164,10 @@ public class ReceiveFileConversationComponent
File downloadDir = null;
String incomingFileName = fileTransferRequest.getFileName();
+ // strip characters that are invalid on Windows and maybe other
+ // platforms too
+ incomingFileName = incomingFileName
+ .replaceAll("[\\\\/:*?\"<>|]", "_");
try
{
downloadDir = GuiActivator.getFileAccessService()
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/toolBars/MainToolBar.java b/src/net/java/sip/communicator/impl/gui/main/chat/toolBars/MainToolBar.java
index 6905df9..7080d13 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/toolBars/MainToolBar.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/toolBars/MainToolBar.java
@@ -715,14 +715,19 @@ public class MainToolBar
m.put(opSetClass, ct.getProtocolProvider());
UIContactDetailImpl d = new UIContactDetailImpl(
- ct.getName(),
+ ct.getName() + (ct.getResourceName() == null
+ ? ""
+ : "/" + ct.getResourceName()),
ct.getDisplayName(),
null,
- null,
+ (ct.getResourceName() == null
+ ? Arrays.asList(GuiActivator.getResources().getI18NString("service.gui.VIA") + ": "
+ + ct.getProtocolProvider().getAccountID().getAccountAddress())
+ : null),
null,
m,
null,
- ct.getName());
+ ct);
PresenceStatus status = ct.getStatus();
byte[] statusIconBytes = status.getStatusIcon();
@@ -736,7 +741,7 @@ public class MainToolBar
res.add(d);
}
-
+
Point location = new Point(callButton.getX(),
callButton.getY() + callButton.getHeight());
diff --git a/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomTableDialog.java b/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomTableDialog.java
index 0efb860..28f3e08 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomTableDialog.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomTableDialog.java
@@ -55,6 +55,13 @@ public class ChatRoomTableDialog
"REMOVE_ROOM_ON_FIRST_JOIN_FAILED";
/**
+ * Whether we should make rooms autojoin by default.
+ */
+ private static final String ENABLE_ROOM_AUTO_JOIN_ON_CREATION
+ = "net.java.sip.communicator.impl.gui.main.chatroomslist." +
+ "ENABLE_ROOM_AUTO_JOIN_ON_CREATION";
+
+ /**
* The global/shared <code>ChatRoomTableDialog</code> currently showing.
*/
private static ChatRoomTableDialog chatRoomTableDialog;
@@ -425,6 +432,12 @@ public class ChatRoomTableDialog
chatRoomWrapper.getChatRoomID(),
chatRoomWrapper.getChatRoomID(),
chatRoomWrapper.getChatRoomName());
+
+ if(GuiActivator.getConfigurationService()
+ .getBoolean(ENABLE_ROOM_AUTO_JOIN_ON_CREATION, false))
+ {
+ chatRoomWrapper.setAutoJoin(true);
+ }
}
String nickName = nicknameField.getText().trim();
diff --git a/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ServerChatRoomsChoiceDialog.java b/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ServerChatRoomsChoiceDialog.java
index 3eeb783..4725a08 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ServerChatRoomsChoiceDialog.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ServerChatRoomsChoiceDialog.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,97 +15,97 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.gui.main.chatroomslist;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import net.java.sip.communicator.impl.gui.*;
-import net.java.sip.communicator.impl.gui.main.contactlist.*;
-import net.java.sip.communicator.impl.gui.utils.*;
-import net.java.sip.communicator.service.contactsource.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.muc.*;
-
-/**
- * A dialog that lists the existing chat rooms on the server.
- *
- * @author Hristo Terezov
- */
-public class ServerChatRoomsChoiceDialog
- extends OneChoiceInviteDialog
-{
-
- /**
- * Generated serial id.
- */
- private static final long serialVersionUID = 428358553225114162L;
-
- /**
- * The contact source that generates the list of chat rooms.
- */
- private ContactSourceService contactSource;
-
- /**
- * Creates new instance of <tt>ServerChatRoomsChoiceDialog</tt>.
- *
- * @param title the title of the window.
- * @param pps the protocol provider service associated with the list of chat
- * rooms.
- */
- public ServerChatRoomsChoiceDialog(String title,
- ChatRoomProviderWrapper pps)
- {
- super(title);
- contactList.setDefaultFilter(new SearchFilter(contactList));
- contactList.removeAllContactSources();
- contactSource = GuiActivator.getMUCService()
- .getServerChatRoomsContactSourceForProvider(pps);
- contactList.addContactSource(
- contactSource);
-
- setInfoText(GuiActivator.getResources().getI18NString(
- "service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT"));
-
- contactList.applyDefaultFilter();
- this.setMinimumSize(new Dimension(300, 300));
- addOkButtonListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- UIContact uiContact = getSelectedContact();
-
- if (uiContact != null)
- {
- ChatRoomTableDialog.setChatRoomField(
- uiContact.getDisplayName());
- }
-
- setVisible(false);
- dispose();
- }
- });
- addCancelButtonListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- setVisible(false);
- dispose();
- }
- });
- }
-
- /**
- * Handles provider change.
- *
- * @param provider the provider.
- */
- public void changeProtocolProvider(ChatRoomProviderWrapper provider)
- {
- contactList.removeContactSource(contactSource);
- contactSource = GuiActivator.getMUCService()
- .getServerChatRoomsContactSourceForProvider(provider);
- contactList.addContactSource(contactSource);
- contactList.applyDefaultFilter();
- }
-}
+package net.java.sip.communicator.impl.gui.main.chatroomslist;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.contactlist.*;
+import net.java.sip.communicator.impl.gui.utils.*;
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.muc.*;
+
+/**
+ * A dialog that lists the existing chat rooms on the server.
+ *
+ * @author Hristo Terezov
+ */
+public class ServerChatRoomsChoiceDialog
+ extends OneChoiceInviteDialog
+{
+
+ /**
+ * Generated serial id.
+ */
+ private static final long serialVersionUID = 428358553225114162L;
+
+ /**
+ * The contact source that generates the list of chat rooms.
+ */
+ private ContactSourceService contactSource;
+
+ /**
+ * Creates new instance of <tt>ServerChatRoomsChoiceDialog</tt>.
+ *
+ * @param title the title of the window.
+ * @param pps the protocol provider service associated with the list of chat
+ * rooms.
+ */
+ public ServerChatRoomsChoiceDialog(String title,
+ ChatRoomProviderWrapper pps)
+ {
+ super(title);
+ contactList.setDefaultFilter(new SearchFilter(contactList));
+ contactList.removeAllContactSources();
+ contactSource = GuiActivator.getMUCService()
+ .getServerChatRoomsContactSourceForProvider(pps);
+ contactList.addContactSource(
+ contactSource);
+
+ setInfoText(GuiActivator.getResources().getI18NString(
+ "service.gui.SERVER_CHAT_ROOMS_DIALOG_TEXT"));
+
+ contactList.applyDefaultFilter();
+ this.setMinimumSize(new Dimension(300, 300));
+ addOkButtonListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ UIContact uiContact = getSelectedContact();
+
+ if (uiContact != null)
+ {
+ ChatRoomTableDialog.setChatRoomField(
+ uiContact.getDisplayName());
+ }
+
+ setVisible(false);
+ dispose();
+ }
+ });
+ addCancelButtonListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ setVisible(false);
+ dispose();
+ }
+ });
+ }
+
+ /**
+ * Handles provider change.
+ *
+ * @param provider the provider.
+ */
+ public void changeProtocolProvider(ChatRoomProviderWrapper provider)
+ {
+ contactList.removeContactSource(contactSource);
+ contactSource = GuiActivator.getMUCService()
+ .getServerChatRoomsContactSourceForProvider(provider);
+ contactList.addContactSource(contactSource);
+ contactList.applyDefaultFilter();
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/AddContactDialog.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/AddContactDialog.java
index 856ae5b..8d43c7f 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/AddContactDialog.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/AddContactDialog.java
@@ -21,9 +21,14 @@ import java.awt.*;
import java.awt.Container;
import java.awt.event.*;
import java.util.*;
+import java.util.List;
import javax.swing.*;
+import javax.swing.border.*;
import javax.swing.event.*;
+import javax.swing.text.*;
+
+import org.jitsi.util.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.contactlist.addgroup.*;
@@ -163,31 +168,100 @@ public class AddContactDialog
}
/**
+ * Adds a faint gray prompt to the provided text field that
+ * will vanish as soon as text is entered into the field.
+ */
+ private void addPrompt(JTextField field, String text)
+ {
+ final JLabel prompt = new JLabel(text);
+
+ // Give prompt a foreground color like the original
+ // text field, but with half transparency.
+ final Color fg = field.getForeground();
+ final Color color = new Color(
+ fg.getRed(), fg.getGreen(), fg.getBlue(), 128);
+
+ // Mimic properties of given text field
+ prompt.setFont(field.getFont());
+ prompt.setForeground(color);
+ prompt.setBorder(new EmptyBorder(field.getInsets()));
+ prompt.setHorizontalAlignment(JLabel.LEADING);
+
+ // Add handler to hide prompt when text is entered
+ final Document doc = field.getDocument();
+ doc.addDocumentListener( new DocumentListener() {
+ public void insertUpdate(DocumentEvent e)
+ {
+ prompt.setVisible(doc.getLength() == 0);
+ }
+
+ public void removeUpdate(DocumentEvent e)
+ {
+ prompt.setVisible(doc.getLength() == 0);
+ }
+
+ public void changedUpdate(DocumentEvent e) {}
+ });
+
+ // Add prompt to text field
+ field.setLayout( new BorderLayout() );
+ field.add(prompt);
+ }
+
+ /**
* Initializes the dialog.
*/
private void init()
{
+ // Get tool tip text for primary controls
+ final String displayNameInfo =
+ GuiActivator.getResources().getI18NString(
+ "service.gui.DISPLAY_NAME_INFO");
+ final String contactInfo =
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CONTACT_NAME_INFO");
+ final String accountInfo =
+ GuiActivator.getResources().getI18NString(
+ "service.gui.SELECT_ACCOUNT_INFO");
+ final String groupInfo =
+ GuiActivator.getResources().getI18NString(
+ "service.gui.SELECT_GROUP_INFO");
+
+ // Initialize controls
this.accountLabel = new JLabel(
GuiActivator.getResources().getI18NString(
"service.gui.SELECT_ACCOUNT") + ": ");
+ this.accountLabel.setToolTipText(accountInfo);
this.accountCombo = new JComboBox();
-
- this.groupLabel = new JLabel(
- GuiActivator.getResources().getI18NString(
- "service.gui.SELECT_GROUP") + ": ");
+ this.accountCombo.setToolTipText(accountInfo);
this.contactAddressLabel = new JLabel(
GuiActivator.getResources().getI18NString(
"service.gui.CONTACT_NAME") + ": ");
+ this.contactAddressLabel.setToolTipText(contactInfo);
this.displayNameLabel = new JLabel(
GuiActivator.getResources().getI18NString(
"service.gui.DISPLAY_NAME") + ": ");
+ this.displayNameLabel.setToolTipText(displayNameInfo);
this.contactAddressField = new JTextField();
+ this.contactAddressField.setToolTipText(contactInfo);
+ addPrompt(this.contactAddressField,
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CONTACT_NAME_PROMPT"));
this.displayNameField = new JTextField();
+ this.displayNameField.setToolTipText(displayNameInfo);
+ addPrompt(this.displayNameField,
+ GuiActivator.getResources().getI18NString(
+ "service.gui.DISPLAY_NAME_PROMPT"));
+
+ this.groupLabel = new JLabel(
+ GuiActivator.getResources().getI18NString(
+ "service.gui.SELECT_GROUP") + ": ");
+ this.groupLabel.setToolTipText(groupInfo);
this.addButton = new JButton(
GuiActivator.getResources().getI18NString("service.gui.ADD"));
@@ -198,6 +272,7 @@ public class AddContactDialog
this.imageLabel = new JLabel();
this.groupCombo = createGroupCombo(this);
+ this.groupCombo.setToolTipText(groupInfo);
if(metaContact != null)
{
@@ -225,15 +300,15 @@ public class AddContactDialog
fieldsPanel.add(accountCombo);
}
- labelsPanel.add(groupLabel);
- fieldsPanel.add(groupCombo);
-
labelsPanel.add(contactAddressLabel);
fieldsPanel.add(contactAddressField);
labelsPanel.add(displayNameLabel);
fieldsPanel.add(displayNameField);
+ labelsPanel.add(groupLabel);
+ fieldsPanel.add(groupCombo);
+
contactAddressField.getDocument().addDocumentListener(
new DocumentListener()
{
@@ -499,6 +574,26 @@ public class AddContactDialog
final String contactAddress = contactAddressField.getText().trim();
final String displayName = displayNameField.getText();
+ List<String> validationResult = new ArrayList<>(2);
+ if (!protocolProvider.validateContactAddress(contactAddress,
+ validationResult))
+ {
+ new ErrorDialog(GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources()
+ .getI18NString("service.gui.ADD_CONTACT_ERROR_TITLE"),
+ validationResult.get(0), ErrorDialog.WARNING).showDialog();
+ if (validationResult.size() >= 2)
+ {
+ contactAddressField.setText(validationResult.get(1));
+ if (StringUtils.isNullOrEmpty(displayName, true))
+ {
+ displayNameField.setText(contactAddress);
+ }
+ }
+
+ return;
+ }
+
if (!protocolProvider.isRegistered())
{
new ErrorDialog(
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactInfoDialog.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactInfoDialog.java
deleted file mode 100644
index 325be90..0000000
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactInfoDialog.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.gui.main.contactlist;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.impl.gui.customcontrols.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.service.contactlist.*;
-
-/**
- * The <tt>ContactInfoPanel</tt> is a popup dialog containing the contact
- * detailed info.
- *
- * @author Yana Stamcheva
- */
-public class ContactInfoDialog
- extends SIPCommDialog
- implements WindowFocusListener
-{
-
- private JPanel protocolsPanel = new TransparentPanel(new GridLayout(0, 1));
-
- private TransparentBackground bg;
-
- /**
- * Creates an instance of the <tt>ContactInfoPanel</tt>.
- *
- * @param owner The frame owner of this dialog.
- * @param contactItem The <tt>MetaContact</tt> for the info.
- */
- public ContactInfoDialog(Frame owner, MetaContact contactItem)
- {
- super(owner);
-
- this.setUndecorated(true);
-
- this.setModal(true);
-
- // Create the transparent background component
- this.bg = new TransparentBackground(this);
-
- this.bg.setLayout(new BorderLayout());
-
- this.bg.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
-
- this.getContentPane().setLayout(new BorderLayout());
-
- this.init();
-
- this.getContentPane().add(bg, BorderLayout.CENTER);
-
- this.pack();
-
- this.setSize(140, 50);
-
- this.addWindowFocusListener(this);
- }
-
- /**
- * Initializes the <tt>ContactInfoPanel</tt>.
- */
- private void init()
- {
- /*
- * String[] protocolList = this.contactItem.getC();
- *
- * if(protocolsPanel.getComponentCount() == 0){ for(int i = 0; i <
- * protocolList.length; i ++){
- *
- * JLabel protocolLabel = new JLabel(protocolList[i], new
- * ImageIcon(Constants.getProtocolIcon(protocolList[i])), JLabel.LEFT);
- *
- * this.protocolsPanel.add(protocolLabel); } }
- *
- * this.bg.add(protocolsPanel, BorderLayout.CENTER);
- */
- }
-
- /**
- * Returns the panel containing all contact protocols' information.
- *
- * @return the panel containing all contact protocols' information.
- */
- public JPanel getProtocolsPanel()
- {
- return protocolsPanel;
- }
-
- public void windowGainedFocus(WindowEvent e)
- {
-
- }
-
- public void windowLostFocus(WindowEvent e)
- {
- close(false);
- }
-
- public void setPopupLocation(int x, int y)
- {
- this.setLocation(x, y);
-
- this.bg.updateBackground(x, y);
- }
-
- @Override
- protected void close(boolean isEscaped)
- {
- this.setVisible(false);
- this.dispose();
- }
-}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java
index bfe2fd3..ae0e3b0 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java
@@ -1078,7 +1078,7 @@ public class ContactListTreeCellRenderer
UIContactDetail desktopContact
= uiContact.getDefaultContactDetail(
- OperationSetDesktopStreaming.class);
+ OperationSetDesktopSharingServer.class);
if (desktopContact != null
|| (contactPhoneUtil != null
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/PresenceFilter.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/PresenceFilter.java
index cf7108f..011b00a 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/PresenceFilter.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/PresenceFilter.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,353 +15,353 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.gui.main.contactlist;
-
-import java.util.*;
-
-import net.java.sip.communicator.impl.gui.*;
-import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
-import net.java.sip.communicator.service.contactlist.*;
-import net.java.sip.communicator.service.contactsource.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.gui.event.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * The <tt>PresenceFilter</tt> is used to filter offline contacts from the
- * contact list.
- *
- * @author Yana Stamcheva
- */
-public class PresenceFilter
- implements ContactListFilter
-{
- /**
- * The <tt>Logger</tt> used by the <tt>PresenceFilter</tt> class and its
- * instances to print debugging information.
- */
- private static final Logger logger = Logger.getLogger(PresenceFilter.class);
-
- /**
- * Indicates if this presence filter shows or hides the offline contacts.
- */
- private boolean isShowOffline;
-
- /**
- * The initial result count below which we insert all filter results
- * directly to the contact list without firing events.
- */
- private static final int INITIAL_CONTACT_COUNT = 30;
-
- /**
- * Creates an instance of <tt>PresenceFilter</tt>.
- */
- public PresenceFilter()
- {
- isShowOffline = ConfigurationUtils.isShowOffline();
- }
-
- /**
- * Applies this filter. This filter is applied over the
- * <tt>MetaContactListService</tt>.
- *
- * @param filterQuery the query which keeps track of the filtering results
- */
- public void applyFilter(FilterQuery filterQuery)
- {
- // Create the query that will track filtering.
- MetaContactQuery query = new MetaContactQuery();
-
- // Add this query to the filterQuery.
- filterQuery.addContactQuery(query);
-
- TreeContactList contactList = GuiActivator.getContactList();
-
- Collection<UIContactSource> uiContactSourceCollection
- = contactList.getContactSources(
- ContactSourceService.CONTACT_LIST_TYPE);
-
- Iterator<UIContactSource> filterSources
- = uiContactSourceCollection.iterator();
- int maxIndex = 0;
- while (filterSources.hasNext())
- {
- UIContactSource filterSource = filterSources.next();
- int currIx = filterSource.getContactSourceService().getIndex();
- if(maxIndex < currIx)
- maxIndex = currIx;
- }
-
- contactList.getMetaContactListSource().setIndex(maxIndex + 1);
-
- filterSources = uiContactSourceCollection.iterator();
- while (filterSources.hasNext())
- {
- UIContactSource filterSource = filterSources.next();
-
- filterSource.setContactSourceIndex(
- filterSource.getContactSourceService().getIndex());
-
- ContactSourceService sourceService
- = filterSource.getContactSourceService();
-
- ContactQuery contactQuery
- = sourceService.createContactQuery(null);
-
- if(contactQuery == null)
- continue;
-
- // Add this query to the filterQuery.
- filterQuery.addContactQuery(contactQuery);
-
- contactQuery.addContactQueryListener(contactList);
-
- contactQuery.start();
- }
-
- // Closes this filter to indicate that we finished adding queries to it.
- filterQuery.close();
-
- query.addContactQueryListener(GuiActivator.getContactList());
- int resultCount = 0;
-
- addMatching(GuiActivator.getContactListService().getRoot(),
- query,
- resultCount);
-
- query.fireQueryEvent(
- query.isCanceled()
- ? MetaContactQueryStatusEvent.QUERY_CANCELED
- : MetaContactQueryStatusEvent.QUERY_COMPLETED);
- }
-
- /**
- * Indicates if the given <tt>uiContact</tt> is matching this filter.
- *
- * @param uiContact the <tt>UIContact</tt> to check
- * @return <tt>true</tt> if the given <tt>uiContact</tt> is matching
- * this filter, otherwise returns <tt>false</tt>
- */
- public boolean isMatching(UIContact uiContact)
- {
- Object descriptor = uiContact.getDescriptor();
-
- if (descriptor instanceof MetaContact)
- return isMatching((MetaContact) descriptor);
- else if (descriptor instanceof SourceContact)
- return isMatching((SourceContact)descriptor);
- else
- return false;
- }
-
- /**
- * Indicates if the given <tt>uiGroup</tt> is matching this filter.
- *
- * @param uiGroup the <tt>UIGroup</tt> to check
- * @return <tt>true</tt> if the given <tt>uiGroup</tt> is matching
- * this filter, otherwise returns <tt>false</tt>
- */
- public boolean isMatching(UIGroup uiGroup)
- {
- Object descriptor = uiGroup.getDescriptor();
-
- if (descriptor instanceof MetaContactGroup)
- return isMatching((MetaContactGroup) descriptor);
- else
- return false;
- }
-
- /**
- * Sets the show offline property.
- *
- * @param isShowOffline indicates if offline contacts are shown
- */
- public void setShowOffline(boolean isShowOffline)
- {
- this.isShowOffline = isShowOffline;
-
- ConfigurationUtils.setShowOffline(isShowOffline);
- }
-
- /**
- * Returns <tt>true</tt> if offline contacts are shown, otherwise returns
- * <tt>false</tt>.
- *
- * @return <tt>true</tt> if offline contacts are shown, otherwise returns
- * <tt>false</tt>
- */
- public boolean isShowOffline()
- {
- return isShowOffline;
- }
-
- /**
- * Returns <tt>true</tt> if offline contacts are shown or if the given
- * <tt>MetaContact</tt> is online, otherwise returns false.
- *
- * @param metaContact the <tt>MetaContact</tt> to check
- * @return <tt>true</tt> if the given <tt>MetaContact</tt> is matching this
- * filter
- */
- public boolean isMatching(MetaContact metaContact)
- {
- return isShowOffline || isContactOnline(metaContact);
- }
-
- /**
- * Returns <tt>true</tt> if offline contacts are shown or if the given
- * <tt>MetaContact</tt> is online, otherwise returns false.
- *
- * @param contact the <tt>MetaContact</tt> to check
- * @return <tt>true</tt> if the given <tt>MetaContact</tt> is matching this
- * filter
- */
- public boolean isMatching(SourceContact contact)
- {
- // make sure we always show chat rooms and recent messages
- return
- isShowOffline
- || contact.getPresenceStatus().isOnline()
- || contact.getContactSource().getType()
- == ContactSourceService.CONTACT_LIST_TYPE;
- }
-
- /**
- * Returns <tt>true</tt> if offline contacts are shown or if the given
- * <tt>MetaContactGroup</tt> contains online contacts.
- *
- * @param metaGroup the <tt>MetaContactGroup</tt> to check
- * @return <tt>true</tt> if the given <tt>MetaContactGroup</tt> is matching
- * this filter
- */
- private boolean isMatching(MetaContactGroup metaGroup)
- {
- return
- isShowOffline
- || (metaGroup.countOnlineChildContacts() > 0)
- || MetaContactListSource.isNewGroup(metaGroup);
- }
-
- /**
- * Returns <tt>true</tt> if the given meta contact is online, <tt>false</tt>
- * otherwise.
- *
- * @param contact the meta contact
- * @return <tt>true</tt> if the given meta contact is online, <tt>false</tt>
- * otherwise
- */
- private boolean isContactOnline(MetaContact contact)
- {
- // If for some reason the default contact is null we return false.
- Contact defaultContact = contact.getDefaultContact();
- if(defaultContact == null)
- return false;
-
- // Lays on the fact that the default contact is the most connected.
- return defaultContact.getPresenceStatus().getStatus()
- >= PresenceStatus.ONLINE_THRESHOLD;
- }
-
- /**
- * Adds all contacts contained in the given <tt>MetaContactGroup</tt>
- * matching the current filter and not contained in the contact list.
- *
- * @param metaGroup the <tt>MetaContactGroup</tt>, which matching contacts
- * to add
- * @param query the <tt>MetaContactQuery</tt> that notifies interested
- * listeners of the results of this matching
- * @param resultCount the initial result count we would insert directly to
- * the contact list without firing events
- */
- private void addMatching( MetaContactGroup metaGroup,
- MetaContactQuery query,
- int resultCount)
- {
- Iterator<MetaContact> childContacts = metaGroup.getChildContacts();
-
- while (childContacts.hasNext() && !query.isCanceled())
- {
- MetaContact metaContact = childContacts.next();
-
- if(isMatching(metaContact))
- {
-
- resultCount++;
- if (resultCount <= INITIAL_CONTACT_COUNT)
- {
- UIGroup uiGroup = null;
-
- if (!MetaContactListSource.isRootGroup(metaGroup))
- {
- synchronized (metaGroup)
- {
- uiGroup = MetaContactListSource
- .getUIGroup(metaGroup);
- if (uiGroup == null)
- uiGroup = MetaContactListSource
- .createUIGroup(metaGroup);
- }
- }
-
- if (logger.isDebugEnabled())
- logger.debug("Presence filter contact added: "
- + metaContact.getDisplayName());
-
- UIContactImpl newUIContact;
- synchronized (metaContact)
- {
- newUIContact
- = MetaContactListSource.getUIContact(metaContact);
-
- if (newUIContact == null)
- {
- newUIContact = MetaContactListSource
- .createUIContact(metaContact);
- }
- }
-
- GuiActivator.getContactList().addContact(
- newUIContact,
- uiGroup,
- true,
- true);
-
- query.setInitialResultCount(resultCount);
- }
- else
- {
- query.fireQueryEvent(metaContact);
- }
- }
- }
-
- // If in the meantime the filtering has been stopped we return here.
- if (query.isCanceled())
- return;
-
- Iterator<MetaContactGroup> subgroups = metaGroup.getSubgroups();
- while(subgroups.hasNext() && !query.isCanceled())
- {
- MetaContactGroup subgroup = subgroups.next();
-
- if (isMatching(subgroup))
- {
- UIGroup uiGroup;
- synchronized(subgroup)
- {
- uiGroup = MetaContactListSource
- .getUIGroup(subgroup);
-
- if (uiGroup == null)
- uiGroup = MetaContactListSource
- .createUIGroup(subgroup);
- }
-
- GuiActivator.getContactList().addGroup(uiGroup, true);
-
- addMatching(subgroup, query, resultCount);
- }
- }
- }
-}
+package net.java.sip.communicator.impl.gui.main.contactlist;
+
+import java.util.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
+import net.java.sip.communicator.service.contactlist.*;
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.gui.event.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * The <tt>PresenceFilter</tt> is used to filter offline contacts from the
+ * contact list.
+ *
+ * @author Yana Stamcheva
+ */
+public class PresenceFilter
+ implements ContactListFilter
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>PresenceFilter</tt> class and its
+ * instances to print debugging information.
+ */
+ private static final Logger logger = Logger.getLogger(PresenceFilter.class);
+
+ /**
+ * Indicates if this presence filter shows or hides the offline contacts.
+ */
+ private boolean isShowOffline;
+
+ /**
+ * The initial result count below which we insert all filter results
+ * directly to the contact list without firing events.
+ */
+ private static final int INITIAL_CONTACT_COUNT = 30;
+
+ /**
+ * Creates an instance of <tt>PresenceFilter</tt>.
+ */
+ public PresenceFilter()
+ {
+ isShowOffline = ConfigurationUtils.isShowOffline();
+ }
+
+ /**
+ * Applies this filter. This filter is applied over the
+ * <tt>MetaContactListService</tt>.
+ *
+ * @param filterQuery the query which keeps track of the filtering results
+ */
+ public void applyFilter(FilterQuery filterQuery)
+ {
+ // Create the query that will track filtering.
+ MetaContactQuery query = new MetaContactQuery();
+
+ // Add this query to the filterQuery.
+ filterQuery.addContactQuery(query);
+
+ TreeContactList contactList = GuiActivator.getContactList();
+
+ Collection<UIContactSource> uiContactSourceCollection
+ = contactList.getContactSources(
+ ContactSourceService.CONTACT_LIST_TYPE);
+
+ Iterator<UIContactSource> filterSources
+ = uiContactSourceCollection.iterator();
+ int maxIndex = 0;
+ while (filterSources.hasNext())
+ {
+ UIContactSource filterSource = filterSources.next();
+ int currIx = filterSource.getContactSourceService().getIndex();
+ if(maxIndex < currIx)
+ maxIndex = currIx;
+ }
+
+ contactList.getMetaContactListSource().setIndex(maxIndex + 1);
+
+ filterSources = uiContactSourceCollection.iterator();
+ while (filterSources.hasNext())
+ {
+ UIContactSource filterSource = filterSources.next();
+
+ filterSource.setContactSourceIndex(
+ filterSource.getContactSourceService().getIndex());
+
+ ContactSourceService sourceService
+ = filterSource.getContactSourceService();
+
+ ContactQuery contactQuery
+ = sourceService.createContactQuery(null);
+
+ if(contactQuery == null)
+ continue;
+
+ // Add this query to the filterQuery.
+ filterQuery.addContactQuery(contactQuery);
+
+ contactQuery.addContactQueryListener(contactList);
+
+ contactQuery.start();
+ }
+
+ // Closes this filter to indicate that we finished adding queries to it.
+ filterQuery.close();
+
+ query.addContactQueryListener(GuiActivator.getContactList());
+ int resultCount = 0;
+
+ addMatching(GuiActivator.getContactListService().getRoot(),
+ query,
+ resultCount);
+
+ query.fireQueryEvent(
+ query.isCanceled()
+ ? MetaContactQueryStatusEvent.QUERY_CANCELED
+ : MetaContactQueryStatusEvent.QUERY_COMPLETED);
+ }
+
+ /**
+ * Indicates if the given <tt>uiContact</tt> is matching this filter.
+ *
+ * @param uiContact the <tt>UIContact</tt> to check
+ * @return <tt>true</tt> if the given <tt>uiContact</tt> is matching
+ * this filter, otherwise returns <tt>false</tt>
+ */
+ public boolean isMatching(UIContact uiContact)
+ {
+ Object descriptor = uiContact.getDescriptor();
+
+ if (descriptor instanceof MetaContact)
+ return isMatching((MetaContact) descriptor);
+ else if (descriptor instanceof SourceContact)
+ return isMatching((SourceContact)descriptor);
+ else
+ return false;
+ }
+
+ /**
+ * Indicates if the given <tt>uiGroup</tt> is matching this filter.
+ *
+ * @param uiGroup the <tt>UIGroup</tt> to check
+ * @return <tt>true</tt> if the given <tt>uiGroup</tt> is matching
+ * this filter, otherwise returns <tt>false</tt>
+ */
+ public boolean isMatching(UIGroup uiGroup)
+ {
+ Object descriptor = uiGroup.getDescriptor();
+
+ if (descriptor instanceof MetaContactGroup)
+ return isMatching((MetaContactGroup) descriptor);
+ else
+ return false;
+ }
+
+ /**
+ * Sets the show offline property.
+ *
+ * @param isShowOffline indicates if offline contacts are shown
+ */
+ public void setShowOffline(boolean isShowOffline)
+ {
+ this.isShowOffline = isShowOffline;
+
+ ConfigurationUtils.setShowOffline(isShowOffline);
+ }
+
+ /**
+ * Returns <tt>true</tt> if offline contacts are shown, otherwise returns
+ * <tt>false</tt>.
+ *
+ * @return <tt>true</tt> if offline contacts are shown, otherwise returns
+ * <tt>false</tt>
+ */
+ public boolean isShowOffline()
+ {
+ return isShowOffline;
+ }
+
+ /**
+ * Returns <tt>true</tt> if offline contacts are shown or if the given
+ * <tt>MetaContact</tt> is online, otherwise returns false.
+ *
+ * @param metaContact the <tt>MetaContact</tt> to check
+ * @return <tt>true</tt> if the given <tt>MetaContact</tt> is matching this
+ * filter
+ */
+ public boolean isMatching(MetaContact metaContact)
+ {
+ return isShowOffline || isContactOnline(metaContact);
+ }
+
+ /**
+ * Returns <tt>true</tt> if offline contacts are shown or if the given
+ * <tt>MetaContact</tt> is online, otherwise returns false.
+ *
+ * @param contact the <tt>MetaContact</tt> to check
+ * @return <tt>true</tt> if the given <tt>MetaContact</tt> is matching this
+ * filter
+ */
+ public boolean isMatching(SourceContact contact)
+ {
+ // make sure we always show chat rooms and recent messages
+ return
+ isShowOffline
+ || contact.getPresenceStatus().isOnline()
+ || contact.getContactSource().getType()
+ == ContactSourceService.CONTACT_LIST_TYPE;
+ }
+
+ /**
+ * Returns <tt>true</tt> if offline contacts are shown or if the given
+ * <tt>MetaContactGroup</tt> contains online contacts.
+ *
+ * @param metaGroup the <tt>MetaContactGroup</tt> to check
+ * @return <tt>true</tt> if the given <tt>MetaContactGroup</tt> is matching
+ * this filter
+ */
+ private boolean isMatching(MetaContactGroup metaGroup)
+ {
+ return
+ isShowOffline
+ || (metaGroup.countOnlineChildContacts() > 0)
+ || MetaContactListSource.isNewGroup(metaGroup);
+ }
+
+ /**
+ * Returns <tt>true</tt> if the given meta contact is online, <tt>false</tt>
+ * otherwise.
+ *
+ * @param contact the meta contact
+ * @return <tt>true</tt> if the given meta contact is online, <tt>false</tt>
+ * otherwise
+ */
+ private boolean isContactOnline(MetaContact contact)
+ {
+ // If for some reason the default contact is null we return false.
+ Contact defaultContact = contact.getDefaultContact();
+ if(defaultContact == null)
+ return false;
+
+ // Lays on the fact that the default contact is the most connected.
+ return defaultContact.getPresenceStatus().getStatus()
+ >= PresenceStatus.ONLINE_THRESHOLD;
+ }
+
+ /**
+ * Adds all contacts contained in the given <tt>MetaContactGroup</tt>
+ * matching the current filter and not contained in the contact list.
+ *
+ * @param metaGroup the <tt>MetaContactGroup</tt>, which matching contacts
+ * to add
+ * @param query the <tt>MetaContactQuery</tt> that notifies interested
+ * listeners of the results of this matching
+ * @param resultCount the initial result count we would insert directly to
+ * the contact list without firing events
+ */
+ private void addMatching( MetaContactGroup metaGroup,
+ MetaContactQuery query,
+ int resultCount)
+ {
+ Iterator<MetaContact> childContacts = metaGroup.getChildContacts();
+
+ while (childContacts.hasNext() && !query.isCanceled())
+ {
+ MetaContact metaContact = childContacts.next();
+
+ if(isMatching(metaContact))
+ {
+
+ resultCount++;
+ if (resultCount <= INITIAL_CONTACT_COUNT)
+ {
+ UIGroup uiGroup = null;
+
+ if (!MetaContactListSource.isRootGroup(metaGroup))
+ {
+ synchronized (metaGroup)
+ {
+ uiGroup = MetaContactListSource
+ .getUIGroup(metaGroup);
+ if (uiGroup == null)
+ uiGroup = MetaContactListSource
+ .createUIGroup(metaGroup);
+ }
+ }
+
+ if (logger.isDebugEnabled())
+ logger.debug("Presence filter contact added: "
+ + metaContact.getDisplayName());
+
+ UIContactImpl newUIContact;
+ synchronized (metaContact)
+ {
+ newUIContact
+ = MetaContactListSource.getUIContact(metaContact);
+
+ if (newUIContact == null)
+ {
+ newUIContact = MetaContactListSource
+ .createUIContact(metaContact);
+ }
+ }
+
+ GuiActivator.getContactList().addContact(
+ newUIContact,
+ uiGroup,
+ true,
+ true);
+
+ query.setInitialResultCount(resultCount);
+ }
+ else
+ {
+ query.fireQueryEvent(metaContact);
+ }
+ }
+ }
+
+ // If in the meantime the filtering has been stopped we return here.
+ if (query.isCanceled())
+ return;
+
+ Iterator<MetaContactGroup> subgroups = metaGroup.getSubgroups();
+ while(subgroups.hasNext() && !query.isCanceled())
+ {
+ MetaContactGroup subgroup = subgroups.next();
+
+ if (isMatching(subgroup))
+ {
+ UIGroup uiGroup;
+ synchronized(subgroup)
+ {
+ uiGroup = MetaContactListSource
+ .getUIGroup(subgroup);
+
+ if (uiGroup == null)
+ uiGroup = MetaContactListSource
+ .createUIGroup(subgroup);
+ }
+
+ GuiActivator.getContactList().addGroup(uiGroup, true);
+
+ addMatching(subgroup, query, resultCount);
+ }
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFilter.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFilter.java
index 837d369..4735892 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFilter.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFilter.java
@@ -270,14 +270,13 @@ public class SearchFilter
*/
private boolean isMatching(String text)
{
- if (filterPattern != null)
- return filterPattern.matcher(text).find();
+ if (filterPattern != null && filterPattern.matcher(text).find())
+ return true;
if(isSearchingPhoneNumber && this.filterString != null)
return GuiActivator.getPhoneNumberI18nService()
.phoneNumbersMatch(this.filterString, text);
return true;
-
}
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java
index a916b2b..119e000 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java
@@ -565,10 +565,6 @@ public class TreeContactList
if (isActive)
{
activeContacts.add(contactNode);
-// SystrayService stray = GuiActivator.getSystrayService();
-//
-// if (stray != null)
-// stray.setSystrayIcon(SystrayService.ENVELOPE_IMG_TYPE);
}
else
activeContacts.remove(contactNode);
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/SourceUIContact.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/SourceUIContact.java
index 72bec25..1419416 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/SourceUIContact.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/SourceUIContact.java
@@ -573,7 +573,7 @@ public class SourceUIContact
}
else
{
- labelText = contactDetail.getDetail();
+ labelText = contactDetail.getDisplayName();
}
jLabels[i] = new JLabel(filterAddressDisplay(labelText));
@@ -709,11 +709,9 @@ public class SourceUIContact
case AIM:
case ICQ:
case Jabber:
- case MSN:
case Yahoo:
case Skype:
case GoogleTalk:
- case Facebook:
label = subCategory.value();
break;
default:
diff --git a/src/net/java/sip/communicator/impl/gui/main/menus/MacOSXPreferencesRegistration.java b/src/net/java/sip/communicator/impl/gui/main/menus/MacOSXPreferencesRegistration.java
index cfb5420..5a75ff1 100644
--- a/src/net/java/sip/communicator/impl/gui/main/menus/MacOSXPreferencesRegistration.java
+++ b/src/net/java/sip/communicator/impl/gui/main/menus/MacOSXPreferencesRegistration.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,30 +15,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.gui.main.menus;
-
-import com.apple.eawt.*;
-
-/**
- * @author Lubomir Marinov
- */
-public final class MacOSXPreferencesRegistration
-{
- public static boolean run(final Object userData)
- {
- Application application = Application.getApplication();
- if (application != null)
- {
- application.setPreferencesHandler(new PreferencesHandler()
- {
- public void handlePreferences(
- AppEvent.PreferencesEvent preferencesEvent)
- {
- ((ToolsMenu) userData).configActionPerformed();
- }
- });
- return true;
- }
- return false;
- }
-}
+package net.java.sip.communicator.impl.gui.main.menus;
+
+import com.apple.eawt.*;
+
+/**
+ * @author Lubomir Marinov
+ */
+public final class MacOSXPreferencesRegistration
+{
+ public static boolean run(final Object userData)
+ {
+ Application application = Application.getApplication();
+ if (application != null)
+ {
+ application.setPreferencesHandler(new PreferencesHandler()
+ {
+ public void handlePreferences(
+ AppEvent.PreferencesEvent preferencesEvent)
+ {
+ ((ToolsMenu) userData).configActionPerformed();
+ }
+ });
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/menus/MacOSXQuitRegistration.java b/src/net/java/sip/communicator/impl/gui/main/menus/MacOSXQuitRegistration.java
index 594623b..4b786b2 100644
--- a/src/net/java/sip/communicator/impl/gui/main/menus/MacOSXQuitRegistration.java
+++ b/src/net/java/sip/communicator/impl/gui/main/menus/MacOSXQuitRegistration.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,68 +15,68 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.gui.main.menus;
-
-import com.apple.eawt.*;
-
-/**
- * @author Lubomir Marinov
- */
-public final class MacOSXQuitRegistration
-{
- public static boolean run(final Object userData)
- {
- Application application = Application.getApplication();
- if (application != null)
- {
- application.setQuitHandler(new QuitHandler()
- {
- public void handleQuitRequestWith(AppEvent.QuitEvent quitEvent,
- final QuitResponse quitResponse)
- {
- ((FileMenu) userData).closeActionPerformed();
-
- /*
- * Tell Mac OS X that it shouldn't terminate the
- * application. We've already initiated the quit and we'll
- * eventually complete it i.e. we'll honor the request of
- * Mac OS X to quit.
- *
- * (2011-06-10) Changed to true, we tell that quit is handled
- * as otherwise will stop OS from logout or shutdown and
- * a notification will be shown to user to inform about it.
- *
- * (2011-07-12) Wait before answering to the OS or we will
- * end too quickly. 15sec is the time our shutdown timer
- * waits before force the shutdown.
- */
-
- synchronized(this)
- {
- try
- {
- wait(15000);
- }catch (InterruptedException ex){}
- }
-
- /**
- * Free the event dispatch thread before performing the
- * quit (System.exit), shutdown timer may also has started
- * the quit and is waiting to free the threads which
- * we may be blocking.
- */
- new Thread(new Runnable()
- {
- public void run()
- {
- quitResponse.performQuit();
- }
- }).start();
- }
- });
-
- return true;
- }
- return false;
- }
-}
+package net.java.sip.communicator.impl.gui.main.menus;
+
+import com.apple.eawt.*;
+
+/**
+ * @author Lubomir Marinov
+ */
+public final class MacOSXQuitRegistration
+{
+ public static boolean run(final Object userData)
+ {
+ Application application = Application.getApplication();
+ if (application != null)
+ {
+ application.setQuitHandler(new QuitHandler()
+ {
+ public void handleQuitRequestWith(AppEvent.QuitEvent quitEvent,
+ final QuitResponse quitResponse)
+ {
+ ((FileMenu) userData).closeActionPerformed();
+
+ /*
+ * Tell Mac OS X that it shouldn't terminate the
+ * application. We've already initiated the quit and we'll
+ * eventually complete it i.e. we'll honor the request of
+ * Mac OS X to quit.
+ *
+ * (2011-06-10) Changed to true, we tell that quit is handled
+ * as otherwise will stop OS from logout or shutdown and
+ * a notification will be shown to user to inform about it.
+ *
+ * (2011-07-12) Wait before answering to the OS or we will
+ * end too quickly. 15sec is the time our shutdown timer
+ * waits before force the shutdown.
+ */
+
+ synchronized(this)
+ {
+ try
+ {
+ wait(15000);
+ }catch (InterruptedException ex){}
+ }
+
+ /**
+ * Free the event dispatch thread before performing the
+ * quit (System.exit), shutdown timer may also has started
+ * the quit and is waiting to free the threads which
+ * we may be blocking.
+ */
+ new Thread(new Runnable()
+ {
+ public void run()
+ {
+ quitResponse.performQuit();
+ }
+ }).start();
+ }
+ });
+
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf b/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf
index 1861c4a..2795ef9 100644
--- a/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf
+++ b/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf
@@ -72,12 +72,12 @@ Import-Package: com.apple.eawt,
org.jitsi.service.neomedia.event,
org.jitsi.service.neomedia.format,
org.jitsi.service.neomedia.recording,
+ org.jitsi.service.neomedia.stats,
org.jitsi.service.resources,
org.jitsi.util,
org.jitsi.util.event,
org.jitsi.util.swing,
org.osgi.framework,
- say.swing,
net.java.sip.communicator.service.credentialsstorage,
net.java.sip.communicator.service.muc,
net.java.sip.communicator.plugin.desktoputil.chat,
diff --git a/src/net/java/sip/communicator/impl/gui/utils/PluginContainer.java b/src/net/java/sip/communicator/impl/gui/utils/PluginContainer.java
index e85c51c..d24855f 100644
--- a/src/net/java/sip/communicator/impl/gui/utils/PluginContainer.java
+++ b/src/net/java/sip/communicator/impl/gui/utils/PluginContainer.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,318 +15,318 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.gui.utils;
-
-import java.awt.*;
-import java.util.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.impl.gui.*;
-import net.java.sip.communicator.impl.gui.event.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.gui.Container;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * Provides capabilities to a specific <code>JComponent</code> to contain
- * <code>PluginComponent</code>s, track when they are added and removed.
- *
- * @author Lyubomir Marinov
- */
-public class PluginContainer
- implements PluginComponentListener
-{
- /**
- * The <tt>Logger</tt> used by the <tt>PluginContainer</tt> class and its
- * instances for logging output.
- */
- private static final Logger logger
- = Logger.getLogger(PluginContainer.class);
-
- /**
- * The <code>JComponent</code> which contains the components of the
- * <code>PluginComponent</code>s managed by this instance.
- */
- private final JComponent container;
-
- /**
- * The container id of the <code>PluginComponent</code> managed by this
- * instance.
- */
- private final Container containerId;
-
- /**
- * The list of <code>PluginComponent</code> instances which have their
- * components added to this <code>PluginContainer</code>.
- */
- private final java.util.List<PluginComponent> pluginComponents
- = new LinkedList<PluginComponent>();
-
- /**
- * Initializes a new <code>PluginContainer</code> instance which is to
- * provide capabilities to a specific <code>JComponent</code> container with
- * a specific <code>Container</code> id to contain
- * <code>PluginComponent</code> and track when they are added and removed.
- *
- * @param container
- * the <code>JComponent</code> container the new instance is to
- * provide its capabilities to
- * @param containerId
- * the <code>Container</code> id of the specified
- * <code>container</code>
- */
- public PluginContainer(JComponent container, Container containerId)
- {
- this.container = container;
- this.containerId = containerId;
-
- initPluginComponents();
- }
-
- /**
- * Adds a specific <tt>Component</tt> to a specific <tt>JComponent</tt>
- * container. Allows extenders to apply custom logic to the exact placement
- * of the specified <tt>Component</tt> in the specified container.
- *
- * @param component the <tt>Component</tt> to be added to the specified
- * <tt>JComponent</tt> container
- * @param container the <tt>JComponent</tt> container to add the specified
- * <tt>Component</tt> to
- * @param preferredIndex the index at which <tt>component</tt> is to be
- * added to <tt>container</tt> if possible or <tt>-1</tt> if there is no
- * preference with respect to the index in question
- */
- protected void addComponentToContainer(
- Component component,
- JComponent container,
- int preferredIndex)
- {
- if ((0 <= preferredIndex)
- && (preferredIndex < getComponentCount(container)))
- container.add(component, preferredIndex);
- else
- container.add(component);
- }
-
- /**
- * Adds the component of a specific <tt>PluginComponent</tt> to the
- * associated <tt>Container</tt>.
- *
- * @param factory the <tt>PluginComponentFactory</tt> which is to have its
- * component added to the <tt>Container</tt> associated with this
- * <tt>PluginContainer</tt>
- */
- private synchronized void addPluginComponent(PluginComponentFactory factory)
- {
- PluginComponent c =
- factory.getPluginComponentInstance(PluginContainer.this);
-
- if (logger.isInfoEnabled())
- logger.info("Will add plugin component: " + c);
-
- /*
- * Try to respect positionIndex of PluginComponent to some extent:
- * PluginComponents with positionIndex equal to 0 go at the beginning,
- * these with positionIndex equal to -1 follow them and then go these
- * with positionIndex greater than 0.
- */
- int cIndex = factory.getPositionIndex();
- int index = -1;
- int i = 0;
-
- for (PluginComponent pluginComponent : pluginComponents)
- {
- if (pluginComponent.equals(c))
- return;
-
- if (-1 == index)
- {
- int pluginComponentIndex = factory.getPositionIndex();
-
- if ((0 == cIndex) || (-1 == cIndex))
- {
- if ((0 != pluginComponentIndex)
- && (cIndex != pluginComponentIndex))
- index = i;
- }
- else if (cIndex < pluginComponentIndex)
- index = i;
- }
-
- i++;
- }
-
- int pluginComponentCount = pluginComponents.size();
-
- if (-1 == index)
- index = pluginComponents.size();
-
- /*
- * The container may have added Components of its own apart from the
- * ones this PluginContainer has added to it. Since the common case for
- * the additional Components is to have them appear at the beginning,
- * adjust the index so it gets correct in the common case.
- */
- int containerComponentCount = getComponentCount(container);
-
- addComponentToContainer(
- (Component) c.getComponent(),
- container,
- (containerComponentCount > pluginComponentCount)
- ? (index + (containerComponentCount - pluginComponentCount))
- : index);
- pluginComponents.add(index, c);
-
- container.revalidate();
- container.repaint();
- }
-
- /**
- * Runs clean-up for associated resources which need explicit disposal (e.g.
- * listeners keeping this instance alive because they were added to the
- * model which operationally outlives this instance).
- */
- public void dispose()
- {
- GuiActivator.getUIService().removePluginComponentListener(this);
-
- /*
- * Explicitly remove the components of the PluginComponent instances
- * because the latter are registered with OSGi and are thus global.
- */
- synchronized (this)
- {
- for (PluginComponent pluginComponent : pluginComponents)
- container.remove((Component) pluginComponent.getComponent());
- pluginComponents.clear();
- }
- }
-
- /**
- * Gets the number of <tt>Component</tt>s in a specific <tt>JComponent</tt>
- * container. For example, returns the result of
- * <tt>getMenuComponentCount()</tt> if <tt>container</tt> is an instance of
- * <tt>JMenu</tt>.
- *
- * @param container the <tt>JComponent</tt> container to get the number of
- * <tt>Component</tt>s of
- * @return the number of <tt>Component</tt>s in the specified
- * <tt>container</tt>
- */
- protected int getComponentCount(JComponent container)
- {
- return
- (container instanceof JMenu)
- ? ((JMenu) container).getMenuComponentCount()
- : container.getComponentCount();
- }
-
- /**
- * Gets the <tt>PluginComponent</tt>s of this <tt>PluginContainer</tt>.
- *
- * @return an <tt>Iterable</tt> over the <tt>PluginComponent</tt>s of this
- * <tt>PluginContainer</tt>
- */
- public Iterable<PluginComponent> getPluginComponents()
- {
- return pluginComponents;
- }
-
- /**
- * Adds the <tt>Component</tt>s of the <tt>PluginComponent</tt>s registered
- * in the OSGi <tt>BundleContext</tt> in the associated <tt>Container</tt>.
- */
- private void initPluginComponents()
- {
- GuiActivator.getUIService().addPluginComponentListener(this);
-
- // Look for PluginComponents registered in the OSGi BundleContext.
- ServiceReference[] serRefs = null;
-
- try
- {
- serRefs
- = GuiActivator
- .bundleContext
- .getServiceReferences(
- PluginComponentFactory.class.getName(),
- "("
- + Container.CONTAINER_ID
- + "="
- + containerId.getID()
- + ")");
- }
- catch (InvalidSyntaxException exc)
- {
- logger.error("Could not obtain plugin reference.", exc);
- }
-
- if (serRefs != null)
- {
- for (ServiceReference serRef : serRefs)
- {
- PluginComponentFactory factory
- = (PluginComponentFactory)
- GuiActivator.bundleContext.getService(serRef);
-
- addPluginComponent(factory);
- }
- }
- }
-
- /**
- * Implements
- * {@link PluginComponentListener#pluginComponentAdded(PluginComponentEvent)}.
- *
- * @param event a <tt>PluginComponentEvent</tt> which specifies the
- * <tt>PluginComponent</tt> which has been added
- */
- public void pluginComponentAdded(PluginComponentEvent event)
- {
- PluginComponentFactory factory = event.getPluginComponentFactory();
-
- if (factory.getContainer().equals(containerId))
- addPluginComponent(factory);
- }
-
- /**
- * Implements
- * {@link PluginComponentListener#pluginComponentRemoved(PluginComponentEvent)}.
- *
- * @param event a <tt>PluginComponentEvent</tt> which specifies the
- * <tt>PluginComponent</tt> which has been added
- */
- public void pluginComponentRemoved(PluginComponentEvent event)
- {
- PluginComponentFactory factory = event.getPluginComponentFactory();
-
- if (factory.getContainer().equals(containerId))
- removePluginComponent(factory);
- }
-
- /**
- * Removes the component of a specific <code>PluginComponent</code> from
- * this <code>PluginContainer</code>.
- *
- * @param factory
- * the <code>PluginComponent</code> which is to have its
- * component removed from this <code>PluginContainer</code>
- */
- private synchronized void removePluginComponent(
- PluginComponentFactory factory)
- {
- Iterator<PluginComponent> iterator = pluginComponents.iterator();
- while(iterator.hasNext())
- {
- PluginComponent c = iterator.next();
- if(c.getParentFactory().equals(factory))
- {
- iterator.remove();
- container.remove((Component)c.getComponent());
- }
- }
- }
-}
+package net.java.sip.communicator.impl.gui.utils;
+
+import java.awt.*;
+import java.util.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.event.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.gui.Container;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * Provides capabilities to a specific <code>JComponent</code> to contain
+ * <code>PluginComponent</code>s, track when they are added and removed.
+ *
+ * @author Lyubomir Marinov
+ */
+public class PluginContainer
+ implements PluginComponentListener
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>PluginContainer</tt> class and its
+ * instances for logging output.
+ */
+ private static final Logger logger
+ = Logger.getLogger(PluginContainer.class);
+
+ /**
+ * The <code>JComponent</code> which contains the components of the
+ * <code>PluginComponent</code>s managed by this instance.
+ */
+ private final JComponent container;
+
+ /**
+ * The container id of the <code>PluginComponent</code> managed by this
+ * instance.
+ */
+ private final Container containerId;
+
+ /**
+ * The list of <code>PluginComponent</code> instances which have their
+ * components added to this <code>PluginContainer</code>.
+ */
+ private final java.util.List<PluginComponent> pluginComponents
+ = new LinkedList<PluginComponent>();
+
+ /**
+ * Initializes a new <code>PluginContainer</code> instance which is to
+ * provide capabilities to a specific <code>JComponent</code> container with
+ * a specific <code>Container</code> id to contain
+ * <code>PluginComponent</code> and track when they are added and removed.
+ *
+ * @param container
+ * the <code>JComponent</code> container the new instance is to
+ * provide its capabilities to
+ * @param containerId
+ * the <code>Container</code> id of the specified
+ * <code>container</code>
+ */
+ public PluginContainer(JComponent container, Container containerId)
+ {
+ this.container = container;
+ this.containerId = containerId;
+
+ initPluginComponents();
+ }
+
+ /**
+ * Adds a specific <tt>Component</tt> to a specific <tt>JComponent</tt>
+ * container. Allows extenders to apply custom logic to the exact placement
+ * of the specified <tt>Component</tt> in the specified container.
+ *
+ * @param component the <tt>Component</tt> to be added to the specified
+ * <tt>JComponent</tt> container
+ * @param container the <tt>JComponent</tt> container to add the specified
+ * <tt>Component</tt> to
+ * @param preferredIndex the index at which <tt>component</tt> is to be
+ * added to <tt>container</tt> if possible or <tt>-1</tt> if there is no
+ * preference with respect to the index in question
+ */
+ protected void addComponentToContainer(
+ Component component,
+ JComponent container,
+ int preferredIndex)
+ {
+ if ((0 <= preferredIndex)
+ && (preferredIndex < getComponentCount(container)))
+ container.add(component, preferredIndex);
+ else
+ container.add(component);
+ }
+
+ /**
+ * Adds the component of a specific <tt>PluginComponent</tt> to the
+ * associated <tt>Container</tt>.
+ *
+ * @param factory the <tt>PluginComponentFactory</tt> which is to have its
+ * component added to the <tt>Container</tt> associated with this
+ * <tt>PluginContainer</tt>
+ */
+ private synchronized void addPluginComponent(PluginComponentFactory factory)
+ {
+ PluginComponent c =
+ factory.getPluginComponentInstance(PluginContainer.this);
+
+ if (logger.isInfoEnabled())
+ logger.info("Will add plugin component: " + c);
+
+ /*
+ * Try to respect positionIndex of PluginComponent to some extent:
+ * PluginComponents with positionIndex equal to 0 go at the beginning,
+ * these with positionIndex equal to -1 follow them and then go these
+ * with positionIndex greater than 0.
+ */
+ int cIndex = factory.getPositionIndex();
+ int index = -1;
+ int i = 0;
+
+ for (PluginComponent pluginComponent : pluginComponents)
+ {
+ if (pluginComponent.equals(c))
+ return;
+
+ if (-1 == index)
+ {
+ int pluginComponentIndex = factory.getPositionIndex();
+
+ if ((0 == cIndex) || (-1 == cIndex))
+ {
+ if ((0 != pluginComponentIndex)
+ && (cIndex != pluginComponentIndex))
+ index = i;
+ }
+ else if (cIndex < pluginComponentIndex)
+ index = i;
+ }
+
+ i++;
+ }
+
+ int pluginComponentCount = pluginComponents.size();
+
+ if (-1 == index)
+ index = pluginComponents.size();
+
+ /*
+ * The container may have added Components of its own apart from the
+ * ones this PluginContainer has added to it. Since the common case for
+ * the additional Components is to have them appear at the beginning,
+ * adjust the index so it gets correct in the common case.
+ */
+ int containerComponentCount = getComponentCount(container);
+
+ addComponentToContainer(
+ (Component) c.getComponent(),
+ container,
+ (containerComponentCount > pluginComponentCount)
+ ? (index + (containerComponentCount - pluginComponentCount))
+ : index);
+ pluginComponents.add(index, c);
+
+ container.revalidate();
+ container.repaint();
+ }
+
+ /**
+ * Runs clean-up for associated resources which need explicit disposal (e.g.
+ * listeners keeping this instance alive because they were added to the
+ * model which operationally outlives this instance).
+ */
+ public void dispose()
+ {
+ GuiActivator.getUIService().removePluginComponentListener(this);
+
+ /*
+ * Explicitly remove the components of the PluginComponent instances
+ * because the latter are registered with OSGi and are thus global.
+ */
+ synchronized (this)
+ {
+ for (PluginComponent pluginComponent : pluginComponents)
+ container.remove((Component) pluginComponent.getComponent());
+ pluginComponents.clear();
+ }
+ }
+
+ /**
+ * Gets the number of <tt>Component</tt>s in a specific <tt>JComponent</tt>
+ * container. For example, returns the result of
+ * <tt>getMenuComponentCount()</tt> if <tt>container</tt> is an instance of
+ * <tt>JMenu</tt>.
+ *
+ * @param container the <tt>JComponent</tt> container to get the number of
+ * <tt>Component</tt>s of
+ * @return the number of <tt>Component</tt>s in the specified
+ * <tt>container</tt>
+ */
+ protected int getComponentCount(JComponent container)
+ {
+ return
+ (container instanceof JMenu)
+ ? ((JMenu) container).getMenuComponentCount()
+ : container.getComponentCount();
+ }
+
+ /**
+ * Gets the <tt>PluginComponent</tt>s of this <tt>PluginContainer</tt>.
+ *
+ * @return an <tt>Iterable</tt> over the <tt>PluginComponent</tt>s of this
+ * <tt>PluginContainer</tt>
+ */
+ public Iterable<PluginComponent> getPluginComponents()
+ {
+ return pluginComponents;
+ }
+
+ /**
+ * Adds the <tt>Component</tt>s of the <tt>PluginComponent</tt>s registered
+ * in the OSGi <tt>BundleContext</tt> in the associated <tt>Container</tt>.
+ */
+ private void initPluginComponents()
+ {
+ GuiActivator.getUIService().addPluginComponentListener(this);
+
+ // Look for PluginComponents registered in the OSGi BundleContext.
+ ServiceReference[] serRefs = null;
+
+ try
+ {
+ serRefs
+ = GuiActivator
+ .bundleContext
+ .getServiceReferences(
+ PluginComponentFactory.class.getName(),
+ "("
+ + Container.CONTAINER_ID
+ + "="
+ + containerId.getID()
+ + ")");
+ }
+ catch (InvalidSyntaxException exc)
+ {
+ logger.error("Could not obtain plugin reference.", exc);
+ }
+
+ if (serRefs != null)
+ {
+ for (ServiceReference serRef : serRefs)
+ {
+ PluginComponentFactory factory
+ = (PluginComponentFactory)
+ GuiActivator.bundleContext.getService(serRef);
+
+ addPluginComponent(factory);
+ }
+ }
+ }
+
+ /**
+ * Implements
+ * {@link PluginComponentListener#pluginComponentAdded(PluginComponentEvent)}.
+ *
+ * @param event a <tt>PluginComponentEvent</tt> which specifies the
+ * <tt>PluginComponent</tt> which has been added
+ */
+ public void pluginComponentAdded(PluginComponentEvent event)
+ {
+ PluginComponentFactory factory = event.getPluginComponentFactory();
+
+ if (factory.getContainer().equals(containerId))
+ addPluginComponent(factory);
+ }
+
+ /**
+ * Implements
+ * {@link PluginComponentListener#pluginComponentRemoved(PluginComponentEvent)}.
+ *
+ * @param event a <tt>PluginComponentEvent</tt> which specifies the
+ * <tt>PluginComponent</tt> which has been added
+ */
+ public void pluginComponentRemoved(PluginComponentEvent event)
+ {
+ PluginComponentFactory factory = event.getPluginComponentFactory();
+
+ if (factory.getContainer().equals(containerId))
+ removePluginComponent(factory);
+ }
+
+ /**
+ * Removes the component of a specific <code>PluginComponent</code> from
+ * this <code>PluginContainer</code>.
+ *
+ * @param factory
+ * the <code>PluginComponent</code> which is to have its
+ * component removed from this <code>PluginContainer</code>
+ */
+ private synchronized void removePluginComponent(
+ PluginComponentFactory factory)
+ {
+ Iterator<PluginComponent> iterator = pluginComponents.iterator();
+ while(iterator.hasNext())
+ {
+ PluginComponent c = iterator.next();
+ if(c.getParentFactory().equals(factory))
+ {
+ iterator.remove();
+ container.remove((Component)c.getComponent());
+ }
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/hid/HIDServiceImpl.java b/src/net/java/sip/communicator/impl/hid/HIDServiceImpl.java
index 00046d7..02552db 100644
--- a/src/net/java/sip/communicator/impl/hid/HIDServiceImpl.java
+++ b/src/net/java/sip/communicator/impl/hid/HIDServiceImpl.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,223 +15,223 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package net.java.sip.communicator.impl.hid;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import net.java.sip.communicator.service.hid.*;
-import net.java.sip.communicator.util.Logger;
-
-import org.jitsi.util.*;
-
-/**
- * Implementation of the HID service to provide way of regenerate key press
- * and mouse interactions.
- *
- * @author Sebastien Vincent
- */
-public class HIDServiceImpl implements HIDService
-{
- /**
- * The <tt>Logger</tt> used by the <tt>NeomediaActivator</tt> class and its
- * instances for logging output.
- */
- private final Logger logger = Logger.getLogger(HIDServiceImpl.class);
-
- /**
- * The robot used to perform some operations (mouse/key interactions).
- */
- private Robot robot = null;
-
- /**
- * Object to regenerates keys with JNI.
- */
- private NativeKeyboard nativeKeyboard = null;
-
- /**
- * Constructor.
- */
- protected HIDServiceImpl()
- {
- try
- {
- robot = new Robot();
- nativeKeyboard = new NativeKeyboard();
- }
- catch(Throwable e)
- {
- if(!GraphicsEnvironment.isHeadless())
- logger.error(
- "Error when creating Robot/NativeKeyboard instance", e);
- }
- }
-
- /**
- * Press a specific key using its keycode.
- *
- * @param keycode the Java keycode, all available keycodes can be found
- * in java.awt.event.KeyEvent class (VK_A, VK_SPACE, ...)
- * @see java.awt.event.KeyEvent
- */
- public void keyPress(int keycode)
- {
- if(OSUtils.IS_WINDOWS || OSUtils.IS_MAC)
- {
- /* do not allow modifiers for Windows (as
- * they are handled in native code with
- * VkScanCode) and Mac OS X
- */
- if(keycode == KeyEvent.VK_ALT ||
- keycode == KeyEvent.VK_SHIFT ||
- keycode == KeyEvent.VK_ALT_GRAPH)
- {
- return;
- }
- }
-
- /* AltGr does not seems to work with robot, handle it via our
- * JNI code
- */
- if(keycode == KeyEvent.VK_ALT_GRAPH)
- {
- symbolPress("altgr");
- }
- else
- {
- robot.keyPress(keycode);
- }
- }
-
- /**
- * Release a specific key using its keycode.
- *
- * @param keycode the Java keycode, all available keycode can be found
- * in java.awt.event.KeyEvent class (VK_A, VK_SPACE, ...)
- * @see java.awt.event.KeyEvent
- */
- public void keyRelease(int keycode)
- {
- /* AltGr does not seems to work with robot, handle it via our
- * JNI code
- */
- if(keycode == KeyEvent.VK_ALT_GRAPH)
- {
- symbolRelease("altgr");
- }
- else
- {
- robot.keyRelease(keycode);
- }
- }
-
- /**
- * Press a specific key using its char representation.
- *
- * @param key char representation of the key
- */
- public void keyPress(char key)
- {
- /* check for CTRL+X where X is [A-Z]
- * CTRL+A = 1, A = 65
- */
- if(key >= 1 && key <= 0x1A)
- {
- key = (char)(key + 64);
- robot.keyPress(key);
- return;
- }
-
- nativeKeyboard.keyPress(key);
- }
-
- /**
- * Release a specific key using its char representation.
- *
- * @param key char representation of the key
- */
- public void keyRelease(char key)
- {
- /* check for CTRL+X where X is [A-Z]
- * CTRL+A = 1, A = 65
- */
- if(key >= 1 && key <= 0x1A)
- {
- key = (char)(key + 64);
- robot.keyRelease(key);
- return;
- }
-
- if(nativeKeyboard != null)
- nativeKeyboard.keyRelease(key);
- }
-
- /**
- * Press a specific symbol (such as SHIFT or CTRL).
- *
- * @param symbol symbol name
- */
- private void symbolPress(String symbol)
- {
- if(nativeKeyboard != null)
- nativeKeyboard.symbolPress(symbol);
- }
-
- /**
- * Release a specific symbol (such as SHIFT or CTRL).
- *
- * @param symbol symbol name
- */
- private void symbolRelease(String symbol)
- {
- if(nativeKeyboard != null)
- nativeKeyboard.symbolRelease(symbol);
- }
-
- /**
- * Press a mouse button(s).
- *
- * @param btns button masks
- * @see java.awt.Robot#mousePress(int btns)
- */
- public void mousePress(int btns)
- {
- robot.mousePress(btns);
- }
-
- /**
- * Release a mouse button(s).
- *
- * @param btns button masks
- * @see java.awt.Robot#mouseRelease(int btns)
- */
- public void mouseRelease(int btns)
- {
- robot.mouseRelease(btns);
- }
-
- /**
- * Move the mouse on the screen.
- *
- * @param x x position on the screen
- * @param y y position on the screen
- * @see java.awt.Robot#mouseMove(int x, int y)
- */
- public void mouseMove(int x, int y)
- {
- robot.mouseMove(x, y);
- }
-
- /**
- * Release a mouse button(s).
- *
- * @param rotation wheel rotation (could be negative or positive depending
- * on the direction).
- * @see java.awt.Robot#mouseWheel(int wheelAmt)
- */
- public void mouseWheel(int rotation)
- {
- robot.mouseWheel(rotation);
- }
-}
+
+package net.java.sip.communicator.impl.hid;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import net.java.sip.communicator.service.hid.*;
+import net.java.sip.communicator.util.Logger;
+
+import org.jitsi.util.*;
+
+/**
+ * Implementation of the HID service to provide way of regenerate key press
+ * and mouse interactions.
+ *
+ * @author Sebastien Vincent
+ */
+public class HIDServiceImpl implements HIDService
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>NeomediaActivator</tt> class and its
+ * instances for logging output.
+ */
+ private final Logger logger = Logger.getLogger(HIDServiceImpl.class);
+
+ /**
+ * The robot used to perform some operations (mouse/key interactions).
+ */
+ private Robot robot = null;
+
+ /**
+ * Object to regenerates keys with JNI.
+ */
+ private NativeKeyboard nativeKeyboard = null;
+
+ /**
+ * Constructor.
+ */
+ protected HIDServiceImpl()
+ {
+ try
+ {
+ robot = new Robot();
+ nativeKeyboard = new NativeKeyboard();
+ }
+ catch(Throwable e)
+ {
+ if(!GraphicsEnvironment.isHeadless())
+ logger.error(
+ "Error when creating Robot/NativeKeyboard instance", e);
+ }
+ }
+
+ /**
+ * Press a specific key using its keycode.
+ *
+ * @param keycode the Java keycode, all available keycodes can be found
+ * in java.awt.event.KeyEvent class (VK_A, VK_SPACE, ...)
+ * @see java.awt.event.KeyEvent
+ */
+ public void keyPress(int keycode)
+ {
+ if(OSUtils.IS_WINDOWS || OSUtils.IS_MAC)
+ {
+ /* do not allow modifiers for Windows (as
+ * they are handled in native code with
+ * VkScanCode) and Mac OS X
+ */
+ if(keycode == KeyEvent.VK_ALT ||
+ keycode == KeyEvent.VK_SHIFT ||
+ keycode == KeyEvent.VK_ALT_GRAPH)
+ {
+ return;
+ }
+ }
+
+ /* AltGr does not seems to work with robot, handle it via our
+ * JNI code
+ */
+ if(keycode == KeyEvent.VK_ALT_GRAPH)
+ {
+ symbolPress("altgr");
+ }
+ else
+ {
+ robot.keyPress(keycode);
+ }
+ }
+
+ /**
+ * Release a specific key using its keycode.
+ *
+ * @param keycode the Java keycode, all available keycode can be found
+ * in java.awt.event.KeyEvent class (VK_A, VK_SPACE, ...)
+ * @see java.awt.event.KeyEvent
+ */
+ public void keyRelease(int keycode)
+ {
+ /* AltGr does not seems to work with robot, handle it via our
+ * JNI code
+ */
+ if(keycode == KeyEvent.VK_ALT_GRAPH)
+ {
+ symbolRelease("altgr");
+ }
+ else
+ {
+ robot.keyRelease(keycode);
+ }
+ }
+
+ /**
+ * Press a specific key using its char representation.
+ *
+ * @param key char representation of the key
+ */
+ public void keyPress(char key)
+ {
+ /* check for CTRL+X where X is [A-Z]
+ * CTRL+A = 1, A = 65
+ */
+ if(key >= 1 && key <= 0x1A)
+ {
+ key = (char)(key + 64);
+ robot.keyPress(key);
+ return;
+ }
+
+ nativeKeyboard.keyPress(key);
+ }
+
+ /**
+ * Release a specific key using its char representation.
+ *
+ * @param key char representation of the key
+ */
+ public void keyRelease(char key)
+ {
+ /* check for CTRL+X where X is [A-Z]
+ * CTRL+A = 1, A = 65
+ */
+ if(key >= 1 && key <= 0x1A)
+ {
+ key = (char)(key + 64);
+ robot.keyRelease(key);
+ return;
+ }
+
+ if(nativeKeyboard != null)
+ nativeKeyboard.keyRelease(key);
+ }
+
+ /**
+ * Press a specific symbol (such as SHIFT or CTRL).
+ *
+ * @param symbol symbol name
+ */
+ private void symbolPress(String symbol)
+ {
+ if(nativeKeyboard != null)
+ nativeKeyboard.symbolPress(symbol);
+ }
+
+ /**
+ * Release a specific symbol (such as SHIFT or CTRL).
+ *
+ * @param symbol symbol name
+ */
+ private void symbolRelease(String symbol)
+ {
+ if(nativeKeyboard != null)
+ nativeKeyboard.symbolRelease(symbol);
+ }
+
+ /**
+ * Press a mouse button(s).
+ *
+ * @param btns button masks
+ * @see java.awt.Robot#mousePress(int btns)
+ */
+ public void mousePress(int btns)
+ {
+ robot.mousePress(btns);
+ }
+
+ /**
+ * Release a mouse button(s).
+ *
+ * @param btns button masks
+ * @see java.awt.Robot#mouseRelease(int btns)
+ */
+ public void mouseRelease(int btns)
+ {
+ robot.mouseRelease(btns);
+ }
+
+ /**
+ * Move the mouse on the screen.
+ *
+ * @param x x position on the screen
+ * @param y y position on the screen
+ * @see java.awt.Robot#mouseMove(int x, int y)
+ */
+ public void mouseMove(int x, int y)
+ {
+ robot.mouseMove(x, y);
+ }
+
+ /**
+ * Release a mouse button(s).
+ *
+ * @param rotation wheel rotation (could be negative or positive depending
+ * on the direction).
+ * @see java.awt.Robot#mouseWheel(int wheelAmt)
+ */
+ public void mouseWheel(int rotation)
+ {
+ robot.mouseWheel(rotation);
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/ldap/LdapPersonFoundImpl.java b/src/net/java/sip/communicator/impl/ldap/LdapPersonFoundImpl.java
index 3d8e6bf..36632fa 100644
--- a/src/net/java/sip/communicator/impl/ldap/LdapPersonFoundImpl.java
+++ b/src/net/java/sip/communicator/impl/ldap/LdapPersonFoundImpl.java
@@ -433,4 +433,10 @@ public class LdapPersonFoundImpl
return this.toString().equals(o.toString()) &&
this.getDN().equals(((LdapPersonFound) o).getDN());
}
+
+ @Override
+ public int hashCode()
+ {
+ return Objects.hash(toString(), getDN());
+ }
}
diff --git a/src/net/java/sip/communicator/impl/ldap/LdapSSLSocketFactoryDelegate.java b/src/net/java/sip/communicator/impl/ldap/LdapSSLSocketFactoryDelegate.java
index dabb4c6..9888628 100644
--- a/src/net/java/sip/communicator/impl/ldap/LdapSSLSocketFactoryDelegate.java
+++ b/src/net/java/sip/communicator/impl/ldap/LdapSSLSocketFactoryDelegate.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,75 +15,75 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.ldap;
-
-import java.io.*;
-import java.net.*;
-import java.security.*;
-
-import javax.net.*;
-
-import net.java.sip.communicator.service.certificate.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Utility class to delegate the creation of sockets to LDAP servers to our
- * {@link CertificateService}.
- * <p>
- * Note that the documentation says to extend {@link SocketFactory}, but the
- * LDAP directory context tries to create an unconnected socket without a
- * hostname first by calling <tt>createSocket</tt>. It would be impossible to
- * validate the hostname against the certificate, which leads to an insecure
- * communication. It only calls {@link #createSocket(String, int)} when
- * <tt>createSocket</tt> is not found
- *
- * @author Ingo Bauersachs
- */
-public class LdapSSLSocketFactoryDelegate
-{
- /**
- * Logger for this class.
- */
- private final static Logger logger =
- Logger.getLogger(LdapSSLSocketFactoryDelegate.class);
-
- /**
- * Get default SSL socket factory delegate.
- *
- * @return default SSL socket factory delegate.
- */
- public static Object getDefault()
- {
- return new LdapSSLSocketFactoryDelegate();
- }
-
- /**
- * Creates a socket for the specified destination host and port.
- *
- * @param host The hostname that the socket connects to.
- * @param port The port that the socket connects to.
- * @return The created socket.
- * @throws IOException
- * @throws UnknownHostException When the hostname cannot be resolved to an
- * IP address.
- */
- public Socket createSocket(String host, int port)
- throws IOException,
- UnknownHostException
- {
- try
- {
- return LdapServiceImpl
- .getCertificateService()
- .getSSLContext(
- LdapServiceImpl.getCertificateService().getTrustManager(
- host)).getSocketFactory().createSocket(host, port);
- }
- catch (GeneralSecurityException e)
- {
- logger.error(
- "unable to create socket through the certificate service", e);
- throw new IOException(e.getMessage());
- }
- }
-}
+package net.java.sip.communicator.impl.ldap;
+
+import java.io.*;
+import java.net.*;
+import java.security.*;
+
+import javax.net.*;
+
+import net.java.sip.communicator.service.certificate.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Utility class to delegate the creation of sockets to LDAP servers to our
+ * {@link CertificateService}.
+ * <p>
+ * Note that the documentation says to extend {@link SocketFactory}, but the
+ * LDAP directory context tries to create an unconnected socket without a
+ * hostname first by calling <tt>createSocket</tt>. It would be impossible to
+ * validate the hostname against the certificate, which leads to an insecure
+ * communication. It only calls {@link #createSocket(String, int)} when
+ * <tt>createSocket</tt> is not found
+ *
+ * @author Ingo Bauersachs
+ */
+public class LdapSSLSocketFactoryDelegate
+{
+ /**
+ * Logger for this class.
+ */
+ private final static Logger logger =
+ Logger.getLogger(LdapSSLSocketFactoryDelegate.class);
+
+ /**
+ * Get default SSL socket factory delegate.
+ *
+ * @return default SSL socket factory delegate.
+ */
+ public static Object getDefault()
+ {
+ return new LdapSSLSocketFactoryDelegate();
+ }
+
+ /**
+ * Creates a socket for the specified destination host and port.
+ *
+ * @param host The hostname that the socket connects to.
+ * @param port The port that the socket connects to.
+ * @return The created socket.
+ * @throws IOException
+ * @throws UnknownHostException When the hostname cannot be resolved to an
+ * IP address.
+ */
+ public Socket createSocket(String host, int port)
+ throws IOException,
+ UnknownHostException
+ {
+ try
+ {
+ return LdapServiceImpl
+ .getCertificateService()
+ .getSSLContext(
+ LdapServiceImpl.getCertificateService().getTrustManager(
+ host)).getSocketFactory().createSocket(host, port);
+ }
+ catch (GeneralSecurityException e)
+ {
+ logger.error(
+ "unable to create socket through the certificate service", e);
+ throw new IOException(e.getMessage());
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/muc/BaseChatRoomSourceContact.java b/src/net/java/sip/communicator/impl/muc/BaseChatRoomSourceContact.java
index 3225af9..28f43e3 100644
--- a/src/net/java/sip/communicator/impl/muc/BaseChatRoomSourceContact.java
+++ b/src/net/java/sip/communicator/impl/muc/BaseChatRoomSourceContact.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,141 +15,141 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.muc;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.contactsource.*;
-import net.java.sip.communicator.service.muc.*;
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * Basic source contact for the chat rooms.
- *
- * @author Hristo Terezov
- */
-public class BaseChatRoomSourceContact
- extends SortedGenericSourceContact
-{
-
- /**
- * The parent contact query.
- */
- protected final ContactQuery parentQuery;
-
- /**
- * The name of the chat room associated with the contact.
- */
- private String chatRoomName;
-
- /**
- * The ID of the chat room associated with the contact.
- */
- private String chatRoomID;
-
- /**
- * The protocol provider of the chat room associated with the contact.
- */
- private ProtocolProviderService provider;
-
- /**
- * Contsructs new chat room source contact.
- * @param chatRoomName the name of the chat room associated with the room.
- * @param chatRoomID the id of the chat room associated with the room.
- * @param query the query associated with the contact.
- * @param pps the protocol provider of the contact.
- */
- public BaseChatRoomSourceContact(String chatRoomName,
- String chatRoomID, ContactQuery query, ProtocolProviderService pps)
- {
- super(query, query.getContactSource(), chatRoomName,
- generateDefaultContactDetails(chatRoomName));
-
- this.chatRoomName = chatRoomName;
- this.chatRoomID = chatRoomID;
- this.provider = pps;
- this.parentQuery = query;
-
- initContactProperties(ChatRoomPresenceStatus.CHAT_ROOM_OFFLINE);
- setDisplayDetails(pps.getAccountID().getDisplayName());
- }
-
-
- /**
- * Sets the given presence status and the name of the chat room associated
- * with the contact.
- * @param status the presence status to be set.
- */
- protected void initContactProperties(PresenceStatus status)
- {
- setPresenceStatus(status);
- setContactAddress(chatRoomName);
- }
-
- /**
- * Generates the default contact details for
- * <tt>BaseChatRoomSourceContact</tt> instances.
- *
- * @param chatRoomName the name of the chat room associated with the contact
- * @return list of default <tt>ContactDetail</tt>s for the contact.
- */
- private static List<ContactDetail> generateDefaultContactDetails(
- String chatRoomName)
- {
- ContactDetail contactDetail
- = new ContactDetail(chatRoomName);
- List<Class<? extends OperationSet>> supportedOpSets
- = new ArrayList<Class<? extends OperationSet>>();
-
- supportedOpSets.add(OperationSetMultiUserChat.class);
- contactDetail.setSupportedOpSets(supportedOpSets);
-
- List<ContactDetail> contactDetails
- = new ArrayList<ContactDetail>();
-
- contactDetails.add(contactDetail);
- return contactDetails;
- }
-
- /**
- * Returns the id of the chat room associated with the contact.
- *
- * @return the chat room id.
- */
- public String getChatRoomID()
- {
- return chatRoomID;
- }
-
- /**
- * Returns the name of the chat room associated with the contact.
- *
- * @return the chat room name
- */
- public String getChatRoomName()
- {
- return chatRoomName;
- }
-
- /**
- * Returns the provider of the chat room associated with the contact.
- *
- * @return the provider
- */
- public ProtocolProviderService getProvider()
- {
- return provider;
- }
-
- /**
- * Returns the index of this source contact in its parent group.
- *
- * @return the index of this contact in its parent
- */
- public int getIndex()
- {
- if(parentQuery instanceof ServerChatRoomQuery)
- return ((ServerChatRoomQuery)parentQuery).indexOf(this);
- return -1;
- }
-}
+package net.java.sip.communicator.impl.muc;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.muc.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * Basic source contact for the chat rooms.
+ *
+ * @author Hristo Terezov
+ */
+public class BaseChatRoomSourceContact
+ extends SortedGenericSourceContact
+{
+
+ /**
+ * The parent contact query.
+ */
+ protected final ContactQuery parentQuery;
+
+ /**
+ * The name of the chat room associated with the contact.
+ */
+ private String chatRoomName;
+
+ /**
+ * The ID of the chat room associated with the contact.
+ */
+ private String chatRoomID;
+
+ /**
+ * The protocol provider of the chat room associated with the contact.
+ */
+ private ProtocolProviderService provider;
+
+ /**
+ * Contsructs new chat room source contact.
+ * @param chatRoomName the name of the chat room associated with the room.
+ * @param chatRoomID the id of the chat room associated with the room.
+ * @param query the query associated with the contact.
+ * @param pps the protocol provider of the contact.
+ */
+ public BaseChatRoomSourceContact(String chatRoomName,
+ String chatRoomID, ContactQuery query, ProtocolProviderService pps)
+ {
+ super(query, query.getContactSource(), chatRoomName,
+ generateDefaultContactDetails(chatRoomName));
+
+ this.chatRoomName = chatRoomName;
+ this.chatRoomID = chatRoomID;
+ this.provider = pps;
+ this.parentQuery = query;
+
+ initContactProperties(ChatRoomPresenceStatus.CHAT_ROOM_OFFLINE);
+ setDisplayDetails(pps.getAccountID().getDisplayName());
+ }
+
+
+ /**
+ * Sets the given presence status and the name of the chat room associated
+ * with the contact.
+ * @param status the presence status to be set.
+ */
+ protected void initContactProperties(PresenceStatus status)
+ {
+ setPresenceStatus(status);
+ setContactAddress(chatRoomName);
+ }
+
+ /**
+ * Generates the default contact details for
+ * <tt>BaseChatRoomSourceContact</tt> instances.
+ *
+ * @param chatRoomName the name of the chat room associated with the contact
+ * @return list of default <tt>ContactDetail</tt>s for the contact.
+ */
+ private static List<ContactDetail> generateDefaultContactDetails(
+ String chatRoomName)
+ {
+ ContactDetail contactDetail
+ = new ContactDetail(chatRoomName);
+ List<Class<? extends OperationSet>> supportedOpSets
+ = new ArrayList<Class<? extends OperationSet>>();
+
+ supportedOpSets.add(OperationSetMultiUserChat.class);
+ contactDetail.setSupportedOpSets(supportedOpSets);
+
+ List<ContactDetail> contactDetails
+ = new ArrayList<ContactDetail>();
+
+ contactDetails.add(contactDetail);
+ return contactDetails;
+ }
+
+ /**
+ * Returns the id of the chat room associated with the contact.
+ *
+ * @return the chat room id.
+ */
+ public String getChatRoomID()
+ {
+ return chatRoomID;
+ }
+
+ /**
+ * Returns the name of the chat room associated with the contact.
+ *
+ * @return the chat room name
+ */
+ public String getChatRoomName()
+ {
+ return chatRoomName;
+ }
+
+ /**
+ * Returns the provider of the chat room associated with the contact.
+ *
+ * @return the provider
+ */
+ public ProtocolProviderService getProvider()
+ {
+ return provider;
+ }
+
+ /**
+ * Returns the index of this source contact in its parent group.
+ *
+ * @return the index of this contact in its parent
+ */
+ public int getIndex()
+ {
+ if(parentQuery instanceof ServerChatRoomQuery)
+ return ((ServerChatRoomQuery)parentQuery).indexOf(this);
+ return -1;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/muc/ChatRoomQuery.java b/src/net/java/sip/communicator/impl/muc/ChatRoomQuery.java
index 24a3ebd..9cd1c21 100644
--- a/src/net/java/sip/communicator/impl/muc/ChatRoomQuery.java
+++ b/src/net/java/sip/communicator/impl/muc/ChatRoomQuery.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,543 +15,543 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.muc;
-
-import java.util.*;
-import java.util.regex.*;
-
-import net.java.sip.communicator.service.contactsource.*;
-import net.java.sip.communicator.service.muc.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-
-import org.osgi.framework.*;
-
-/**
- * The <tt>ChatRoomQuery</tt> is a query over the
- * <tt>ChatRoomContactSourceService</tt>.
- *
- * @author Hristo Terezov
- */
-public class ChatRoomQuery
- extends AsyncContactQuery<ContactSourceService>
- implements LocalUserChatRoomPresenceListener,
- ChatRoomListChangeListener,
- ChatRoomProviderWrapperListener
-{
- /**
- * The query string.
- */
- private String queryString;
-
- /**
- * List with the current results for the query.
- */
- private Set<ChatRoomSourceContact> contactResults
- = new TreeSet<ChatRoomSourceContact>();
-
- /**
- * MUC service.
- */
- private MUCServiceImpl mucService;
-
- /**
- * The number of contact query listeners.
- */
- private int contactQueryListenersCount = 0;
-
- /**
- * The protocol provider registration listener.
- */
- private ServiceListener protolProviderRegistrationListener = null;
-
- /**
- * Creates an instance of <tt>ChatRoomQuery</tt> by specifying
- * the parent contact source, the query string to match and the maximum
- * result contacts to return.
- *
- * @param queryString the query string to match
- * @param contactSource the parent contact source
- */
- public ChatRoomQuery(String queryString,
- ChatRoomContactSourceService contactSource)
- {
- super(contactSource,
- Pattern.compile(queryString, Pattern.CASE_INSENSITIVE
- | Pattern.LITERAL), true);
- this.queryString = queryString;
-
- mucService = MUCActivator.getMUCService();
-
- }
-
- /**
- * Adds listeners for the query
- */
- private void initListeners()
- {
- for(ProtocolProviderService pps : MUCActivator.getChatRoomProviders())
- {
- addQueryToProviderPresenceListeners(pps);
- }
-
- mucService.addChatRoomListChangeListener(this);
- mucService.addChatRoomProviderWrapperListener(this);
- protolProviderRegistrationListener = new ProtocolProviderRegListener();
- MUCActivator.bundleContext.addServiceListener(
- protolProviderRegistrationListener);
- }
-
- /**
- * Adds the query as presence listener to protocol provider service.
- * @param pps the protocol provider service.
- */
- public void addQueryToProviderPresenceListeners(ProtocolProviderService pps)
- {
- OperationSetMultiUserChat opSetMUC
- = pps.getOperationSet(OperationSetMultiUserChat.class);
- if(opSetMUC != null)
- {
- opSetMUC.addPresenceListener(this);
- }
- }
-
- /**
- * Removes the query from protocol provider service presence listeners.
- * @param pps the protocol provider service.
- */
- public void removeQueryFromProviderPresenceListeners(
- ProtocolProviderService pps)
- {
- OperationSetMultiUserChat opSetMUC
- = pps.getOperationSet(OperationSetMultiUserChat.class);
- if(opSetMUC != null)
- {
- opSetMUC.removePresenceListener(this);
- }
- }
-
- @Override
- protected void run()
- {
- Iterator<ChatRoomProviderWrapper> chatRoomProviders
- = mucService.getChatRoomProviders();
-
- while (chatRoomProviders.hasNext())
- {
- ChatRoomProviderWrapper provider = chatRoomProviders.next();
- providerAdded(provider, true);
- }
-
- if (getStatus() != QUERY_CANCELED)
- setStatus(QUERY_COMPLETED);
- }
-
- /**
- * Handles adding a chat room provider.
- * @param provider the provider.
- * @param addQueryResult indicates whether we should add the chat room to
- * the query results or fire an event without adding it to the results.
- */
- private void providerAdded(ChatRoomProviderWrapper provider,
- boolean addQueryResult)
- {
-
- for(int i = 0; i < provider.countChatRooms(); i++)
- {
- ChatRoomWrapper chatRoom = provider.getChatRoom(i);
- addChatRoom( provider.getProtocolProvider(),
- chatRoom.getChatRoomName(), chatRoom.getChatRoomID(),
- addQueryResult, chatRoom.isAutojoin());
- }
- }
-
- /**
- * Handles chat room presence status updates.
- *
- * @param evt the <tt>LocalUserChatRoomPresenceChangeEvent</tt> instance
- * containing the chat room and the type, and reason of the change
- */
- @Override
- public void localUserPresenceChanged(
- LocalUserChatRoomPresenceChangeEvent evt)
- {
- ChatRoom sourceChatRoom = evt.getChatRoom();
-
- String eventType = evt.getEventType();
-
- boolean existingContact = false;
- ChatRoomSourceContact foundContact = null;
- synchronized (contactResults)
- {
- for (ChatRoomSourceContact contact : contactResults)
- {
- if (contactEqualsChatRoom(contact, sourceChatRoom))
- {
- existingContact = true;
- foundContact = contact;
- contactResults.remove(contact);
- break;
- }
- }
- }
-
- if (LocalUserChatRoomPresenceChangeEvent
- .LOCAL_USER_JOINED.equals(eventType))
- {
- if(existingContact)
- {
- foundContact.setPresenceStatus(
- ChatRoomPresenceStatus.CHAT_ROOM_ONLINE);
- synchronized (contactResults)
- {
- contactResults.add(foundContact);
- }
- fireContactChanged(foundContact);
- }
- else
- {
- ChatRoomWrapper chatRoom
- = MUCActivator.getMUCService()
- .findChatRoomWrapperFromChatRoom(sourceChatRoom);
- if(chatRoom != null)
- addChatRoom(sourceChatRoom, false, chatRoom.isAutojoin());
- }
- }
- else if ((LocalUserChatRoomPresenceChangeEvent
- .LOCAL_USER_LEFT.equals(eventType)
- || LocalUserChatRoomPresenceChangeEvent
- .LOCAL_USER_KICKED.equals(eventType)
- || LocalUserChatRoomPresenceChangeEvent
- .LOCAL_USER_DROPPED.equals(eventType))
- )
- {
- if(existingContact)
- {
- foundContact.setPresenceStatus(
- ChatRoomPresenceStatus.CHAT_ROOM_OFFLINE);
- synchronized (contactResults)
- {
- contactResults.add(foundContact);
- }
- fireContactChanged(foundContact);
- }
- }
- }
-
- /**
- * Adds found result to the query results.
- *
- * @param room the chat room.
- * @param addQueryResult indicates whether we should add the chat room to
- * the query results or fire an event without adding it to the results.
- * @param isAutoJoin the auto join state of the contact.
- */
- private void addChatRoom(ChatRoom room, boolean addQueryResult,
- boolean isAutoJoin)
- {
- if(queryString == null
- || ((room.getName().contains(
- queryString)
- || room.getIdentifier().contains(queryString)
- )))
- {
- ChatRoomSourceContact contact
- = new ChatRoomSourceContact(room, this, isAutoJoin);
- synchronized (contactResults)
- {
- contactResults.add(contact);
- }
-
- if(addQueryResult)
- {
- addQueryResult(contact, false);
- }
- else
- {
- fireContactReceived(contact, false);
- }
- }
- }
-
- /**
- * Adds found result to the query results.
- *
- * @param pps the protocol provider associated with the found chat room.
- * @param chatRoomName the name of the chat room.
- * @param chatRoomID the id of the chat room.
- * @param addQueryResult indicates whether we should add the chat room to
- * the query results or fire an event without adding it to the results.
- * @param isAutoJoin the auto join state of the contact.
- */
- private void addChatRoom(ProtocolProviderService pps,
- String chatRoomName, String chatRoomID, boolean addQueryResult,
- boolean isAutoJoin)
- {
- if(queryString == null
- || ((chatRoomName.contains(
- queryString)
- || chatRoomID.contains(queryString)
- )))
- {
- ChatRoomSourceContact contact
- = new ChatRoomSourceContact(chatRoomName, chatRoomID, this, pps,
- isAutoJoin);
- synchronized (contactResults)
- {
- contactResults.add(contact);
- }
-
- if(addQueryResult)
- {
- addQueryResult(contact, false);
- }
- else
- {
- fireContactReceived(contact, false);
- }
- }
- }
-
- /**
- * Indicates that a change has occurred in the chat room data list.
- * @param evt the event that describes the change.
- */
- @Override
- public void contentChanged(final ChatRoomListChangeEvent evt)
- {
- ChatRoomWrapper chatRoom = evt.getSourceChatRoom();
- switch (evt.getEventID())
- {
- case ChatRoomListChangeEvent.CHAT_ROOM_ADDED:
- addChatRoom(chatRoom.getChatRoom(), false,
- chatRoom.isAutojoin());
- break;
- case ChatRoomListChangeEvent.CHAT_ROOM_REMOVED:
- LinkedList<ChatRoomSourceContact> tmpContactResults;
- synchronized (contactResults)
- {
- tmpContactResults
- = new LinkedList<ChatRoomSourceContact>(contactResults);
-
- for (ChatRoomSourceContact contact : tmpContactResults)
- {
- if (contactEqualsChatRoom(contact, chatRoom))
- {
- contactResults.remove(contact);
- fireContactRemoved(contact);
- break;
- }
- }
- }
- break;
- case ChatRoomListChangeEvent.CHAT_ROOM_CHANGED:
- synchronized (contactResults)
- {
- for (ChatRoomSourceContact contact : contactResults)
- {
- if (contactEqualsChatRoom(contact,
- chatRoom.getChatRoom()))
- {
- if (chatRoom.isAutojoin() != contact.isAutoJoin())
- {
- contact.setAutoJoin(chatRoom.isAutojoin());
- fireContactChanged(contact);
- }
- break;
- }
- }
- }
- break;
- default:
- break;
- }
- }
-
- @Override
- public void chatRoomProviderWrapperAdded(ChatRoomProviderWrapper provider)
- {
- providerAdded(provider, false);
- }
-
- @Override
- public void chatRoomProviderWrapperRemoved(ChatRoomProviderWrapper provider)
- {
- LinkedList<ChatRoomSourceContact> tmpContactResults;
- synchronized (contactResults)
- {
- tmpContactResults
- = new LinkedList<ChatRoomSourceContact>(contactResults);
-
- for(ChatRoomSourceContact contact : tmpContactResults)
- {
- if(contact.getProvider().equals(provider.getProtocolProvider()))
- {
- contactResults.remove(contact);
- fireContactRemoved(contact);
- }
- }
- }
- }
-
- /**
- * Test equality of contact to chat room. This test recognizes that chat
- * rooms may have equal names but connected to different accounts.
- *
- * @param contact the contact
- * @param chatRoom the chat room
- * @return returns <tt>true</tt> if they are equal, or <tt>false</tt> if
- * they are different
- */
- private boolean contactEqualsChatRoom(final ChatRoomSourceContact contact,
- final ChatRoom chatRoom)
- {
- return contact.getProvider() == chatRoom.getParentProvider()
- && chatRoom.getIdentifier().equals(contact.getContactAddress());
- }
-
- /**
- * Test equality of contact to chat room wrapper. This method does not rely
- * on a chat room instance, since that may not be available in case of
- * removal.
- *
- * @param contact the contact
- * @param chatRoomWrapper the chat room wrapper
- * @return returns <tt>true</tt> if they are equal, or <tt>false</tt> if
- * they are different.
- */
- private boolean contactEqualsChatRoom(final ChatRoomSourceContact contact,
- final ChatRoomWrapper chatRoomWrapper)
- {
- return contact.getProvider() == chatRoomWrapper.getParentProvider()
- .getProtocolProvider()
- && contact.getContactAddress().equals(
- chatRoomWrapper.getChatRoomID());
- }
-
- /**
- * Returns the index of the contact in the contact results list.
- * @param contact the contact.
- * @return the index of the contact in the contact results list.
- */
- public synchronized int indexOf(ChatRoomSourceContact contact)
- {
- Iterator<ChatRoomSourceContact> it = contactResults.iterator();
- int i = 0;
- while(it.hasNext())
- {
- if(contact.equals(it.next()))
- {
- return i;
- }
- i++;
- }
- return -1;
- }
-
- /**
- * Clears any listener we used.
- */
- private void clearListeners()
- {
- mucService.removeChatRoomListChangeListener(this);
- mucService.removeChatRoomProviderWrapperListener(this);
- if(protolProviderRegistrationListener != null)
- MUCActivator.bundleContext.removeServiceListener(
- protolProviderRegistrationListener);
- protolProviderRegistrationListener = null;
- for(ProtocolProviderService pps : MUCActivator.getChatRoomProviders())
- {
- removeQueryFromProviderPresenceListeners(pps);
- }
- }
-
- /**
- * Cancels this <tt>ContactQuery</tt>.
- *
- * @see ContactQuery#cancel()
- */
- public void cancel()
- {
- clearListeners();
-
- super.cancel();
- }
-
- /**
- * If query has status changed to cancel, let's clear listeners.
- * @param status {@link ContactQuery#QUERY_CANCELED},
- * {@link ContactQuery#QUERY_COMPLETED}
- */
- public void setStatus(int status)
- {
- if(status == QUERY_CANCELED)
- clearListeners();
-
- super.setStatus(status);
- }
-
- @Override
- public void addContactQueryListener(ContactQueryListener l)
- {
- super.addContactQueryListener(l);
- contactQueryListenersCount++;
- if(contactQueryListenersCount == 1)
- {
- initListeners();
- }
- }
-
- @Override
- public void removeContactQueryListener(ContactQueryListener l)
- {
- super.removeContactQueryListener(l);
- contactQueryListenersCount--;
- if(contactQueryListenersCount == 0)
- {
- clearListeners();
- }
- }
-
- /**
- * Listens for <tt>ProtocolProviderService</tt> registrations.
- */
- private class ProtocolProviderRegListener
- implements ServiceListener
- {
- /**
- * Handles service change events.
- */
- public void serviceChanged(ServiceEvent event)
- {
- ServiceReference serviceRef = event.getServiceReference();
-
- // if the event is caused by a bundle being stopped, we don't want to
- // know
- if (serviceRef.getBundle().getState() == Bundle.STOPPING)
- {
- return;
- }
-
- Object service = MUCActivator.bundleContext.getService(serviceRef);
-
- // we don't care if the source service is not a protocol provider
- if (!(service instanceof ProtocolProviderService))
- {
- return;
- }
-
- switch (event.getType())
- {
- case ServiceEvent.REGISTERED:
- addQueryToProviderPresenceListeners(
- (ProtocolProviderService) service);
- break;
- case ServiceEvent.UNREGISTERING:
- removeQueryFromProviderPresenceListeners(
- (ProtocolProviderService) service);
- break;
- }
- }
- }
+package net.java.sip.communicator.impl.muc;
+
+import java.util.*;
+import java.util.regex.*;
+
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.muc.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+
+import org.osgi.framework.*;
+
+/**
+ * The <tt>ChatRoomQuery</tt> is a query over the
+ * <tt>ChatRoomContactSourceService</tt>.
+ *
+ * @author Hristo Terezov
+ */
+public class ChatRoomQuery
+ extends AsyncContactQuery<ContactSourceService>
+ implements LocalUserChatRoomPresenceListener,
+ ChatRoomListChangeListener,
+ ChatRoomProviderWrapperListener
+{
+ /**
+ * The query string.
+ */
+ private String queryString;
+
+ /**
+ * List with the current results for the query.
+ */
+ private Set<ChatRoomSourceContact> contactResults
+ = new TreeSet<ChatRoomSourceContact>();
+
+ /**
+ * MUC service.
+ */
+ private MUCServiceImpl mucService;
+
+ /**
+ * The number of contact query listeners.
+ */
+ private int contactQueryListenersCount = 0;
+
+ /**
+ * The protocol provider registration listener.
+ */
+ private ServiceListener protolProviderRegistrationListener = null;
+
+ /**
+ * Creates an instance of <tt>ChatRoomQuery</tt> by specifying
+ * the parent contact source, the query string to match and the maximum
+ * result contacts to return.
+ *
+ * @param queryString the query string to match
+ * @param contactSource the parent contact source
+ */
+ public ChatRoomQuery(String queryString,
+ ChatRoomContactSourceService contactSource)
+ {
+ super(contactSource,
+ Pattern.compile(queryString, Pattern.CASE_INSENSITIVE
+ | Pattern.LITERAL), true);
+ this.queryString = queryString;
+
+ mucService = MUCActivator.getMUCService();
+
+ }
+
+ /**
+ * Adds listeners for the query
+ */
+ private void initListeners()
+ {
+ for(ProtocolProviderService pps : MUCActivator.getChatRoomProviders())
+ {
+ addQueryToProviderPresenceListeners(pps);
+ }
+
+ mucService.addChatRoomListChangeListener(this);
+ mucService.addChatRoomProviderWrapperListener(this);
+ protolProviderRegistrationListener = new ProtocolProviderRegListener();
+ MUCActivator.bundleContext.addServiceListener(
+ protolProviderRegistrationListener);
+ }
+
+ /**
+ * Adds the query as presence listener to protocol provider service.
+ * @param pps the protocol provider service.
+ */
+ public void addQueryToProviderPresenceListeners(ProtocolProviderService pps)
+ {
+ OperationSetMultiUserChat opSetMUC
+ = pps.getOperationSet(OperationSetMultiUserChat.class);
+ if(opSetMUC != null)
+ {
+ opSetMUC.addPresenceListener(this);
+ }
+ }
+
+ /**
+ * Removes the query from protocol provider service presence listeners.
+ * @param pps the protocol provider service.
+ */
+ public void removeQueryFromProviderPresenceListeners(
+ ProtocolProviderService pps)
+ {
+ OperationSetMultiUserChat opSetMUC
+ = pps.getOperationSet(OperationSetMultiUserChat.class);
+ if(opSetMUC != null)
+ {
+ opSetMUC.removePresenceListener(this);
+ }
+ }
+
+ @Override
+ protected void run()
+ {
+ Iterator<ChatRoomProviderWrapper> chatRoomProviders
+ = mucService.getChatRoomProviders();
+
+ while (chatRoomProviders.hasNext())
+ {
+ ChatRoomProviderWrapper provider = chatRoomProviders.next();
+ providerAdded(provider, true);
+ }
+
+ if (getStatus() != QUERY_CANCELED)
+ setStatus(QUERY_COMPLETED);
+ }
+
+ /**
+ * Handles adding a chat room provider.
+ * @param provider the provider.
+ * @param addQueryResult indicates whether we should add the chat room to
+ * the query results or fire an event without adding it to the results.
+ */
+ private void providerAdded(ChatRoomProviderWrapper provider,
+ boolean addQueryResult)
+ {
+
+ for(int i = 0; i < provider.countChatRooms(); i++)
+ {
+ ChatRoomWrapper chatRoom = provider.getChatRoom(i);
+ addChatRoom( provider.getProtocolProvider(),
+ chatRoom.getChatRoomName(), chatRoom.getChatRoomID(),
+ addQueryResult, chatRoom.isAutojoin());
+ }
+ }
+
+ /**
+ * Handles chat room presence status updates.
+ *
+ * @param evt the <tt>LocalUserChatRoomPresenceChangeEvent</tt> instance
+ * containing the chat room and the type, and reason of the change
+ */
+ @Override
+ public void localUserPresenceChanged(
+ LocalUserChatRoomPresenceChangeEvent evt)
+ {
+ ChatRoom sourceChatRoom = evt.getChatRoom();
+
+ String eventType = evt.getEventType();
+
+ boolean existingContact = false;
+ ChatRoomSourceContact foundContact = null;
+ synchronized (contactResults)
+ {
+ for (ChatRoomSourceContact contact : contactResults)
+ {
+ if (contactEqualsChatRoom(contact, sourceChatRoom))
+ {
+ existingContact = true;
+ foundContact = contact;
+ contactResults.remove(contact);
+ break;
+ }
+ }
+ }
+
+ if (LocalUserChatRoomPresenceChangeEvent
+ .LOCAL_USER_JOINED.equals(eventType))
+ {
+ if(existingContact)
+ {
+ foundContact.setPresenceStatus(
+ ChatRoomPresenceStatus.CHAT_ROOM_ONLINE);
+ synchronized (contactResults)
+ {
+ contactResults.add(foundContact);
+ }
+ fireContactChanged(foundContact);
+ }
+ else
+ {
+ ChatRoomWrapper chatRoom
+ = MUCActivator.getMUCService()
+ .findChatRoomWrapperFromChatRoom(sourceChatRoom);
+ if(chatRoom != null)
+ addChatRoom(sourceChatRoom, false, chatRoom.isAutojoin());
+ }
+ }
+ else if ((LocalUserChatRoomPresenceChangeEvent
+ .LOCAL_USER_LEFT.equals(eventType)
+ || LocalUserChatRoomPresenceChangeEvent
+ .LOCAL_USER_KICKED.equals(eventType)
+ || LocalUserChatRoomPresenceChangeEvent
+ .LOCAL_USER_DROPPED.equals(eventType))
+ )
+ {
+ if(existingContact)
+ {
+ foundContact.setPresenceStatus(
+ ChatRoomPresenceStatus.CHAT_ROOM_OFFLINE);
+ synchronized (contactResults)
+ {
+ contactResults.add(foundContact);
+ }
+ fireContactChanged(foundContact);
+ }
+ }
+ }
+
+ /**
+ * Adds found result to the query results.
+ *
+ * @param room the chat room.
+ * @param addQueryResult indicates whether we should add the chat room to
+ * the query results or fire an event without adding it to the results.
+ * @param isAutoJoin the auto join state of the contact.
+ */
+ private void addChatRoom(ChatRoom room, boolean addQueryResult,
+ boolean isAutoJoin)
+ {
+ if(queryString == null
+ || ((room.getName().contains(
+ queryString)
+ || room.getIdentifier().contains(queryString)
+ )))
+ {
+ ChatRoomSourceContact contact
+ = new ChatRoomSourceContact(room, this, isAutoJoin);
+ synchronized (contactResults)
+ {
+ contactResults.add(contact);
+ }
+
+ if(addQueryResult)
+ {
+ addQueryResult(contact, false);
+ }
+ else
+ {
+ fireContactReceived(contact, false);
+ }
+ }
+ }
+
+ /**
+ * Adds found result to the query results.
+ *
+ * @param pps the protocol provider associated with the found chat room.
+ * @param chatRoomName the name of the chat room.
+ * @param chatRoomID the id of the chat room.
+ * @param addQueryResult indicates whether we should add the chat room to
+ * the query results or fire an event without adding it to the results.
+ * @param isAutoJoin the auto join state of the contact.
+ */
+ private void addChatRoom(ProtocolProviderService pps,
+ String chatRoomName, String chatRoomID, boolean addQueryResult,
+ boolean isAutoJoin)
+ {
+ if(queryString == null
+ || ((chatRoomName.contains(
+ queryString)
+ || chatRoomID.contains(queryString)
+ )))
+ {
+ ChatRoomSourceContact contact
+ = new ChatRoomSourceContact(chatRoomName, chatRoomID, this, pps,
+ isAutoJoin);
+ synchronized (contactResults)
+ {
+ contactResults.add(contact);
+ }
+
+ if(addQueryResult)
+ {
+ addQueryResult(contact, false);
+ }
+ else
+ {
+ fireContactReceived(contact, false);
+ }
+ }
+ }
+
+ /**
+ * Indicates that a change has occurred in the chat room data list.
+ * @param evt the event that describes the change.
+ */
+ @Override
+ public void contentChanged(final ChatRoomListChangeEvent evt)
+ {
+ ChatRoomWrapper chatRoom = evt.getSourceChatRoom();
+ switch (evt.getEventID())
+ {
+ case ChatRoomListChangeEvent.CHAT_ROOM_ADDED:
+ addChatRoom(chatRoom.getChatRoom(), false,
+ chatRoom.isAutojoin());
+ break;
+ case ChatRoomListChangeEvent.CHAT_ROOM_REMOVED:
+ LinkedList<ChatRoomSourceContact> tmpContactResults;
+ synchronized (contactResults)
+ {
+ tmpContactResults
+ = new LinkedList<ChatRoomSourceContact>(contactResults);
+
+ for (ChatRoomSourceContact contact : tmpContactResults)
+ {
+ if (contactEqualsChatRoom(contact, chatRoom))
+ {
+ contactResults.remove(contact);
+ fireContactRemoved(contact);
+ break;
+ }
+ }
+ }
+ break;
+ case ChatRoomListChangeEvent.CHAT_ROOM_CHANGED:
+ synchronized (contactResults)
+ {
+ for (ChatRoomSourceContact contact : contactResults)
+ {
+ if (contactEqualsChatRoom(contact,
+ chatRoom.getChatRoom()))
+ {
+ if (chatRoom.isAutojoin() != contact.isAutoJoin())
+ {
+ contact.setAutoJoin(chatRoom.isAutojoin());
+ fireContactChanged(contact);
+ }
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public void chatRoomProviderWrapperAdded(ChatRoomProviderWrapper provider)
+ {
+ providerAdded(provider, false);
+ }
+
+ @Override
+ public void chatRoomProviderWrapperRemoved(ChatRoomProviderWrapper provider)
+ {
+ LinkedList<ChatRoomSourceContact> tmpContactResults;
+ synchronized (contactResults)
+ {
+ tmpContactResults
+ = new LinkedList<ChatRoomSourceContact>(contactResults);
+
+ for(ChatRoomSourceContact contact : tmpContactResults)
+ {
+ if(contact.getProvider().equals(provider.getProtocolProvider()))
+ {
+ contactResults.remove(contact);
+ fireContactRemoved(contact);
+ }
+ }
+ }
+ }
+
+ /**
+ * Test equality of contact to chat room. This test recognizes that chat
+ * rooms may have equal names but connected to different accounts.
+ *
+ * @param contact the contact
+ * @param chatRoom the chat room
+ * @return returns <tt>true</tt> if they are equal, or <tt>false</tt> if
+ * they are different
+ */
+ private boolean contactEqualsChatRoom(final ChatRoomSourceContact contact,
+ final ChatRoom chatRoom)
+ {
+ return contact.getProvider() == chatRoom.getParentProvider()
+ && chatRoom.getIdentifier().equals(contact.getContactAddress());
+ }
+
+ /**
+ * Test equality of contact to chat room wrapper. This method does not rely
+ * on a chat room instance, since that may not be available in case of
+ * removal.
+ *
+ * @param contact the contact
+ * @param chatRoomWrapper the chat room wrapper
+ * @return returns <tt>true</tt> if they are equal, or <tt>false</tt> if
+ * they are different.
+ */
+ private boolean contactEqualsChatRoom(final ChatRoomSourceContact contact,
+ final ChatRoomWrapper chatRoomWrapper)
+ {
+ return contact.getProvider() == chatRoomWrapper.getParentProvider()
+ .getProtocolProvider()
+ && contact.getContactAddress().equals(
+ chatRoomWrapper.getChatRoomID());
+ }
+
+ /**
+ * Returns the index of the contact in the contact results list.
+ * @param contact the contact.
+ * @return the index of the contact in the contact results list.
+ */
+ public synchronized int indexOf(ChatRoomSourceContact contact)
+ {
+ Iterator<ChatRoomSourceContact> it = contactResults.iterator();
+ int i = 0;
+ while(it.hasNext())
+ {
+ if(contact.equals(it.next()))
+ {
+ return i;
+ }
+ i++;
+ }
+ return -1;
+ }
+
+ /**
+ * Clears any listener we used.
+ */
+ private void clearListeners()
+ {
+ mucService.removeChatRoomListChangeListener(this);
+ mucService.removeChatRoomProviderWrapperListener(this);
+ if(protolProviderRegistrationListener != null)
+ MUCActivator.bundleContext.removeServiceListener(
+ protolProviderRegistrationListener);
+ protolProviderRegistrationListener = null;
+ for(ProtocolProviderService pps : MUCActivator.getChatRoomProviders())
+ {
+ removeQueryFromProviderPresenceListeners(pps);
+ }
+ }
+
+ /**
+ * Cancels this <tt>ContactQuery</tt>.
+ *
+ * @see ContactQuery#cancel()
+ */
+ public void cancel()
+ {
+ clearListeners();
+
+ super.cancel();
+ }
+
+ /**
+ * If query has status changed to cancel, let's clear listeners.
+ * @param status {@link ContactQuery#QUERY_CANCELED},
+ * {@link ContactQuery#QUERY_COMPLETED}
+ */
+ public void setStatus(int status)
+ {
+ if(status == QUERY_CANCELED)
+ clearListeners();
+
+ super.setStatus(status);
+ }
+
+ @Override
+ public void addContactQueryListener(ContactQueryListener l)
+ {
+ super.addContactQueryListener(l);
+ contactQueryListenersCount++;
+ if(contactQueryListenersCount == 1)
+ {
+ initListeners();
+ }
+ }
+
+ @Override
+ public void removeContactQueryListener(ContactQueryListener l)
+ {
+ super.removeContactQueryListener(l);
+ contactQueryListenersCount--;
+ if(contactQueryListenersCount == 0)
+ {
+ clearListeners();
+ }
+ }
+
+ /**
+ * Listens for <tt>ProtocolProviderService</tt> registrations.
+ */
+ private class ProtocolProviderRegListener
+ implements ServiceListener
+ {
+ /**
+ * Handles service change events.
+ */
+ public void serviceChanged(ServiceEvent event)
+ {
+ ServiceReference serviceRef = event.getServiceReference();
+
+ // if the event is caused by a bundle being stopped, we don't want to
+ // know
+ if (serviceRef.getBundle().getState() == Bundle.STOPPING)
+ {
+ return;
+ }
+
+ Object service = MUCActivator.bundleContext.getService(serviceRef);
+
+ // we don't care if the source service is not a protocol provider
+ if (!(service instanceof ProtocolProviderService))
+ {
+ return;
+ }
+
+ switch (event.getType())
+ {
+ case ServiceEvent.REGISTERED:
+ addQueryToProviderPresenceListeners(
+ (ProtocolProviderService) service);
+ break;
+ case ServiceEvent.UNREGISTERING:
+ removeQueryFromProviderPresenceListeners(
+ (ProtocolProviderService) service);
+ break;
+ }
+ }
+ }
}
diff --git a/src/net/java/sip/communicator/impl/muc/ChatRoomSourceContact.java b/src/net/java/sip/communicator/impl/muc/ChatRoomSourceContact.java
index a659a6e..842cc15 100644
--- a/src/net/java/sip/communicator/impl/muc/ChatRoomSourceContact.java
+++ b/src/net/java/sip/communicator/impl/muc/ChatRoomSourceContact.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,113 +15,113 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.muc;
-
-import net.java.sip.communicator.service.muc.*;
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * Source contact for the chat rooms.
- *
- * @author Hristo Terezov
- */
-public class ChatRoomSourceContact
- extends BaseChatRoomSourceContact
-{
- /**
- * The protocol provider of the chat room associated with the contact.
- */
- private boolean isAutoJoin;
-
- /**
- * Constructs a new chat room source contact.
- *
- * @param chatRoomName the name of the chat room associated with the room.
- * @param chatRoomID the id of the chat room associated with the room.
- * @param query the query associated with the contact.
- * @param pps the protocol provider of the contact.
- * @param isAutoJoin the auto join state.
- */
- public ChatRoomSourceContact(String chatRoomName,
- String chatRoomID, ChatRoomQuery query, ProtocolProviderService pps,
- boolean isAutoJoin)
- {
- super(chatRoomName, chatRoomID, query, pps);
-
- this.isAutoJoin = isAutoJoin;
-
- initContactProperties(getChatRoomStateByName());
- }
-
- /**
- * Constructs new chat room source contact.
- *
- * @param chatRoom the chat room associated with the contact.
- * @param query the query associated with the contact.
- * @param isAutoJoin the auto join state
- */
- public ChatRoomSourceContact(ChatRoom chatRoom, ChatRoomQuery query,
- boolean isAutoJoin)
- {
- super(chatRoom.getName(), chatRoom.getIdentifier(), query,
- chatRoom.getParentProvider());
- this.isAutoJoin = isAutoJoin;
-
- initContactProperties(
- chatRoom.isJoined()
- ? ChatRoomPresenceStatus.CHAT_ROOM_ONLINE
- : ChatRoomPresenceStatus.CHAT_ROOM_OFFLINE);
-
- }
-
- /**
- * Checks if the chat room associated with the contact is joined or not and
- * returns it presence status.
- *
- * @return the presence status of the chat room associated with the contact.
- */
- private PresenceStatus getChatRoomStateByName()
- {
- for(ChatRoom room :
- getProvider().getOperationSet(OperationSetMultiUserChat.class)
- .getCurrentlyJoinedChatRooms())
- {
- if(room.getName().equals(getChatRoomName()))
- {
- return ChatRoomPresenceStatus.CHAT_ROOM_ONLINE;
- }
- }
- return ChatRoomPresenceStatus.CHAT_ROOM_OFFLINE;
- }
-
- /**
- * Returns the index of this source contact in its parent group.
- *
- * @return the index of this contact in its parent
- */
- @Override
- public int getIndex()
- {
- return ((ChatRoomQuery)parentQuery).indexOf(this);
- }
-
- /**
- * Returns the auto join state of the contact.
- *
- * @return the auto join state of the contact.
- */
- public boolean isAutoJoin()
- {
- return isAutoJoin;
- }
-
- /**
- * Sets the auto join state of the contact.
- *
- * @param isAutoJoin the auto join state to be set.
- */
- public void setAutoJoin(boolean isAutoJoin)
- {
- this.isAutoJoin = isAutoJoin;
- }
-}
+package net.java.sip.communicator.impl.muc;
+
+import net.java.sip.communicator.service.muc.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * Source contact for the chat rooms.
+ *
+ * @author Hristo Terezov
+ */
+public class ChatRoomSourceContact
+ extends BaseChatRoomSourceContact
+{
+ /**
+ * The protocol provider of the chat room associated with the contact.
+ */
+ private boolean isAutoJoin;
+
+ /**
+ * Constructs a new chat room source contact.
+ *
+ * @param chatRoomName the name of the chat room associated with the room.
+ * @param chatRoomID the id of the chat room associated with the room.
+ * @param query the query associated with the contact.
+ * @param pps the protocol provider of the contact.
+ * @param isAutoJoin the auto join state.
+ */
+ public ChatRoomSourceContact(String chatRoomName,
+ String chatRoomID, ChatRoomQuery query, ProtocolProviderService pps,
+ boolean isAutoJoin)
+ {
+ super(chatRoomName, chatRoomID, query, pps);
+
+ this.isAutoJoin = isAutoJoin;
+
+ initContactProperties(getChatRoomStateByName());
+ }
+
+ /**
+ * Constructs new chat room source contact.
+ *
+ * @param chatRoom the chat room associated with the contact.
+ * @param query the query associated with the contact.
+ * @param isAutoJoin the auto join state
+ */
+ public ChatRoomSourceContact(ChatRoom chatRoom, ChatRoomQuery query,
+ boolean isAutoJoin)
+ {
+ super(chatRoom.getName(), chatRoom.getIdentifier(), query,
+ chatRoom.getParentProvider());
+ this.isAutoJoin = isAutoJoin;
+
+ initContactProperties(
+ chatRoom.isJoined()
+ ? ChatRoomPresenceStatus.CHAT_ROOM_ONLINE
+ : ChatRoomPresenceStatus.CHAT_ROOM_OFFLINE);
+
+ }
+
+ /**
+ * Checks if the chat room associated with the contact is joined or not and
+ * returns it presence status.
+ *
+ * @return the presence status of the chat room associated with the contact.
+ */
+ private PresenceStatus getChatRoomStateByName()
+ {
+ for(ChatRoom room :
+ getProvider().getOperationSet(OperationSetMultiUserChat.class)
+ .getCurrentlyJoinedChatRooms())
+ {
+ if(room.getName().equals(getChatRoomName()))
+ {
+ return ChatRoomPresenceStatus.CHAT_ROOM_ONLINE;
+ }
+ }
+ return ChatRoomPresenceStatus.CHAT_ROOM_OFFLINE;
+ }
+
+ /**
+ * Returns the index of this source contact in its parent group.
+ *
+ * @return the index of this contact in its parent
+ */
+ @Override
+ public int getIndex()
+ {
+ return ((ChatRoomQuery)parentQuery).indexOf(this);
+ }
+
+ /**
+ * Returns the auto join state of the contact.
+ *
+ * @return the auto join state of the contact.
+ */
+ public boolean isAutoJoin()
+ {
+ return isAutoJoin;
+ }
+
+ /**
+ * Sets the auto join state of the contact.
+ *
+ * @param isAutoJoin the auto join state to be set.
+ */
+ public void setAutoJoin(boolean isAutoJoin)
+ {
+ this.isAutoJoin = isAutoJoin;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/muc/MUCCustomContactActionService.java b/src/net/java/sip/communicator/impl/muc/MUCCustomContactActionService.java
index 7c45b1d..0f4622d 100644
--- a/src/net/java/sip/communicator/impl/muc/MUCCustomContactActionService.java
+++ b/src/net/java/sip/communicator/impl/muc/MUCCustomContactActionService.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,845 +15,845 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.muc;
-
-import java.util.*;
-
-import net.java.sip.communicator.plugin.desktoputil.chat.*;
-import net.java.sip.communicator.service.contactsource.*;
-import net.java.sip.communicator.service.customcontactactions.*;
-import net.java.sip.communicator.service.muc.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.resources.*;
-
-/**
- * Implements <tt>CustomContactActionsService</tt> for MUC contact source.
- *
- * @author Hristo Terezov
- */
-public class MUCCustomContactActionService
- implements CustomContactActionsService<SourceContact>
-{
- /**
- * List of custom menu items.
- */
- private final List<ContactActionMenuItem<SourceContact>> mucActionMenuItems
- = new LinkedList<ContactActionMenuItem<SourceContact>>();
-
- /**
- * List of custom actions.
- */
- private final List<ContactAction<SourceContact>> mucActions
- = new LinkedList<ContactAction<SourceContact>>();
-
- /**
- *
- */
- private static final String OWNER_CANT_REMOVE_CHATROOM_PROPERTY
- = "net.java.sip.communicator.impl.muc.OWNER_CANT_REMOVE_CHATROOM";
-
- /**
- * Array of names for the custom actions.
- */
- private String[] actionsNames = {
- "leave",
- "join",
- "autojoin",
- "autojoin_pressed",
- "destroy_chatroom"
- };
-
- /**
- * Array of labels for the custom actions.
- */
- private String[] actionsLabels = {
- "service.gui.LEAVE",
- "service.gui.JOIN",
- "service.gui.JOIN_AUTOMATICALLY",
- "service.gui.JOIN_AUTOMATICALLY",
- "service.gui.DESTROY_CHATROOM"
- };
-
- /**
- * Array of icons for the custom actions.
- */
- private String[] actionsIcons = {
- "service.gui.icons.LEAVE_ICON_BUTTON",
- "service.gui.icons.JOIN_ICON_BUTTON",
- "service.gui.icons.AUTOJOIN_ON_ICON_BUTTON",
- "service.gui.icons.AUTOJOIN_OFF_ICON_BUTTON",
- "service.gui.icons.DESTROY_ICON_BUTTON"
- };
-
- /**
- * Array of rollover icons for the custom actions.
- */
- private String[] actionsIconsRollover = {
- "service.gui.icons.LEAVE_ICON_ROLLOVER_BUTTON",
- "service.gui.icons.JOIN_ICON_ROLLOVER_BUTTON",
- "service.gui.icons.AUTOJOIN_ON_ICON_ROLLOVER_BUTTON",
- "service.gui.icons.AUTOJOIN_OFF_ICON_ROLLOVER_BUTTON",
- "service.gui.icons.DESTROY_ICON_ROLLOVER_BUTTON"
- };
-
- /**
- * Array of pressed icons for the custom actions.
- */
- private String[] actionsIconsPressed = {
- "service.gui.icons.LEAVE_ICON_PRESSED_BUTTON",
- "service.gui.icons.JOIN_ICON_PRESSED_BUTTON",
- "service.gui.icons.AUTOJOIN_ON_ICON_PRESSED_BUTTON",
- "service.gui.icons.AUTOJOIN_OFF_ICON_PRESSED_BUTTON",
- "service.gui.icons.DESTROY_ICON_PRESSED_BUTTON"
- };
-
- /**
- * Array of names for the custom menu items.
- */
- private String[] menuActionsNames = {
- "open",
- "join",
- "join_as",
- "leave",
- "remove",
- "change_nick",
- "autojoin",
- "autojoin_pressed",
- "open_automatically",
- "destroy_chatroom"
- };
-
- /**
- * Array of labels for the custom menu items.
- */
- private String[] menuActionsLabels = {
- "service.gui.OPEN",
- "service.gui.JOIN",
- "service.gui.JOIN_AS",
- "service.gui.LEAVE",
- "service.gui.REMOVE",
- "service.gui.CHANGE_NICK",
- "service.gui.JOIN_AUTOMATICALLY",
- "service.gui.DONT_JOIN_AUTOMATICALLY",
- "service.gui.OPEN_AUTOMATICALLY",
- "service.gui.DESTROY_CHATROOM"
- };
-
- /**
- * Array of icons for the custom menu items.
- */
- private String[] menuActionsIcons = {
- "service.gui.icons.CHAT_ROOM_16x16_ICON",
- "service.gui.icons.JOIN_ICON",
- "service.gui.icons.JOIN_AS_ICON",
- "service.gui.icons.LEAVE_ICON",
- "service.gui.icons.REMOVE_CHAT_ICON",
- "service.gui.icons.RENAME_16x16_ICON",
- "service.gui.icons.AUTOJOIN",
- "service.gui.icons.AUTOJOIN",
- "service.gui.icons.OPEN_AUTOMATICALLY",
- "service.gui.icons.DESTROY_CHATROOM"
- };
-
- /**
- * A runnable that leaves the chat room.
- */
- private MUCCustomActionRunnable leaveRunnable
- = new MUCCustomActionRunnable()
- {
-
- @Override
- public void run()
- {
- ChatRoomWrapper leavedRoomWrapped
- = MUCActivator.getMUCService().leaveChatRoom(
- chatRoomWrapper);
- if(leavedRoomWrapped != null)
- MUCActivator.getUIService().closeChatRoomWindow(
- leavedRoomWrapped);
- }
- };
-
- /**
- * A runnable that joins the chat room.
- */
- private MUCCustomActionRunnable joinRunnable
- = new MUCCustomActionRunnable()
- {
-
- @Override
- public void run()
- {
- String[] joinOptions;
- String subject = null;
- String nickName = null;
-
- nickName =
- ConfigurationUtils.getChatRoomProperty(
- chatRoomWrapper.getParentProvider()
- .getProtocolProvider(), chatRoomWrapper
- .getChatRoomID(), "userNickName");
- if(nickName == null)
- {
- joinOptions = ChatRoomJoinOptionsDialog.getJoinOptions(
- chatRoomWrapper.getParentProvider()
- .getProtocolProvider(),
- chatRoomWrapper.getChatRoomID(),
- MUCActivator.getGlobalDisplayDetailsService()
- .getDisplayName(chatRoomWrapper.getParentProvider()
- .getProtocolProvider()));
- nickName = joinOptions[0];
- subject = joinOptions[1];
- }
-
- if (nickName != null)
- MUCActivator.getMUCService().joinChatRoom(chatRoomWrapper,
- nickName, null, subject);
- }
- };
-
- /**
- * A runnable that sets / unsets auto join setting of the chat room.
- */
- private MUCCustomActionRunnable autoJoinRunnable
- = new MUCCustomActionRunnable()
- {
-
- @Override
- public void run()
- {
- chatRoomWrapper.setAutoJoin(!chatRoomWrapper.isAutojoin());
-
- }
- };
-
- /**
- * A runnable that destroys the chat room.
- */
- private MUCCustomActionRunnable destroyActionRunnable
- = new MUCCustomActionRunnable()
- {
-
- @Override
- public void run()
- {
- String destroyOptions[]
- = ChatRoomDestroyReasonDialog.getDestroyOptions();
- if(destroyOptions == null)
- return;
-
- MUCActivator.getMUCService().destroyChatRoom(chatRoomWrapper,
- destroyOptions[0], destroyOptions[1]);
-
- }
- };
-
- /**
- * Array of <tt>MUCCustomActionRunnable</tt> objects for the custom menu
- * items. They will be executed when the item is pressed.
- */
- private MUCCustomActionRunnable[] actionsRunnable = {
- leaveRunnable,
- joinRunnable,
- autoJoinRunnable,
- autoJoinRunnable,
- destroyActionRunnable
- };
-
- /**
- * Array of <tt>MUCCustomActionRunnable</tt> objects for the custom menu
- * items. They will be executed when the item is pressed.
- */
- private MUCCustomActionRunnable[] menuActionsRunnable = {
- new MUCCustomActionRunnable()
- {
- @Override
- public void run()
- {
- MUCActivator.getMUCService().openChatRoom(chatRoomWrapper);
- }
- },
- joinRunnable,
- new MUCCustomActionRunnable()
- {
-
- @Override
- public void run()
- {
- String[] joinOptions;
- joinOptions = ChatRoomJoinOptionsDialog.getJoinOptions(
- chatRoomWrapper.getParentProvider().getProtocolProvider(),
- chatRoomWrapper.getChatRoomID(),
- MUCActivator.getGlobalDisplayDetailsService()
- .getDisplayName(chatRoomWrapper.getParentProvider()
- .getProtocolProvider()));
- if(joinOptions[0] == null)
- return;
- MUCActivator.getMUCService()
- .joinChatRoom(chatRoomWrapper, joinOptions[0], null,
- joinOptions[1]);
- }
- },
- leaveRunnable,
- new MUCCustomActionRunnable()
- {
-
- @Override
- public void run()
- {
- ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
-
- if (chatRoom != null)
- {
- ChatRoomWrapper leavedRoomWrapped
- = MUCActivator.getMUCService().leaveChatRoom(
- chatRoomWrapper);
- if(leavedRoomWrapped != null)
- MUCActivator.getUIService().closeChatRoomWindow(
- leavedRoomWrapped);
- }
-
- MUCActivator.getUIService().closeChatRoomWindow(chatRoomWrapper);
-
- MUCActivator.getMUCService().removeChatRoom(chatRoomWrapper);
- }
- },
- new MUCCustomActionRunnable()
- {
-
- @Override
- public void run()
- {
- ChatRoomJoinOptionsDialog.getJoinOptions(true,
- chatRoomWrapper.getParentProvider().getProtocolProvider(),
- chatRoomWrapper.getChatRoomID(),
- MUCActivator.getGlobalDisplayDetailsService()
- .getDisplayName(chatRoomWrapper.getParentProvider()
- .getProtocolProvider()));
- }
- },
- autoJoinRunnable,
- autoJoinRunnable,
- new MUCCustomActionRunnable()
- {
-
- @Override
- public void run()
- {
- MUCActivator.getUIService().showChatRoomAutoOpenConfigDialog(
- chatRoomWrapper.getParentProvider().getProtocolProvider(),
- chatRoomWrapper.getChatRoomID());
- }
- },
- destroyActionRunnable
- };
-
- /**
- * Array of <tt>EnableChecker</tt> objects for the custom menu items. They
- * are used to check if the item is enabled or disabled.
- */
- private EnableChecker[] actionsEnabledCheckers = {
- null,
- new JoinEnableChecker(),
- new JoinEnableChecker(),
- new LeaveEnableChecker(),
- null,
- null,
- null,
- null,
- null,
- null
- };
-
- /**
- * The resource management service instance.
- */
- ResourceManagementService resources = MUCActivator.getResources();
-
- /**
- * Constructs the custom actions.
- */
- public MUCCustomContactActionService()
- {
- for(int i = 0; i < menuActionsLabels.length; i++)
- {
- MUCActionMenuItems item
- = new MUCActionMenuItems(
- menuActionsNames[i],
- menuActionsLabels[i],
- menuActionsIcons[i],
- menuActionsRunnable[i]);
- mucActionMenuItems.add(item);
- if(actionsEnabledCheckers[i] != null)
- item.setEnabled(actionsEnabledCheckers[i]);
- }
-
- for(int i = 0; i < actionsLabels.length; i++)
- {
- MUCAction item = new MUCAction(
- actionsNames[i],
- actionsLabels[i],
- actionsIcons[i],
- actionsIconsRollover[i],
- actionsIconsPressed[i],
- actionsRunnable[i]);
- mucActions.add(item);
- }
-
- }
-
- /**
- * Returns the template class that this service has been initialized with
- *
- * @return the template class
- */
- public Class<SourceContact> getContactSourceClass()
- {
- return SourceContact.class;
- }
-
- @Override
- public Iterator<ContactActionMenuItem<SourceContact>>
- getCustomContactActionsMenuItems()
- {
- return mucActionMenuItems.iterator();
- }
-
-
- @Override
- public Iterator<ContactAction<SourceContact>> getCustomContactActions()
- {
- return mucActions.iterator();
- }
-
- /**
- * Implements the MUC custom action.
- */
- private class MUCAction
- implements ContactAction<SourceContact>
- {
- /**
- * The text of the action.
- */
- private String text;
-
- /**
- * The icon of the action
- */
- private byte[] icon;
-
- /**
- * The icon that is shown when the action is pressed.
- */
- private byte[] iconPressed;
-
- /**
- * The runnable that is executed when the action is pressed.
- */
- private MUCCustomActionRunnable actionPerformed;
-
- /**
- * The icon that is shown when the mouse is over the action.
- */
- private byte[] iconRollover;
-
- /**
- * The name of the action.
- */
- private String name;
-
- /**
- * Constructs <tt>MUCAction</tt> instance.
- *
- * @param textKey the key used to retrieve the label for the action.
- * @param iconKey the key used to retrieve the icon for the action.
- * @param actionPerformed the action executed when the action is
- * pressed.
- * @param iconRolloverKey the key used to retrieve the rollover icon for
- * the action.
- * @param iconPressedKey the key used to retrieve the pressed icon for
- * the action.
- */
- public MUCAction(String name, String textKey, String iconKey,
- String iconRolloverKey, String iconPressedKey,
- MUCCustomActionRunnable actionPerformed)
- {
- this.name = name;
- this.text = resources.getI18NString(textKey);
- this.icon = resources.getImageInBytes(iconKey);
- this.iconRollover = resources.getImageInBytes(iconRolloverKey);
- this.iconPressed = resources.getImageInBytes(iconPressedKey);
- this.actionPerformed = actionPerformed;
- }
-
- @Override
- public void actionPerformed(SourceContact actionSource, int x, int y)
- throws OperationFailedException
- {
- if(!(actionSource instanceof ChatRoomSourceContact))
- return;
- actionPerformed.setContact(actionSource);
- new Thread(actionPerformed).start();
- }
-
- @Override
- public byte[] getIcon()
- {
- return icon;
- }
-
- @Override
- public byte[] getRolloverIcon()
- {
- return iconRollover;
- }
-
- @Override
- public byte[] getPressedIcon()
- {
- return iconPressed;
- }
-
- @Override
- public String getToolTipText()
- {
- return text;
- }
-
- @Override
- public boolean isVisible(SourceContact actionSource)
- {
- if(actionSource instanceof ChatRoomSourceContact)
- {
- if(name.equals("leave"))
- {
- return actionsEnabledCheckers[3].check(actionSource);
- }
- else if(name.equals("join"))
- {
- return actionsEnabledCheckers[1].check(actionSource);
- }
- else if(name.equals("destroy_chatroom"))
- {
- ChatRoomSourceContact contact
- = (ChatRoomSourceContact) actionSource;
- ChatRoomWrapper room = MUCActivator.getMUCService()
- .findChatRoomWrapperFromSourceContact(contact);
- if(room == null || room.getChatRoom() == null)
- return false;
- if(room.getChatRoom().getUserRole().equals(ChatRoomMemberRole.OWNER))
- return true;
- return false;
- }
- else
- {
- ChatRoomSourceContact contact
- = (ChatRoomSourceContact) actionSource;
- ChatRoomWrapper room = MUCActivator.getMUCService()
- .findChatRoomWrapperFromSourceContact(contact);
- if(room == null)
- return false;
-
- if(name.equals("autojoin"))
- return room.isAutojoin();
- else if(name.equals("autojoin_pressed"))
- return !room.isAutojoin();
- }
- }
- return false;
- }
-
- }
-
- /**
- * Implements the MUC custom menu items.
- */
- private class MUCActionMenuItems
- implements ContactActionMenuItem<SourceContact>
- {
- /**
- * The label for the menu item.
- */
- private String text;
-
- /**
- * The the icon for the menu item.
- */
- private byte[] image;
-
- /**
- * The action executed when the menu item is pressed.
- */
- private MUCCustomActionRunnable actionPerformed;
-
- /**
- * Object that is used to check if the item is enabled or disabled.
- */
- private EnableChecker enabled;
-
- /**
- * The name of the custom action menu item.
- */
- private String name;
-
- /**
- * The mnemonic for the action.
- */
- private char mnemonics;
-
- /**
- * Constructs <tt>MUCActionMenuItems</tt> instance.
- *
- * @param textKey the key used to retrieve the label for the menu item.
- * @param imageKey the key used to retrieve the icon for the menu item.
- * @param actionPerformed the action executed when the menu item is
- * pressed.
- */
- public MUCActionMenuItems(String name, String textKey, String imageKey,
- MUCCustomActionRunnable actionPerformed)
- {
- this.text = resources.getI18NString(textKey);
- this.image = (imageKey == null)? null :
- resources.getImageInBytes(imageKey);
- this.actionPerformed = actionPerformed;
- this.enabled = new EnableChecker();
- this.name = name;
- this.mnemonics = resources.getI18nMnemonic(textKey);
- }
-
- @Override
- public void actionPerformed(SourceContact actionSource)
- throws OperationFailedException
- {
- if(!(actionSource instanceof ChatRoomSourceContact))
- return;
- actionPerformed.setContact(actionSource);
- new Thread(actionPerformed).start();
- }
-
- @Override
- public byte[] getIcon()
- {
- return image;
- }
-
-
- @Override
- public String getText(SourceContact actionSource)
- {
- if(!(actionSource instanceof ChatRoomSourceContact))
- return "";
-
- if(!name.equals("open_automatically"))
- return text;
-
- String openAutomaticallyValue
- = MUCService.getChatRoomAutoOpenOption(
- ((ChatRoomSourceContact)actionSource).getProvider(),
- ((ChatRoomSourceContact)actionSource).getChatRoomID());
- if(openAutomaticallyValue == null)
- openAutomaticallyValue = MUCService.DEFAULT_AUTO_OPEN_BEHAVIOUR;
- String openAutomaticallyKey = MUCService.autoOpenConfigValuesTexts
- .get(openAutomaticallyValue);
- return "<html>" + text + "...<br><font size=\"2\"><center> ("
- + resources.getI18NString(openAutomaticallyKey)
- + ")</center></font></html>";
- }
-
- @Override
- public boolean isVisible(SourceContact actionSource)
- {
- if(!(actionSource instanceof ChatRoomSourceContact))
- return false;
-
- ChatRoomSourceContact contact
- = (ChatRoomSourceContact) actionSource;
- ChatRoomWrapper room = MUCActivator.getMUCService()
- .findChatRoomWrapperFromSourceContact(contact);
- if(name.equals("autojoin") || name.equals("autojoin_pressed"))
- {
- if(room == null)
- return true;
-
- if(name.equals("autojoin"))
- return !room.isAutojoin();
-
- if(name.equals("autojoin_pressed"))
- return room.isAutojoin();
- }
- else if(name.equals("remove"))
- {
- if(room == null || room.getChatRoom() == null)
- return true;
-
- boolean ownerCannotRemoveRoom
- = MUCActivator.getConfigurationService().getBoolean(
- OWNER_CANT_REMOVE_CHATROOM_PROPERTY, false);
-
- // when joined role will be owner or member
- // when not joined and if we never has entered the room role
- // will be guest, if we joined and left the room the role
- // will be owner or member
- if(room.getChatRoom().getUserRole().equals(
- ChatRoomMemberRole.MEMBER))
- {
- return true;
- }
- else
- {
- if(ownerCannotRemoveRoom)
- return false;
- else
- return true;
- }
- }
- else if(name.equals("destroy_chatroom"))
- {
- if(room == null || room.getChatRoom() == null)
- return false;
- if(room.getChatRoom().getUserRole().equals(
- ChatRoomMemberRole.OWNER))
- return true;
- return false;
- }
- return true;
- }
-
- @Override
- public char getMnemonics()
- {
- return mnemonics;
- }
-
- @Override
- public boolean isEnabled(SourceContact actionSource)
- {
- return enabled.check(actionSource);
- }
-
- /**
- * Sets <tt>EnabledChecker</tt> instance that will be used to check if
- * the item should be enabled or disabled.
- *
- * @param enabled the <tt>EnabledChecker</tt> instance.
- */
- public void setEnabled(EnableChecker enabled)
- {
- this.enabled = enabled;
- }
-
- @Override
- public boolean isCheckBox()
- {
- return false;
- }
-
- @Override
- public boolean isSelected(SourceContact contact)
- {
- ChatRoomWrapper chatRoomWrapper = MUCActivator.getMUCService()
- .findChatRoomWrapperFromSourceContact(contact);
- if(chatRoomWrapper == null)
- return false;
- return chatRoomWrapper.isAutojoin();
- }
-
- }
-
- /**
- * Checks if the menu item should be enabled or disabled. This is default
- * implementation. Always returns that the item should be enabled.
- */
- private static class EnableChecker
- {
- /**
- * Checks if the menu item should be enabled or disabled.
- *
- * @param contact the contact associated with the menu item.
- * @return always <tt>true</tt>
- */
- public boolean check(SourceContact contact)
- {
- return true;
- }
- }
-
- /**
- * Implements <tt>EnableChecker</tt> for the join menu items.
- */
- private static class JoinEnableChecker
- extends EnableChecker
- {
- /**
- * Checks if the menu item should be enabled or disabled.
- *
- * @param contact the contact associated with the menu item.
- * @return <tt>true</tt> if the item should be enabled and
- * <tt>false</tt> if not.
- */
- public boolean check(SourceContact contact)
- {
- ChatRoomWrapper chatRoomWrapper = MUCActivator.getMUCService()
- .findChatRoomWrapperFromSourceContact(contact);
- ChatRoom chatRoom = null;
- if(chatRoomWrapper != null)
- {
- chatRoom = chatRoomWrapper.getChatRoom();
- }
-
- if((chatRoom != null) && chatRoom.isJoined())
- return false;
- return true;
- }
- }
-
- /**
- * Implements <tt>EnableChecker</tt> for the leave menu item.
- */
- private static class LeaveEnableChecker
- extends JoinEnableChecker
- {
- /**
- * Checks if the menu item should be enabled or disabled.
- *
- * @param contact the contact associated with the menu item.
- * @return <tt>true</tt> if the item should be enabled and
- * <tt>false</tt> if not.
- */
- public boolean check(SourceContact contact)
- {
- return !super.check(contact);
- }
- }
-
- /**
- * Implements base properties for the MUC menu items.These properties are
- * used when the menu item is pressed.
- */
- private abstract class MUCCustomActionRunnable
- implements Runnable
- {
- /**
- * The contact associated with the menu item.
- */
- protected SourceContact contact;
-
- /**
- * The contact associated with the menu item.
- */
- protected ChatRoomWrapper chatRoomWrapper;
-
- /**
- * Sets the source contact.
- * @param contact the contact to set
- */
- public void setContact(SourceContact contact)
- {
- this.contact = contact;
- chatRoomWrapper = MUCActivator.getMUCService()
- .findChatRoomWrapperFromSourceContact(contact);
- }
- }
-}
+package net.java.sip.communicator.impl.muc;
+
+import java.util.*;
+
+import net.java.sip.communicator.plugin.desktoputil.chat.*;
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.customcontactactions.*;
+import net.java.sip.communicator.service.muc.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.resources.*;
+
+/**
+ * Implements <tt>CustomContactActionsService</tt> for MUC contact source.
+ *
+ * @author Hristo Terezov
+ */
+public class MUCCustomContactActionService
+ implements CustomContactActionsService<SourceContact>
+{
+ /**
+ * List of custom menu items.
+ */
+ private final List<ContactActionMenuItem<SourceContact>> mucActionMenuItems
+ = new LinkedList<ContactActionMenuItem<SourceContact>>();
+
+ /**
+ * List of custom actions.
+ */
+ private final List<ContactAction<SourceContact>> mucActions
+ = new LinkedList<ContactAction<SourceContact>>();
+
+ /**
+ *
+ */
+ private static final String OWNER_CANT_REMOVE_CHATROOM_PROPERTY
+ = "net.java.sip.communicator.impl.muc.OWNER_CANT_REMOVE_CHATROOM";
+
+ /**
+ * Array of names for the custom actions.
+ */
+ private String[] actionsNames = {
+ "leave",
+ "join",
+ "autojoin",
+ "autojoin_pressed",
+ "destroy_chatroom"
+ };
+
+ /**
+ * Array of labels for the custom actions.
+ */
+ private String[] actionsLabels = {
+ "service.gui.LEAVE",
+ "service.gui.JOIN",
+ "service.gui.JOIN_AUTOMATICALLY",
+ "service.gui.JOIN_AUTOMATICALLY",
+ "service.gui.DESTROY_CHATROOM"
+ };
+
+ /**
+ * Array of icons for the custom actions.
+ */
+ private String[] actionsIcons = {
+ "service.gui.icons.LEAVE_ICON_BUTTON",
+ "service.gui.icons.JOIN_ICON_BUTTON",
+ "service.gui.icons.AUTOJOIN_ON_ICON_BUTTON",
+ "service.gui.icons.AUTOJOIN_OFF_ICON_BUTTON",
+ "service.gui.icons.DESTROY_ICON_BUTTON"
+ };
+
+ /**
+ * Array of rollover icons for the custom actions.
+ */
+ private String[] actionsIconsRollover = {
+ "service.gui.icons.LEAVE_ICON_ROLLOVER_BUTTON",
+ "service.gui.icons.JOIN_ICON_ROLLOVER_BUTTON",
+ "service.gui.icons.AUTOJOIN_ON_ICON_ROLLOVER_BUTTON",
+ "service.gui.icons.AUTOJOIN_OFF_ICON_ROLLOVER_BUTTON",
+ "service.gui.icons.DESTROY_ICON_ROLLOVER_BUTTON"
+ };
+
+ /**
+ * Array of pressed icons for the custom actions.
+ */
+ private String[] actionsIconsPressed = {
+ "service.gui.icons.LEAVE_ICON_PRESSED_BUTTON",
+ "service.gui.icons.JOIN_ICON_PRESSED_BUTTON",
+ "service.gui.icons.AUTOJOIN_ON_ICON_PRESSED_BUTTON",
+ "service.gui.icons.AUTOJOIN_OFF_ICON_PRESSED_BUTTON",
+ "service.gui.icons.DESTROY_ICON_PRESSED_BUTTON"
+ };
+
+ /**
+ * Array of names for the custom menu items.
+ */
+ private String[] menuActionsNames = {
+ "open",
+ "join",
+ "join_as",
+ "leave",
+ "remove",
+ "change_nick",
+ "autojoin",
+ "autojoin_pressed",
+ "open_automatically",
+ "destroy_chatroom"
+ };
+
+ /**
+ * Array of labels for the custom menu items.
+ */
+ private String[] menuActionsLabels = {
+ "service.gui.OPEN",
+ "service.gui.JOIN",
+ "service.gui.JOIN_AS",
+ "service.gui.LEAVE",
+ "service.gui.REMOVE",
+ "service.gui.CHANGE_NICK",
+ "service.gui.JOIN_AUTOMATICALLY",
+ "service.gui.DONT_JOIN_AUTOMATICALLY",
+ "service.gui.OPEN_AUTOMATICALLY",
+ "service.gui.DESTROY_CHATROOM"
+ };
+
+ /**
+ * Array of icons for the custom menu items.
+ */
+ private String[] menuActionsIcons = {
+ "service.gui.icons.CHAT_ROOM_16x16_ICON",
+ "service.gui.icons.JOIN_ICON",
+ "service.gui.icons.JOIN_AS_ICON",
+ "service.gui.icons.LEAVE_ICON",
+ "service.gui.icons.REMOVE_CHAT_ICON",
+ "service.gui.icons.RENAME_16x16_ICON",
+ "service.gui.icons.AUTOJOIN",
+ "service.gui.icons.AUTOJOIN",
+ "service.gui.icons.OPEN_AUTOMATICALLY",
+ "service.gui.icons.DESTROY_CHATROOM"
+ };
+
+ /**
+ * A runnable that leaves the chat room.
+ */
+ private MUCCustomActionRunnable leaveRunnable
+ = new MUCCustomActionRunnable()
+ {
+
+ @Override
+ public void run()
+ {
+ ChatRoomWrapper leavedRoomWrapped
+ = MUCActivator.getMUCService().leaveChatRoom(
+ chatRoomWrapper);
+ if(leavedRoomWrapped != null)
+ MUCActivator.getUIService().closeChatRoomWindow(
+ leavedRoomWrapped);
+ }
+ };
+
+ /**
+ * A runnable that joins the chat room.
+ */
+ private MUCCustomActionRunnable joinRunnable
+ = new MUCCustomActionRunnable()
+ {
+
+ @Override
+ public void run()
+ {
+ String[] joinOptions;
+ String subject = null;
+ String nickName = null;
+
+ nickName =
+ ConfigurationUtils.getChatRoomProperty(
+ chatRoomWrapper.getParentProvider()
+ .getProtocolProvider(), chatRoomWrapper
+ .getChatRoomID(), "userNickName");
+ if(nickName == null)
+ {
+ joinOptions = ChatRoomJoinOptionsDialog.getJoinOptions(
+ chatRoomWrapper.getParentProvider()
+ .getProtocolProvider(),
+ chatRoomWrapper.getChatRoomID(),
+ MUCActivator.getGlobalDisplayDetailsService()
+ .getDisplayName(chatRoomWrapper.getParentProvider()
+ .getProtocolProvider()));
+ nickName = joinOptions[0];
+ subject = joinOptions[1];
+ }
+
+ if (nickName != null)
+ MUCActivator.getMUCService().joinChatRoom(chatRoomWrapper,
+ nickName, null, subject);
+ }
+ };
+
+ /**
+ * A runnable that sets / unsets auto join setting of the chat room.
+ */
+ private MUCCustomActionRunnable autoJoinRunnable
+ = new MUCCustomActionRunnable()
+ {
+
+ @Override
+ public void run()
+ {
+ chatRoomWrapper.setAutoJoin(!chatRoomWrapper.isAutojoin());
+
+ }
+ };
+
+ /**
+ * A runnable that destroys the chat room.
+ */
+ private MUCCustomActionRunnable destroyActionRunnable
+ = new MUCCustomActionRunnable()
+ {
+
+ @Override
+ public void run()
+ {
+ String destroyOptions[]
+ = ChatRoomDestroyReasonDialog.getDestroyOptions();
+ if(destroyOptions == null)
+ return;
+
+ MUCActivator.getMUCService().destroyChatRoom(chatRoomWrapper,
+ destroyOptions[0], destroyOptions[1]);
+
+ }
+ };
+
+ /**
+ * Array of <tt>MUCCustomActionRunnable</tt> objects for the custom menu
+ * items. They will be executed when the item is pressed.
+ */
+ private MUCCustomActionRunnable[] actionsRunnable = {
+ leaveRunnable,
+ joinRunnable,
+ autoJoinRunnable,
+ autoJoinRunnable,
+ destroyActionRunnable
+ };
+
+ /**
+ * Array of <tt>MUCCustomActionRunnable</tt> objects for the custom menu
+ * items. They will be executed when the item is pressed.
+ */
+ private MUCCustomActionRunnable[] menuActionsRunnable = {
+ new MUCCustomActionRunnable()
+ {
+ @Override
+ public void run()
+ {
+ MUCActivator.getMUCService().openChatRoom(chatRoomWrapper);
+ }
+ },
+ joinRunnable,
+ new MUCCustomActionRunnable()
+ {
+
+ @Override
+ public void run()
+ {
+ String[] joinOptions;
+ joinOptions = ChatRoomJoinOptionsDialog.getJoinOptions(
+ chatRoomWrapper.getParentProvider().getProtocolProvider(),
+ chatRoomWrapper.getChatRoomID(),
+ MUCActivator.getGlobalDisplayDetailsService()
+ .getDisplayName(chatRoomWrapper.getParentProvider()
+ .getProtocolProvider()));
+ if(joinOptions[0] == null)
+ return;
+ MUCActivator.getMUCService()
+ .joinChatRoom(chatRoomWrapper, joinOptions[0], null,
+ joinOptions[1]);
+ }
+ },
+ leaveRunnable,
+ new MUCCustomActionRunnable()
+ {
+
+ @Override
+ public void run()
+ {
+ ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
+
+ if (chatRoom != null)
+ {
+ ChatRoomWrapper leavedRoomWrapped
+ = MUCActivator.getMUCService().leaveChatRoom(
+ chatRoomWrapper);
+ if(leavedRoomWrapped != null)
+ MUCActivator.getUIService().closeChatRoomWindow(
+ leavedRoomWrapped);
+ }
+
+ MUCActivator.getUIService().closeChatRoomWindow(chatRoomWrapper);
+
+ MUCActivator.getMUCService().removeChatRoom(chatRoomWrapper);
+ }
+ },
+ new MUCCustomActionRunnable()
+ {
+
+ @Override
+ public void run()
+ {
+ ChatRoomJoinOptionsDialog.getJoinOptions(true,
+ chatRoomWrapper.getParentProvider().getProtocolProvider(),
+ chatRoomWrapper.getChatRoomID(),
+ MUCActivator.getGlobalDisplayDetailsService()
+ .getDisplayName(chatRoomWrapper.getParentProvider()
+ .getProtocolProvider()));
+ }
+ },
+ autoJoinRunnable,
+ autoJoinRunnable,
+ new MUCCustomActionRunnable()
+ {
+
+ @Override
+ public void run()
+ {
+ MUCActivator.getUIService().showChatRoomAutoOpenConfigDialog(
+ chatRoomWrapper.getParentProvider().getProtocolProvider(),
+ chatRoomWrapper.getChatRoomID());
+ }
+ },
+ destroyActionRunnable
+ };
+
+ /**
+ * Array of <tt>EnableChecker</tt> objects for the custom menu items. They
+ * are used to check if the item is enabled or disabled.
+ */
+ private EnableChecker[] actionsEnabledCheckers = {
+ null,
+ new JoinEnableChecker(),
+ new JoinEnableChecker(),
+ new LeaveEnableChecker(),
+ null,
+ null,
+ null,
+ null,
+ null,
+ null
+ };
+
+ /**
+ * The resource management service instance.
+ */
+ ResourceManagementService resources = MUCActivator.getResources();
+
+ /**
+ * Constructs the custom actions.
+ */
+ public MUCCustomContactActionService()
+ {
+ for(int i = 0; i < menuActionsLabels.length; i++)
+ {
+ MUCActionMenuItems item
+ = new MUCActionMenuItems(
+ menuActionsNames[i],
+ menuActionsLabels[i],
+ menuActionsIcons[i],
+ menuActionsRunnable[i]);
+ mucActionMenuItems.add(item);
+ if(actionsEnabledCheckers[i] != null)
+ item.setEnabled(actionsEnabledCheckers[i]);
+ }
+
+ for(int i = 0; i < actionsLabels.length; i++)
+ {
+ MUCAction item = new MUCAction(
+ actionsNames[i],
+ actionsLabels[i],
+ actionsIcons[i],
+ actionsIconsRollover[i],
+ actionsIconsPressed[i],
+ actionsRunnable[i]);
+ mucActions.add(item);
+ }
+
+ }
+
+ /**
+ * Returns the template class that this service has been initialized with
+ *
+ * @return the template class
+ */
+ public Class<SourceContact> getContactSourceClass()
+ {
+ return SourceContact.class;
+ }
+
+ @Override
+ public Iterator<ContactActionMenuItem<SourceContact>>
+ getCustomContactActionsMenuItems()
+ {
+ return mucActionMenuItems.iterator();
+ }
+
+
+ @Override
+ public Iterator<ContactAction<SourceContact>> getCustomContactActions()
+ {
+ return mucActions.iterator();
+ }
+
+ /**
+ * Implements the MUC custom action.
+ */
+ private class MUCAction
+ implements ContactAction<SourceContact>
+ {
+ /**
+ * The text of the action.
+ */
+ private String text;
+
+ /**
+ * The icon of the action
+ */
+ private byte[] icon;
+
+ /**
+ * The icon that is shown when the action is pressed.
+ */
+ private byte[] iconPressed;
+
+ /**
+ * The runnable that is executed when the action is pressed.
+ */
+ private MUCCustomActionRunnable actionPerformed;
+
+ /**
+ * The icon that is shown when the mouse is over the action.
+ */
+ private byte[] iconRollover;
+
+ /**
+ * The name of the action.
+ */
+ private String name;
+
+ /**
+ * Constructs <tt>MUCAction</tt> instance.
+ *
+ * @param textKey the key used to retrieve the label for the action.
+ * @param iconKey the key used to retrieve the icon for the action.
+ * @param actionPerformed the action executed when the action is
+ * pressed.
+ * @param iconRolloverKey the key used to retrieve the rollover icon for
+ * the action.
+ * @param iconPressedKey the key used to retrieve the pressed icon for
+ * the action.
+ */
+ public MUCAction(String name, String textKey, String iconKey,
+ String iconRolloverKey, String iconPressedKey,
+ MUCCustomActionRunnable actionPerformed)
+ {
+ this.name = name;
+ this.text = resources.getI18NString(textKey);
+ this.icon = resources.getImageInBytes(iconKey);
+ this.iconRollover = resources.getImageInBytes(iconRolloverKey);
+ this.iconPressed = resources.getImageInBytes(iconPressedKey);
+ this.actionPerformed = actionPerformed;
+ }
+
+ @Override
+ public void actionPerformed(SourceContact actionSource, int x, int y)
+ throws OperationFailedException
+ {
+ if(!(actionSource instanceof ChatRoomSourceContact))
+ return;
+ actionPerformed.setContact(actionSource);
+ new Thread(actionPerformed).start();
+ }
+
+ @Override
+ public byte[] getIcon()
+ {
+ return icon;
+ }
+
+ @Override
+ public byte[] getRolloverIcon()
+ {
+ return iconRollover;
+ }
+
+ @Override
+ public byte[] getPressedIcon()
+ {
+ return iconPressed;
+ }
+
+ @Override
+ public String getToolTipText()
+ {
+ return text;
+ }
+
+ @Override
+ public boolean isVisible(SourceContact actionSource)
+ {
+ if(actionSource instanceof ChatRoomSourceContact)
+ {
+ if(name.equals("leave"))
+ {
+ return actionsEnabledCheckers[3].check(actionSource);
+ }
+ else if(name.equals("join"))
+ {
+ return actionsEnabledCheckers[1].check(actionSource);
+ }
+ else if(name.equals("destroy_chatroom"))
+ {
+ ChatRoomSourceContact contact
+ = (ChatRoomSourceContact) actionSource;
+ ChatRoomWrapper room = MUCActivator.getMUCService()
+ .findChatRoomWrapperFromSourceContact(contact);
+ if(room == null || room.getChatRoom() == null)
+ return false;
+ if(room.getChatRoom().getUserRole().equals(ChatRoomMemberRole.OWNER))
+ return true;
+ return false;
+ }
+ else
+ {
+ ChatRoomSourceContact contact
+ = (ChatRoomSourceContact) actionSource;
+ ChatRoomWrapper room = MUCActivator.getMUCService()
+ .findChatRoomWrapperFromSourceContact(contact);
+ if(room == null)
+ return false;
+
+ if(name.equals("autojoin"))
+ return room.isAutojoin();
+ else if(name.equals("autojoin_pressed"))
+ return !room.isAutojoin();
+ }
+ }
+ return false;
+ }
+
+ }
+
+ /**
+ * Implements the MUC custom menu items.
+ */
+ private class MUCActionMenuItems
+ implements ContactActionMenuItem<SourceContact>
+ {
+ /**
+ * The label for the menu item.
+ */
+ private String text;
+
+ /**
+ * The the icon for the menu item.
+ */
+ private byte[] image;
+
+ /**
+ * The action executed when the menu item is pressed.
+ */
+ private MUCCustomActionRunnable actionPerformed;
+
+ /**
+ * Object that is used to check if the item is enabled or disabled.
+ */
+ private EnableChecker enabled;
+
+ /**
+ * The name of the custom action menu item.
+ */
+ private String name;
+
+ /**
+ * The mnemonic for the action.
+ */
+ private char mnemonics;
+
+ /**
+ * Constructs <tt>MUCActionMenuItems</tt> instance.
+ *
+ * @param textKey the key used to retrieve the label for the menu item.
+ * @param imageKey the key used to retrieve the icon for the menu item.
+ * @param actionPerformed the action executed when the menu item is
+ * pressed.
+ */
+ public MUCActionMenuItems(String name, String textKey, String imageKey,
+ MUCCustomActionRunnable actionPerformed)
+ {
+ this.text = resources.getI18NString(textKey);
+ this.image = (imageKey == null)? null :
+ resources.getImageInBytes(imageKey);
+ this.actionPerformed = actionPerformed;
+ this.enabled = new EnableChecker();
+ this.name = name;
+ this.mnemonics = resources.getI18nMnemonic(textKey);
+ }
+
+ @Override
+ public void actionPerformed(SourceContact actionSource)
+ throws OperationFailedException
+ {
+ if(!(actionSource instanceof ChatRoomSourceContact))
+ return;
+ actionPerformed.setContact(actionSource);
+ new Thread(actionPerformed).start();
+ }
+
+ @Override
+ public byte[] getIcon()
+ {
+ return image;
+ }
+
+
+ @Override
+ public String getText(SourceContact actionSource)
+ {
+ if(!(actionSource instanceof ChatRoomSourceContact))
+ return "";
+
+ if(!name.equals("open_automatically"))
+ return text;
+
+ String openAutomaticallyValue
+ = MUCService.getChatRoomAutoOpenOption(
+ ((ChatRoomSourceContact)actionSource).getProvider(),
+ ((ChatRoomSourceContact)actionSource).getChatRoomID());
+ if(openAutomaticallyValue == null)
+ openAutomaticallyValue = MUCService.DEFAULT_AUTO_OPEN_BEHAVIOUR;
+ String openAutomaticallyKey = MUCService.autoOpenConfigValuesTexts
+ .get(openAutomaticallyValue);
+ return "<html>" + text + "...<br><font size=\"2\"><center> ("
+ + resources.getI18NString(openAutomaticallyKey)
+ + ")</center></font></html>";
+ }
+
+ @Override
+ public boolean isVisible(SourceContact actionSource)
+ {
+ if(!(actionSource instanceof ChatRoomSourceContact))
+ return false;
+
+ ChatRoomSourceContact contact
+ = (ChatRoomSourceContact) actionSource;
+ ChatRoomWrapper room = MUCActivator.getMUCService()
+ .findChatRoomWrapperFromSourceContact(contact);
+ if(name.equals("autojoin") || name.equals("autojoin_pressed"))
+ {
+ if(room == null)
+ return true;
+
+ if(name.equals("autojoin"))
+ return !room.isAutojoin();
+
+ if(name.equals("autojoin_pressed"))
+ return room.isAutojoin();
+ }
+ else if(name.equals("remove"))
+ {
+ if(room == null || room.getChatRoom() == null)
+ return true;
+
+ boolean ownerCannotRemoveRoom
+ = MUCActivator.getConfigurationService().getBoolean(
+ OWNER_CANT_REMOVE_CHATROOM_PROPERTY, false);
+
+ // when joined role will be owner or member
+ // when not joined and if we never has entered the room role
+ // will be guest, if we joined and left the room the role
+ // will be owner or member
+ if(room.getChatRoom().getUserRole().equals(
+ ChatRoomMemberRole.MEMBER))
+ {
+ return true;
+ }
+ else
+ {
+ if(ownerCannotRemoveRoom)
+ return false;
+ else
+ return true;
+ }
+ }
+ else if(name.equals("destroy_chatroom"))
+ {
+ if(room == null || room.getChatRoom() == null)
+ return false;
+ if(room.getChatRoom().getUserRole().equals(
+ ChatRoomMemberRole.OWNER))
+ return true;
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public char getMnemonics()
+ {
+ return mnemonics;
+ }
+
+ @Override
+ public boolean isEnabled(SourceContact actionSource)
+ {
+ return enabled.check(actionSource);
+ }
+
+ /**
+ * Sets <tt>EnabledChecker</tt> instance that will be used to check if
+ * the item should be enabled or disabled.
+ *
+ * @param enabled the <tt>EnabledChecker</tt> instance.
+ */
+ public void setEnabled(EnableChecker enabled)
+ {
+ this.enabled = enabled;
+ }
+
+ @Override
+ public boolean isCheckBox()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isSelected(SourceContact contact)
+ {
+ ChatRoomWrapper chatRoomWrapper = MUCActivator.getMUCService()
+ .findChatRoomWrapperFromSourceContact(contact);
+ if(chatRoomWrapper == null)
+ return false;
+ return chatRoomWrapper.isAutojoin();
+ }
+
+ }
+
+ /**
+ * Checks if the menu item should be enabled or disabled. This is default
+ * implementation. Always returns that the item should be enabled.
+ */
+ private static class EnableChecker
+ {
+ /**
+ * Checks if the menu item should be enabled or disabled.
+ *
+ * @param contact the contact associated with the menu item.
+ * @return always <tt>true</tt>
+ */
+ public boolean check(SourceContact contact)
+ {
+ return true;
+ }
+ }
+
+ /**
+ * Implements <tt>EnableChecker</tt> for the join menu items.
+ */
+ private static class JoinEnableChecker
+ extends EnableChecker
+ {
+ /**
+ * Checks if the menu item should be enabled or disabled.
+ *
+ * @param contact the contact associated with the menu item.
+ * @return <tt>true</tt> if the item should be enabled and
+ * <tt>false</tt> if not.
+ */
+ public boolean check(SourceContact contact)
+ {
+ ChatRoomWrapper chatRoomWrapper = MUCActivator.getMUCService()
+ .findChatRoomWrapperFromSourceContact(contact);
+ ChatRoom chatRoom = null;
+ if(chatRoomWrapper != null)
+ {
+ chatRoom = chatRoomWrapper.getChatRoom();
+ }
+
+ if((chatRoom != null) && chatRoom.isJoined())
+ return false;
+ return true;
+ }
+ }
+
+ /**
+ * Implements <tt>EnableChecker</tt> for the leave menu item.
+ */
+ private static class LeaveEnableChecker
+ extends JoinEnableChecker
+ {
+ /**
+ * Checks if the menu item should be enabled or disabled.
+ *
+ * @param contact the contact associated with the menu item.
+ * @return <tt>true</tt> if the item should be enabled and
+ * <tt>false</tt> if not.
+ */
+ public boolean check(SourceContact contact)
+ {
+ return !super.check(contact);
+ }
+ }
+
+ /**
+ * Implements base properties for the MUC menu items.These properties are
+ * used when the menu item is pressed.
+ */
+ private abstract class MUCCustomActionRunnable
+ implements Runnable
+ {
+ /**
+ * The contact associated with the menu item.
+ */
+ protected SourceContact contact;
+
+ /**
+ * The contact associated with the menu item.
+ */
+ protected ChatRoomWrapper chatRoomWrapper;
+
+ /**
+ * Sets the source contact.
+ * @param contact the contact to set
+ */
+ public void setContact(SourceContact contact)
+ {
+ this.contact = contact;
+ chatRoomWrapper = MUCActivator.getMUCService()
+ .findChatRoomWrapperFromSourceContact(contact);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/muc/MUCServiceImpl.java b/src/net/java/sip/communicator/impl/muc/MUCServiceImpl.java
index f6dd1c7..be02255 100644
--- a/src/net/java/sip/communicator/impl/muc/MUCServiceImpl.java
+++ b/src/net/java/sip/communicator/impl/muc/MUCServiceImpl.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,1117 +15,1117 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.muc;
-
-import static net.java.sip.communicator.service.muc.ChatRoomWrapper.*;
-
-import java.util.*;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.plugin.desktoputil.chat.*;
-import net.java.sip.communicator.service.contactsource.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.muc.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.globalstatus.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.resources.*;
-
-/**
- * The <tt>MUCServiceImpl</tt> class implements the service for the chat rooms.
- *
- * @author Hristo Terezov
- */
-public class MUCServiceImpl
- extends MUCService
-{
-
- /**
- * The list of persistent chat rooms.
- */
- private final ChatRoomListImpl chatRoomList = new ChatRoomListImpl();
-
- /**
- * The <tt>Logger</tt> used by the <tt>MUCServiceImpl</tt> class and its
- * instances for logging output.
- */
- private static Logger logger = Logger.getLogger(MUCServiceImpl.class);
-
- /**
- * Called to accept an incoming invitation. Adds the invitation chat room
- * to the list of chat rooms and joins it.
- *
- * @param invitation the invitation to accept.
- */
- public void acceptInvitation(ChatRoomInvitation invitation)
- {
- ChatRoom chatRoom = invitation.getTargetChatRoom();
- byte[] password = invitation.getChatRoomPassword();
-
- String nickName =
- ConfigurationUtils.getChatRoomProperty(
- chatRoom.getParentProvider(),
- chatRoom.getIdentifier(), "userNickName");
- if(nickName == null)
- {
- String[] joinOptions = ChatRoomJoinOptionsDialog.getJoinOptions(
- true,
- chatRoom.getParentProvider(),
- chatRoom.getIdentifier(),
- MUCActivator.getGlobalDisplayDetailsService()
- .getDisplayName(chatRoom.getParentProvider()));
- nickName = joinOptions[0];
- }
-
- joinChatRoom(chatRoom, nickName, password);
- }
-
- /**
- * Adds a change listener to the <tt>ChatRoomList</tt>.
- *
- * @param l the listener.
- */
- public void addChatRoomListChangeListener(ChatRoomListChangeListener l)
- {
- chatRoomList.addChatRoomListChangeListener(l);
- }
-
- /**
- * Removes a change listener to the <tt>ChatRoomList</tt>.
- *
- * @param l the listener.
- */
- public void removeChatRoomListChangeListener(ChatRoomListChangeListener l)
- {
- chatRoomList.removeChatRoomListChangeListener(l);
- }
-
- /**
- * Fires a <tt>ChatRoomListChangedEvent</tt> event.
- *
- * @param chatRoomWrapper the chat room.
- * @param eventID the id of the event.
- */
- public void fireChatRoomListChangedEvent( ChatRoomWrapper chatRoomWrapper,
- int eventID)
- {
- chatRoomList.fireChatRoomListChangedEvent(chatRoomWrapper, eventID);
- }
-
- /**
- * Joins the given chat room with the given password and manages all the
- * exceptions that could occur during the join process.
- *
- * @param chatRoomWrapper the chat room to join.
- * @param nickName the nickname we choose for the given chat room.
- * @param password the password.
- * @param rememberPassword if true the password should be saved.
- * @param isFirstAttempt is this the first attempt to join room, used
- * to check whether to show some error messages
- * @param subject the subject which will be set to the room after the user
- * join successful.
- */
- private void joinChatRoom( ChatRoomWrapper chatRoomWrapper,
- String nickName,
- byte[] password,
- boolean rememberPassword,
- boolean isFirstAttempt,
- String subject)
- {
- ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
-
- if(chatRoom == null)
- {
- MUCActivator.getAlertUIService().showAlertDialog(
- MUCActivator.getResources().getI18NString("service.gui.WARNING"),
- MUCActivator.getResources().getI18NString(
- "service.gui.CHAT_ROOM_NOT_CONNECTED",
- new String[]{chatRoomWrapper.getChatRoomName()}));
- return;
- }
-
- new JoinChatRoomTask(
- (ChatRoomWrapperImpl)chatRoomWrapper,
- nickName,
- password,
- rememberPassword,
- isFirstAttempt,
- subject)
- .start();
- }
-
- /**
- * Joins the given chat room with the given password and manages all the
- * exceptions that could occur during the join process.
- *
- * @param chatRoomWrapper the chat room to join.
- * @param nickName the nickname we choose for the given chat room.
- * @param password the password.
- */
- public void joinChatRoom( ChatRoomWrapper chatRoomWrapper,
- String nickName,
- byte[] password)
- {
- if (chatRoomWrapper.getChatRoom() == null)
- {
- chatRoomWrapper = createChatRoom(
- chatRoomWrapper.getChatRoomName(),
- chatRoomWrapper.getParentProvider().getProtocolProvider(),
- new ArrayList<String>(), "", false, false, true);
- }
-
- ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
-
- if(chatRoom == null)
- {
- MUCActivator.getAlertUIService().showAlertDialog(
- MUCActivator.getResources().getI18NString("service.gui.WARNING"),
- MUCActivator.getResources().getI18NString(
- "service.gui.CHAT_ROOM_NOT_CONNECTED",
- new String[]{chatRoomWrapper.getChatRoomName()}));
- return;
- }
-
- new JoinChatRoomTask(
- (ChatRoomWrapperImpl)chatRoomWrapper, nickName, password)
- .start();
- }
-
- /**
- * Joins the given chat room with the given password and manages all the
- * exceptions that could occur during the join process.
- *
- * @param chatRoomWrapper the chat room to join.
- * @param nickName the nickname we choose for the given chat room.
- * @param password the password.
- * @param subject the subject which will be set to the room after the user
- * join successful.
- */
- public void joinChatRoom( ChatRoomWrapper chatRoomWrapper,
- String nickName,
- byte[] password,
- String subject)
- {
- if (chatRoomWrapper.getChatRoom() == null)
- {
- chatRoomWrapper = createChatRoom(
- chatRoomWrapper.getChatRoomName(),
- chatRoomWrapper.getParentProvider().getProtocolProvider(),
- new ArrayList<String>(), "", false, false, true);
- }
-
- ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
- if (chatRoom == null)
- {
- MUCActivator.getAlertUIService().showAlertDialog(
- MUCActivator.getResources().getI18NString("service.gui.WARNING"),
- MUCActivator.getResources().getI18NString(
- "service.gui.CHAT_ROOM_NOT_CONNECTED",
- new String[]{chatRoomWrapper.getChatRoomName()}));
-
- return;
- }
-
- // join from add chat room dialog
-
- new JoinChatRoomTask(
- (ChatRoomWrapperImpl) chatRoomWrapper,
- nickName,
- password,
- subject)
- .start();
- }
-
-
- /**
- * Join chat room.
- * @param chatRoomWrapper
- */
- public void joinChatRoom(ChatRoomWrapper chatRoomWrapper)
- {
- if (chatRoomWrapper.getChatRoom() == null)
- {
- chatRoomWrapper = createChatRoom(
- chatRoomWrapper.getChatRoomName(),
- chatRoomWrapper.getParentProvider().getProtocolProvider(),
- new ArrayList<String>(), "", false, false, true);
- }
-
- ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
-
- if(chatRoom == null)
- {
- MUCActivator.getAlertUIService().showAlertDialog(
- MUCActivator.getResources().getI18NString("service.gui.WARNING"),
- MUCActivator.getResources().getI18NString(
- "service.gui.CHAT_ROOM_NOT_CONNECTED",
- new String[]{chatRoomWrapper.getChatRoomName()}));
-
- return;
- }
-
- new JoinChatRoomTask((ChatRoomWrapperImpl)chatRoomWrapper, null, null)
- .start();
- }
-
-
- /**
- * Joins the given chat room and manages all the exceptions that could
- * occur during the join process.
- *
- * @param chatRoom the chat room to join
- * @param nickname the nickname we're using to join
- * @param password the password we're using to join
- */
- public void joinChatRoom( ChatRoom chatRoom,
- String nickname,
- byte[] password)
- {
- ChatRoomWrapper chatRoomWrapper
- = chatRoomList.findChatRoomWrapperFromChatRoom(chatRoom);
-
- if(chatRoomWrapper == null)
- {
- ChatRoomProviderWrapper parentProvider
- = chatRoomList.findServerWrapperFromProvider(
- chatRoom.getParentProvider());
-
- chatRoomWrapper
- = new ChatRoomWrapperImpl(parentProvider, chatRoom);
-
- chatRoomList.addChatRoom(chatRoomWrapper);
-
- }
-
- this.joinChatRoom(chatRoomWrapper, nickname, password);
- }
-
- /**
- * Joins the room with the given name though the given chat room provider.
- *
- * @param chatRoomName the name of the room to join.
- * @param chatRoomProvider the chat room provider to join through.
- */
- public void joinChatRoom( String chatRoomName,
- ChatRoomProviderWrapper chatRoomProvider)
- {
- OperationSetMultiUserChat groupChatOpSet
- = chatRoomProvider
- .getProtocolProvider().getOperationSet(
- OperationSetMultiUserChat.class);
-
- ChatRoom chatRoom = null;
- try
- {
- chatRoom = groupChatOpSet.findRoom(chatRoomName);
- }
- catch (Exception e)
- {
- if (logger.isTraceEnabled())
- logger.trace("Un exception occurred while searching for room:"
- + chatRoomName, e);
- }
-
- if (chatRoom != null)
- {
- ChatRoomWrapper chatRoomWrapper
- = chatRoomList.findChatRoomWrapperFromChatRoom(chatRoom);
-
- if(chatRoomWrapper == null)
- {
- ChatRoomProviderWrapper parentProvider
- = chatRoomList
- .findServerWrapperFromProvider(
- chatRoom.getParentProvider());
-
- chatRoomWrapper
- = new ChatRoomWrapperImpl(parentProvider, chatRoom);
-
- chatRoomList.addChatRoom(chatRoomWrapper);
-
- fireChatRoomListChangedEvent(
- chatRoomWrapper,
- ChatRoomListChangeEvent.CHAT_ROOM_ADDED);
- }
- joinChatRoom(chatRoomWrapper);
- }
- else
- MUCActivator.getAlertUIService().showAlertDialog(
- MUCActivator.getResources().getI18NString("service.gui.ERROR"),
- MUCActivator.getResources().getI18NString(
- "service.gui.CHAT_ROOM_NOT_EXIST",
- new String[]{chatRoomName,
- chatRoomProvider.getProtocolProvider()
- .getAccountID().getService()}));
- }
-
-
- /**
- * Creates a chat room, by specifying the chat room name, the parent
- * protocol provider and eventually, the contacts invited to participate in
- * this chat room.
- *
- * @param roomName the name of the room
- * @param protocolProvider the parent protocol provider.
- * @param contacts the contacts invited when creating the chat room.
- * @param reason
- * @param persistent is the room persistent
- * @param isPrivate whether the room will be private or public.
- * @return the <tt>ChatRoomWrapper</tt> corresponding to the created room
- */
- public ChatRoomWrapper createChatRoom(
- String roomName,
- ProtocolProviderService protocolProvider,
- Collection<String> contacts,
- String reason,
- boolean persistent,
- boolean isPrivate)
- {
- return createChatRoom(
- roomName, protocolProvider, contacts, reason, true, persistent,
- isPrivate);
- }
-
- /**
- * Creates a chat room, by specifying the chat room name, the parent
- * protocol provider and eventually, the contacts invited to participate in
- * this chat room.
- *
- * @param roomName the name of the room
- * @param protocolProvider the parent protocol provider.
- * @param contacts the contacts invited when creating the chat room.
- * @param reason
- * @param persistent is the room persistent
- * @return the <tt>ChatRoomWrapper</tt> corresponding to the created room
- */
- public ChatRoomWrapper createChatRoom(
- String roomName,
- ProtocolProviderService protocolProvider,
- Collection<String> contacts,
- String reason,
- boolean persistent)
- {
- return createChatRoom(
- roomName, protocolProvider, contacts, reason, true, persistent,
- false);
- }
-
- /**
- * Creates a chat room, by specifying the chat room name, the parent
- * protocol provider and eventually, the contacts invited to participate in
- * this chat room.
- *
- * @param roomName the name of the room
- * @param protocolProvider the parent protocol provider.
- * @param contacts the contacts invited when creating the chat room.
- * @param reason
- * @param join whether we should join the room after creating it.
- * @param persistent whether the newly created room will be persistent.
- * @param isPrivate whether the room will be private or public.
- * @return the <tt>ChatRoomWrapper</tt> corresponding to the created room or
- * <tt>null</tt> if the protocol fails to create the chat room.
- */
- public ChatRoomWrapper createChatRoom(
- String roomName,
- ProtocolProviderService protocolProvider,
- Collection<String> contacts,
- String reason,
- boolean join,
- boolean persistent,
- boolean isPrivate)
- {
- ChatRoomWrapper chatRoomWrapper = null;
- OperationSetMultiUserChat groupChatOpSet
- = protocolProvider.getOperationSet(OperationSetMultiUserChat.class);
-
- // If there's no group chat operation set we have nothing to do here.
- if (groupChatOpSet == null)
- return null;
-
- ChatRoom chatRoom = null;
- try
- {
-
-
- HashMap<String, Object> roomProperties =
- new HashMap<String, Object>();
- roomProperties.put("isPrivate", isPrivate);
- chatRoom = groupChatOpSet.createChatRoom(roomName, roomProperties);
-
- if(join)
- {
- chatRoom.join();
-
- for(String contact : contacts)
- chatRoom.invite(contact, reason);
- }
- }
- catch (OperationFailedException ex)
- {
- logger.error("Failed to create chat room.", ex);
-
- MUCActivator.getAlertUIService().showAlertDialog(
- MUCActivator.getResources().getI18NString("service.gui.ERROR"),
- MUCActivator.getResources().getI18NString(
- "service.gui.CREATE_CHAT_ROOM_ERROR",
- new String[]{protocolProvider.getProtocolDisplayName()}),
- ex);
- }
- catch (OperationNotSupportedException ex)
- {
- logger.error("Failed to create chat room.", ex);
-
- MUCActivator.getAlertUIService().showAlertDialog(
- MUCActivator.getResources().getI18NString("service.gui.ERROR"),
- MUCActivator.getResources().getI18NString(
- "service.gui.CREATE_CHAT_ROOM_ERROR",
- new String[]{protocolProvider.getProtocolDisplayName()}),
- ex);
- }
-
- if(chatRoom != null)
- {
- ChatRoomProviderWrapper parentProvider
- = chatRoomList.findServerWrapperFromProvider(protocolProvider);
-
- // if there is the same room ids don't add new wrapper as old one
- // maybe already created
- chatRoomWrapper =
- chatRoomList.findChatRoomWrapperFromChatRoom(chatRoom);
-
- if(chatRoomWrapper == null)
- {
- chatRoomWrapper
- = new ChatRoomWrapperImpl(parentProvider, chatRoom);
- chatRoomWrapper.setPersistent(persistent);
- chatRoomList.addChatRoom(chatRoomWrapper);
- }
- }
-
- return chatRoomWrapper;
- }
-
- /**
- * Creates a private chat room, by specifying the parent
- * protocol provider and eventually, the contacts invited to participate in
- * this chat room.
- *
- * @param protocolProvider the parent protocol provider.
- * @param contacts the contacts invited when creating the chat room.
- * @param reason
- * @param persistent is the room persistent
- * @return the <tt>ChatRoomWrapper</tt> corresponding to the created room
- */
- public ChatRoomWrapper createPrivateChatRoom(
- ProtocolProviderService protocolProvider,
- Collection<String> contacts,
- String reason,
- boolean persistent)
- {
- return this.createChatRoom(
- null, protocolProvider, contacts, reason, persistent, true);
- }
-
-
- /**
- * Returns existing chat rooms for the given <tt>chatRoomProvider</tt>.
- * @param chatRoomProvider the <tt>ChatRoomProviderWrapper</tt>, which
- * chat rooms we're looking for
- * @return existing chat rooms for the given <tt>chatRoomProvider</tt>
- */
- public List<String> getExistingChatRooms(
- ChatRoomProviderWrapper chatRoomProvider)
- {
- if (chatRoomProvider == null)
- return null;
-
- ProtocolProviderService protocolProvider
- = chatRoomProvider.getProtocolProvider();
-
- if (protocolProvider == null)
- return null;
-
- OperationSetMultiUserChat groupChatOpSet
- = protocolProvider
- .getOperationSet(OperationSetMultiUserChat.class);
-
- if (groupChatOpSet == null)
- return null;
-
- List<String> chatRooms = null;
- try
- {
- chatRooms = groupChatOpSet.getExistingChatRooms();
- }
- catch (OperationFailedException e)
- {
- if (logger.isTraceEnabled())
- logger.trace("Failed to obtain existing chat rooms for server: "
- + protocolProvider.getAccountID().getService(), e);
- }
- catch (OperationNotSupportedException e)
- {
- if (logger.isTraceEnabled())
- logger.trace("Failed to obtain existing chat rooms for server: "
- + protocolProvider.getAccountID().getService(), e);
- }
-
- return chatRooms;
- }
-
- /**
- * Rejects the given invitation with the specified reason.
- *
- * @param multiUserChatOpSet the operation set to use for rejecting the
- * invitation
- * @param invitation the invitation to reject
- * @param reason the reason for the rejection
- */
- public void rejectInvitation( OperationSetMultiUserChat multiUserChatOpSet,
- ChatRoomInvitation invitation,
- String reason)
- {
- multiUserChatOpSet.rejectInvitation(invitation, reason);
- }
-
- /**
- * Leaves the given chat room.
- *
- * @param chatRoomWrapper the chat room to leave.
- * @return <tt>ChatRoomWrapper</tt> instance associated with the chat room.
- */
- public ChatRoomWrapper leaveChatRoom(ChatRoomWrapper chatRoomWrapper)
- {
- ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
-
- if (chatRoom == null)
- {
- ResourceManagementService resources = MUCActivator.getResources();
-
- MUCActivator.getAlertUIService().showAlertDialog(
- resources.getI18NString("service.gui.WARNING"),
- resources
- .getI18NString(
- "service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED"));
-
- return null;
- }
-
- if (chatRoom.isJoined())
- chatRoom.leave();
-
- ChatRoomWrapper existChatRoomWrapper
- = chatRoomList.findChatRoomWrapperFromChatRoom(chatRoom);
-
- if(existChatRoomWrapper == null)
- return null;
-
- // We save the choice of the user, before the chat room is really
- // joined, because even the join fails we want the next time when
- // we login to join this chat room automatically.
- ConfigurationUtils.updateChatRoomStatus(
- chatRoomWrapper.getParentProvider().getProtocolProvider(),
- chatRoomWrapper.getChatRoomID(),
- GlobalStatusEnum.OFFLINE_STATUS);
-
- return existChatRoomWrapper;
- }
-
- /**
- * Joins a chat room in an asynchronous way.
- */
- private class JoinChatRoomTask
- extends Thread
- {
- private final ChatRoomWrapperImpl chatRoomWrapper;
-
- private final String nickName;
-
- private final byte[] password;
-
- private final boolean rememberPassword;
-
- private final boolean isFirstAttempt;
-
- private final String subject;
-
- private ResourceManagementService resources
- = MUCActivator.getResources();
-
- JoinChatRoomTask( ChatRoomWrapperImpl chatRoomWrapper,
- String nickName,
- byte[] password,
- boolean rememberPassword,
- boolean isFirstAttempt,
- String subject)
- {
- this.chatRoomWrapper = chatRoomWrapper;
- this.nickName = nickName;
- this.isFirstAttempt = isFirstAttempt;
- this.subject = subject;
-
- if(password == null)
- {
- String passString = chatRoomWrapper.loadPassword();
- if(passString != null)
- {
- this.password = passString.getBytes();
- }
- else
- {
- this.password = null;
- }
- }
- else
- {
- this.password = password;
- }
- this.rememberPassword = rememberPassword;
- }
-
- JoinChatRoomTask( ChatRoomWrapperImpl chatRoomWrapper,
- String nickName,
- byte[] password)
- {
- this(chatRoomWrapper, nickName, password, false, true, null);
- }
-
- JoinChatRoomTask( ChatRoomWrapperImpl chatRoomWrapper,
- String nickName,
- byte[] password,
- String subject)
- {
- this(chatRoomWrapper, nickName, password, false, true, subject);
- }
-
- /**
- * @override {@link Thread}{@link #run()} to perform all asynchronous
- * tasks.
- */
- @Override
- public void run()
- {
- ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
-
- try
- {
- if(password != null && password.length > 0)
- chatRoom.joinAs(nickName, password);
- else if (nickName != null)
- chatRoom.joinAs(nickName);
- else
- chatRoom.join();
-
- done(JOIN_SUCCESS_PROP);
- }
- catch (OperationFailedException e)
- {
- if (logger.isTraceEnabled())
- logger.trace("Failed to join chat room: "
- + chatRoom.getName(), e);
-
- switch (e.getErrorCode())
- {
- case OperationFailedException.AUTHENTICATION_FAILED:
- done(JOIN_AUTHENTICATION_FAILED_PROP);
- break;
- case OperationFailedException.REGISTRATION_REQUIRED:
- done(JOIN_REGISTRATION_REQUIRED_PROP);
- break;
- case OperationFailedException.PROVIDER_NOT_REGISTERED:
- done(JOIN_PROVIDER_NOT_REGISTERED_PROP);
- break;
- case OperationFailedException.SUBSCRIPTION_ALREADY_EXISTS:
- done(JOIN_SUBSCRIPTION_ALREADY_EXISTS_PROP);
- break;
- default:
- done(JOIN_UNKNOWN_ERROR_PROP);
- }
- }
- }
-
- /**
- * Performs UI changes after the chat room join task has finished.
- * @param returnCode the result code from the chat room join task.
- */
- private void done(String returnCode)
- {
- ConfigurationUtils.updateChatRoomStatus(
- chatRoomWrapper.getParentProvider().getProtocolProvider(),
- chatRoomWrapper.getChatRoomID(),
- GlobalStatusEnum.ONLINE_STATUS);
-
- String errorMessage = null;
- if(JOIN_AUTHENTICATION_FAILED_PROP.equals(returnCode))
- {
- chatRoomWrapper.removePassword();
-
- AuthenticationWindowService authWindowsService
- = ServiceUtils.getService(
- MUCActivator.bundleContext,
- AuthenticationWindowService.class);
-
- AuthenticationWindowService.AuthenticationWindow authWindow =
- authWindowsService.create(
- null, null, null, false,
- chatRoomWrapper.isPersistent(),
- AuthenticationWindow.getAuthenticationWindowIcon(
- chatRoomWrapper.getParentProvider()
- .getProtocolProvider()),
- resources.getI18NString(
- "service.gui.AUTHENTICATION_WINDOW_TITLE",
- new String[]{chatRoomWrapper.getParentProvider()
- .getName()}),
- resources.getI18NString(
- "service.gui.CHAT_ROOM_REQUIRES_PASSWORD",
- new String[]{
- chatRoomWrapper.getChatRoomName()}),
- "", null,
- isFirstAttempt ?
- null :
- resources.getI18NString(
- "service.gui.AUTHENTICATION_FAILED",
- new String[]{chatRoomWrapper.getChatRoomName()}),
- null);
-
- authWindow.setVisible(true);
-
- if (!authWindow.isCanceled())
- {
- joinChatRoom(
- chatRoomWrapper,
- nickName,
- new String(authWindow.getPassword()).getBytes(),
- authWindow.isRememberPassword(),
- false,
- subject);
- }
- }
- else if(JOIN_REGISTRATION_REQUIRED_PROP.equals(returnCode))
- {
- errorMessage
- = resources
- .getI18NString(
- "service.gui.CHAT_ROOM_REGISTRATION_REQUIRED",
- new String[]{chatRoomWrapper.getChatRoomName()});
- }
- else if(JOIN_PROVIDER_NOT_REGISTERED_PROP.equals(returnCode))
- {
- errorMessage
- = resources
- .getI18NString("service.gui.CHAT_ROOM_NOT_CONNECTED",
- new String[]{chatRoomWrapper.getChatRoomName()});
- }
- else if(JOIN_SUBSCRIPTION_ALREADY_EXISTS_PROP.equals(returnCode))
- {
- errorMessage
- = resources
- .getI18NString("service.gui.CHAT_ROOM_ALREADY_JOINED",
- new String[]{chatRoomWrapper.getChatRoomName()});
- }
- else
- {
- errorMessage
- = resources
- .getI18NString("service.gui.FAILED_TO_JOIN_CHAT_ROOM",
- new String[]{chatRoomWrapper.getChatRoomName()});
- }
-
- if (!JOIN_SUCCESS_PROP.equals(returnCode) &&
- !JOIN_AUTHENTICATION_FAILED_PROP.equals(returnCode))
- {
- MUCActivator.getAlertUIService().showAlertPopup(
- resources.getI18NString("service.gui.ERROR"), errorMessage);
- }
-
- if (JOIN_SUCCESS_PROP.equals(returnCode))
- {
- if(rememberPassword)
- {
- chatRoomWrapper.savePassword(new String(password));
- }
-
- if(subject != null)
- {
- try
- {
- chatRoomWrapper.getChatRoom().setSubject(subject);
- }
- catch(OperationFailedException ex)
- {
- logger.warn("Failed to set subject.");
- }
- }
- }
-
- chatRoomWrapper.firePropertyChange(returnCode);
- }
- }
-
- /**
- * Finds the <tt>ChatRoomWrapper</tt> instance associated with the
- * source contact.
- * @param contact the source contact.
- * @return the <tt>ChatRoomWrapper</tt> instance.
- */
- public ChatRoomWrapper findChatRoomWrapperFromSourceContact(
- SourceContact contact)
- {
- if(!(contact instanceof ChatRoomSourceContact))
- return null;
- ChatRoomSourceContact chatRoomContact = (ChatRoomSourceContact) contact;
- return chatRoomList.findChatRoomWrapperFromChatRoomID(
- chatRoomContact.getChatRoomID(), chatRoomContact.getProvider());
- }
-
- /**
- * Finds the <tt>ChatRoomWrapper</tt> instance associated with the
- * chat room.
- * @param chatRoomID the id of the chat room.
- * @param pps the provider of the chat room.
- * @return the <tt>ChatRoomWrapper</tt> instance.
- */
- public ChatRoomWrapper findChatRoomWrapperFromChatRoomID(String chatRoomID,
- ProtocolProviderService pps)
- {
- return chatRoomList.findChatRoomWrapperFromChatRoomID(chatRoomID, pps);
- }
-
- /**
- * Searches for chat room wrapper in chat room list by chat room.
- *
- * @param chatRoom the chat room.
- * @param create if <tt>true</tt> and the chat room wrapper is not found new
- * chatRoomWrapper is created.
- * @return found chat room wrapper or the created chat room wrapper.
- */
- @Override
- public ChatRoomWrapper getChatRoomWrapperByChatRoom(ChatRoom chatRoom,
- boolean create)
- {
- ChatRoomWrapper chatRoomWrapper
- = chatRoomList.findChatRoomWrapperFromChatRoom(chatRoom);
-
- if ((chatRoomWrapper == null) && create)
- {
- ChatRoomProviderWrapper parentProvider
- = chatRoomList.findServerWrapperFromProvider(
- chatRoom.getParentProvider());
-
- chatRoomWrapper
- = new ChatRoomWrapperImpl(
- parentProvider, chatRoom);
-
- chatRoomList.addChatRoom(chatRoomWrapper);
- }
- return chatRoomWrapper;
- }
-
- /**
- * Goes through the locally stored chat rooms list and for each
- * {@link ChatRoomWrapper} tries to find the corresponding server stored
- * {@link ChatRoom} in the specified operation set. Joins automatically all
- * found chat rooms.
- *
- * @param protocolProvider the protocol provider for the account to
- * synchronize
- * @param opSet the multi user chat operation set, which give us access to
- * chat room server
- */
- public void synchronizeOpSetWithLocalContactList(
- ProtocolProviderService protocolProvider,
- final OperationSetMultiUserChat opSet)
- {
- ChatRoomProviderWrapper chatRoomProvider
- = findServerWrapperFromProvider(protocolProvider);
-
- if(chatRoomProvider == null)
- {
- chatRoomProvider = chatRoomList.addRegisteredChatProvider(protocolProvider);
- }
-
- if (chatRoomProvider != null)
- {
- chatRoomProvider.synchronizeProvider();
- }
- }
-
- /**
- * Returns an iterator to the list of chat room providers.
- *
- * @return an iterator to the list of chat room providers.
- */
- public Iterator<ChatRoomProviderWrapper> getChatRoomProviders()
- {
- return chatRoomList.getChatRoomProviders();
- }
-
- /**
- * Removes the given <tt>ChatRoom</tt> from the list of all chat rooms.
- *
- * @param chatRoomWrapper the <tt>ChatRoomWrapper</tt> to remove
- */
- public void removeChatRoom(ChatRoomWrapper chatRoomWrapper)
- {
- chatRoomList.removeChatRoom(chatRoomWrapper);
- }
-
- /**
- * Destroys the given <tt>ChatRoom</tt> from the list of all chat rooms.
- *
- * @param chatRoomWrapper the <tt>ChatRoomWrapper</tt> to be destroyed.
- * @param reason the reason for destroying.
- * @param alternateAddress the alternate address.
- */
- public void destroyChatRoom(ChatRoomWrapper chatRoomWrapper,
- String reason, String alternateAddress)
- {
- if(chatRoomWrapper.getChatRoom().destroy(reason, alternateAddress))
- {
- MUCActivator.getUIService().closeChatRoomWindow(
- chatRoomWrapper);
- chatRoomList.removeChatRoom(chatRoomWrapper);
- }
- else
- {
- // if we leave a chat room which is not persistent
- // the room can be destroyed on the server, and error is returned
- // when we try to destroy it not-authorized(401)
- if(!chatRoomWrapper.getChatRoom().isPersistent()
- && !chatRoomWrapper.getChatRoom().isJoined())
- {
- chatRoomList.removeChatRoom(chatRoomWrapper);
- }
- }
-
- }
-
- /**
- * Adds a ChatRoomProviderWrapperListener to the listener list.
- *
- * @param listener the ChatRoomProviderWrapperListener to be added
- */
- public void addChatRoomProviderWrapperListener(
- ChatRoomProviderWrapperListener listener)
- {
- chatRoomList.addChatRoomProviderWrapperListener(listener);
- }
-
- /**
- * Removes the ChatRoomProviderWrapperListener to the listener list.
- *
- * @param listener the ChatRoomProviderWrapperListener to be removed
- */
- public void removeChatRoomProviderWrapperListener(
- ChatRoomProviderWrapperListener listener)
- {
- chatRoomList.removeChatRoomProviderWrapperListener(listener);
- }
-
- /**
- * Returns the <tt>ChatRoomProviderWrapper</tt> that correspond to the
- * given <tt>ProtocolProviderService</tt>. If the list doesn't contain a
- * corresponding wrapper - returns null.
- *
- * @param protocolProvider the protocol provider that we're looking for
- * @return the <tt>ChatRoomProvider</tt> object corresponding to
- * the given <tt>ProtocolProviderService</tt>
- */
- public ChatRoomProviderWrapper findServerWrapperFromProvider(
- ProtocolProviderService protocolProvider)
- {
- return chatRoomList.findServerWrapperFromProvider(protocolProvider);
- }
-
- /**
- * Returns the <tt>ChatRoomWrapper</tt> that correspond to the given
- * <tt>ChatRoom</tt>. If the list of chat rooms doesn't contain a
- * corresponding wrapper - returns null.
- *
- * @param chatRoom the <tt>ChatRoom</tt> that we're looking for
- * @return the <tt>ChatRoomWrapper</tt> object corresponding to the given
- * <tt>ChatRoom</tt>
- */
- public ChatRoomWrapper findChatRoomWrapperFromChatRoom(ChatRoom chatRoom)
- {
- return chatRoomList.findChatRoomWrapperFromChatRoom(chatRoom);
- }
-
- /**
- * Opens a chat window for the chat room.
- *
- * @param room the chat room.
- */
- public void openChatRoom(ChatRoomWrapper room)
- {
- if (room.getChatRoom() == null)
- {
- room = createChatRoom(
- room.getChatRoomName(),
- room.getParentProvider().getProtocolProvider(),
- new ArrayList<String>(),"", false, false, true);
-
- // leave the chatroom because getChatRoom().isJoined() returns true
- // otherwise
- if (room.getChatRoom().isJoined())
- room.getChatRoom().leave();
-
- }
-
- if(!room.getChatRoom().isJoined())
- {
- String savedNick =
- ConfigurationUtils.getChatRoomProperty(room
- .getParentProvider().getProtocolProvider(), room
- .getChatRoomID(), "userNickName");
- String subject = null;
-
- if (savedNick == null)
- {
- String[] joinOptions = ChatRoomJoinOptionsDialog.getJoinOptions(
- room.getParentProvider().getProtocolProvider(),
- room.getChatRoomID(),
- MUCActivator.getGlobalDisplayDetailsService()
- .getDisplayName(
- room.getParentProvider().getProtocolProvider()));
- savedNick = joinOptions[0];
- subject = joinOptions[1];
-
- }
-
- if (savedNick != null)
- {
- joinChatRoom(room, savedNick, null,
- subject);
- }
- else
- return;
- }
-
- MUCActivator.getUIService().openChatRoomWindow(room);
- }
-
- /**
- * Returns instance of the <tt>ServerChatRoomContactSourceService</tt>
- * contact source.
- * @return instance of the <tt>ServerChatRoomContactSourceService</tt>
- * contact source.
- */
- public ContactSourceService getServerChatRoomsContactSourceForProvider(
- ChatRoomProviderWrapper pps)
- {
- return new ServerChatRoomContactSourceService(pps);
- }
-
- /**
- * Returns <tt>true</tt> if the contact is <tt>ChatRoomSourceContact</tt>
- *
- * @param contact the contact
- * @return <tt>true</tt> if the contact is <tt>ChatRoomSourceContact</tt>
- */
- public boolean isMUCSourceContact(SourceContact contact)
- {
- return (contact instanceof ChatRoomSourceContact);
- }
-}
+package net.java.sip.communicator.impl.muc;
+
+import static net.java.sip.communicator.service.muc.ChatRoomWrapper.*;
+
+import java.util.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.plugin.desktoputil.chat.*;
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.muc.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.globalstatus.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.resources.*;
+
+/**
+ * The <tt>MUCServiceImpl</tt> class implements the service for the chat rooms.
+ *
+ * @author Hristo Terezov
+ */
+public class MUCServiceImpl
+ extends MUCService
+{
+
+ /**
+ * The list of persistent chat rooms.
+ */
+ private final ChatRoomListImpl chatRoomList = new ChatRoomListImpl();
+
+ /**
+ * The <tt>Logger</tt> used by the <tt>MUCServiceImpl</tt> class and its
+ * instances for logging output.
+ */
+ private static Logger logger = Logger.getLogger(MUCServiceImpl.class);
+
+ /**
+ * Called to accept an incoming invitation. Adds the invitation chat room
+ * to the list of chat rooms and joins it.
+ *
+ * @param invitation the invitation to accept.
+ */
+ public void acceptInvitation(ChatRoomInvitation invitation)
+ {
+ ChatRoom chatRoom = invitation.getTargetChatRoom();
+ byte[] password = invitation.getChatRoomPassword();
+
+ String nickName =
+ ConfigurationUtils.getChatRoomProperty(
+ chatRoom.getParentProvider(),
+ chatRoom.getIdentifier(), "userNickName");
+ if(nickName == null)
+ {
+ String[] joinOptions = ChatRoomJoinOptionsDialog.getJoinOptions(
+ true,
+ chatRoom.getParentProvider(),
+ chatRoom.getIdentifier(),
+ MUCActivator.getGlobalDisplayDetailsService()
+ .getDisplayName(chatRoom.getParentProvider()));
+ nickName = joinOptions[0];
+ }
+
+ joinChatRoom(chatRoom, nickName, password);
+ }
+
+ /**
+ * Adds a change listener to the <tt>ChatRoomList</tt>.
+ *
+ * @param l the listener.
+ */
+ public void addChatRoomListChangeListener(ChatRoomListChangeListener l)
+ {
+ chatRoomList.addChatRoomListChangeListener(l);
+ }
+
+ /**
+ * Removes a change listener to the <tt>ChatRoomList</tt>.
+ *
+ * @param l the listener.
+ */
+ public void removeChatRoomListChangeListener(ChatRoomListChangeListener l)
+ {
+ chatRoomList.removeChatRoomListChangeListener(l);
+ }
+
+ /**
+ * Fires a <tt>ChatRoomListChangedEvent</tt> event.
+ *
+ * @param chatRoomWrapper the chat room.
+ * @param eventID the id of the event.
+ */
+ public void fireChatRoomListChangedEvent( ChatRoomWrapper chatRoomWrapper,
+ int eventID)
+ {
+ chatRoomList.fireChatRoomListChangedEvent(chatRoomWrapper, eventID);
+ }
+
+ /**
+ * Joins the given chat room with the given password and manages all the
+ * exceptions that could occur during the join process.
+ *
+ * @param chatRoomWrapper the chat room to join.
+ * @param nickName the nickname we choose for the given chat room.
+ * @param password the password.
+ * @param rememberPassword if true the password should be saved.
+ * @param isFirstAttempt is this the first attempt to join room, used
+ * to check whether to show some error messages
+ * @param subject the subject which will be set to the room after the user
+ * join successful.
+ */
+ private void joinChatRoom( ChatRoomWrapper chatRoomWrapper,
+ String nickName,
+ byte[] password,
+ boolean rememberPassword,
+ boolean isFirstAttempt,
+ String subject)
+ {
+ ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
+
+ if(chatRoom == null)
+ {
+ MUCActivator.getAlertUIService().showAlertDialog(
+ MUCActivator.getResources().getI18NString("service.gui.WARNING"),
+ MUCActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_NOT_CONNECTED",
+ new String[]{chatRoomWrapper.getChatRoomName()}));
+ return;
+ }
+
+ new JoinChatRoomTask(
+ (ChatRoomWrapperImpl)chatRoomWrapper,
+ nickName,
+ password,
+ rememberPassword,
+ isFirstAttempt,
+ subject)
+ .start();
+ }
+
+ /**
+ * Joins the given chat room with the given password and manages all the
+ * exceptions that could occur during the join process.
+ *
+ * @param chatRoomWrapper the chat room to join.
+ * @param nickName the nickname we choose for the given chat room.
+ * @param password the password.
+ */
+ public void joinChatRoom( ChatRoomWrapper chatRoomWrapper,
+ String nickName,
+ byte[] password)
+ {
+ if (chatRoomWrapper.getChatRoom() == null)
+ {
+ chatRoomWrapper = createChatRoom(
+ chatRoomWrapper.getChatRoomName(),
+ chatRoomWrapper.getParentProvider().getProtocolProvider(),
+ new ArrayList<String>(), "", false, false, true);
+ }
+
+ ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
+
+ if(chatRoom == null)
+ {
+ MUCActivator.getAlertUIService().showAlertDialog(
+ MUCActivator.getResources().getI18NString("service.gui.WARNING"),
+ MUCActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_NOT_CONNECTED",
+ new String[]{chatRoomWrapper.getChatRoomName()}));
+ return;
+ }
+
+ new JoinChatRoomTask(
+ (ChatRoomWrapperImpl)chatRoomWrapper, nickName, password)
+ .start();
+ }
+
+ /**
+ * Joins the given chat room with the given password and manages all the
+ * exceptions that could occur during the join process.
+ *
+ * @param chatRoomWrapper the chat room to join.
+ * @param nickName the nickname we choose for the given chat room.
+ * @param password the password.
+ * @param subject the subject which will be set to the room after the user
+ * join successful.
+ */
+ public void joinChatRoom( ChatRoomWrapper chatRoomWrapper,
+ String nickName,
+ byte[] password,
+ String subject)
+ {
+ if (chatRoomWrapper.getChatRoom() == null)
+ {
+ chatRoomWrapper = createChatRoom(
+ chatRoomWrapper.getChatRoomName(),
+ chatRoomWrapper.getParentProvider().getProtocolProvider(),
+ new ArrayList<String>(), "", false, false, true);
+ }
+
+ ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
+ if (chatRoom == null)
+ {
+ MUCActivator.getAlertUIService().showAlertDialog(
+ MUCActivator.getResources().getI18NString("service.gui.WARNING"),
+ MUCActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_NOT_CONNECTED",
+ new String[]{chatRoomWrapper.getChatRoomName()}));
+
+ return;
+ }
+
+ // join from add chat room dialog
+
+ new JoinChatRoomTask(
+ (ChatRoomWrapperImpl) chatRoomWrapper,
+ nickName,
+ password,
+ subject)
+ .start();
+ }
+
+
+ /**
+ * Join chat room.
+ * @param chatRoomWrapper
+ */
+ public void joinChatRoom(ChatRoomWrapper chatRoomWrapper)
+ {
+ if (chatRoomWrapper.getChatRoom() == null)
+ {
+ chatRoomWrapper = createChatRoom(
+ chatRoomWrapper.getChatRoomName(),
+ chatRoomWrapper.getParentProvider().getProtocolProvider(),
+ new ArrayList<String>(), "", false, false, true);
+ }
+
+ ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
+
+ if(chatRoom == null)
+ {
+ MUCActivator.getAlertUIService().showAlertDialog(
+ MUCActivator.getResources().getI18NString("service.gui.WARNING"),
+ MUCActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_NOT_CONNECTED",
+ new String[]{chatRoomWrapper.getChatRoomName()}));
+
+ return;
+ }
+
+ new JoinChatRoomTask((ChatRoomWrapperImpl)chatRoomWrapper, null, null)
+ .start();
+ }
+
+
+ /**
+ * Joins the given chat room and manages all the exceptions that could
+ * occur during the join process.
+ *
+ * @param chatRoom the chat room to join
+ * @param nickname the nickname we're using to join
+ * @param password the password we're using to join
+ */
+ public void joinChatRoom( ChatRoom chatRoom,
+ String nickname,
+ byte[] password)
+ {
+ ChatRoomWrapper chatRoomWrapper
+ = chatRoomList.findChatRoomWrapperFromChatRoom(chatRoom);
+
+ if(chatRoomWrapper == null)
+ {
+ ChatRoomProviderWrapper parentProvider
+ = chatRoomList.findServerWrapperFromProvider(
+ chatRoom.getParentProvider());
+
+ chatRoomWrapper
+ = new ChatRoomWrapperImpl(parentProvider, chatRoom);
+
+ chatRoomList.addChatRoom(chatRoomWrapper);
+
+ }
+
+ this.joinChatRoom(chatRoomWrapper, nickname, password);
+ }
+
+ /**
+ * Joins the room with the given name though the given chat room provider.
+ *
+ * @param chatRoomName the name of the room to join.
+ * @param chatRoomProvider the chat room provider to join through.
+ */
+ public void joinChatRoom( String chatRoomName,
+ ChatRoomProviderWrapper chatRoomProvider)
+ {
+ OperationSetMultiUserChat groupChatOpSet
+ = chatRoomProvider
+ .getProtocolProvider().getOperationSet(
+ OperationSetMultiUserChat.class);
+
+ ChatRoom chatRoom = null;
+ try
+ {
+ chatRoom = groupChatOpSet.findRoom(chatRoomName);
+ }
+ catch (Exception e)
+ {
+ if (logger.isTraceEnabled())
+ logger.trace("Un exception occurred while searching for room:"
+ + chatRoomName, e);
+ }
+
+ if (chatRoom != null)
+ {
+ ChatRoomWrapper chatRoomWrapper
+ = chatRoomList.findChatRoomWrapperFromChatRoom(chatRoom);
+
+ if(chatRoomWrapper == null)
+ {
+ ChatRoomProviderWrapper parentProvider
+ = chatRoomList
+ .findServerWrapperFromProvider(
+ chatRoom.getParentProvider());
+
+ chatRoomWrapper
+ = new ChatRoomWrapperImpl(parentProvider, chatRoom);
+
+ chatRoomList.addChatRoom(chatRoomWrapper);
+
+ fireChatRoomListChangedEvent(
+ chatRoomWrapper,
+ ChatRoomListChangeEvent.CHAT_ROOM_ADDED);
+ }
+ joinChatRoom(chatRoomWrapper);
+ }
+ else
+ MUCActivator.getAlertUIService().showAlertDialog(
+ MUCActivator.getResources().getI18NString("service.gui.ERROR"),
+ MUCActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_NOT_EXIST",
+ new String[]{chatRoomName,
+ chatRoomProvider.getProtocolProvider()
+ .getAccountID().getService()}));
+ }
+
+
+ /**
+ * Creates a chat room, by specifying the chat room name, the parent
+ * protocol provider and eventually, the contacts invited to participate in
+ * this chat room.
+ *
+ * @param roomName the name of the room
+ * @param protocolProvider the parent protocol provider.
+ * @param contacts the contacts invited when creating the chat room.
+ * @param reason
+ * @param persistent is the room persistent
+ * @param isPrivate whether the room will be private or public.
+ * @return the <tt>ChatRoomWrapper</tt> corresponding to the created room
+ */
+ public ChatRoomWrapper createChatRoom(
+ String roomName,
+ ProtocolProviderService protocolProvider,
+ Collection<String> contacts,
+ String reason,
+ boolean persistent,
+ boolean isPrivate)
+ {
+ return createChatRoom(
+ roomName, protocolProvider, contacts, reason, true, persistent,
+ isPrivate);
+ }
+
+ /**
+ * Creates a chat room, by specifying the chat room name, the parent
+ * protocol provider and eventually, the contacts invited to participate in
+ * this chat room.
+ *
+ * @param roomName the name of the room
+ * @param protocolProvider the parent protocol provider.
+ * @param contacts the contacts invited when creating the chat room.
+ * @param reason
+ * @param persistent is the room persistent
+ * @return the <tt>ChatRoomWrapper</tt> corresponding to the created room
+ */
+ public ChatRoomWrapper createChatRoom(
+ String roomName,
+ ProtocolProviderService protocolProvider,
+ Collection<String> contacts,
+ String reason,
+ boolean persistent)
+ {
+ return createChatRoom(
+ roomName, protocolProvider, contacts, reason, true, persistent,
+ false);
+ }
+
+ /**
+ * Creates a chat room, by specifying the chat room name, the parent
+ * protocol provider and eventually, the contacts invited to participate in
+ * this chat room.
+ *
+ * @param roomName the name of the room
+ * @param protocolProvider the parent protocol provider.
+ * @param contacts the contacts invited when creating the chat room.
+ * @param reason
+ * @param join whether we should join the room after creating it.
+ * @param persistent whether the newly created room will be persistent.
+ * @param isPrivate whether the room will be private or public.
+ * @return the <tt>ChatRoomWrapper</tt> corresponding to the created room or
+ * <tt>null</tt> if the protocol fails to create the chat room.
+ */
+ public ChatRoomWrapper createChatRoom(
+ String roomName,
+ ProtocolProviderService protocolProvider,
+ Collection<String> contacts,
+ String reason,
+ boolean join,
+ boolean persistent,
+ boolean isPrivate)
+ {
+ ChatRoomWrapper chatRoomWrapper = null;
+ OperationSetMultiUserChat groupChatOpSet
+ = protocolProvider.getOperationSet(OperationSetMultiUserChat.class);
+
+ // If there's no group chat operation set we have nothing to do here.
+ if (groupChatOpSet == null)
+ return null;
+
+ ChatRoom chatRoom = null;
+ try
+ {
+
+
+ HashMap<String, Object> roomProperties =
+ new HashMap<String, Object>();
+ roomProperties.put("isPrivate", isPrivate);
+ chatRoom = groupChatOpSet.createChatRoom(roomName, roomProperties);
+
+ if(join)
+ {
+ chatRoom.join();
+
+ for(String contact : contacts)
+ chatRoom.invite(contact, reason);
+ }
+ }
+ catch (OperationFailedException ex)
+ {
+ logger.error("Failed to create chat room.", ex);
+
+ MUCActivator.getAlertUIService().showAlertDialog(
+ MUCActivator.getResources().getI18NString("service.gui.ERROR"),
+ MUCActivator.getResources().getI18NString(
+ "service.gui.CREATE_CHAT_ROOM_ERROR",
+ new String[]{protocolProvider.getProtocolDisplayName()}),
+ ex);
+ }
+ catch (OperationNotSupportedException ex)
+ {
+ logger.error("Failed to create chat room.", ex);
+
+ MUCActivator.getAlertUIService().showAlertDialog(
+ MUCActivator.getResources().getI18NString("service.gui.ERROR"),
+ MUCActivator.getResources().getI18NString(
+ "service.gui.CREATE_CHAT_ROOM_ERROR",
+ new String[]{protocolProvider.getProtocolDisplayName()}),
+ ex);
+ }
+
+ if(chatRoom != null)
+ {
+ ChatRoomProviderWrapper parentProvider
+ = chatRoomList.findServerWrapperFromProvider(protocolProvider);
+
+ // if there is the same room ids don't add new wrapper as old one
+ // maybe already created
+ chatRoomWrapper =
+ chatRoomList.findChatRoomWrapperFromChatRoom(chatRoom);
+
+ if(chatRoomWrapper == null)
+ {
+ chatRoomWrapper
+ = new ChatRoomWrapperImpl(parentProvider, chatRoom);
+ chatRoomWrapper.setPersistent(persistent);
+ chatRoomList.addChatRoom(chatRoomWrapper);
+ }
+ }
+
+ return chatRoomWrapper;
+ }
+
+ /**
+ * Creates a private chat room, by specifying the parent
+ * protocol provider and eventually, the contacts invited to participate in
+ * this chat room.
+ *
+ * @param protocolProvider the parent protocol provider.
+ * @param contacts the contacts invited when creating the chat room.
+ * @param reason
+ * @param persistent is the room persistent
+ * @return the <tt>ChatRoomWrapper</tt> corresponding to the created room
+ */
+ public ChatRoomWrapper createPrivateChatRoom(
+ ProtocolProviderService protocolProvider,
+ Collection<String> contacts,
+ String reason,
+ boolean persistent)
+ {
+ return this.createChatRoom(
+ null, protocolProvider, contacts, reason, persistent, true);
+ }
+
+
+ /**
+ * Returns existing chat rooms for the given <tt>chatRoomProvider</tt>.
+ * @param chatRoomProvider the <tt>ChatRoomProviderWrapper</tt>, which
+ * chat rooms we're looking for
+ * @return existing chat rooms for the given <tt>chatRoomProvider</tt>
+ */
+ public List<String> getExistingChatRooms(
+ ChatRoomProviderWrapper chatRoomProvider)
+ {
+ if (chatRoomProvider == null)
+ return null;
+
+ ProtocolProviderService protocolProvider
+ = chatRoomProvider.getProtocolProvider();
+
+ if (protocolProvider == null)
+ return null;
+
+ OperationSetMultiUserChat groupChatOpSet
+ = protocolProvider
+ .getOperationSet(OperationSetMultiUserChat.class);
+
+ if (groupChatOpSet == null)
+ return null;
+
+ List<String> chatRooms = null;
+ try
+ {
+ chatRooms = groupChatOpSet.getExistingChatRooms();
+ }
+ catch (OperationFailedException e)
+ {
+ if (logger.isTraceEnabled())
+ logger.trace("Failed to obtain existing chat rooms for server: "
+ + protocolProvider.getAccountID().getService(), e);
+ }
+ catch (OperationNotSupportedException e)
+ {
+ if (logger.isTraceEnabled())
+ logger.trace("Failed to obtain existing chat rooms for server: "
+ + protocolProvider.getAccountID().getService(), e);
+ }
+
+ return chatRooms;
+ }
+
+ /**
+ * Rejects the given invitation with the specified reason.
+ *
+ * @param multiUserChatOpSet the operation set to use for rejecting the
+ * invitation
+ * @param invitation the invitation to reject
+ * @param reason the reason for the rejection
+ */
+ public void rejectInvitation( OperationSetMultiUserChat multiUserChatOpSet,
+ ChatRoomInvitation invitation,
+ String reason)
+ {
+ multiUserChatOpSet.rejectInvitation(invitation, reason);
+ }
+
+ /**
+ * Leaves the given chat room.
+ *
+ * @param chatRoomWrapper the chat room to leave.
+ * @return <tt>ChatRoomWrapper</tt> instance associated with the chat room.
+ */
+ public ChatRoomWrapper leaveChatRoom(ChatRoomWrapper chatRoomWrapper)
+ {
+ ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
+
+ if (chatRoom == null)
+ {
+ ResourceManagementService resources = MUCActivator.getResources();
+
+ MUCActivator.getAlertUIService().showAlertDialog(
+ resources.getI18NString("service.gui.WARNING"),
+ resources
+ .getI18NString(
+ "service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED"));
+
+ return null;
+ }
+
+ if (chatRoom.isJoined())
+ chatRoom.leave();
+
+ ChatRoomWrapper existChatRoomWrapper
+ = chatRoomList.findChatRoomWrapperFromChatRoom(chatRoom);
+
+ if(existChatRoomWrapper == null)
+ return null;
+
+ // We save the choice of the user, before the chat room is really
+ // joined, because even the join fails we want the next time when
+ // we login to join this chat room automatically.
+ ConfigurationUtils.updateChatRoomStatus(
+ chatRoomWrapper.getParentProvider().getProtocolProvider(),
+ chatRoomWrapper.getChatRoomID(),
+ GlobalStatusEnum.OFFLINE_STATUS);
+
+ return existChatRoomWrapper;
+ }
+
+ /**
+ * Joins a chat room in an asynchronous way.
+ */
+ private class JoinChatRoomTask
+ extends Thread
+ {
+ private final ChatRoomWrapperImpl chatRoomWrapper;
+
+ private final String nickName;
+
+ private final byte[] password;
+
+ private final boolean rememberPassword;
+
+ private final boolean isFirstAttempt;
+
+ private final String subject;
+
+ private ResourceManagementService resources
+ = MUCActivator.getResources();
+
+ JoinChatRoomTask( ChatRoomWrapperImpl chatRoomWrapper,
+ String nickName,
+ byte[] password,
+ boolean rememberPassword,
+ boolean isFirstAttempt,
+ String subject)
+ {
+ this.chatRoomWrapper = chatRoomWrapper;
+ this.nickName = nickName;
+ this.isFirstAttempt = isFirstAttempt;
+ this.subject = subject;
+
+ if(password == null)
+ {
+ String passString = chatRoomWrapper.loadPassword();
+ if(passString != null)
+ {
+ this.password = passString.getBytes();
+ }
+ else
+ {
+ this.password = null;
+ }
+ }
+ else
+ {
+ this.password = password;
+ }
+ this.rememberPassword = rememberPassword;
+ }
+
+ JoinChatRoomTask( ChatRoomWrapperImpl chatRoomWrapper,
+ String nickName,
+ byte[] password)
+ {
+ this(chatRoomWrapper, nickName, password, false, true, null);
+ }
+
+ JoinChatRoomTask( ChatRoomWrapperImpl chatRoomWrapper,
+ String nickName,
+ byte[] password,
+ String subject)
+ {
+ this(chatRoomWrapper, nickName, password, false, true, subject);
+ }
+
+ /**
+ * @override {@link Thread}{@link #run()} to perform all asynchronous
+ * tasks.
+ */
+ @Override
+ public void run()
+ {
+ ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
+
+ try
+ {
+ if(password != null && password.length > 0)
+ chatRoom.joinAs(nickName, password);
+ else if (nickName != null)
+ chatRoom.joinAs(nickName);
+ else
+ chatRoom.join();
+
+ done(JOIN_SUCCESS_PROP);
+ }
+ catch (OperationFailedException e)
+ {
+ if (logger.isTraceEnabled())
+ logger.trace("Failed to join chat room: "
+ + chatRoom.getName(), e);
+
+ switch (e.getErrorCode())
+ {
+ case OperationFailedException.AUTHENTICATION_FAILED:
+ done(JOIN_AUTHENTICATION_FAILED_PROP);
+ break;
+ case OperationFailedException.REGISTRATION_REQUIRED:
+ done(JOIN_REGISTRATION_REQUIRED_PROP);
+ break;
+ case OperationFailedException.PROVIDER_NOT_REGISTERED:
+ done(JOIN_PROVIDER_NOT_REGISTERED_PROP);
+ break;
+ case OperationFailedException.SUBSCRIPTION_ALREADY_EXISTS:
+ done(JOIN_SUBSCRIPTION_ALREADY_EXISTS_PROP);
+ break;
+ default:
+ done(JOIN_UNKNOWN_ERROR_PROP);
+ }
+ }
+ }
+
+ /**
+ * Performs UI changes after the chat room join task has finished.
+ * @param returnCode the result code from the chat room join task.
+ */
+ private void done(String returnCode)
+ {
+ ConfigurationUtils.updateChatRoomStatus(
+ chatRoomWrapper.getParentProvider().getProtocolProvider(),
+ chatRoomWrapper.getChatRoomID(),
+ GlobalStatusEnum.ONLINE_STATUS);
+
+ String errorMessage = null;
+ if(JOIN_AUTHENTICATION_FAILED_PROP.equals(returnCode))
+ {
+ chatRoomWrapper.removePassword();
+
+ AuthenticationWindowService authWindowsService
+ = ServiceUtils.getService(
+ MUCActivator.bundleContext,
+ AuthenticationWindowService.class);
+
+ AuthenticationWindowService.AuthenticationWindow authWindow =
+ authWindowsService.create(
+ null, null, null, false,
+ chatRoomWrapper.isPersistent(),
+ AuthenticationWindow.getAuthenticationWindowIcon(
+ chatRoomWrapper.getParentProvider()
+ .getProtocolProvider()),
+ resources.getI18NString(
+ "service.gui.AUTHENTICATION_WINDOW_TITLE",
+ new String[]{chatRoomWrapper.getParentProvider()
+ .getName()}),
+ resources.getI18NString(
+ "service.gui.CHAT_ROOM_REQUIRES_PASSWORD",
+ new String[]{
+ chatRoomWrapper.getChatRoomName()}),
+ "", null,
+ isFirstAttempt ?
+ null :
+ resources.getI18NString(
+ "service.gui.AUTHENTICATION_FAILED",
+ new String[]{chatRoomWrapper.getChatRoomName()}),
+ null);
+
+ authWindow.setVisible(true);
+
+ if (!authWindow.isCanceled())
+ {
+ joinChatRoom(
+ chatRoomWrapper,
+ nickName,
+ new String(authWindow.getPassword()).getBytes(),
+ authWindow.isRememberPassword(),
+ false,
+ subject);
+ }
+ }
+ else if(JOIN_REGISTRATION_REQUIRED_PROP.equals(returnCode))
+ {
+ errorMessage
+ = resources
+ .getI18NString(
+ "service.gui.CHAT_ROOM_REGISTRATION_REQUIRED",
+ new String[]{chatRoomWrapper.getChatRoomName()});
+ }
+ else if(JOIN_PROVIDER_NOT_REGISTERED_PROP.equals(returnCode))
+ {
+ errorMessage
+ = resources
+ .getI18NString("service.gui.CHAT_ROOM_NOT_CONNECTED",
+ new String[]{chatRoomWrapper.getChatRoomName()});
+ }
+ else if(JOIN_SUBSCRIPTION_ALREADY_EXISTS_PROP.equals(returnCode))
+ {
+ errorMessage
+ = resources
+ .getI18NString("service.gui.CHAT_ROOM_ALREADY_JOINED",
+ new String[]{chatRoomWrapper.getChatRoomName()});
+ }
+ else
+ {
+ errorMessage
+ = resources
+ .getI18NString("service.gui.FAILED_TO_JOIN_CHAT_ROOM",
+ new String[]{chatRoomWrapper.getChatRoomName()});
+ }
+
+ if (!JOIN_SUCCESS_PROP.equals(returnCode) &&
+ !JOIN_AUTHENTICATION_FAILED_PROP.equals(returnCode))
+ {
+ MUCActivator.getAlertUIService().showAlertPopup(
+ resources.getI18NString("service.gui.ERROR"), errorMessage);
+ }
+
+ if (JOIN_SUCCESS_PROP.equals(returnCode))
+ {
+ if(rememberPassword)
+ {
+ chatRoomWrapper.savePassword(new String(password));
+ }
+
+ if(subject != null)
+ {
+ try
+ {
+ chatRoomWrapper.getChatRoom().setSubject(subject);
+ }
+ catch(OperationFailedException ex)
+ {
+ logger.warn("Failed to set subject.");
+ }
+ }
+ }
+
+ chatRoomWrapper.firePropertyChange(returnCode);
+ }
+ }
+
+ /**
+ * Finds the <tt>ChatRoomWrapper</tt> instance associated with the
+ * source contact.
+ * @param contact the source contact.
+ * @return the <tt>ChatRoomWrapper</tt> instance.
+ */
+ public ChatRoomWrapper findChatRoomWrapperFromSourceContact(
+ SourceContact contact)
+ {
+ if(!(contact instanceof ChatRoomSourceContact))
+ return null;
+ ChatRoomSourceContact chatRoomContact = (ChatRoomSourceContact) contact;
+ return chatRoomList.findChatRoomWrapperFromChatRoomID(
+ chatRoomContact.getChatRoomID(), chatRoomContact.getProvider());
+ }
+
+ /**
+ * Finds the <tt>ChatRoomWrapper</tt> instance associated with the
+ * chat room.
+ * @param chatRoomID the id of the chat room.
+ * @param pps the provider of the chat room.
+ * @return the <tt>ChatRoomWrapper</tt> instance.
+ */
+ public ChatRoomWrapper findChatRoomWrapperFromChatRoomID(String chatRoomID,
+ ProtocolProviderService pps)
+ {
+ return chatRoomList.findChatRoomWrapperFromChatRoomID(chatRoomID, pps);
+ }
+
+ /**
+ * Searches for chat room wrapper in chat room list by chat room.
+ *
+ * @param chatRoom the chat room.
+ * @param create if <tt>true</tt> and the chat room wrapper is not found new
+ * chatRoomWrapper is created.
+ * @return found chat room wrapper or the created chat room wrapper.
+ */
+ @Override
+ public ChatRoomWrapper getChatRoomWrapperByChatRoom(ChatRoom chatRoom,
+ boolean create)
+ {
+ ChatRoomWrapper chatRoomWrapper
+ = chatRoomList.findChatRoomWrapperFromChatRoom(chatRoom);
+
+ if ((chatRoomWrapper == null) && create)
+ {
+ ChatRoomProviderWrapper parentProvider
+ = chatRoomList.findServerWrapperFromProvider(
+ chatRoom.getParentProvider());
+
+ chatRoomWrapper
+ = new ChatRoomWrapperImpl(
+ parentProvider, chatRoom);
+
+ chatRoomList.addChatRoom(chatRoomWrapper);
+ }
+ return chatRoomWrapper;
+ }
+
+ /**
+ * Goes through the locally stored chat rooms list and for each
+ * {@link ChatRoomWrapper} tries to find the corresponding server stored
+ * {@link ChatRoom} in the specified operation set. Joins automatically all
+ * found chat rooms.
+ *
+ * @param protocolProvider the protocol provider for the account to
+ * synchronize
+ * @param opSet the multi user chat operation set, which give us access to
+ * chat room server
+ */
+ public void synchronizeOpSetWithLocalContactList(
+ ProtocolProviderService protocolProvider,
+ final OperationSetMultiUserChat opSet)
+ {
+ ChatRoomProviderWrapper chatRoomProvider
+ = findServerWrapperFromProvider(protocolProvider);
+
+ if(chatRoomProvider == null)
+ {
+ chatRoomProvider = chatRoomList.addRegisteredChatProvider(protocolProvider);
+ }
+
+ if (chatRoomProvider != null)
+ {
+ chatRoomProvider.synchronizeProvider();
+ }
+ }
+
+ /**
+ * Returns an iterator to the list of chat room providers.
+ *
+ * @return an iterator to the list of chat room providers.
+ */
+ public Iterator<ChatRoomProviderWrapper> getChatRoomProviders()
+ {
+ return chatRoomList.getChatRoomProviders();
+ }
+
+ /**
+ * Removes the given <tt>ChatRoom</tt> from the list of all chat rooms.
+ *
+ * @param chatRoomWrapper the <tt>ChatRoomWrapper</tt> to remove
+ */
+ public void removeChatRoom(ChatRoomWrapper chatRoomWrapper)
+ {
+ chatRoomList.removeChatRoom(chatRoomWrapper);
+ }
+
+ /**
+ * Destroys the given <tt>ChatRoom</tt> from the list of all chat rooms.
+ *
+ * @param chatRoomWrapper the <tt>ChatRoomWrapper</tt> to be destroyed.
+ * @param reason the reason for destroying.
+ * @param alternateAddress the alternate address.
+ */
+ public void destroyChatRoom(ChatRoomWrapper chatRoomWrapper,
+ String reason, String alternateAddress)
+ {
+ if(chatRoomWrapper.getChatRoom().destroy(reason, alternateAddress))
+ {
+ MUCActivator.getUIService().closeChatRoomWindow(
+ chatRoomWrapper);
+ chatRoomList.removeChatRoom(chatRoomWrapper);
+ }
+ else
+ {
+ // if we leave a chat room which is not persistent
+ // the room can be destroyed on the server, and error is returned
+ // when we try to destroy it not-authorized(401)
+ if(!chatRoomWrapper.getChatRoom().isPersistent()
+ && !chatRoomWrapper.getChatRoom().isJoined())
+ {
+ chatRoomList.removeChatRoom(chatRoomWrapper);
+ }
+ }
+
+ }
+
+ /**
+ * Adds a ChatRoomProviderWrapperListener to the listener list.
+ *
+ * @param listener the ChatRoomProviderWrapperListener to be added
+ */
+ public void addChatRoomProviderWrapperListener(
+ ChatRoomProviderWrapperListener listener)
+ {
+ chatRoomList.addChatRoomProviderWrapperListener(listener);
+ }
+
+ /**
+ * Removes the ChatRoomProviderWrapperListener to the listener list.
+ *
+ * @param listener the ChatRoomProviderWrapperListener to be removed
+ */
+ public void removeChatRoomProviderWrapperListener(
+ ChatRoomProviderWrapperListener listener)
+ {
+ chatRoomList.removeChatRoomProviderWrapperListener(listener);
+ }
+
+ /**
+ * Returns the <tt>ChatRoomProviderWrapper</tt> that correspond to the
+ * given <tt>ProtocolProviderService</tt>. If the list doesn't contain a
+ * corresponding wrapper - returns null.
+ *
+ * @param protocolProvider the protocol provider that we're looking for
+ * @return the <tt>ChatRoomProvider</tt> object corresponding to
+ * the given <tt>ProtocolProviderService</tt>
+ */
+ public ChatRoomProviderWrapper findServerWrapperFromProvider(
+ ProtocolProviderService protocolProvider)
+ {
+ return chatRoomList.findServerWrapperFromProvider(protocolProvider);
+ }
+
+ /**
+ * Returns the <tt>ChatRoomWrapper</tt> that correspond to the given
+ * <tt>ChatRoom</tt>. If the list of chat rooms doesn't contain a
+ * corresponding wrapper - returns null.
+ *
+ * @param chatRoom the <tt>ChatRoom</tt> that we're looking for
+ * @return the <tt>ChatRoomWrapper</tt> object corresponding to the given
+ * <tt>ChatRoom</tt>
+ */
+ public ChatRoomWrapper findChatRoomWrapperFromChatRoom(ChatRoom chatRoom)
+ {
+ return chatRoomList.findChatRoomWrapperFromChatRoom(chatRoom);
+ }
+
+ /**
+ * Opens a chat window for the chat room.
+ *
+ * @param room the chat room.
+ */
+ public void openChatRoom(ChatRoomWrapper room)
+ {
+ if (room.getChatRoom() == null)
+ {
+ room = createChatRoom(
+ room.getChatRoomName(),
+ room.getParentProvider().getProtocolProvider(),
+ new ArrayList<String>(),"", false, false, true);
+
+ // leave the chatroom because getChatRoom().isJoined() returns true
+ // otherwise
+ if (room.getChatRoom().isJoined())
+ room.getChatRoom().leave();
+
+ }
+
+ if(!room.getChatRoom().isJoined())
+ {
+ String savedNick =
+ ConfigurationUtils.getChatRoomProperty(room
+ .getParentProvider().getProtocolProvider(), room
+ .getChatRoomID(), "userNickName");
+ String subject = null;
+
+ if (savedNick == null)
+ {
+ String[] joinOptions = ChatRoomJoinOptionsDialog.getJoinOptions(
+ room.getParentProvider().getProtocolProvider(),
+ room.getChatRoomID(),
+ MUCActivator.getGlobalDisplayDetailsService()
+ .getDisplayName(
+ room.getParentProvider().getProtocolProvider()));
+ savedNick = joinOptions[0];
+ subject = joinOptions[1];
+
+ }
+
+ if (savedNick != null)
+ {
+ joinChatRoom(room, savedNick, null,
+ subject);
+ }
+ else
+ return;
+ }
+
+ MUCActivator.getUIService().openChatRoomWindow(room);
+ }
+
+ /**
+ * Returns instance of the <tt>ServerChatRoomContactSourceService</tt>
+ * contact source.
+ * @return instance of the <tt>ServerChatRoomContactSourceService</tt>
+ * contact source.
+ */
+ public ContactSourceService getServerChatRoomsContactSourceForProvider(
+ ChatRoomProviderWrapper pps)
+ {
+ return new ServerChatRoomContactSourceService(pps);
+ }
+
+ /**
+ * Returns <tt>true</tt> if the contact is <tt>ChatRoomSourceContact</tt>
+ *
+ * @param contact the contact
+ * @return <tt>true</tt> if the contact is <tt>ChatRoomSourceContact</tt>
+ */
+ public boolean isMUCSourceContact(SourceContact contact)
+ {
+ return (contact instanceof ChatRoomSourceContact);
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/muc/ServerChatRoomQuery.java b/src/net/java/sip/communicator/impl/muc/ServerChatRoomQuery.java
index 47785ee..a98e5ed 100644
--- a/src/net/java/sip/communicator/impl/muc/ServerChatRoomQuery.java
+++ b/src/net/java/sip/communicator/impl/muc/ServerChatRoomQuery.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,331 +15,331 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.muc;
-
-import java.util.*;
-import java.util.regex.*;
-
-import net.java.sip.communicator.service.contactsource.*;
-import net.java.sip.communicator.service.muc.*;
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * The <tt>ServerChatRoomQuery</tt> is a query over the
- * <tt>ServerChatRoomContactSourceService</tt>.
- *
- * @author Hristo Terezov
- */
-public class ServerChatRoomQuery
- extends AsyncContactQuery<ContactSourceService>
- implements ChatRoomProviderWrapperListener
-{
- /**
- * The query string.
- */
- private String queryString;
-
- /**
- * List with the current results for the query.
- */
- private Set<BaseChatRoomSourceContact> contactResults
- = new TreeSet<BaseChatRoomSourceContact>();
-
- /**
- * MUC service.
- */
- private MUCServiceImpl mucService;
-
- /**
- * The number of contact query listeners.
- */
- private int contactQueryListenersCount = 0;
-
- /**
- * The provider associated with the query.
- */
- private ChatRoomProviderWrapper provider = null;
-
- /**
- * Creates an instance of <tt>ChatRoomQuery</tt> by specifying
- * the parent contact source, the query string to match and the maximum
- * result contacts to return.
- *
- * @param contactSource the parent contact source
- * @param queryString the query string to match
- * @param provider the provider associated with the query
- */
- public ServerChatRoomQuery(String queryString,
- ServerChatRoomContactSourceService contactSource,
- ChatRoomProviderWrapper provider)
- {
- super(contactSource,
- Pattern.compile(queryString, Pattern.CASE_INSENSITIVE
- | Pattern.LITERAL), true);
- this.queryString = queryString;
-
- mucService = MUCActivator.getMUCService();
-
- this.provider = provider;
- }
-
- /**
- * Adds listeners for the query
- */
- private void initListeners()
- {
- mucService.addChatRoomProviderWrapperListener(this);
- }
-
- @Override
- protected void run()
- {
- if(provider == null)
- {
- Iterator<ChatRoomProviderWrapper> chatRoomProviders
- = mucService.getChatRoomProviders();
- while (chatRoomProviders.hasNext())
- {
- ChatRoomProviderWrapper provider = chatRoomProviders.next();
- providerAdded(provider, true);
- }
- }
- else
- {
- providerAdded(provider, true);
- }
-
- if (getStatus() != QUERY_CANCELED)
- setStatus(QUERY_COMPLETED);
- }
-
- /**
- * Handles adding a chat room provider.
- * @param provider the provider.
- * @param addQueryResult indicates whether we should add the chat room to
- * the query results or fire an event without adding it to the results.
- */
- private void providerAdded(final ChatRoomProviderWrapper provider,
- final boolean addQueryResult)
- {
- final ProtocolProviderService pps = provider.getProtocolProvider();
- List<String> chatRoomNames =
- MUCActivator.getMUCService().getExistingChatRooms(provider);
- if (chatRoomNames == null)
- {
- return;
- }
-
- // Already create all the BaseChatRoomSourceContact instances since all
- // the data is already available.
- final Set<BaseChatRoomSourceContact> chatRooms =
- new HashSet<BaseChatRoomSourceContact>(chatRoomNames.size());
- for (final String name : chatRoomNames)
- {
- chatRooms.add(new BaseChatRoomSourceContact(name, name, this, pps));
- }
- addChatRooms(pps, chatRooms, addQueryResult);
- }
-
-
- /**
- * Adds found result to the query results.
- *
- * @param pps the protocol provider associated with the found chat room.
- * @param chatRoomName the name of the chat room.
- * @param chatRoomID the id of the chat room.
- * @param addQueryResult indicates whether we should add the chat room to
- * the query results or fire an event without adding it to the results.
- */
- private void addChatRoom(ProtocolProviderService pps,
- String chatRoomName, String chatRoomID, boolean addQueryResult)
- {
- if((queryString == null
- || ((chatRoomName.contains(
- queryString)
- || chatRoomID.contains(queryString)
- ))) && isMatching(chatRoomID, pps))
- {
- BaseChatRoomSourceContact contact
- = new BaseChatRoomSourceContact(chatRoomName, chatRoomID, this,
- pps);
- synchronized (contactResults)
- {
- contactResults.add(contact);
- }
-
- if(addQueryResult)
- {
- addQueryResult(contact, false);
- }
- else
- {
- fireContactReceived(contact, false);
- }
- }
- }
-
- /**
- * Adds found results to the query results.
- *
- * @param pps the protocol provider associated with the found chat room.
- * @param chatRooms The set of chat rooms based on
- * BaseChatRoomSourceContact. This is the full set and it will be
- * filtered according to demands of the queryString.
- * @param addQueryResult indicates whether we should add the chat room to
- * the query results or fire an event without adding it to the
- * results.
- */
- private void addChatRooms(final ProtocolProviderService pps,
- final Set<BaseChatRoomSourceContact> chatRooms,
- final boolean addQueryResult)
- {
- BaseChatRoomSourceContact room;
- Iterator<BaseChatRoomSourceContact> iterator = chatRooms.iterator();
- while (iterator.hasNext())
- {
- room = iterator.next();
-
- // Notice the NOT operator at the start ...
- if (!((queryString == null || (room.getChatRoomName().contains(
- queryString) || room.getChatRoomID().contains(queryString)))
- && isMatching(room.getChatRoomID(), pps)))
- {
- iterator.remove();
- }
- }
-
- synchronized (contactResults)
- {
- contactResults.addAll(chatRooms);
- }
-
- if (addQueryResult)
- {
- addQueryResults(chatRooms);
- }
- else
- {
- // TODO Need something to fire one event for multiple contacts.
- for (SourceContact contact : chatRooms)
- {
- fireContactReceived(contact, false);
- }
- }
- }
-
- @Override
- public void chatRoomProviderWrapperAdded(ChatRoomProviderWrapper provider)
- {
- providerAdded(provider, false);
- }
-
- @Override
- public void chatRoomProviderWrapperRemoved(ChatRoomProviderWrapper provider)
- {
- LinkedList<BaseChatRoomSourceContact> tmpContactResults;
- synchronized (contactResults)
- {
- tmpContactResults
- = new LinkedList<BaseChatRoomSourceContact>(contactResults);
-
- for(BaseChatRoomSourceContact contact : tmpContactResults)
- {
- if(contact.getProvider().equals(provider.getProtocolProvider()))
- {
- contactResults.remove(contact);
- fireContactRemoved(contact);
- }
- }
- }
- }
-
-
- /**
- * Clears any listener we used.
- */
- private void clearListeners()
- {
- mucService.removeChatRoomProviderWrapperListener(this);
- }
-
- /**
- * Cancels this <tt>ContactQuery</tt>.
- *
- * @see ContactQuery#cancel()
- */
- public void cancel()
- {
- clearListeners();
-
- super.cancel();
- }
-
- /**
- * If query has status changed to cancel, let's clear listeners.
- * @param status {@link ContactQuery#QUERY_CANCELED},
- * {@link ContactQuery#QUERY_COMPLETED}
- */
- public void setStatus(int status)
- {
- if(status == QUERY_CANCELED)
- clearListeners();
-
- super.setStatus(status);
- }
-
- @Override
- public void addContactQueryListener(ContactQueryListener l)
- {
- super.addContactQueryListener(l);
- contactQueryListenersCount++;
- if(contactQueryListenersCount == 1)
- {
- initListeners();
- }
- }
-
- @Override
- public void removeContactQueryListener(ContactQueryListener l)
- {
- super.removeContactQueryListener(l);
- contactQueryListenersCount--;
- if(contactQueryListenersCount == 0)
- {
- clearListeners();
- }
- }
-
- /**
- * Checks if the contact should be added to results or not.
- * @param chatRoomID the chat room id associated with the contact.
- * @param pps the provider of the chat room contact.
- * @return <tt>true</tt> if the result should be added to the results and
- * <tt>false</tt> if not.
- */
- public boolean isMatching(String chatRoomID, ProtocolProviderService pps)
- {
- return (MUCActivator.getMUCService().findChatRoomWrapperFromChatRoomID(
- chatRoomID, pps) == null);
- }
-
- /**
- * Returns the index of the contact in the contact results list.
- * @param contact the contact.
- * @return the index of the contact in the contact results list.
- */
- public int indexOf(BaseChatRoomSourceContact contact)
- {
- Iterator<BaseChatRoomSourceContact> it = contactResults.iterator();
- int i = 0;
- while(it.hasNext())
- {
- if(contact.equals(it.next()))
- {
- return i;
- }
- i++;
- }
- return -1;
- }
-}
+package net.java.sip.communicator.impl.muc;
+
+import java.util.*;
+import java.util.regex.*;
+
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.muc.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The <tt>ServerChatRoomQuery</tt> is a query over the
+ * <tt>ServerChatRoomContactSourceService</tt>.
+ *
+ * @author Hristo Terezov
+ */
+public class ServerChatRoomQuery
+ extends AsyncContactQuery<ContactSourceService>
+ implements ChatRoomProviderWrapperListener
+{
+ /**
+ * The query string.
+ */
+ private String queryString;
+
+ /**
+ * List with the current results for the query.
+ */
+ private Set<BaseChatRoomSourceContact> contactResults
+ = new TreeSet<BaseChatRoomSourceContact>();
+
+ /**
+ * MUC service.
+ */
+ private MUCServiceImpl mucService;
+
+ /**
+ * The number of contact query listeners.
+ */
+ private int contactQueryListenersCount = 0;
+
+ /**
+ * The provider associated with the query.
+ */
+ private ChatRoomProviderWrapper provider = null;
+
+ /**
+ * Creates an instance of <tt>ChatRoomQuery</tt> by specifying
+ * the parent contact source, the query string to match and the maximum
+ * result contacts to return.
+ *
+ * @param contactSource the parent contact source
+ * @param queryString the query string to match
+ * @param provider the provider associated with the query
+ */
+ public ServerChatRoomQuery(String queryString,
+ ServerChatRoomContactSourceService contactSource,
+ ChatRoomProviderWrapper provider)
+ {
+ super(contactSource,
+ Pattern.compile(queryString, Pattern.CASE_INSENSITIVE
+ | Pattern.LITERAL), true);
+ this.queryString = queryString;
+
+ mucService = MUCActivator.getMUCService();
+
+ this.provider = provider;
+ }
+
+ /**
+ * Adds listeners for the query
+ */
+ private void initListeners()
+ {
+ mucService.addChatRoomProviderWrapperListener(this);
+ }
+
+ @Override
+ protected void run()
+ {
+ if(provider == null)
+ {
+ Iterator<ChatRoomProviderWrapper> chatRoomProviders
+ = mucService.getChatRoomProviders();
+ while (chatRoomProviders.hasNext())
+ {
+ ChatRoomProviderWrapper provider = chatRoomProviders.next();
+ providerAdded(provider, true);
+ }
+ }
+ else
+ {
+ providerAdded(provider, true);
+ }
+
+ if (getStatus() != QUERY_CANCELED)
+ setStatus(QUERY_COMPLETED);
+ }
+
+ /**
+ * Handles adding a chat room provider.
+ * @param provider the provider.
+ * @param addQueryResult indicates whether we should add the chat room to
+ * the query results or fire an event without adding it to the results.
+ */
+ private void providerAdded(final ChatRoomProviderWrapper provider,
+ final boolean addQueryResult)
+ {
+ final ProtocolProviderService pps = provider.getProtocolProvider();
+ List<String> chatRoomNames =
+ MUCActivator.getMUCService().getExistingChatRooms(provider);
+ if (chatRoomNames == null)
+ {
+ return;
+ }
+
+ // Already create all the BaseChatRoomSourceContact instances since all
+ // the data is already available.
+ final Set<BaseChatRoomSourceContact> chatRooms =
+ new HashSet<BaseChatRoomSourceContact>(chatRoomNames.size());
+ for (final String name : chatRoomNames)
+ {
+ chatRooms.add(new BaseChatRoomSourceContact(name, name, this, pps));
+ }
+ addChatRooms(pps, chatRooms, addQueryResult);
+ }
+
+
+ /**
+ * Adds found result to the query results.
+ *
+ * @param pps the protocol provider associated with the found chat room.
+ * @param chatRoomName the name of the chat room.
+ * @param chatRoomID the id of the chat room.
+ * @param addQueryResult indicates whether we should add the chat room to
+ * the query results or fire an event without adding it to the results.
+ */
+ private void addChatRoom(ProtocolProviderService pps,
+ String chatRoomName, String chatRoomID, boolean addQueryResult)
+ {
+ if((queryString == null
+ || ((chatRoomName.contains(
+ queryString)
+ || chatRoomID.contains(queryString)
+ ))) && isMatching(chatRoomID, pps))
+ {
+ BaseChatRoomSourceContact contact
+ = new BaseChatRoomSourceContact(chatRoomName, chatRoomID, this,
+ pps);
+ synchronized (contactResults)
+ {
+ contactResults.add(contact);
+ }
+
+ if(addQueryResult)
+ {
+ addQueryResult(contact, false);
+ }
+ else
+ {
+ fireContactReceived(contact, false);
+ }
+ }
+ }
+
+ /**
+ * Adds found results to the query results.
+ *
+ * @param pps the protocol provider associated with the found chat room.
+ * @param chatRooms The set of chat rooms based on
+ * BaseChatRoomSourceContact. This is the full set and it will be
+ * filtered according to demands of the queryString.
+ * @param addQueryResult indicates whether we should add the chat room to
+ * the query results or fire an event without adding it to the
+ * results.
+ */
+ private void addChatRooms(final ProtocolProviderService pps,
+ final Set<BaseChatRoomSourceContact> chatRooms,
+ final boolean addQueryResult)
+ {
+ BaseChatRoomSourceContact room;
+ Iterator<BaseChatRoomSourceContact> iterator = chatRooms.iterator();
+ while (iterator.hasNext())
+ {
+ room = iterator.next();
+
+ // Notice the NOT operator at the start ...
+ if (!((queryString == null || (room.getChatRoomName().contains(
+ queryString) || room.getChatRoomID().contains(queryString)))
+ && isMatching(room.getChatRoomID(), pps)))
+ {
+ iterator.remove();
+ }
+ }
+
+ synchronized (contactResults)
+ {
+ contactResults.addAll(chatRooms);
+ }
+
+ if (addQueryResult)
+ {
+ addQueryResults(chatRooms);
+ }
+ else
+ {
+ // TODO Need something to fire one event for multiple contacts.
+ for (SourceContact contact : chatRooms)
+ {
+ fireContactReceived(contact, false);
+ }
+ }
+ }
+
+ @Override
+ public void chatRoomProviderWrapperAdded(ChatRoomProviderWrapper provider)
+ {
+ providerAdded(provider, false);
+ }
+
+ @Override
+ public void chatRoomProviderWrapperRemoved(ChatRoomProviderWrapper provider)
+ {
+ LinkedList<BaseChatRoomSourceContact> tmpContactResults;
+ synchronized (contactResults)
+ {
+ tmpContactResults
+ = new LinkedList<BaseChatRoomSourceContact>(contactResults);
+
+ for(BaseChatRoomSourceContact contact : tmpContactResults)
+ {
+ if(contact.getProvider().equals(provider.getProtocolProvider()))
+ {
+ contactResults.remove(contact);
+ fireContactRemoved(contact);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Clears any listener we used.
+ */
+ private void clearListeners()
+ {
+ mucService.removeChatRoomProviderWrapperListener(this);
+ }
+
+ /**
+ * Cancels this <tt>ContactQuery</tt>.
+ *
+ * @see ContactQuery#cancel()
+ */
+ public void cancel()
+ {
+ clearListeners();
+
+ super.cancel();
+ }
+
+ /**
+ * If query has status changed to cancel, let's clear listeners.
+ * @param status {@link ContactQuery#QUERY_CANCELED},
+ * {@link ContactQuery#QUERY_COMPLETED}
+ */
+ public void setStatus(int status)
+ {
+ if(status == QUERY_CANCELED)
+ clearListeners();
+
+ super.setStatus(status);
+ }
+
+ @Override
+ public void addContactQueryListener(ContactQueryListener l)
+ {
+ super.addContactQueryListener(l);
+ contactQueryListenersCount++;
+ if(contactQueryListenersCount == 1)
+ {
+ initListeners();
+ }
+ }
+
+ @Override
+ public void removeContactQueryListener(ContactQueryListener l)
+ {
+ super.removeContactQueryListener(l);
+ contactQueryListenersCount--;
+ if(contactQueryListenersCount == 0)
+ {
+ clearListeners();
+ }
+ }
+
+ /**
+ * Checks if the contact should be added to results or not.
+ * @param chatRoomID the chat room id associated with the contact.
+ * @param pps the provider of the chat room contact.
+ * @return <tt>true</tt> if the result should be added to the results and
+ * <tt>false</tt> if not.
+ */
+ public boolean isMatching(String chatRoomID, ProtocolProviderService pps)
+ {
+ return (MUCActivator.getMUCService().findChatRoomWrapperFromChatRoomID(
+ chatRoomID, pps) == null);
+ }
+
+ /**
+ * Returns the index of the contact in the contact results list.
+ * @param contact the contact.
+ * @return the index of the contact in the contact results list.
+ */
+ public int indexOf(BaseChatRoomSourceContact contact)
+ {
+ Iterator<BaseChatRoomSourceContact> it = contactResults.iterator();
+ int i = 0;
+ while(it.hasNext())
+ {
+ if(contact.equals(it.next()))
+ {
+ return i;
+ }
+ i++;
+ }
+ return -1;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/neomedia/AbstractDeviceConfigurationListener.java b/src/net/java/sip/communicator/impl/neomedia/AbstractDeviceConfigurationListener.java
index a1814e8..3c84aa2 100644
--- a/src/net/java/sip/communicator/impl/neomedia/AbstractDeviceConfigurationListener.java
+++ b/src/net/java/sip/communicator/impl/neomedia/AbstractDeviceConfigurationListener.java
@@ -187,8 +187,7 @@ public abstract class AbstractDeviceConfigurationListener
body
+ "\r\n\r\n"
+ NeomediaActivator.getResources().getI18NString(
- "impl.media.configform"
- + ".AUDIO_DEVICE_CONFIG_MANAGMENT_CLICK"),
+ "impl.media.configform.AUDIO_DEVICE_CONFIG_MANAGMENT_CLICK"),
null,
extras);
}
diff --git a/src/net/java/sip/communicator/impl/neomedia/AudioDeviceConfigurationListener.java b/src/net/java/sip/communicator/impl/neomedia/AudioDeviceConfigurationListener.java
index 75f1fc3..fe06f15 100644
--- a/src/net/java/sip/communicator/impl/neomedia/AudioDeviceConfigurationListener.java
+++ b/src/net/java/sip/communicator/impl/neomedia/AudioDeviceConfigurationListener.java
@@ -159,10 +159,8 @@ public class AudioDeviceConfigurationListener
capturePropertyChangeEvent.getOldValue()))
{
body.append("\r\n")
- .append(
- r.getI18NString(
- "impl.media.configform"
- + ".AUDIO_DEVICE_SELECTED_AUDIO_IN"))
+ .append(r.getI18NString(
+ "impl.media.configform.AUDIO_DEVICE_SELECTED_AUDIO_IN"))
.append("\r\n\t")
.append(cdi.getName());
selectedHasChanged = true;
@@ -179,10 +177,8 @@ public class AudioDeviceConfigurationListener
playbackPropertyChangeEvent.getOldValue()))
{
body.append("\r\n")
- .append(
- r.getI18NString(
- "impl.media.configform"
- + ".AUDIO_DEVICE_SELECTED_AUDIO_OUT"))
+ .append(r.getI18NString(
+ "impl.media.configform.AUDIO_DEVICE_SELECTED_AUDIO_OUT"))
.append("\r\n\t")
.append(cdi.getName());
selectedHasChanged = true;
@@ -199,10 +195,8 @@ public class AudioDeviceConfigurationListener
notifyPropertyChangeEvent.getOldValue()))
{
body.append("\r\n")
- .append(
- r.getI18NString(
- "impl.media.configform"
- + ".AUDIO_DEVICE_SELECTED_AUDIO_NOTIFICATIONS"))
+ .append(r.getI18NString(
+ "impl.media.configform.AUDIO_DEVICE_SELECTED_AUDIO_NOTIFICATIONS"))
.append("\r\n\t")
.append(cdi.getName());
selectedHasChanged = true;
diff --git a/src/net/java/sip/communicator/impl/neomedia/DeviceConfigurationComboBoxModel.java b/src/net/java/sip/communicator/impl/neomedia/DeviceConfigurationComboBoxModel.java
index 1c5bf93..9bacb4c 100644
--- a/src/net/java/sip/communicator/impl/neomedia/DeviceConfigurationComboBoxModel.java
+++ b/src/net/java/sip/communicator/impl/neomedia/DeviceConfigurationComboBoxModel.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,456 +15,456 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.neomedia;
-
-import java.beans.*;
-import java.util.*;
-
-import javax.media.*;
-import javax.swing.*;
-import javax.swing.event.*;
-
-import org.jitsi.impl.neomedia.device.*;
-import org.jitsi.service.neomedia.*;
-
-/**
- * Implements <tt>ComboBoxModel</tt> for a specific <tt>DeviceConfiguration</tt>
- * so that the latter may be displayed and manipulated in the user interface as
- * a combo box.
- *
- * @author Lyubomir Marinov
- * @author Damian Minkov
- */
-public class DeviceConfigurationComboBoxModel
- implements ComboBoxModel,
- ListModel,
- PropertyChangeListener
-{
- /**
- * Type of the model - audio.
- */
- public static final int AUDIO = 1;
-
- /**
- * Audio Capture Device.
- */
- public static final int AUDIO_CAPTURE = 3;
-
- /**
- * Audio device for notification sounds.
- */
- public static final int AUDIO_NOTIFY = 5;
-
- /**
- * Audio playback device.
- */
- public static final int AUDIO_PLAYBACK = 4;
-
- /**
- * Type of the model - video.
- */
- public static final int VIDEO = 2;
-
- private AudioSystem[] audioSystems;
-
- /**
- * The current device configuration.
- */
- private final DeviceConfiguration deviceConfiguration;
-
- /**
- * All the devices.
- */
- private CaptureDevice[] devices;
-
- /**
- * The <tt>ListDataListener</tt>s registered with this instance.
- */
- private final List<ListDataListener> listeners
- = new ArrayList<ListDataListener>();
-
- /**
- * The type of the media for this combo.
- */
- private final int type;
-
- /**
- * Creates device combobox model
- * @param parent the parent component
- * @param deviceConfiguration the current device configuration
- * @param type the device - audio/video
- */
- public DeviceConfigurationComboBoxModel(
- DeviceConfiguration deviceConfiguration,
- int type)
- {
- if (deviceConfiguration == null)
- throw new IllegalArgumentException("deviceConfiguration");
- if ((type != AUDIO)
- && (type != AUDIO_CAPTURE)
- && (type != AUDIO_NOTIFY)
- && (type != AUDIO_PLAYBACK)
- && (type != VIDEO))
- throw new IllegalArgumentException("type");
-
- this.deviceConfiguration = deviceConfiguration;
- this.type = type;
-
- if (type == AUDIO
- || type == AUDIO_CAPTURE
- || type == AUDIO_NOTIFY
- || type == AUDIO_PLAYBACK)
- {
- deviceConfiguration.addPropertyChangeListener(this);
- }
- }
-
- public void addListDataListener(ListDataListener listener)
- {
- if (listener == null)
- throw new IllegalArgumentException("listener");
-
- if (!listeners.contains(listener))
- listeners.add(listener);
- }
-
- /**
- * Change of the content.
- * @param index0 from index.
- * @param index1 to index.
- */
- protected void fireContentsChanged(int index0, int index1)
- {
- ListDataListener[] listeners
- = this.listeners.toArray(
- new ListDataListener[this.listeners.size()]);
- ListDataEvent event
- = new ListDataEvent(
- this,
- ListDataEvent.CONTENTS_CHANGED,
- index0,
- index1);
-
- for (ListDataListener listener : listeners)
- listener.contentsChanged(event);
- }
-
- private AudioSystem[] getAudioSystems()
- {
- if (type != AUDIO)
- throw new IllegalStateException("type");
-
- audioSystems = deviceConfiguration.getAvailableAudioSystems();
- return audioSystems;
- }
-
- /**
- * Extracts the devices for the current type.
- * @return the devices.
- */
- private CaptureDevice[] getDevices()
- {
- if (type == AUDIO)
- throw new IllegalStateException("type");
-
- if (devices != null)
- return devices;
-
- AudioSystem audioSystem;
- List<? extends CaptureDeviceInfo> infos = null;
-
- switch (type)
- {
- case AUDIO_CAPTURE:
- audioSystem = deviceConfiguration.getAudioSystem();
- infos = (audioSystem == null)
- ? null
- : audioSystem.getDevices(AudioSystem.DataFlow.CAPTURE);
- break;
- case AUDIO_NOTIFY:
- audioSystem = deviceConfiguration.getAudioSystem();
- infos = (audioSystem == null)
- ? null
- : audioSystem.getDevices(AudioSystem.DataFlow.NOTIFY);
- break;
- case AUDIO_PLAYBACK:
- audioSystem = deviceConfiguration.getAudioSystem();
- infos = (audioSystem == null)
- ? null
- : audioSystem.getDevices(AudioSystem.DataFlow.PLAYBACK);
- break;
- case VIDEO:
- infos = deviceConfiguration.getAvailableVideoCaptureDevices(
- MediaUseCase.CALL);
- break;
- default:
- throw new IllegalStateException("type");
- }
-
- final int deviceCount = (infos == null) ? 0 : infos.size();
- devices = new CaptureDevice[deviceCount + 1];
-
- if (deviceCount > 0)
- {
- for (int i = 0; i < deviceCount; i++)
- devices[i] = new CaptureDevice(infos.get(i));
- }
- devices[deviceCount] = new CaptureDevice(null);
-
- return devices;
- }
-
- public Object getElementAt(int index)
- {
- if (type == AUDIO)
- return getAudioSystems()[index];
- else
- return getDevices()[index];
- }
-
- /**
- * Extracts the devices selected by the configuration.
- * @return <tt>CaptureDevice</tt> selected
- */
- private CaptureDevice getSelectedDevice()
- {
- AudioSystem audioSystem;
- CaptureDeviceInfo info;
-
- switch (type)
- {
- case AUDIO_CAPTURE:
- audioSystem = deviceConfiguration.getAudioSystem();
- info = (audioSystem == null)
- ? null
- : audioSystem.getSelectedDevice(AudioSystem.DataFlow.CAPTURE);
- break;
- case AUDIO_NOTIFY:
- audioSystem = deviceConfiguration.getAudioSystem();
- info = (audioSystem == null)
- ? null
- : audioSystem.getSelectedDevice(AudioSystem.DataFlow.NOTIFY);
- break;
- case AUDIO_PLAYBACK:
- audioSystem = deviceConfiguration.getAudioSystem();
- info = (audioSystem == null)
- ? null
- : audioSystem.getSelectedDevice(AudioSystem.DataFlow.PLAYBACK);
- break;
- case VIDEO:
- info = deviceConfiguration.getVideoCaptureDevice(MediaUseCase.ANY);
- break;
- default:
- throw new IllegalStateException("type");
- }
-
- for (CaptureDevice device : getDevices())
- {
- if (device.equals(info))
- return device;
- }
- return null;
- }
-
- public Object getSelectedItem()
- {
- if (type == AUDIO)
- return deviceConfiguration.getAudioSystem();
- else
- return getSelectedDevice();
- }
-
- public int getSize()
- {
- if (type == AUDIO)
- return getAudioSystems().length;
- else
- return getDevices().length;
- }
-
- /**
- * Notifies this instance about changes in the values of the properties of
- * {@link #deviceConfiguration} so that this instance keeps itself
- * up-to-date with respect to the list of devices.
- *
- * @param ev a <tt>PropertyChangeEvent</tt> which describes the name of the
- * property whose value has changed and the old and new values of that
- * property
- */
- public void propertyChange(final PropertyChangeEvent ev)
- {
- if (DeviceConfiguration.PROP_AUDIO_SYSTEM_DEVICES.equals(
- ev.getPropertyName()))
- {
- if (SwingUtilities.isEventDispatchThread())
- {
- audioSystems = null;
- devices = null;
- fireContentsChanged(0, getSize() - 1);
- }
- else
- {
- SwingUtilities.invokeLater(
- new Runnable()
- {
- public void run()
- {
- propertyChange(ev);
- }
- });
- }
- }
- }
-
- public void removeListDataListener(ListDataListener listener)
- {
- if (listener == null)
- throw new IllegalArgumentException("listener");
-
- listeners.remove(listener);
- }
-
- /**
- * Selects and saves the new choice.
- * @param device the device we choose.
- */
- private void setSelectedDevice(CaptureDevice device)
- {
- // We cannot clear the selection of DeviceConfiguration.
- if (device == null)
- return;
-
- CaptureDevice selectedDevice = getSelectedDevice();
-
- if (selectedDevice != device)
- {
- AudioSystem audioSystem;
-
- switch (type)
- {
- case AUDIO_CAPTURE:
- audioSystem = deviceConfiguration.getAudioSystem();
- if (audioSystem != null)
- {
- audioSystem.setDevice(
- AudioSystem.DataFlow.CAPTURE,
- ((CaptureDeviceInfo2) device.info),
- true);
- }
- break;
- case AUDIO_NOTIFY:
- audioSystem = deviceConfiguration.getAudioSystem();
- if (audioSystem != null)
- {
- audioSystem.setDevice(
- AudioSystem.DataFlow.NOTIFY,
- ((CaptureDeviceInfo2) device.info),
- true);
- }
- break;
- case AUDIO_PLAYBACK:
- audioSystem = deviceConfiguration.getAudioSystem();
- if (audioSystem != null)
- {
- audioSystem.setDevice(
- AudioSystem.DataFlow.PLAYBACK,
- ((CaptureDeviceInfo2) device.info),
- true);
- }
- break;
- case VIDEO:
- deviceConfiguration.setVideoCaptureDevice(device.info, true);
- break;
- }
-
- fireContentsChanged(-1, -1);
- }
- }
-
- public void setSelectedItem(Object item)
- {
- if (type == AUDIO)
- {
- AudioSystem audioSystem = (AudioSystem) item;
-
- if(!audioSystem.equals(deviceConfiguration.getAudioSystem()))
- {
- deviceConfiguration.setAudioSystem(audioSystem, true);
- fireContentsChanged(-1, -1);
- }
- }
- else
- setSelectedDevice((CaptureDevice) item);
- }
-
- /**
- * Encapsulates a <tt>CaptureDeviceInfo</tt> for the purposes of its display
- * in the user interface.
- */
- public static class CaptureDevice
- {
- /**
- * The encapsulated info.
- */
- public final CaptureDeviceInfo info;
-
- /**
- * Creates the wrapper.
- * @param info the info object we wrap.
- */
- public CaptureDevice(CaptureDeviceInfo info)
- {
- this.info = info;
- }
-
- /**
- * Determines whether the <tt>CaptureDeviceInfo</tt> encapsulated by
- * this instance is equal (by value) to a specific
- * <tt>CaptureDeviceInfo</tt>.
- *
- * @param cdi the <tt>CaptureDeviceInfo</tt> to be determined whether it
- * is equal (by value) to the <tt>CaptureDeviceInfo</tt> encapsulated by
- * this instance
- * @return <tt>true</tt> if the <tt>CaptureDeviceInfo</tt> encapsulated
- * by this instance is equal (by value) to the specified <tt>cdi</tt>;
- * otherwise, <tt>false</tt>
- */
- public boolean equals(CaptureDeviceInfo cdi)
- {
- return (info == null) ? (cdi == null) : info.equals(cdi);
- }
-
- /**
- * Gets a human-readable <tt>String</tt> representation of this
- * instance.
- *
- * @return a <tt>String</tt> value which is a human-readable
- * representation of this instance
- */
- @Override
- public String toString()
- {
- String s;
-
- if(info == null)
- {
- s
- = NeomediaActivator.getResources().getI18NString(
- "impl.media.configform.NO_DEVICE");
- }
- else
- {
- s = info.getName();
- if(info instanceof CaptureDeviceInfo2)
- {
- String transportType
- = ((CaptureDeviceInfo2) info).getTransportType();
-
- if(transportType != null)
- s += " (" + transportType + ")";
- }
- }
- return s;
- }
- }
-}
+package net.java.sip.communicator.impl.neomedia;
+
+import java.beans.*;
+import java.util.*;
+
+import javax.media.*;
+import javax.swing.*;
+import javax.swing.event.*;
+
+import org.jitsi.impl.neomedia.device.*;
+import org.jitsi.service.neomedia.*;
+
+/**
+ * Implements <tt>ComboBoxModel</tt> for a specific <tt>DeviceConfiguration</tt>
+ * so that the latter may be displayed and manipulated in the user interface as
+ * a combo box.
+ *
+ * @author Lyubomir Marinov
+ * @author Damian Minkov
+ */
+public class DeviceConfigurationComboBoxModel
+ implements ComboBoxModel,
+ ListModel,
+ PropertyChangeListener
+{
+ /**
+ * Type of the model - audio.
+ */
+ public static final int AUDIO = 1;
+
+ /**
+ * Audio Capture Device.
+ */
+ public static final int AUDIO_CAPTURE = 3;
+
+ /**
+ * Audio device for notification sounds.
+ */
+ public static final int AUDIO_NOTIFY = 5;
+
+ /**
+ * Audio playback device.
+ */
+ public static final int AUDIO_PLAYBACK = 4;
+
+ /**
+ * Type of the model - video.
+ */
+ public static final int VIDEO = 2;
+
+ private AudioSystem[] audioSystems;
+
+ /**
+ * The current device configuration.
+ */
+ private final DeviceConfiguration deviceConfiguration;
+
+ /**
+ * All the devices.
+ */
+ private CaptureDevice[] devices;
+
+ /**
+ * The <tt>ListDataListener</tt>s registered with this instance.
+ */
+ private final List<ListDataListener> listeners
+ = new ArrayList<ListDataListener>();
+
+ /**
+ * The type of the media for this combo.
+ */
+ private final int type;
+
+ /**
+ * Creates device combobox model
+ * @param parent the parent component
+ * @param deviceConfiguration the current device configuration
+ * @param type the device - audio/video
+ */
+ public DeviceConfigurationComboBoxModel(
+ DeviceConfiguration deviceConfiguration,
+ int type)
+ {
+ if (deviceConfiguration == null)
+ throw new IllegalArgumentException("deviceConfiguration");
+ if ((type != AUDIO)
+ && (type != AUDIO_CAPTURE)
+ && (type != AUDIO_NOTIFY)
+ && (type != AUDIO_PLAYBACK)
+ && (type != VIDEO))
+ throw new IllegalArgumentException("type");
+
+ this.deviceConfiguration = deviceConfiguration;
+ this.type = type;
+
+ if (type == AUDIO
+ || type == AUDIO_CAPTURE
+ || type == AUDIO_NOTIFY
+ || type == AUDIO_PLAYBACK)
+ {
+ deviceConfiguration.addPropertyChangeListener(this);
+ }
+ }
+
+ public void addListDataListener(ListDataListener listener)
+ {
+ if (listener == null)
+ throw new IllegalArgumentException("listener");
+
+ if (!listeners.contains(listener))
+ listeners.add(listener);
+ }
+
+ /**
+ * Change of the content.
+ * @param index0 from index.
+ * @param index1 to index.
+ */
+ protected void fireContentsChanged(int index0, int index1)
+ {
+ ListDataListener[] listeners
+ = this.listeners.toArray(
+ new ListDataListener[this.listeners.size()]);
+ ListDataEvent event
+ = new ListDataEvent(
+ this,
+ ListDataEvent.CONTENTS_CHANGED,
+ index0,
+ index1);
+
+ for (ListDataListener listener : listeners)
+ listener.contentsChanged(event);
+ }
+
+ private AudioSystem[] getAudioSystems()
+ {
+ if (type != AUDIO)
+ throw new IllegalStateException("type");
+
+ audioSystems = deviceConfiguration.getAvailableAudioSystems();
+ return audioSystems;
+ }
+
+ /**
+ * Extracts the devices for the current type.
+ * @return the devices.
+ */
+ private CaptureDevice[] getDevices()
+ {
+ if (type == AUDIO)
+ throw new IllegalStateException("type");
+
+ if (devices != null)
+ return devices;
+
+ AudioSystem audioSystem;
+ List<? extends CaptureDeviceInfo> infos = null;
+
+ switch (type)
+ {
+ case AUDIO_CAPTURE:
+ audioSystem = deviceConfiguration.getAudioSystem();
+ infos = (audioSystem == null)
+ ? null
+ : audioSystem.getDevices(AudioSystem.DataFlow.CAPTURE);
+ break;
+ case AUDIO_NOTIFY:
+ audioSystem = deviceConfiguration.getAudioSystem();
+ infos = (audioSystem == null)
+ ? null
+ : audioSystem.getDevices(AudioSystem.DataFlow.NOTIFY);
+ break;
+ case AUDIO_PLAYBACK:
+ audioSystem = deviceConfiguration.getAudioSystem();
+ infos = (audioSystem == null)
+ ? null
+ : audioSystem.getDevices(AudioSystem.DataFlow.PLAYBACK);
+ break;
+ case VIDEO:
+ infos = deviceConfiguration.getAvailableVideoCaptureDevices(
+ MediaUseCase.CALL);
+ break;
+ default:
+ throw new IllegalStateException("type");
+ }
+
+ final int deviceCount = (infos == null) ? 0 : infos.size();
+ devices = new CaptureDevice[deviceCount + 1];
+
+ if (deviceCount > 0)
+ {
+ for (int i = 0; i < deviceCount; i++)
+ devices[i] = new CaptureDevice(infos.get(i));
+ }
+ devices[deviceCount] = new CaptureDevice(null);
+
+ return devices;
+ }
+
+ public Object getElementAt(int index)
+ {
+ if (type == AUDIO)
+ return getAudioSystems()[index];
+ else
+ return getDevices()[index];
+ }
+
+ /**
+ * Extracts the devices selected by the configuration.
+ * @return <tt>CaptureDevice</tt> selected
+ */
+ private CaptureDevice getSelectedDevice()
+ {
+ AudioSystem audioSystem;
+ CaptureDeviceInfo info;
+
+ switch (type)
+ {
+ case AUDIO_CAPTURE:
+ audioSystem = deviceConfiguration.getAudioSystem();
+ info = (audioSystem == null)
+ ? null
+ : audioSystem.getSelectedDevice(AudioSystem.DataFlow.CAPTURE);
+ break;
+ case AUDIO_NOTIFY:
+ audioSystem = deviceConfiguration.getAudioSystem();
+ info = (audioSystem == null)
+ ? null
+ : audioSystem.getSelectedDevice(AudioSystem.DataFlow.NOTIFY);
+ break;
+ case AUDIO_PLAYBACK:
+ audioSystem = deviceConfiguration.getAudioSystem();
+ info = (audioSystem == null)
+ ? null
+ : audioSystem.getSelectedDevice(AudioSystem.DataFlow.PLAYBACK);
+ break;
+ case VIDEO:
+ info = deviceConfiguration.getVideoCaptureDevice(MediaUseCase.ANY);
+ break;
+ default:
+ throw new IllegalStateException("type");
+ }
+
+ for (CaptureDevice device : getDevices())
+ {
+ if (device.equals(info))
+ return device;
+ }
+ return null;
+ }
+
+ public Object getSelectedItem()
+ {
+ if (type == AUDIO)
+ return deviceConfiguration.getAudioSystem();
+ else
+ return getSelectedDevice();
+ }
+
+ public int getSize()
+ {
+ if (type == AUDIO)
+ return getAudioSystems().length;
+ else
+ return getDevices().length;
+ }
+
+ /**
+ * Notifies this instance about changes in the values of the properties of
+ * {@link #deviceConfiguration} so that this instance keeps itself
+ * up-to-date with respect to the list of devices.
+ *
+ * @param ev a <tt>PropertyChangeEvent</tt> which describes the name of the
+ * property whose value has changed and the old and new values of that
+ * property
+ */
+ public void propertyChange(final PropertyChangeEvent ev)
+ {
+ if (DeviceConfiguration.PROP_AUDIO_SYSTEM_DEVICES.equals(
+ ev.getPropertyName()))
+ {
+ if (SwingUtilities.isEventDispatchThread())
+ {
+ audioSystems = null;
+ devices = null;
+ fireContentsChanged(0, getSize() - 1);
+ }
+ else
+ {
+ SwingUtilities.invokeLater(
+ new Runnable()
+ {
+ public void run()
+ {
+ propertyChange(ev);
+ }
+ });
+ }
+ }
+ }
+
+ public void removeListDataListener(ListDataListener listener)
+ {
+ if (listener == null)
+ throw new IllegalArgumentException("listener");
+
+ listeners.remove(listener);
+ }
+
+ /**
+ * Selects and saves the new choice.
+ * @param device the device we choose.
+ */
+ private void setSelectedDevice(CaptureDevice device)
+ {
+ // We cannot clear the selection of DeviceConfiguration.
+ if (device == null)
+ return;
+
+ CaptureDevice selectedDevice = getSelectedDevice();
+
+ if (selectedDevice != device)
+ {
+ AudioSystem audioSystem;
+
+ switch (type)
+ {
+ case AUDIO_CAPTURE:
+ audioSystem = deviceConfiguration.getAudioSystem();
+ if (audioSystem != null)
+ {
+ audioSystem.setDevice(
+ AudioSystem.DataFlow.CAPTURE,
+ ((CaptureDeviceInfo2) device.info),
+ true);
+ }
+ break;
+ case AUDIO_NOTIFY:
+ audioSystem = deviceConfiguration.getAudioSystem();
+ if (audioSystem != null)
+ {
+ audioSystem.setDevice(
+ AudioSystem.DataFlow.NOTIFY,
+ ((CaptureDeviceInfo2) device.info),
+ true);
+ }
+ break;
+ case AUDIO_PLAYBACK:
+ audioSystem = deviceConfiguration.getAudioSystem();
+ if (audioSystem != null)
+ {
+ audioSystem.setDevice(
+ AudioSystem.DataFlow.PLAYBACK,
+ ((CaptureDeviceInfo2) device.info),
+ true);
+ }
+ break;
+ case VIDEO:
+ deviceConfiguration.setVideoCaptureDevice(device.info, true);
+ break;
+ }
+
+ fireContentsChanged(-1, -1);
+ }
+ }
+
+ public void setSelectedItem(Object item)
+ {
+ if (type == AUDIO)
+ {
+ AudioSystem audioSystem = (AudioSystem) item;
+
+ if(!audioSystem.equals(deviceConfiguration.getAudioSystem()))
+ {
+ deviceConfiguration.setAudioSystem(audioSystem, true);
+ fireContentsChanged(-1, -1);
+ }
+ }
+ else
+ setSelectedDevice((CaptureDevice) item);
+ }
+
+ /**
+ * Encapsulates a <tt>CaptureDeviceInfo</tt> for the purposes of its display
+ * in the user interface.
+ */
+ public static class CaptureDevice
+ {
+ /**
+ * The encapsulated info.
+ */
+ public final CaptureDeviceInfo info;
+
+ /**
+ * Creates the wrapper.
+ * @param info the info object we wrap.
+ */
+ public CaptureDevice(CaptureDeviceInfo info)
+ {
+ this.info = info;
+ }
+
+ /**
+ * Determines whether the <tt>CaptureDeviceInfo</tt> encapsulated by
+ * this instance is equal (by value) to a specific
+ * <tt>CaptureDeviceInfo</tt>.
+ *
+ * @param cdi the <tt>CaptureDeviceInfo</tt> to be determined whether it
+ * is equal (by value) to the <tt>CaptureDeviceInfo</tt> encapsulated by
+ * this instance
+ * @return <tt>true</tt> if the <tt>CaptureDeviceInfo</tt> encapsulated
+ * by this instance is equal (by value) to the specified <tt>cdi</tt>;
+ * otherwise, <tt>false</tt>
+ */
+ public boolean equals(CaptureDeviceInfo cdi)
+ {
+ return (info == null) ? (cdi == null) : info.equals(cdi);
+ }
+
+ /**
+ * Gets a human-readable <tt>String</tt> representation of this
+ * instance.
+ *
+ * @return a <tt>String</tt> value which is a human-readable
+ * representation of this instance
+ */
+ @Override
+ public String toString()
+ {
+ String s;
+
+ if(info == null)
+ {
+ s
+ = NeomediaActivator.getResources().getI18NString(
+ "impl.media.configform.NO_DEVICE");
+ }
+ else
+ {
+ s = info.getName();
+ if(info instanceof CaptureDeviceInfo2)
+ {
+ String transportType
+ = ((CaptureDeviceInfo2) info).getTransportType();
+
+ if(transportType != null)
+ s += " (" + transportType + ")";
+ }
+ }
+ return s;
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/neomedia/EncodingConfigurationTableModel.java b/src/net/java/sip/communicator/impl/neomedia/EncodingConfigurationTableModel.java
index 925184c..f8cf447 100644
--- a/src/net/java/sip/communicator/impl/neomedia/EncodingConfigurationTableModel.java
+++ b/src/net/java/sip/communicator/impl/neomedia/EncodingConfigurationTableModel.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,272 +15,272 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.neomedia;
-
-import java.util.*;
-
-import javax.swing.table.*;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-
-import org.jitsi.impl.neomedia.*;
-import org.jitsi.impl.neomedia.format.*;
-import org.jitsi.service.neomedia.*;
-import org.jitsi.service.neomedia.codec.*;
-import org.jitsi.service.neomedia.format.*;
-
-/**
- * Implements {@link TableModel} for {@link EncodingConfiguration}.
- *
- * @author Lyubomir Marinov
- */
-public class EncodingConfigurationTableModel
- extends MoveableTableModel
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- private final EncodingConfiguration encodingConfiguration;
-
- private MediaFormat[] encodings;
-
- private final MediaType type;
-
- /**
- * Constructor.
- *
- * @param encodingConfiguration the encoding configuration
- * @param type media type
- */
- public EncodingConfigurationTableModel(int type,
- EncodingConfiguration encodingConfiguration)
- {
- if (encodingConfiguration == null)
- throw new IllegalArgumentException("encodingConfiguration");
- this.encodingConfiguration = encodingConfiguration;
-
- switch (type)
- {
- case DeviceConfigurationComboBoxModel.AUDIO:
- this.type = MediaType.AUDIO;
- break;
- case DeviceConfigurationComboBoxModel.VIDEO:
- this.type = MediaType.VIDEO;
- break;
- default:
- throw new IllegalArgumentException("type");
- }
- }
-
- @Override
- public Class<?> getColumnClass(int columnIndex)
- {
- return
- (columnIndex == 0)
- ? Boolean.class
- : super.getColumnClass(columnIndex);
- }
-
- public int getColumnCount()
- {
- return 2;
- }
-
- private MediaFormat[] getEncodings()
- {
- if (encodings != null)
- return encodings;
-
- MediaFormat[] availableEncodings
- = encodingConfiguration.getAllEncodings(type);
- int encodingCount = availableEncodings.length;
-
- if (encodingCount < 1)
- encodings = MediaUtils.EMPTY_MEDIA_FORMATS;
- else
- {
- /*
- * The MediaFormats will be displayed by encoding (name) and clock
- * rate and EncodingConfiguration will store them that way so this
- * TableModel should better display unique encoding-clock rate
- * pairs.
- */
- HashMap<String, MediaFormat> availableEncodingSet
- = new HashMap<String, MediaFormat>();
-
- for (MediaFormat availableEncoding : availableEncodings)
- {
- availableEncodingSet.put(
- availableEncoding.getEncoding()
- + "/"
- + availableEncoding.getClockRateString(),
- availableEncoding);
- }
- availableEncodings
- = availableEncodingSet.values().toArray(
- MediaUtils.EMPTY_MEDIA_FORMATS);
- encodingCount = availableEncodings.length;
-
- encodings = new MediaFormat[encodingCount];
- System
- .arraycopy(availableEncodings, 0, encodings, 0, encodingCount);
- // Display the encodings in decreasing priority.
- Arrays
- .sort(encodings, 0, encodingCount, new Comparator<MediaFormat>()
- {
- public int compare(MediaFormat format0, MediaFormat format1)
- {
- int ret
- = encodingConfiguration.getPriority(format1)
- - encodingConfiguration.getPriority(format0);
-
- if (ret == 0)
- {
- /*
- * In the cases of equal priorities, display them
- * sorted by encoding name in increasing order.
- */
- ret
- = format0.getEncoding().compareToIgnoreCase(
- format1.getEncoding());
- if (ret == 0)
- {
- /*
- * In the cases of equal priorities and equal
- * encoding names, display them sorted by clock
- * rate in decreasing order.
- */
- ret
- = Double.compare(
- format1.getClockRate(),
- format0.getClockRate());
- }
- }
- return ret;
- }
- });
- }
- return encodings;
- }
-
- private int[] getPriorities()
- {
- MediaFormat[] encodings = getEncodings();
- final int count = encodings.length;
- int[] priorities = new int[count];
-
- for (int i = 0; i < count; i++)
- {
- int priority = encodingConfiguration.getPriority(encodings[i]);
-
- priorities[i] = (priority > 0) ? (count - i) : 0;
- }
- return priorities;
- }
-
- public int getRowCount()
- {
- return getEncodings().length;
- }
-
- public Object getValueAt(int rowIndex, int columnIndex)
- {
- MediaFormat encoding = getEncodings()[rowIndex];
-
- switch (columnIndex)
- {
- case 0:
- return (encodingConfiguration.getPriority(encoding) > 0);
- case 1:
- if (MediaType.VIDEO.equals(encoding.getMediaType())
- && (VideoMediaFormatImpl.DEFAULT_CLOCK_RATE
- == encoding.getClockRate()))
- return encoding.getEncoding();
- else
- {
- return encoding.getEncoding()
- + "/"
- + encoding.getRealUsedClockRateString();
- }
- default:
- return null;
- }
- }
-
- @Override
- public boolean isCellEditable(int rowIndex, int columnIndex)
- {
- return (columnIndex == 0);
- }
-
- /**
- * Move the row.
- *
- * @param rowIndex index of the row
- * @param up true to move up, false to move down
- * @return the next row index
- */
- @Override
- public int move(int rowIndex, boolean up)
- {
- if (up)
- {
- if (rowIndex <= 0)
- throw new IllegalArgumentException("rowIndex");
-
- return move(rowIndex - 1, false) - 1;
- }
-
- if (rowIndex >= (getRowCount() - 1))
- throw new IllegalArgumentException("rowIndex");
-
- int[] priorities = getPriorities();
- final int nextRowIndex = rowIndex + 1;
-
- if (priorities[rowIndex] > 0)
- priorities[rowIndex] = priorities.length - nextRowIndex;
- if (priorities[nextRowIndex] > 0)
- priorities[nextRowIndex] = priorities.length - rowIndex;
- setPriorities(priorities);
-
- MediaFormat swap = encodings[rowIndex];
-
- encodings[rowIndex] = encodings[nextRowIndex];
- encodings[nextRowIndex] = swap;
-
- fireTableRowsUpdated(rowIndex, nextRowIndex);
- return nextRowIndex;
- }
-
- private void setPriorities(int[] priorities)
- {
- final int count = encodings.length;
-
- if (priorities.length != count)
- throw new IllegalArgumentException("priorities");
- for (int i = 0; i < count; i++)
- {
- encodingConfiguration.setPriority(encodings[i], priorities[i]);
- }
- }
-
- @Override
- public void setValueAt(Object value, int rowIndex, int columnIndex)
- {
- if ((columnIndex == 0) && (value instanceof Boolean))
- {
- int priority
- = ((Boolean) value) ? (getPriorities().length - rowIndex) : 0;
- MediaFormat encoding = encodings[rowIndex];
-
-
- // We fire the update event before setting the configuration
- // property in order to have more reactive user interface.
- fireTableCellUpdated(rowIndex, columnIndex);
-
- encodingConfiguration.setPriority(encoding, priority);
- }
- }
-}
+package net.java.sip.communicator.impl.neomedia;
+
+import java.util.*;
+
+import javax.swing.table.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+
+import org.jitsi.impl.neomedia.*;
+import org.jitsi.impl.neomedia.format.*;
+import org.jitsi.service.neomedia.*;
+import org.jitsi.service.neomedia.codec.*;
+import org.jitsi.service.neomedia.format.*;
+
+/**
+ * Implements {@link TableModel} for {@link EncodingConfiguration}.
+ *
+ * @author Lyubomir Marinov
+ */
+public class EncodingConfigurationTableModel
+ extends MoveableTableModel
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ private final EncodingConfiguration encodingConfiguration;
+
+ private MediaFormat[] encodings;
+
+ private final MediaType type;
+
+ /**
+ * Constructor.
+ *
+ * @param encodingConfiguration the encoding configuration
+ * @param type media type
+ */
+ public EncodingConfigurationTableModel(int type,
+ EncodingConfiguration encodingConfiguration)
+ {
+ if (encodingConfiguration == null)
+ throw new IllegalArgumentException("encodingConfiguration");
+ this.encodingConfiguration = encodingConfiguration;
+
+ switch (type)
+ {
+ case DeviceConfigurationComboBoxModel.AUDIO:
+ this.type = MediaType.AUDIO;
+ break;
+ case DeviceConfigurationComboBoxModel.VIDEO:
+ this.type = MediaType.VIDEO;
+ break;
+ default:
+ throw new IllegalArgumentException("type");
+ }
+ }
+
+ @Override
+ public Class<?> getColumnClass(int columnIndex)
+ {
+ return
+ (columnIndex == 0)
+ ? Boolean.class
+ : super.getColumnClass(columnIndex);
+ }
+
+ public int getColumnCount()
+ {
+ return 2;
+ }
+
+ private MediaFormat[] getEncodings()
+ {
+ if (encodings != null)
+ return encodings;
+
+ MediaFormat[] availableEncodings
+ = encodingConfiguration.getAllEncodings(type);
+ int encodingCount = availableEncodings.length;
+
+ if (encodingCount < 1)
+ encodings = MediaUtils.EMPTY_MEDIA_FORMATS;
+ else
+ {
+ /*
+ * The MediaFormats will be displayed by encoding (name) and clock
+ * rate and EncodingConfiguration will store them that way so this
+ * TableModel should better display unique encoding-clock rate
+ * pairs.
+ */
+ HashMap<String, MediaFormat> availableEncodingSet
+ = new HashMap<String, MediaFormat>();
+
+ for (MediaFormat availableEncoding : availableEncodings)
+ {
+ availableEncodingSet.put(
+ availableEncoding.getEncoding()
+ + "/"
+ + availableEncoding.getClockRateString(),
+ availableEncoding);
+ }
+ availableEncodings
+ = availableEncodingSet.values().toArray(
+ MediaUtils.EMPTY_MEDIA_FORMATS);
+ encodingCount = availableEncodings.length;
+
+ encodings = new MediaFormat[encodingCount];
+ System
+ .arraycopy(availableEncodings, 0, encodings, 0, encodingCount);
+ // Display the encodings in decreasing priority.
+ Arrays
+ .sort(encodings, 0, encodingCount, new Comparator<MediaFormat>()
+ {
+ public int compare(MediaFormat format0, MediaFormat format1)
+ {
+ int ret
+ = encodingConfiguration.getPriority(format1)
+ - encodingConfiguration.getPriority(format0);
+
+ if (ret == 0)
+ {
+ /*
+ * In the cases of equal priorities, display them
+ * sorted by encoding name in increasing order.
+ */
+ ret
+ = format0.getEncoding().compareToIgnoreCase(
+ format1.getEncoding());
+ if (ret == 0)
+ {
+ /*
+ * In the cases of equal priorities and equal
+ * encoding names, display them sorted by clock
+ * rate in decreasing order.
+ */
+ ret
+ = Double.compare(
+ format1.getClockRate(),
+ format0.getClockRate());
+ }
+ }
+ return ret;
+ }
+ });
+ }
+ return encodings;
+ }
+
+ private int[] getPriorities()
+ {
+ MediaFormat[] encodings = getEncodings();
+ final int count = encodings.length;
+ int[] priorities = new int[count];
+
+ for (int i = 0; i < count; i++)
+ {
+ int priority = encodingConfiguration.getPriority(encodings[i]);
+
+ priorities[i] = (priority > 0) ? (count - i) : 0;
+ }
+ return priorities;
+ }
+
+ public int getRowCount()
+ {
+ return getEncodings().length;
+ }
+
+ public Object getValueAt(int rowIndex, int columnIndex)
+ {
+ MediaFormat encoding = getEncodings()[rowIndex];
+
+ switch (columnIndex)
+ {
+ case 0:
+ return (encodingConfiguration.getPriority(encoding) > 0);
+ case 1:
+ if (MediaType.VIDEO.equals(encoding.getMediaType())
+ && (VideoMediaFormatImpl.DEFAULT_CLOCK_RATE
+ == encoding.getClockRate()))
+ return encoding.getEncoding();
+ else
+ {
+ return encoding.getEncoding()
+ + "/"
+ + encoding.getRealUsedClockRateString();
+ }
+ default:
+ return null;
+ }
+ }
+
+ @Override
+ public boolean isCellEditable(int rowIndex, int columnIndex)
+ {
+ return (columnIndex == 0);
+ }
+
+ /**
+ * Move the row.
+ *
+ * @param rowIndex index of the row
+ * @param up true to move up, false to move down
+ * @return the next row index
+ */
+ @Override
+ public int move(int rowIndex, boolean up)
+ {
+ if (up)
+ {
+ if (rowIndex <= 0)
+ throw new IllegalArgumentException("rowIndex");
+
+ return move(rowIndex - 1, false) - 1;
+ }
+
+ if (rowIndex >= (getRowCount() - 1))
+ throw new IllegalArgumentException("rowIndex");
+
+ int[] priorities = getPriorities();
+ final int nextRowIndex = rowIndex + 1;
+
+ if (priorities[rowIndex] > 0)
+ priorities[rowIndex] = priorities.length - nextRowIndex;
+ if (priorities[nextRowIndex] > 0)
+ priorities[nextRowIndex] = priorities.length - rowIndex;
+ setPriorities(priorities);
+
+ MediaFormat swap = encodings[rowIndex];
+
+ encodings[rowIndex] = encodings[nextRowIndex];
+ encodings[nextRowIndex] = swap;
+
+ fireTableRowsUpdated(rowIndex, nextRowIndex);
+ return nextRowIndex;
+ }
+
+ private void setPriorities(int[] priorities)
+ {
+ final int count = encodings.length;
+
+ if (priorities.length != count)
+ throw new IllegalArgumentException("priorities");
+ for (int i = 0; i < count; i++)
+ {
+ encodingConfiguration.setPriority(encodings[i], priorities[i]);
+ }
+ }
+
+ @Override
+ public void setValueAt(Object value, int rowIndex, int columnIndex)
+ {
+ if ((columnIndex == 0) && (value instanceof Boolean))
+ {
+ int priority
+ = ((Boolean) value) ? (getPriorities().length - rowIndex) : 0;
+ MediaFormat encoding = encodings[rowIndex];
+
+
+ // We fire the update event before setting the configuration
+ // property in order to have more reactive user interface.
+ fireTableCellUpdated(rowIndex, columnIndex);
+
+ encodingConfiguration.setPriority(encoding, priority);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/neomedia/MediaConfigurationImpl.java b/src/net/java/sip/communicator/impl/neomedia/MediaConfigurationImpl.java
index d561c92..00e8aac 100644
--- a/src/net/java/sip/communicator/impl/neomedia/MediaConfigurationImpl.java
+++ b/src/net/java/sip/communicator/impl/neomedia/MediaConfigurationImpl.java
@@ -1773,8 +1773,7 @@ public class MediaConfigurationImpl
{
String noAvailableAudioDevice
= NeomediaActivator.getResources().getI18NString(
- "impl.media.configform"
- + ".NO_AVAILABLE_AUDIO_DEVICE");
+ "impl.media.configform.NO_AVAILABLE_AUDIO_DEVICE");
preview = new TransparentPanel(new GridBagLayout());
preview.add(new JLabel(noAvailableAudioDevice));
diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/ConfigurationPanel.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/ConfigurationPanel.java
index 1381d21..a3ea318 100644
--- a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/ConfigurationPanel.java
+++ b/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/ConfigurationPanel.java
@@ -150,8 +150,7 @@ public class ConfigurationPanel
JCheckBox defaultIntraRefreshCheckBox
= new SIPCommCheckBox(
r.getI18NString(
- "impl.neomedia.configform.H264"
- + ".defaultIntraRefresh"));
+ "impl.neomedia.configform.H264.defaultIntraRefresh"));
cnstrnts.gridwidth = GridBagConstraints.REMAINDER;
cnstrnts.gridx = 0;
cnstrnts.gridy = 3;
diff --git a/src/net/java/sip/communicator/impl/netaddr/netaddr.manifest.mf b/src/net/java/sip/communicator/impl/netaddr/netaddr.manifest.mf
index f02d7e4..935ff09 100644
--- a/src/net/java/sip/communicator/impl/netaddr/netaddr.manifest.mf
+++ b/src/net/java/sip/communicator/impl/netaddr/netaddr.manifest.mf
@@ -12,21 +12,16 @@ Import-Package: org.jitsi.service.configuration,
net.java.sip.communicator.service.sysactivity,
net.java.sip.communicator.service.sysactivity.event,
org.osgi.framework,
+ org.ice4j,
+ org.ice4j.ice,
+ org.ice4j.ice.harvest,
+ org.ice4j.security,
org.ice4j.stack,
org.xml.sax,
org.xml.sax.helpers,
javax.crypto,
javax.crypto.spec,
- javax.sdp,
- gov.nist.javax.sdp.fields,
com.sun.jna,
com.sun.jna.ptr
Export-Package: net.java.sip.communicator.service.netaddr,
- net.java.sip.communicator.service.netaddr.event,
- org.ice4j,
- org.ice4j.socket,
- org.ice4j.stack,
- org.ice4j.ice,
- org.ice4j.ice.harvest,
- org.ice4j.ice.sdp,
- org.ice4j.security
+ net.java.sip.communicator.service.netaddr.event
diff --git a/src/net/java/sip/communicator/impl/osdependent/Desktop.java b/src/net/java/sip/communicator/impl/osdependent/Desktop.java
index 885dd02..53728e8 100644
--- a/src/net/java/sip/communicator/impl/osdependent/Desktop.java
+++ b/src/net/java/sip/communicator/impl/osdependent/Desktop.java
@@ -22,6 +22,7 @@ import java.io.*;
import java.lang.reflect.*;
import java.net.*;
+import net.java.sip.communicator.impl.osdependent.systemtray.SystemTray;
import net.java.sip.communicator.util.Logger;
/**
diff --git a/src/net/java/sip/communicator/impl/osdependent/PopupMessageHandlerTrayIconImpl.java b/src/net/java/sip/communicator/impl/osdependent/PopupMessageHandlerTrayIconImpl.java
index 7416b75..592e5af 100644
--- a/src/net/java/sip/communicator/impl/osdependent/PopupMessageHandlerTrayIconImpl.java
+++ b/src/net/java/sip/communicator/impl/osdependent/PopupMessageHandlerTrayIconImpl.java
@@ -19,6 +19,7 @@ package net.java.sip.communicator.impl.osdependent;
import java.awt.event.*;
+import net.java.sip.communicator.impl.osdependent.systemtray.TrayIcon;
import net.java.sip.communicator.service.systray.*;
import net.java.sip.communicator.service.systray.event.*;
diff --git a/src/net/java/sip/communicator/impl/osdependent/SystemTray.java b/src/net/java/sip/communicator/impl/osdependent/SystemTray.java
deleted file mode 100644
index 0c0a4a2..0000000
--- a/src/net/java/sip/communicator/impl/osdependent/SystemTray.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.osdependent;
-
-import java.awt.*;
-import java.lang.reflect.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.impl.osdependent.TrayIcon.AWTTrayIconPeer;
-import net.java.sip.communicator.impl.osdependent.TrayIcon.TrayIconPeer;
-import net.java.sip.communicator.util.*;
-
-/**
- * @author Lubomir Marinov
- */
-public class SystemTray
-{
- /**
- * The <tt>Logger</tt> used by the <tt>SystemTray</tt> class and its
- * instances for logging output.
- */
- private static final Logger logger = Logger.getLogger(SystemTray.class);
-
- private static SystemTray defaultSystemTray;
-
- public static SystemTray getDefaultSystemTray()
- throws UnsupportedOperationException,
- HeadlessException,
- SecurityException
- {
- if (defaultSystemTray != null)
- return defaultSystemTray;
-
- Class<?> awtSystemTrayClass = null;
- try
- {
- awtSystemTrayClass = Class.forName("java.awt.SystemTray");
- }
- catch (ClassNotFoundException ex)
- {
- // We'll try org.jdesktop.jdic.tray then.
- }
- SystemTrayPeer peer = null;
- if (awtSystemTrayClass != null)
- try
- {
- peer = new AWTSystemTrayPeer(awtSystemTrayClass);
- }
- catch (Exception ex)
- {
- if(!GraphicsEnvironment.isHeadless())
- logger.error("Failed to initialize java.awt.SystemTray",
- ex);
-
- // We'll try org.jdesktop.jdic.tray then.
- }
- if (peer == null)
- {
- logger.error(
- "Failed to initialize the desktop.tray implementation.");
- throw new UnsupportedOperationException(
- "Failed to initialize the desktop.tray implementation.");
- }
- return (defaultSystemTray = new SystemTray(peer));
- }
-
- private final SystemTrayPeer peer;
-
- private SystemTray(SystemTrayPeer peer)
- {
- this.peer = peer;
- }
-
- public void addTrayIcon(TrayIcon trayIcon)
- throws NullPointerException,
- IllegalArgumentException
- {
- if (peer != null)
- peer.addTrayIcon(trayIcon.getPeer());
- }
-
- SystemTrayPeer getPeer()
- {
- return peer;
- }
-
- public boolean isSwing()
- {
- if (peer != null)
- return getPeer().isSwing();
- return false;
- }
-
- static interface SystemTrayPeer
- {
- void addTrayIcon(TrayIconPeer trayIconPeer)
- throws NullPointerException,
- IllegalArgumentException;
-
- TrayIconPeer createTrayIcon(ImageIcon icon,
- String tooltip,
- Object popup)
- throws IllegalArgumentException,
- UnsupportedOperationException,
- HeadlessException,
- SecurityException;
-
- boolean isSwing();
- }
-
- private static class AWTSystemTrayPeer
- implements SystemTrayPeer
- {
- private final Method addTrayIcon;
-
- private final Object impl;
-
- private final Class<?> trayIconClass;
-
- public AWTSystemTrayPeer(Class<?> clazz)
- throws UnsupportedOperationException,
- HeadlessException,
- SecurityException
- {
- Method getDefaultSystemTray;
- try
- {
- getDefaultSystemTray =
- clazz.getMethod("getSystemTray", (Class<?>[]) null);
- trayIconClass = Class.forName("java.awt.TrayIcon");
- addTrayIcon = clazz.getMethod("add", new Class<?>[]
- { trayIconClass });
- }
- catch (ClassNotFoundException ex)
- {
- throw new UnsupportedOperationException(ex);
- }
- catch (NoSuchMethodException ex)
- {
- throw new UnsupportedOperationException(ex);
- }
-
- try
- {
- impl = getDefaultSystemTray.invoke(null, (Object[]) null);
- }
- catch (IllegalAccessException ex)
- {
- throw new UnsupportedOperationException(ex);
- }
- catch (InvocationTargetException ex)
- {
- throw new UnsupportedOperationException(ex);
- }
- }
-
- public void addTrayIcon(TrayIconPeer trayIconPeer)
- throws NullPointerException,
- IllegalArgumentException
- {
- try
- {
- addTrayIcon.invoke(impl, new Object[]
- { ((AWTTrayIconPeer) trayIconPeer).getImpl() });
- }
- catch (IllegalAccessException ex)
- {
- throw new UndeclaredThrowableException(ex);
- }
- catch (InvocationTargetException ex)
- {
- Throwable cause = ex.getCause();
- if (cause == null)
- throw new UndeclaredThrowableException(ex);
- if (cause instanceof NullPointerException)
- throw (NullPointerException) cause;
- if (cause instanceof IllegalArgumentException)
- throw (IllegalArgumentException) cause;
- throw new UndeclaredThrowableException(cause);
- }
- }
-
- public TrayIconPeer createTrayIcon(ImageIcon icon, String tooltip,
- Object popup)
- throws IllegalArgumentException,
- UnsupportedOperationException,
- HeadlessException,
- SecurityException
- {
- return new AWTTrayIconPeer(trayIconClass, (icon == null) ? null
- : icon.getImage(), tooltip, popup);
- }
-
- public boolean isSwing()
- {
- return false;
- }
- }
-}
diff --git a/src/net/java/sip/communicator/impl/osdependent/TrayIcon.java b/src/net/java/sip/communicator/impl/osdependent/TrayIcon.java
deleted file mode 100644
index 974ed96..0000000
--- a/src/net/java/sip/communicator/impl/osdependent/TrayIcon.java
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.osdependent;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.lang.reflect.*;
-
-import javax.swing.*;
-import javax.swing.event.*;
-
-import net.java.sip.communicator.impl.osdependent.SystemTray.SystemTrayPeer;
-
-import org.jitsi.util.*;
-
-/**
- * @author Lubomir Marinov
- */
-public class TrayIcon
-{
- private final TrayIconPeer peer;
-
- public TrayIcon(ImageIcon icon, String tooltip, Object popup)
- throws IllegalArgumentException,
- UnsupportedOperationException,
- HeadlessException,
- SecurityException
- {
- SystemTrayPeer systemTrayPeer =
- SystemTray.getDefaultSystemTray().getPeer();
- if (systemTrayPeer != null)
- peer = systemTrayPeer.createTrayIcon(icon, tooltip, popup);
- else
- peer = null;
- }
-
- public void addActionListener(ActionListener listener)
- {
- if (peer != null)
- peer.addActionListener(listener);
- }
-
- public void addBalloonActionListener(ActionListener listener)
- {
- if (peer != null)
- peer.addBalloonActionListener(listener);
- }
-
- public void displayMessage(String caption, String text,
- java.awt.TrayIcon.MessageType messageType)
- throws NullPointerException
- {
- if (peer != null)
- peer.displayMessage(caption, text, messageType);
- }
-
- TrayIconPeer getPeer()
- {
- return peer;
- }
-
- public void setIcon(ImageIcon icon) throws NullPointerException
- {
- if (peer != null)
- peer.setIcon(icon);
- }
-
- public void setIconAutoSize(boolean autoSize)
- {
- if (peer != null)
- peer.setIconAutoSize(autoSize);
- }
-
- static interface TrayIconPeer
- {
- void addActionListener(ActionListener listener);
-
- void addBalloonActionListener(ActionListener listener);
-
- void displayMessage(String caption, String text,
- java.awt.TrayIcon.MessageType messageType)
- throws NullPointerException;
-
- void setIcon(ImageIcon icon) throws NullPointerException;
-
- void setIconAutoSize(boolean autoSize);
- }
-
- static class AWTTrayIconPeer
- implements TrayIconPeer
- {
- private final Method addActionListener;
-
- private final Method addMouseListener;
-
- private final Method displayMessage;
-
- private final Object impl;
-
- private final Class<?> messageTypeClass;
-
- private final Method setIcon;
-
- private final Method setIconAutoSize;
-
- public AWTTrayIconPeer(Class<?> clazz, Image image, String tooltip,
- Object popup)
- throws IllegalArgumentException,
- UnsupportedOperationException,
- HeadlessException,
- SecurityException
- {
- Constructor<?> constructor;
- try
- {
- if (popup instanceof JPopupMenu)
- {
- constructor = clazz.getConstructor(new Class<?>[]
- { Image.class, String.class });
- }
- else
- {
- constructor = clazz.getConstructor(new Class<?>[]
- { Image.class, String.class, PopupMenu.class });
- }
- addActionListener =
- clazz.getMethod("addActionListener", new Class<?>[]
- { ActionListener.class });
- addMouseListener =
- clazz.getMethod("addMouseListener", new Class<?>[]
- { MouseListener.class });
- messageTypeClass =
- Class.forName("java.awt.TrayIcon$MessageType");
- displayMessage =
- clazz.getMethod("displayMessage", new Class<?>[]
- { String.class, String.class, messageTypeClass });
- setIcon = clazz.getMethod("setImage", new Class<?>[]
- { Image.class });
- setIconAutoSize =
- clazz.getMethod("setImageAutoSize", new Class<?>[]
- { boolean.class });
- }
- catch (ClassNotFoundException ex)
- {
- throw new UnsupportedOperationException(ex);
- }
- catch (NoSuchMethodException ex)
- {
- throw new UnsupportedOperationException(ex);
- }
-
- try
- {
- if (popup instanceof JPopupMenu)
- {
- impl = constructor.newInstance(
- new Object[] { image, tooltip });
- addMouseListener(new AWTMouseAdapter((JPopupMenu) popup));
- }
- else
- {
- impl = constructor.newInstance(
- new Object[] { image, tooltip, popup });
- }
- }
- catch (IllegalAccessException ex)
- {
- throw new UnsupportedOperationException(ex);
- }
- catch (InstantiationException ex)
- {
- throw new UnsupportedOperationException(ex);
- }
- catch (InvocationTargetException ex)
- {
- Throwable cause = ex.getCause();
- if (cause == null)
- throw new UnsupportedOperationException(ex);
- if (cause instanceof IllegalArgumentException)
- throw (IllegalArgumentException) cause;
- if (cause instanceof UnsupportedOperationException)
- throw (UnsupportedOperationException) cause;
- if (cause instanceof HeadlessException)
- throw (HeadlessException) cause;
- if (cause instanceof SecurityException)
- throw (SecurityException) cause;
- throw new UnsupportedOperationException(cause);
- }
- }
-
- public void addActionListener(ActionListener listener)
- {
- try
- {
- addActionListener.invoke(getImpl(), new Object[]
- { listener });
- }
- catch (IllegalAccessException ex)
- {
- throw new UndeclaredThrowableException(ex);
- }
- catch (InvocationTargetException ex)
- {
- Throwable cause = ex.getCause();
- throw new UndeclaredThrowableException((cause == null) ? ex
- : cause);
- }
- }
-
- public void addMouseListener(MouseListener listener)
- {
- try
- {
- addMouseListener.invoke(getImpl(), new Object[] { listener });
- }
- catch (IllegalAccessException ex)
- {
- throw new UndeclaredThrowableException(ex);
- }
- catch (InvocationTargetException ex)
- {
- Throwable cause = ex.getCause();
- throw new UndeclaredThrowableException((cause == null) ? ex
- : cause);
- }
- }
-
- public void addBalloonActionListener(ActionListener listener)
- {
- // java.awt.TrayIcon doesn't support addBalloonActionListener()
- }
-
- public void displayMessage(String caption, String text,
- java.awt.TrayIcon.MessageType messageType)
- throws NullPointerException
- {
- try
- {
- displayMessage.invoke(getImpl(), new Object[]
- { caption, text, messageType.name() });
- }
- catch (IllegalAccessException ex)
- {
- throw new UndeclaredThrowableException(ex);
- }
- catch (InvocationTargetException ex)
- {
- Throwable cause = ex.getCause();
- if (cause instanceof NullPointerException)
- throw (NullPointerException) cause;
- throw new UndeclaredThrowableException((cause == null) ? ex
- : cause);
- }
- }
-
- public Object getImpl()
- {
- return impl;
- }
-
- public void setIcon(ImageIcon icon) throws NullPointerException
- {
- try
- {
- setIcon.invoke(getImpl(), new Object[]
- { (icon == null) ? null : icon.getImage() });
- }
- catch (IllegalAccessException ex)
- {
- throw new UndeclaredThrowableException(ex);
- }
- catch (InvocationTargetException ex)
- {
- Throwable cause = ex.getCause();
- if (cause instanceof NullPointerException)
- throw (NullPointerException) cause;
- throw new UndeclaredThrowableException((cause == null) ? ex
- : cause);
- }
- }
-
- public void setIconAutoSize(boolean autoSize)
- {
- try
- {
- setIconAutoSize.invoke(getImpl(), new Object[]
- { autoSize });
- }
- catch (IllegalAccessException ex)
- {
- throw new UndeclaredThrowableException(ex);
- }
- catch (InvocationTargetException ex)
- {
- Throwable cause = ex.getCause();
- throw new UndeclaredThrowableException((cause == null) ? ex
- : cause);
- }
- }
- }
-
- /**
- * Extended mouse adapter to show the JPopupMenu in Java 6
- * Based on : http://weblogs.java.net/blog/ixmal/archive/2006/05/using_jpopupmen.html
- * And : http://weblogs.java.net/blog/alexfromsun/archive/2008/02/jtrayicon_updat.html
- *
- * Use a hidden JWindow (JDialog for Windows) to manage the JPopupMenu.
- *
- * @author Damien Roth
- */
- private static class AWTMouseAdapter
- extends MouseAdapter
- {
- private JPopupMenu popup = null;
- private Window hiddenWindow = null;
-
- public AWTMouseAdapter(JPopupMenu p)
- {
- this.popup = p;
- this.popup.addPopupMenuListener(new PopupMenuListener()
- {
- public void popupMenuWillBecomeVisible(PopupMenuEvent e)
- {}
-
- public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
- {
- if (hiddenWindow != null)
- {
- hiddenWindow.dispose();
- hiddenWindow = null;
- }
- }
-
- public void popupMenuCanceled(PopupMenuEvent e)
- {
- if (hiddenWindow != null)
- {
- hiddenWindow.dispose();
- hiddenWindow = null;
- }
- }
- });
- }
-
- @Override
- public void mouseReleased(MouseEvent e)
- {
- showPopupMenu(e);
- }
-
- @Override
- public void mousePressed(MouseEvent e)
- {
- showPopupMenu(e);
- }
-
- private void showPopupMenu(MouseEvent e)
- {
- if (e.isPopupTrigger() && popup != null)
- {
- if (hiddenWindow == null)
- {
- if (OSUtils.IS_WINDOWS)
- {
- hiddenWindow = new JDialog((Frame) null);
- ((JDialog) hiddenWindow).setUndecorated(true);
- }
- else
- hiddenWindow = new JWindow((Frame) null);
-
- hiddenWindow.setAlwaysOnTop(true);
- Dimension size = popup.getPreferredSize();
-
- Point centerPoint = GraphicsEnvironment
- .getLocalGraphicsEnvironment()
- .getCenterPoint();
-
- if(e.getY() > centerPoint.getY())
- hiddenWindow
- .setLocation(e.getX(), e.getY() - size.height);
- else
- hiddenWindow
- .setLocation(e.getX(), e.getY());
-
- hiddenWindow.setVisible(true);
-
- popup.show(
- ((RootPaneContainer)hiddenWindow).getContentPane(),
- 0, 0);
-
- // popup works only for focused windows
- hiddenWindow.toFront();
- }
- }
- }
- }
-}
diff --git a/src/net/java/sip/communicator/impl/osdependent/jdic/StatusSubMenu.java b/src/net/java/sip/communicator/impl/osdependent/jdic/StatusSubMenu.java
index 2d77621..92088fa 100644
--- a/src/net/java/sip/communicator/impl/osdependent/jdic/StatusSubMenu.java
+++ b/src/net/java/sip/communicator/impl/osdependent/jdic/StatusSubMenu.java
@@ -66,7 +66,7 @@ public class StatusSubMenu
* @param swing <tt>true</tt> to represent this instance with a Swing
* <tt>JMenu</tt>; <tt>false</tt> to use an AWT <tt>Menu</tt>
*/
- public StatusSubMenu(boolean swing)
+ public StatusSubMenu(boolean swing, boolean accountMenuSupported)
{
String text = Resources.getString("impl.systray.SET_STATUS");
@@ -86,6 +86,7 @@ public class StatusSubMenu
this.menu = new Menu(text);
}
+ if (accountMenuSupported)
{
String hideAccountStatusSelectorsProperty
= "impl.gui.HIDE_ACCOUNT_STATUS_SELECTORS";
@@ -103,6 +104,10 @@ public class StatusSubMenu
hideAccountStatusSelectorsProperty,
hideAccountStatusSelectors);
}
+ else
+ {
+ hideAccountStatusSelectors = true;
+ }
PresenceStatus offlineStatus = null;
// creates menu item entry for every global status
@@ -116,9 +121,11 @@ public class StatusSubMenu
// initially it is offline
selectItemFromStatus(offlineStatus.getStatus());
- this.addSeparator();
-
- addMenuItem(menu, new GlobalStatusMessageMenu(swing).getMenu());
+ if (accountMenuSupported)
+ {
+ this.addSeparator();
+ addMenuItem(menu, new GlobalStatusMessageMenu(swing).getMenu());
+ }
if(!hideAccountStatusSelectors)
this.addSeparator();
diff --git a/src/net/java/sip/communicator/impl/osdependent/jdic/SystrayServiceJdicImpl.java b/src/net/java/sip/communicator/impl/osdependent/jdic/SystrayServiceJdicImpl.java
index f774b23..0b40798 100644
--- a/src/net/java/sip/communicator/impl/osdependent/jdic/SystrayServiceJdicImpl.java
+++ b/src/net/java/sip/communicator/impl/osdependent/jdic/SystrayServiceJdicImpl.java
@@ -19,20 +19,25 @@ package net.java.sip.communicator.impl.osdependent.jdic;
import java.awt.*;
import java.awt.event.*;
+import java.awt.image.*;
import java.net.*;
+import java.util.HashMap;
+import java.util.Map;
import javax.swing.*;
import javax.swing.event.*;
import net.java.sip.communicator.impl.osdependent.*;
-import net.java.sip.communicator.impl.osdependent.SystemTray;
-import net.java.sip.communicator.impl.osdependent.TrayIcon;
+import net.java.sip.communicator.impl.osdependent.systemtray.SystemTray;
+import net.java.sip.communicator.impl.osdependent.systemtray.TrayIcon;
+import net.java.sip.communicator.impl.osdependent.windows.*;
import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.systray.*;
import net.java.sip.communicator.service.systray.event.*;
import net.java.sip.communicator.util.Logger;
+import org.apache.commons.lang3.tuple.Pair;
import org.jitsi.util.*;
import org.osgi.framework.*;
@@ -51,7 +56,6 @@ import com.apple.eawt.*;
public class SystrayServiceJdicImpl
extends AbstractSystrayService
{
-
/**
* The systray.
*/
@@ -93,10 +97,6 @@ public class SystrayServiceJdicImpl
private ImageIcon logoIconWhite;
- private ImageIcon envelopeIcon;
-
- private ImageIcon envelopeIconWhite;
-
/**
* The dock Icons used only in Mac version
*/
@@ -131,10 +131,9 @@ public class SystrayServiceJdicImpl
super(OsDependentActivator.bundleContext);
SystemTray systray;
-
try
{
- systray = SystemTray.getDefaultSystemTray();
+ systray = SystemTray.getSystemTray();
}
catch (Throwable t)
{
@@ -147,10 +146,39 @@ public class SystrayServiceJdicImpl
logger.error("Failed to create a systray!", t);
}
}
- this.systray = systray;
+ this.systray = systray;
if (this.systray != null)
+ {
initSystray();
+ }
+ }
+
+ @Override
+ public Map<String, String> getSystrayModes()
+ {
+ return new HashMap<String, String>()
+ {{
+ put("disabled", "service.systray.mode.DISABLED");
+ if (java.awt.SystemTray.isSupported())
+ {
+ put("native", "service.systray.mode.NATIVE");
+ }
+
+ if (!OSUtils.IS_MAC && !OSUtils.IS_WINDOWS)
+ {
+ put("appindicator",
+ "service.systray.mode.APPINDICATOR");
+ put("appindicator_static",
+ "service.systray.mode.APPINDICATOR_STATIC");
+ }
+ }};
+ }
+
+ @Override
+ public String getActiveSystrayMode()
+ {
+ return SystemTray.getSystemTrayMode();
}
/**
@@ -187,53 +215,33 @@ public class SystrayServiceJdicImpl
return;
}
- menu = TrayMenuFactory.createTrayMenu(this, systray.isSwing());
+ Pair<Object, Object> createdMenu = TrayMenuFactory.createTrayMenu(
+ this,
+ systray.useSwingPopupMenu(),
+ systray.supportsDynamicMenu());
+ menu = createdMenu.getLeft();
boolean isMac = OSUtils.IS_MAC;
- // If we're running under Windows, we use a special icon without
- // background.
- if (OSUtils.IS_WINDOWS)
- {
- logoIcon = Resources.getImage("service.systray.TRAY_ICON_WINDOWS");
- logoIconOffline = Resources.getImage(
- "service.systray.TRAY_ICON_WINDOWS_OFFLINE");
- logoIconAway = Resources.getImage(
- "service.systray.TRAY_ICON_WINDOWS_AWAY");
- logoIconExtendedAway = Resources.getImage(
- "service.systray.TRAY_ICON_WINDOWS_EXTENDED_AWAY");
- logoIconFFC = Resources.getImage(
- "service.systray.TRAY_ICON_WINDOWS_FFC");
- logoIconDND = Resources.getImage(
- "service.systray.TRAY_ICON_WINDOWS_DND");
- envelopeIcon = Resources.getImage(
- "service.systray.MESSAGE_ICON_WINDOWS");
- }
- /*
- * If we're running under Mac OS X, we use special black and white icons
- * without background.
- */
- else if (isMac)
+ logoIcon = Resources.getImage("service.systray.TRAY_ICON_WINDOWS");
+ logoIconOffline = Resources.getImage(
+ "service.systray.TRAY_ICON_WINDOWS_OFFLINE");
+ logoIconAway = Resources.getImage(
+ "service.systray.TRAY_ICON_WINDOWS_AWAY");
+ logoIconExtendedAway = Resources.getImage(
+ "service.systray.TRAY_ICON_WINDOWS_EXTENDED_AWAY");
+ logoIconFFC = Resources.getImage(
+ "service.systray.TRAY_ICON_WINDOWS_FFC");
+ logoIconDND = Resources.getImage(
+ "service.systray.TRAY_ICON_WINDOWS_DND");
+
+ // If we're running under Mac OS X, we use special black and white
+ // icons without background.
+ if (isMac)
{
logoIcon = Resources.getImage("service.systray.TRAY_ICON_MACOSX");
logoIconWhite = Resources.getImage(
"service.systray.TRAY_ICON_MACOSX_WHITE");
- envelopeIcon = Resources.getImage(
- "service.systray.MESSAGE_ICON_MACOSX");
- envelopeIconWhite = Resources.getImage(
- "service.systray.MESSAGE_ICON_MACOSX_WHITE");
- }
- else
- {
- logoIcon = Resources.getImage("service.systray.TRAY_ICON");
- logoIconOffline = Resources.getImage(
- "service.systray.TRAY_ICON_OFFLINE");
- logoIconAway = Resources.getImage("service.systray.TRAY_ICON_AWAY");
- logoIconExtendedAway = Resources.getImage(
- "service.systray.TRAY_ICON_EXTENDED_AWAY");
- logoIconFFC = Resources.getImage("service.systray.TRAY_ICON_FFC");
- logoIconDND = Resources.getImage("service.systray.TRAY_ICON_DND");
- envelopeIcon = Resources.getImage("service.systray.MESSAGE_ICON");
}
/*
@@ -243,7 +251,7 @@ public class SystrayServiceJdicImpl
currentIcon = isMac ? logoIcon : logoIconOffline;
trayIcon
- = new TrayIcon(
+ = systray.createTrayIcon(
currentIcon,
Resources.getApplicationString(
"service.gui.APPLICATION_NAME"),
@@ -268,21 +276,15 @@ public class SystrayServiceJdicImpl
}
//Show/hide the contact list when user clicks on the systray.
- trayIcon.addActionListener(
- new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- UIService uiService
- = OsDependentActivator.getUIService();
- ExportedWindow mainWindow
- = uiService.getExportedWindow(
- ExportedWindow.MAIN_WINDOW);
- boolean setIsVisible = !mainWindow.isVisible();
-
- uiService.setVisible(setIsVisible);
- }
- });
+ final Object defaultActionItem;
+ if (systray.useSwingPopupMenu())
+ {
+ defaultActionItem = ((JMenuItem) createdMenu.getRight());
+ }
+ else
+ {
+ defaultActionItem = ((MenuItem) createdMenu.getRight());
+ }
/*
* Change the Mac OS X icon with the white one when the pop-up menu
@@ -296,11 +298,7 @@ public class SystrayServiceJdicImpl
{
public void popupMenuWillBecomeVisible(PopupMenuEvent e)
{
- ImageIcon newIcon
- = (currentIcon == envelopeIcon)
- ? envelopeIconWhite
- : logoIconWhite;
-
+ ImageIcon newIcon = logoIconWhite;
trayIcon.setIcon(newIcon);
currentIcon = newIcon;
}
@@ -308,11 +306,7 @@ public class SystrayServiceJdicImpl
public void popupMenuWillBecomeInvisible(
PopupMenuEvent e)
{
- ImageIcon newIcon
- = (currentIcon == envelopeIconWhite)
- ? envelopeIcon
- : logoIcon;
-
+ ImageIcon newIcon = logoIcon;
getTrayIcon().setIcon(newIcon);
currentIcon = newIcon;
}
@@ -353,12 +347,12 @@ public class SystrayServiceJdicImpl
public void run()
{
systray.addTrayIcon(trayIcon);
+ trayIcon.setDefaultAction(defaultActionItem);
}
});
initialized = true;
-
- uiService.setExitOnMainWindowClose(false);
+ uiService.setMainWindowCanHide(true);
}
/**
@@ -402,12 +396,6 @@ public class SystrayServiceJdicImpl
if (!isMac)
systrayIconToSet = logoIconDND;
break;
- case SystrayService.ENVELOPE_IMG_TYPE:
- systrayIconToSet
- = (isMac && TrayMenuFactory.isVisible(menu))
- ? envelopeIconWhite
- : envelopeIcon;
- break;
}
if (systrayIconToSet != null)
@@ -469,14 +457,90 @@ public class SystrayServiceJdicImpl
}
}
- private boolean checkInitialized()
+ @Override
+ public boolean checkInitialized()
{
- if (!initialized)
- logger.error("Systray not init");
return initialized;
}
/**
+ * Set the number of pending notifications to the the application icon
+ * (Dock on OSX, TaskBar on Windows, nothing on Linux currently).
+ */
+ @Override
+ public void setNotificationCount(int count)
+ {
+ if (OSUtils.IS_MAC)
+ {
+ Application application = Application.getApplication();
+ application.setDockIconBadge(new Integer(count).toString());
+ }
+ else if (OSUtils.IS_WINDOWS)
+ {
+ UIService uiService = OsDependentActivator.getUIService();
+ if (uiService == null)
+ {
+ return;
+ }
+
+ ExportedWindow mainWindow =
+ uiService.getExportedWindow(ExportedWindow.MAIN_WINDOW);
+ if (mainWindow == null
+ || !(mainWindow.getSource() instanceof Component))
+ {
+ return;
+ }
+
+ BufferedImage img = null;
+ if (count > 0)
+ {
+ img = createOverlayImage(new Integer(count).toString());
+ }
+
+ try
+ {
+ TaskBarList3.getInstance().SetOverlayIcon(
+ (Component) mainWindow.getSource(), img, null);
+ }
+ catch (Exception ex)
+ {
+ logger.error("Could not set the notification count.", ex);
+ }
+ }
+ }
+
+ private BufferedImage createOverlayImage(String text)
+ {
+ int size = 16;
+ BufferedImage image =
+ new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g = image.createGraphics();
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+
+ //background
+ g.setPaint(new Color(0, 0, 0, 102));
+ g.fillRoundRect(0, 0, size, size, size, size);
+
+ //filling
+ int mainRadius = 14;
+ g.setPaint(new Color(255, 98, 89));
+ g.fillRoundRect(size / 2 - mainRadius / 2, size / 2 - mainRadius / 2,
+ mainRadius, mainRadius, size, size);
+
+ //text
+ Font font = g.getFont();
+ g.setFont(new Font(font.getName(), Font.BOLD, 9));
+ FontMetrics fontMetrics = g.getFontMetrics();
+ int textWidth = fontMetrics.stringWidth(text);
+ g.setColor(Color.white);
+ g.drawString(text, size / 2 - textWidth / 2,
+ size / 2 - fontMetrics.getHeight() / 2 + fontMetrics.getAscent());
+
+ return image;
+ }
+
+ /**
* @return the trayIcon
*/
public TrayIcon getTrayIcon()
@@ -551,7 +615,7 @@ public class SystrayServiceJdicImpl
OsDependentActivator.bundleContext.removeServiceListener(
this);
- if (!initialized)
+ if (!initialized && systray != null)
initSystray();
}
}
diff --git a/src/net/java/sip/communicator/impl/osdependent/jdic/TrayMenuFactory.java b/src/net/java/sip/communicator/impl/osdependent/jdic/TrayMenuFactory.java
index 2b5df19..cae3ada 100644
--- a/src/net/java/sip/communicator/impl/osdependent/jdic/TrayMenuFactory.java
+++ b/src/net/java/sip/communicator/impl/osdependent/jdic/TrayMenuFactory.java
@@ -26,6 +26,7 @@ import javax.swing.event.*;
import net.java.sip.communicator.impl.osdependent.*;
import net.java.sip.communicator.service.gui.*;
+import org.apache.commons.lang3.tuple.*;
import org.jitsi.util.*;
/**
@@ -139,16 +140,16 @@ public final class TrayMenuFactory
*
* @param tray the system tray for which we're creating a menu
* @param swing indicates if we should create a Swing or an AWT menu
- * @return a tray menu for the given system tray
+ * @return a tray menu for the given system tray (first) and the default
+ * menu item (second)
*/
- public static Object createTrayMenu(SystrayServiceJdicImpl tray,
- boolean swing)
+ public static Pair<Object, Object> createTrayMenu(
+ SystrayServiceJdicImpl tray,
+ boolean swing,
+ boolean accountMenuSupported
+ )
{
- // Enable swing for java 1.6 except for the mac version
- if (!swing && !OSUtils.IS_MAC)
- swing = true;
-
- Object trayMenu = swing ? new JPopupMenu() : new PopupMenu();
+ final Object trayMenu = swing ? new JPopupMenu() : new PopupMenu();
ActionListener listener = new ActionListener()
{
public void actionPerformed(ActionEvent event)
@@ -184,9 +185,11 @@ public final class TrayMenuFactory
+ "CHAT_PRESENCE_DISABLED",
false);
- if (!chatPresenceDisabled.booleanValue())
+ if (!chatPresenceDisabled.booleanValue() && accountMenuSupported)
{
- add(trayMenu, new StatusSubMenu(swing).getMenu());
+ add(
+ trayMenu,
+ new StatusSubMenu(swing, accountMenuSupported).getMenu());
addSeparator(trayMenu);
}
@@ -201,9 +204,11 @@ public final class TrayMenuFactory
showHideIconId = "service.gui.icons.SEARCH_ICON_16x16";
}
else
+ {
showHideName = "service.gui.SHOW";
showHideTextId = "service.gui.SHOW";
showHideIconId = "service.gui.icons.SEARCH_ICON_16x16";
+ }
final Object showHideMenuItem = createTrayMenuItem( showHideName,
showHideTextId,
@@ -245,7 +250,7 @@ public final class TrayMenuFactory
}
});
- return trayMenu;
+ return Pair.of(trayMenu, showHideMenuItem);
}
/**
diff --git a/src/net/java/sip/communicator/impl/osdependent/osdependent.manifest.mf b/src/net/java/sip/communicator/impl/osdependent/osdependent.manifest.mf
index 0db99ad..91f2791 100644
--- a/src/net/java/sip/communicator/impl/osdependent/osdependent.manifest.mf
+++ b/src/net/java/sip/communicator/impl/osdependent/osdependent.manifest.mf
@@ -5,26 +5,29 @@ Bundle-Vendor: jitsi.org
Bundle-Version: 0.0.1
Bundle-SymbolicName: net.java.sip.communicator.osdependent
Export-Package: net.java.sip.communicator.service.desktop
-Import-Package: org.osgi.framework,
- com.apple.cocoa.application,
+Import-Package: com.apple.cocoa.application,
com.apple.cocoa.foundation,
com.apple.eawt,
- org.jitsi.service.configuration,
+ com.sun.jna,
+ com.sun.jna.platform.win32,
+ com.sun.jna.platform.win32.COM,
+ com.sun.jna.ptr,
+ com.sun.jna.win32,
net.java.sip.communicator.service.gui,
net.java.sip.communicator.service.gui.event,
net.java.sip.communicator.service.protocol,
net.java.sip.communicator.service.protocol.globalstatus,
net.java.sip.communicator.service.protocol.event,
- org.jitsi.service.resources, net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.service.resources,
net.java.sip.communicator.service.shutdown,
net.java.sip.communicator.service.systray,
net.java.sip.communicator.service.systray.event,
- org.jitsi.util,
net.java.sip.communicator.util,
net.java.sip.communicator.plugin.desktoputil,
net.java.sip.communicator.plugin.desktoputil.presence,
javax.accessibility,
javax.imageio,
+ javax.imageio.stream,
javax.swing,
javax.swing.border,
javax.swing.event,
@@ -36,4 +39,9 @@ Import-Package: org.osgi.framework,
javax.swing.text,
javax.swing.text.html,
javax.swing.tree,
- javax.swing.undo
+ javax.swing.undo,
+ org.apache.commons.lang3.tuple,
+ org.jitsi.service.configuration,
+ org.jitsi.service.resources,
+ org.jitsi.util,
+ org.osgi.framework
diff --git a/src/net/java/sip/communicator/impl/osdependent/systemtray/SystemTray.java b/src/net/java/sip/communicator/impl/osdependent/systemtray/SystemTray.java
new file mode 100644
index 0000000..818d1e7
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/osdependent/systemtray/SystemTray.java
@@ -0,0 +1,156 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.osdependent.systemtray;
+
+import java.awt.*;
+
+import javax.swing.*;
+
+import org.jitsi.util.*;
+
+import net.java.sip.communicator.impl.osdependent.*;
+import net.java.sip.communicator.impl.osdependent.systemtray.appindicator.*;
+import net.java.sip.communicator.impl.osdependent.systemtray.awt.*;
+import net.java.sip.communicator.service.systray.*;
+import net.java.sip.communicator.util.Logger;
+
+/**
+ * Base class for all wrappers of <tt>SystemTray</tt> implementations.
+ */
+public abstract class SystemTray
+{
+ private static final Logger logger = Logger.getLogger(SystemTray.class);
+ private static SystemTray systemTray;
+ private static final String DISABLED_TRAY_MODE = "disabled";
+
+ /**
+ * Gets or creates the supported <tt>SystemTray</tt> implementations.
+ * @return a <tt>SystemTray</tt> implementation for the current platform.
+ */
+ public final static SystemTray getSystemTray()
+ {
+ if (systemTray == null)
+ {
+ String mode = getSystemTrayMode();
+ logger.info("Tray for " + mode + " requested");
+ switch (mode)
+ {
+ case DISABLED_TRAY_MODE:
+ return null;
+ case "native":
+ if (java.awt.SystemTray.isSupported())
+ {
+ systemTray = new AWTSystemTray();
+ }
+
+ break;
+ case "appindicator":
+ try
+ {
+ systemTray = new AppIndicatorTray(true);
+ }
+ catch(Exception ex)
+ {
+ logger.error("AppIndicator tray not available", ex);
+ }
+ break;
+ case "appindicator_static":
+ try
+ {
+ systemTray = new AppIndicatorTray(false);
+ }
+ catch(Exception ex)
+ {
+ logger.error("AppIndicator tray not available", ex);
+ }
+
+ break;
+ }
+
+ if (systemTray == null)
+ {
+ OsDependentActivator.getConfigurationService()
+ .setProperty(SystrayService.PNMAE_TRAY_MODE, "disabled");
+ }
+ }
+
+ return systemTray;
+ }
+
+ public static String getSystemTrayMode()
+ {
+ String defaultTrayMode = DISABLED_TRAY_MODE;
+ if (GraphicsEnvironment.isHeadless())
+ {
+ return DISABLED_TRAY_MODE;
+ }
+
+ // setting from cmd-line: request to disable tray in case it failed
+ if (Boolean.getBoolean("disable-tray"))
+ {
+ OsDependentActivator.getConfigurationService().setProperty(
+ SystrayService.PNMAE_TRAY_MODE, DISABLED_TRAY_MODE);
+ }
+
+ if (OSUtils.IS_WINDOWS || OSUtils.IS_MAC)
+ {
+ defaultTrayMode = "native";
+ }
+
+ return OsDependentActivator.getConfigurationService()
+ .getString(SystrayService.PNMAE_TRAY_MODE, defaultTrayMode);
+ }
+
+ /**
+ * Adds a <tt>TrayIcon</tt> to this system tray implementation.
+ *
+ * @param trayIcon the <tt>TrayIcon</tt> to add
+ */
+ public abstract void addTrayIcon(TrayIcon trayIcon);
+
+ /**
+ * Creates an implementation specific <tt>TrayIcon</tt> that can later be
+ * added with {@link #addTrayIcon(TrayIcon)}.
+ *
+ * @param image the <tt>Image</tt> to be used
+ * @param tooltip the string to be used as tooltip text; if the value is
+ * <tt>null</tt> no tooltip is shown
+ * @param popup the menu to be used for the tray icon's popup menu; if the
+ * value is <tt>null</tt> no popup menu is shown
+ * @return a <tt>TrayIcon</tt> instance for this <tt>SystemTray</tt>
+ * implementation.
+ */
+ public abstract TrayIcon createTrayIcon(ImageIcon icon, String tooltip,
+ Object popup);
+
+ /**
+ * Determines if the popup menu for the icon is to be a Swing
+ * <tt>JPopupMenu</tt> or an AWT <tt>PopupMenu</tt>
+ *
+ * @return <tt>true</tt> for a <tt>JPopupMenu</tt>, <tt>false</tt> for a
+ * <tt>PopupMenu</tt>
+ */
+ public abstract boolean useSwingPopupMenu();
+
+ /**
+ * Determines if the tray icon supports dynamic menus.
+ *
+ * @return True if the menu can be changed while running, false otherwise.
+ */
+ public abstract boolean supportsDynamicMenu();
+}
diff --git a/src/net/java/sip/communicator/impl/dns/UnboundException.java b/src/net/java/sip/communicator/impl/osdependent/systemtray/TrayIcon.java
index 3eb2a04..78df44c 100644
--- a/src/net/java/sip/communicator/impl/dns/UnboundException.java
+++ b/src/net/java/sip/communicator/impl/osdependent/systemtray/TrayIcon.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,28 +15,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.dns;
-
-/**
- * Exception that is being thrown when native Unbound code resulted in an error.
- *
- * @author Ingo Bauersachs
- */
-public class UnboundException
- extends Exception
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * Creates a new instance of this class.
- *
- * @param message the detail message.
- */
- public UnboundException(String message)
- {
- super(message);
- }
-}
+package net.java.sip.communicator.impl.osdependent.systemtray;
+
+import java.awt.event.*;
+
+import javax.swing.*;
+
+/**
+ * Interface for all platform specific TrayIcon implementations. See
+ * {@link java.awt.TrayIcon} for a description of the methods.
+ *
+ * @author Lubomir Marinov
+ */
+public interface TrayIcon
+{
+ public void setDefaultAction(Object menuItem);
+
+ public void addBalloonActionListener(ActionListener listener);
+
+ public void displayMessage(String caption, String text,
+ java.awt.TrayIcon.MessageType messageType);
+
+ public void setIcon(ImageIcon icon) throws NullPointerException;
+
+ public void setIconAutoSize(boolean autoSize);
+}
diff --git a/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicator1.java b/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicator1.java
new file mode 100644
index 0000000..85fbd73
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicator1.java
@@ -0,0 +1,189 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.osdependent.systemtray.appindicator;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.*;
+
+/**
+ * JNA mappings for libappindicator1.
+ *
+ * @author Ingo Bauersachs
+ */
+interface AppIndicator1 extends Library
+{
+ static final AppIndicator1 INSTANCE =
+ (AppIndicator1) Native.loadLibrary("appindicator", AppIndicator1.class);
+
+ static final String APP_INDICATOR_SIGNAL_NEW_ICON = "new-icon";
+ static final String APP_INDICATOR_SIGNAL_NEW_ATTENTION_ICON = "new-attention-icon";
+ static final String APP_INDICATOR_SIGNAL_NEW_STATUS = "new-status";
+ static final String APP_INDICATOR_SIGNAL_NEW_LABEL = "new-label";
+ static final String APP_INDICATOR_SIGNAL_CONNECTION_CHANGED = "connection-changed";
+ static final String APP_INDICATOR_SIGNAL_NEW_ICON_THEME_PATH = "new-icon-theme-path";
+ static final String APP_INDICATOR_SIGNAL_SCROLL_EVENT = "scroll-event";
+
+ /**
+ * The category provides grouping for the indicators so that users can find
+ * indicators that are similar together.
+ */
+ enum APP_INDICATOR_CATEGORY
+ {
+ /** The indicator is used to display the status of the application. */
+ APPLICATION_STATUS,
+
+ /** The application is used for communication with other people. */
+ COMMUNICATIONS,
+
+ /** A system indicator relating to something in the user's system. */
+ SYSTEM_SERVICES,
+
+ /** An indicator relating to the user's hardware. */
+ HARDWARE,
+
+ /**
+ * Something not defined in this enum, please don't use unless you
+ * really need it.
+ */
+ OTHER
+ }
+
+ /**
+ * These are the states that the indicator can be on in the user's panel.
+ * The indicator by default starts in the state {@link #PASSIVE} and can be
+ * shown by setting it to {@link #ACTIVE}.
+ */
+ enum APP_INDICATOR_STATUS
+ {
+ /** The indicator should not be shown to the user. */
+ PASSIVE,
+
+ /** The indicator should be shown in it's default state. */
+ ACTIVE,
+
+ /** The indicator should show it's attention icon. */
+ ATTENTION
+ }
+
+ class AppIndicatorClass extends Structure
+ {
+ // Parent
+ public /*Gobject.GObjectClass*/ Pointer parent_class;
+
+ // DBus Signals
+ public Pointer new_icon;
+ public Pointer new_attention_icon;
+ public Pointer new_status;
+ public Pointer new_icon_theme_path;
+ public Pointer new_label;
+
+ // Local Signals
+ public Pointer connection_changed;
+ public Pointer scroll_event;
+ public Pointer app_indicator_reserved_ats;
+
+ // Overridable Functions
+ public Pointer fallback;
+ public Pointer unfallback;
+
+ // Reserved
+ public Pointer app_indicator_reserved_1;
+ public Pointer app_indicator_reserved_2;
+ public Pointer app_indicator_reserved_3;
+ public Pointer app_indicator_reserved_4;
+ public Pointer app_indicator_reserved_5;
+ public Pointer app_indicator_reserved_6;
+
+ @Override
+ protected List getFieldOrder() {
+ return Arrays.asList(
+ "parent_class",
+ "new_icon",
+ "new_attention_icon",
+ "new_status",
+ "new_icon_theme_path",
+ "new_label",
+
+ "connection_changed",
+ "scroll_event",
+ "app_indicator_reserved_ats",
+
+ "fallback",
+ "unfallback",
+
+ "app_indicator_reserved_1",
+ "app_indicator_reserved_2",
+ "app_indicator_reserved_3",
+ "app_indicator_reserved_4",
+ "app_indicator_reserved_5",
+ "app_indicator_reserved_6");
+ }
+ }
+
+ class AppIndicator extends Structure
+ {
+ public /*Gobject.GObject*/ Pointer parent;
+ public Pointer priv;
+
+ @Override
+ protected List getFieldOrder()
+ {
+ return Arrays.asList("parent", "priv");
+ }
+ }
+
+ // GObject Stuff
+ NativeLong app_indicator_get_type();
+ AppIndicator app_indicator_new(String id, String icon_name, int category);
+ AppIndicator app_indicator_new_with_path(String id, String icon_name, int category, String icon_theme_path);
+
+ // Set properties
+ void app_indicator_set_status(AppIndicator self, int status);
+ void app_indicator_set_attention_icon(AppIndicator self, String icon_name);
+ void app_indicator_set_attention_icon_full(AppIndicator self, String name, String icon_desc);
+ void app_indicator_set_menu(AppIndicator self, Pointer menu);
+ void app_indicator_set_icon(AppIndicator self, String icon_name);
+ void app_indicator_set_icon_full(AppIndicator self, String icon_name, String icon_desc);
+ void app_indicator_set_label(AppIndicator self, String label, String guide);
+ void app_indicator_set_icon_theme_path(AppIndicator self, String icon_theme_path);
+ void app_indicator_set_ordering_index(AppIndicator self, int ordering_index);
+ void app_indicator_set_secondary_activate_target(AppIndicator self, Pointer menuitem);
+ void app_indicator_set_title(AppIndicator self, String title);
+
+ // Get properties
+ String app_indicator_get_id(AppIndicator self);
+ int app_indicator_get_category(AppIndicator self);
+ int app_indicator_get_status(AppIndicator self);
+ String app_indicator_get_icon(AppIndicator self);
+ String app_indicator_get_icon_desc(AppIndicator self);
+ String app_indicator_get_icon_theme_path(AppIndicator self);
+ String app_indicator_get_attention_icon(AppIndicator self);
+ String app_indicator_get_attention_icon_desc(AppIndicator self);
+ String app_indicator_get_title(AppIndicator self);
+
+ Pointer app_indicator_get_menu(AppIndicator self);
+ String app_indicator_get_label(AppIndicator self);
+ String app_indicator_get_label_guide(AppIndicator self);
+ int app_indicator_get_ordering_index(AppIndicator self);
+ Pointer app_indicator_get_secondary_activate_target(AppIndicator self, Pointer widget);
+
+ // Helpers
+ void app_indicator_build_menu_from_desktop(AppIndicator self, String desktop_file, String destkop_profile);
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicatorTray.java b/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicatorTray.java
new file mode 100644
index 0000000..90c949a
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicatorTray.java
@@ -0,0 +1,78 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.osdependent.systemtray.appindicator;
+
+import javax.swing.*;
+
+import org.jitsi.util.*;
+
+import net.java.sip.communicator.impl.osdependent.*;
+import net.java.sip.communicator.impl.osdependent.systemtray.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Jitsi system tray abstraction for libappindicator.
+ *
+ * @author Ingo Bauersachs
+ */
+public class AppIndicatorTray extends SystemTray
+{
+ private boolean dynamicMenu;
+
+ public AppIndicatorTray(boolean dynamicMenu) throws Exception
+ {
+ this.dynamicMenu = dynamicMenu;
+ try
+ {
+ // pre-initialize the JNA libraries before attempting to use them
+ AppIndicator1.INSTANCE.toString();
+ Gtk.INSTANCE.toString();
+ Gobject.INSTANCE.toString();
+ Gtk.INSTANCE.gtk_init(0, null);
+ }
+ catch (Throwable t)
+ {
+ throw new Exception("AppIndicator1 tray icon not available", t);
+ }
+ }
+
+ @Override
+ public void addTrayIcon(TrayIcon trayIcon)
+ {
+ ((AppIndicatorTrayIcon) trayIcon).createTray();
+ }
+
+ @Override
+ public TrayIcon createTrayIcon(ImageIcon icon, String tooltip, Object popup)
+ {
+ return new AppIndicatorTrayIcon(icon, tooltip, (JPopupMenu) popup);
+ }
+
+ @Override
+ public boolean useSwingPopupMenu()
+ {
+ // we want icons
+ return true;
+ }
+
+ @Override
+ public boolean supportsDynamicMenu()
+ {
+ return dynamicMenu;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicatorTrayIcon.java b/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicatorTrayIcon.java
new file mode 100644
index 0000000..12334f3
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicatorTrayIcon.java
@@ -0,0 +1,695 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.osdependent.systemtray.appindicator;
+
+import java.awt.*;
+import java.awt.TrayIcon.*;
+import java.awt.event.*;
+import java.awt.image.BufferedImage;
+import java.beans.*;
+import java.io.*;
+import java.net.*;
+import java.nio.file.*;
+import java.util.*;
+import java.util.List;
+import java.util.Timer;
+
+import javax.accessibility.*;
+import javax.imageio.*;
+import javax.imageio.stream.*;
+import javax.print.attribute.standard.*;
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import org.jitsi.util.*;
+import org.jitsi.util.Logger;
+
+import com.sun.jna.*;
+
+import net.java.sip.communicator.impl.osdependent.*;
+import net.java.sip.communicator.impl.osdependent.systemtray.*;
+import net.java.sip.communicator.impl.osdependent.systemtray.TrayIcon;
+import net.java.sip.communicator.impl.osdependent.systemtray.appindicator.Gobject.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * System tray icon implementation based on libappindicator1.
+ *
+ * @author Ingo Bauersachs
+ */
+class AppIndicatorTrayIcon implements TrayIcon
+{
+ private static final Logger logger =
+ Logger.getLogger(AppIndicatorTrayIcon.class);
+
+ // shortcuts
+ private static Gobject gobject = Gobject.INSTANCE;
+ private static Gtk gtk = Gtk.INSTANCE;
+ private static AppIndicator1 ai = AppIndicator1.INSTANCE;
+
+ // references to the root menu and the native icon
+ private ImageIcon mainIcon;
+ private String title;
+ private JPopupMenu popup;
+ private Map<String, String> extractedFiles = new HashMap<>();
+ private PopupMenuPeer popupPeer;
+ private AppIndicator1.AppIndicator appIndicator;
+
+ private PopupMenuPeer defaultMenuPeer;
+
+ public AppIndicatorTrayIcon(ImageIcon mainIcon, String title,
+ JPopupMenu popup)
+ {
+ this.mainIcon = mainIcon;
+ this.title = title;
+ this.popup = popup;
+ this.popupPeer = null;
+ }
+
+ /**
+ * Combines the references of each swing menu item with the GTK counterpart
+ */
+ private class PopupMenuPeer implements ContainerListener
+ {
+ public PopupMenuPeer(PopupMenuPeer parent, Component em)
+ {
+ menuItem = em;
+
+ // if this menu item is a submenu, add ourselves as listener to
+ // add or remove the native counterpart
+ if (em instanceof JMenu)
+ {
+ ((JMenu)em).getPopupMenu().addContainerListener(this);
+ ((JMenu)em).addContainerListener(this);
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable
+ {
+ super.finalize();
+ if (isDefaultMenuItem)
+ {
+ gobject.g_object_unref(gtkMenuItem);
+ }
+ }
+
+ public List<PopupMenuPeer> children = new ArrayList<>();
+ public Pointer gtkMenuItem;
+ public Pointer gtkMenu;
+ public Pointer gtkImage;
+ public Memory gtkImageBuffer;
+ public Pointer gtkPixbuf;
+ public Component menuItem;
+ public MenuItemSignalHandler signalHandler;
+ public long gtkSignalHandler;
+ public boolean isDefaultMenuItem;
+
+ @Override
+ public void componentAdded(ContainerEvent e)
+ {
+ AppIndicatorTrayIcon.this.printMenu(popup.getComponents(), 1);
+ gtk.gdk_threads_enter();
+ try
+ {
+ createGtkMenuItems(this, new Component[]{e.getChild()});
+ gtk.gtk_widget_show_all(popupPeer.gtkMenu);
+ }
+ finally
+ {
+ gtk.gdk_threads_leave();
+ }
+ }
+
+ @Override
+ public void componentRemoved(ContainerEvent e)
+ {
+ AppIndicatorTrayIcon.this.printMenu(popup.getComponents(), 1);
+ for (PopupMenuPeer c : children)
+ {
+ if (c.menuItem == e.getChild())
+ {
+ gtk.gdk_threads_enter();
+ try
+ {
+ cleanMenu(c);
+ }
+ finally
+ {
+ gtk.gdk_threads_leave();
+ }
+
+ children.remove(c);
+ break;
+ }
+ }
+ }
+ }
+
+ public void createTray()
+ {
+ gtk.gdk_threads_enter();
+ try
+ {
+ setupGtkMenu();
+ }
+ finally
+ {
+ gtk.gdk_threads_leave();
+ }
+
+ new Thread()
+ {
+ public void run()
+ {
+ gtk.gtk_main();
+ }
+ }.start();
+ }
+
+ private void setupGtkMenu()
+ {
+ File iconFile = new File(imageIconToPath(mainIcon));
+ appIndicator = ai.app_indicator_new_with_path(
+ "jitsi",
+ iconFile.getName().replaceFirst("[.][^.]+$", ""),
+ AppIndicator1.APP_INDICATOR_CATEGORY.COMMUNICATIONS.ordinal(),
+ iconFile.getParent());
+
+ ai.app_indicator_set_title(appIndicator, title);
+ ai.app_indicator_set_icon_full(
+ appIndicator,
+ iconFile.getAbsolutePath(),
+ "Jitsi");
+
+ // create root menu
+ popupPeer = new PopupMenuPeer(null, popup);
+ popupPeer.gtkMenu = gtk.gtk_menu_new();
+
+ // transfer everything in the swing menu to the gtk menu
+ createGtkMenuItems(popupPeer, popup.getComponents());
+ gtk.gtk_widget_show_all(popupPeer.gtkMenu);
+
+ // attach the menu to the indicator
+ ai.app_indicator_set_menu(appIndicator, popupPeer.gtkMenu);
+ ai.app_indicator_set_status(
+ appIndicator,
+ AppIndicator1.APP_INDICATOR_STATUS.ACTIVE.ordinal());
+ }
+
+ private void cleanMenu(PopupMenuPeer peer)
+ {
+ assert !peer.isDefaultMenuItem;
+ for (PopupMenuPeer p : peer.children)
+ {
+ cleanMenu(p);
+ }
+
+ // - the root menu is released when it's unset from the indicator
+ // - gtk auto-frees menu item, submenu, image, and pixbuf
+ // - the imagebuffer was jna allocated, GC should take care of freeing
+ if (peer.gtkSignalHandler > 0)
+ {
+ gobject.g_signal_handler_disconnect(
+ peer.gtkMenuItem,
+ peer.gtkSignalHandler);
+ }
+
+ gtk.gtk_widget_destroy(peer.gtkMenuItem);
+ peer.gtkImageBuffer = null;
+ if (peer.menuItem instanceof JMenu)
+ {
+ ((JMenu)peer.menuItem).removeContainerListener(peer);
+ ((JMenu)peer.menuItem).getPopupMenu().removeContainerListener(peer);
+ }
+ }
+
+ private void createGtkMenuItems(
+ PopupMenuPeer parent,
+ Component[] components)
+ {
+ for (Component em : components)
+ {
+ PopupMenuPeer peer = new PopupMenuPeer(parent, em);
+ if (em instanceof JPopupMenu.Separator)
+ {
+ logger.debug("Creating separator");
+ peer.gtkMenuItem = gtk.gtk_separator_menu_item_new();
+ }
+
+ if (em instanceof JMenuItem)
+ {
+ createGtkMenuItem(peer);
+ }
+
+ if (em instanceof JMenu && peer.gtkMenuItem != null)
+ {
+ JMenu m = (JMenu)em;
+ logger.debug("Creating submenu on " + m.getText());
+ peer.gtkMenu = gtk.gtk_menu_new();
+ createGtkMenuItems(peer, m.getMenuComponents());
+ gtk.gtk_menu_item_set_submenu(peer.gtkMenuItem, peer.gtkMenu);
+ }
+
+ if (peer.gtkMenuItem != null)
+ {
+ parent.children.add(peer);
+ gtk.gtk_menu_shell_append(parent.gtkMenu, peer.gtkMenuItem);
+ }
+ }
+ }
+
+ private void createGtkMenuItem(PopupMenuPeer peer)
+ {
+ JMenuItem m = (JMenuItem)peer.menuItem;
+ logger.debug("Creating item for " + m.getClass().getName() + ": "
+ + m.getText());
+ if (m instanceof JCheckBoxMenuItem)
+ {
+ peer.gtkMenuItem = gtk.gtk_check_menu_item_new_with_label(
+ m.getText());
+ JCheckBoxMenuItem cb = (JCheckBoxMenuItem)m;
+ gtk.gtk_check_menu_item_set_active(
+ peer.gtkMenuItem,
+ cb.isSelected() ? 1 : 0);
+ }
+ else
+ {
+ peer.gtkMenuItem = gtk.gtk_image_menu_item_new_with_label(
+ m.getText());
+ if (m.getIcon() instanceof ImageIcon)
+ {
+ ImageIcon ii = ((ImageIcon) m.getIcon());
+ imageIconToGtkWidget(peer, ii);
+ if (peer.gtkImage != null)
+ {
+ gtk.gtk_image_menu_item_set_image(
+ peer.gtkMenuItem,
+ peer.gtkImage);
+ gtk.gtk_image_menu_item_set_always_show_image(
+ peer.gtkMenuItem,
+ 1);
+ }
+ }
+ }
+
+ if (peer.gtkMenuItem == null)
+ {
+ logger.debug("Could not create menu item for " + m.getText());
+ return;
+ }
+
+ MenuItemChangeListener micl = new MenuItemChangeListener(peer);
+ m.addPropertyChangeListener(micl);
+ m.addChangeListener(micl);
+
+ // skip GTK events if it's a submenu
+ if (!(m instanceof JMenu))
+ {
+ gtk.gtk_widget_set_sensitive(
+ peer.gtkMenuItem,
+ m.isEnabled() ? 1 : 0);
+ peer.signalHandler = new MenuItemSignalHandler(peer);
+ peer.gtkSignalHandler = gobject.g_signal_connect_data(
+ peer.gtkMenuItem,
+ "activate",
+ peer.signalHandler,
+ null,
+ null,
+ 0);
+ }
+ }
+
+ private String imageIconToPath(ImageIcon ii)
+ {
+ if (ii.getDescription() != null)
+ {
+ String path = extractedFiles.get(ii.getDescription());
+ if (path != null)
+ {
+ return path;
+ }
+ }
+
+ try
+ {
+ File f = File.createTempFile("jitsi-appindicator", ".png");
+ f.deleteOnExit();
+ try (FileImageOutputStream fios = new FileImageOutputStream(f))
+ {
+ if (!ImageIO.write(getBufferedImage(ii), "png", fios))
+ {
+ return null;
+ }
+
+ if (ii.getDescription() != null)
+ {
+ extractedFiles.put(
+ ii.getDescription(),
+ f.getAbsolutePath());
+ }
+
+ return f.getAbsolutePath();
+ }
+ }
+ catch (IOException e)
+ {
+ logger.debug("Failed to extract image: " + ii.getDescription(), e);
+ }
+
+ return null;
+ }
+
+ BufferedImage getBufferedImage(ImageIcon ii)
+ {
+ Image img = ii.getImage();
+ if (img == null)
+ {
+ return null;
+ }
+
+ if (img instanceof BufferedImage)
+ {
+ return (BufferedImage) img;
+ }
+
+ BufferedImage bi = new BufferedImage(
+ img.getWidth(null),
+ img.getHeight(null),
+ BufferedImage.TYPE_INT_ARGB);
+ Graphics g = bi.createGraphics();
+ g.drawImage(img, 0, 0, null);
+ g.dispose();
+ return bi;
+ }
+
+ private void imageIconToGtkWidget(PopupMenuPeer peer, ImageIcon ii)
+ {
+ BufferedImage bi = getBufferedImage(ii);
+ if (bi == null)
+ {
+ return;
+ }
+
+ int[] pixels = bi.getRGB(
+ 0,
+ 0,
+ bi.getWidth(),
+ bi.getHeight(),
+ null,
+ 0,
+ bi.getWidth());
+
+ peer.gtkImageBuffer = new Memory(pixels.length * 4);
+ for (int i = 0; i < pixels.length; i++)
+ {
+ // convert from argb (big endian) -> rgba (little endian) => abgr
+ peer.gtkImageBuffer.setInt(i * 4, (pixels[i] & 0xFF000000) |
+ (pixels[i] << 16) |
+ (pixels[i] & 0xFF00) |
+ (pixels[i] >>> 16 & 0xFF));
+ }
+
+ peer.gtkPixbuf = gtk.gdk_pixbuf_new_from_data(
+ peer.gtkImageBuffer,
+ 0,
+ 1,
+ 8,
+ bi.getWidth(),
+ bi.getHeight(),
+ bi.getWidth() * 4,
+ null,
+ null);
+ peer.gtkImage = gtk.gtk_image_new_from_pixbuf(peer.gtkPixbuf);
+
+ // Now that the image ref's the buffer, we can release our own ref and
+ // the buffer will be free'd along with the image
+ gobject.g_object_unref(peer.gtkPixbuf);
+ }
+
+ private static class MenuItemChangeListener
+ implements PropertyChangeListener, ChangeListener
+ {
+ private PopupMenuPeer peer;
+ private JMenuItem menu;
+
+ public MenuItemChangeListener(PopupMenuPeer peer)
+ {
+ this.peer = peer;
+ this.menu = (JMenuItem)peer.menuItem;
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ if (logger.isDebugEnabled())
+ {
+ logger.debug(menu.getText() + "::" + evt.getPropertyName());
+ }
+
+ switch (evt.getPropertyName())
+ {
+ case JMenuItem.TEXT_CHANGED_PROPERTY:
+ gtk.gdk_threads_enter();
+ try
+ {
+ gtk.gtk_menu_item_set_label(
+ peer.gtkMenuItem,
+ evt.getNewValue().toString());
+ }
+ finally
+ {
+ gtk.gdk_threads_leave();
+ }
+
+ break;
+// case JMenuItem.ICON_CHANGED_PROPERTY:
+// gtk.gtk_image_menu_item_set_image(gtkMenuItem, image);
+// break;
+ case AccessibleContext.ACCESSIBLE_STATE_PROPERTY:
+ gtk.gdk_threads_enter();
+ try
+ {
+ gtk.gtk_widget_set_sensitive(
+ peer.gtkMenuItem,
+ AccessibleState.ENABLED.equals(
+ evt.getNewValue()) ? 1 : 0);
+ }
+ finally
+ {
+ gtk.gdk_threads_leave();
+ }
+ break;
+ }
+ }
+
+ @Override
+ public void stateChanged(ChangeEvent e)
+ {
+ logger.debug(menu.getText() + " -> " + menu.isSelected());
+ gtk.gdk_threads_enter();
+ try
+ {
+ gtk.gtk_check_menu_item_set_active(
+ peer.gtkMenuItem,
+ menu.isSelected() ? 1 : 0);
+ }
+ finally
+ {
+ gtk.gdk_threads_leave();
+ }
+ }
+ }
+
+ private static class MenuItemSignalHandler
+ implements SignalHandler, Runnable
+ {
+ private PopupMenuPeer peer;
+
+ MenuItemSignalHandler(PopupMenuPeer peer)
+ {
+ this.peer = peer;
+ }
+
+ @Override
+ public void signal(Pointer widget, Pointer data)
+ {
+ SwingUtilities.invokeLater(this);
+ }
+
+ @Override
+ public void run()
+ {
+ JMenuItem menu = (JMenuItem)peer.menuItem;
+ if (menu instanceof JCheckBoxMenuItem)
+ {
+ // Ignore GTK callback events if the menu state is
+ // already the same. Setting the selected state on the
+ // GTK sends the "activate" event, and would cause
+ // a loop
+ logger.debug("Checking selected state on: " + menu.getText());
+ if (menu.isSelected() == isGtkSelected())
+ {
+ return;
+ }
+ }
+
+ for (ActionListener l : menu.getActionListeners())
+ {
+ logger.debug("Invoking " + l + " on " + menu.getText());
+ l.actionPerformed(new ActionEvent(menu, 0, "activate"));
+ }
+ }
+
+ private boolean isGtkSelected()
+ {
+ gtk.gdk_threads_enter();
+ try
+ {
+ return gtk.gtk_check_menu_item_get_active(peer.gtkMenuItem) == 1;
+ }
+ finally
+ {
+ gtk.gdk_threads_leave();
+ }
+ }
+ }
+
+ @Override
+ public void setDefaultAction(Object menuItem)
+ {
+ // It shouldn't be necessary that we hold a reference to the
+ // default item, it is contained in the menu. It might even create
+ // a memory leak. But if not set, the indicator loses track of it
+ // (at least on Debian). Unref an existing item, then ref the newly
+ // set
+ if (defaultMenuPeer != null)
+ {
+ gobject.g_object_unref(defaultMenuPeer.gtkMenuItem);
+ }
+
+ PopupMenuPeer peer = findMenuItem(popupPeer, menuItem);
+ if (peer != null && peer.gtkMenuItem != null)
+ {
+ gtk.gdk_threads_enter();
+ try
+ {
+ defaultMenuPeer = peer;
+ gobject.g_object_ref(peer.gtkMenuItem);
+ ai.app_indicator_set_secondary_activate_target(
+ appIndicator,
+ peer.gtkMenuItem);
+ }
+ finally
+ {
+ gtk.gdk_threads_leave();
+ }
+ }
+ }
+
+ private PopupMenuPeer findMenuItem(PopupMenuPeer peer, Object menuItem)
+ {
+ if (peer.menuItem == menuItem)
+ {
+ logger.debug("Setting default action to: "
+ + ((JMenuItem)menuItem).getText()
+ + " @" + peer.gtkMenuItem);
+ return peer;
+ }
+
+ for (PopupMenuPeer p : peer.children)
+ {
+ PopupMenuPeer found = findMenuItem(p, menuItem);
+ if (found != null)
+ {
+ return found;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public void addBalloonActionListener(ActionListener listener)
+ {
+ // not supported
+ }
+
+ @Override
+ public void displayMessage(String caption, String text,
+ MessageType messageType)
+ {
+ // not supported
+ }
+
+ @Override
+ public void setIcon(ImageIcon icon) throws NullPointerException
+ {
+ mainIcon = icon;
+ if (appIndicator != null)
+ {
+ gtk.gdk_threads_enter();
+ try
+ {
+ ai.app_indicator_set_icon(
+ appIndicator,
+ imageIconToPath(icon));
+ }
+ finally
+ {
+ gtk.gdk_threads_leave();
+ }
+ }
+ }
+
+ @Override
+ public void setIconAutoSize(boolean autoSize)
+ {
+ // nothing to do
+ }
+
+ private void printMenu(Component[] components, int indent)
+ {
+ if (!logger.isDebugEnabled())
+ {
+ return;
+ }
+
+ String p = String.format("%0" + indent * 4 + "d", 0).replace('0', ' ');
+ for (Component em : components)
+ {
+ if (em instanceof JPopupMenu.Separator)
+ {
+ logger.debug(p + "-----------------------");
+ }
+
+ if (em instanceof JMenuItem)
+ {
+ JMenuItem m = (JMenuItem) em;
+ logger.debug(p + em.getClass().getName() + ": " + m.getText());
+ }
+
+ if (em instanceof JMenu)
+ {
+ JMenu m = (JMenu) em;
+ printMenu(m.getMenuComponents(), indent + 1);
+ }
+ }
+ }
+}; \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/Gobject.java b/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/Gobject.java
new file mode 100644
index 0000000..cfc7805
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/Gobject.java
@@ -0,0 +1,90 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.osdependent.systemtray.appindicator;
+
+import java.util.*;
+
+import com.sun.jna.*;
+
+/**
+ * JNA mappings for GTK GObject types that are required for the tray menu.
+ *
+ * @author Ingo Bauersachs
+ */
+interface Gobject extends Library
+{
+ static final Gobject INSTANCE =
+ (Gobject) Native.loadLibrary("gobject-2.0", Gobject.class);
+
+ interface SignalHandler extends Callback
+ {
+ void signal(Pointer widget, Pointer data);
+ }
+
+ /**
+ * Connects a GCallback function to a signal for a particular object.
+ * Similar to g_signal_connect(), but allows to provide a GClosureNotify for
+ * the data which will be called when the signal handler is disconnected and
+ * no longer used. Specify connect_flags if you need ..._after() or
+ * ..._swapped() variants of this function.
+ *
+ * @param instance the instance to connect to.
+ * @param detailed_signal a string of the form "signal-name::detail".
+ * @param c_handler the GCallback to connect.
+ * @param data data to pass to c_handler calls.
+ * @param destroy_data a GClosureNotify for data.
+ * @param connect_flags a combination of GConnectFlags.
+ *
+ * @return the handler id (always greater than 0 for successful connections)
+ */
+ long g_signal_connect_data(Pointer instance, String detailed_signal,
+ SignalHandler c_handler, Pointer data, Pointer destroy_data,
+ int connect_flags);
+
+ /**
+ * Disconnects a handler from an instance so it will not be called during
+ * any future or currently ongoing emissions of the signal it has been
+ * connected to. The handler_id becomes invalid and may be reused. The
+ * handler_id has to be a valid signal handler id, connected to a signal of
+ * instance .
+ *
+ * @param instance The instance to remove the signal handler from.
+ * @param handler_id Handler id of the handler to be disconnected.
+ */
+ void g_signal_handler_disconnect(Pointer instance, long handler_id);
+
+ /**
+ * Decreases the reference count of object. When its reference count drops
+ * to 0, the object is finalized (i.e. its memory is freed). If the pointer
+ * to the GObject may be reused in future (for example, if it is an instance
+ * variable of another object), it is recommended to clear the pointer to
+ * NULL rather than retain a dangling pointer to a potentially invalid
+ * GObject instance. Use g_clear_object() for this.
+ *
+ * @param object a GObject.
+ */
+ void g_object_unref(Pointer object);
+
+ /**
+ * Increases the reference count of object.
+ *
+ * @param object a GObject.
+ * @return the same object.
+ */
+ Pointer g_object_ref(Pointer object);
+}
diff --git a/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/Gtk.java b/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/Gtk.java
new file mode 100644
index 0000000..b66d59f
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/Gtk.java
@@ -0,0 +1,68 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.osdependent.systemtray.appindicator;
+
+import com.sun.jna.*;
+
+/**
+ * JNA mappings for the gtk2 library. Only functions required for the tray menu
+ * are defined.
+ *
+ * @author Ingo Bauersachs
+ */
+interface Gtk extends Library
+{
+ static final Gtk INSTANCE =
+ (Gtk) Native.loadLibrary("gtk-x11-2.0", Gtk.class);
+
+ public enum GtkIconSize
+ {
+ INVALID,
+ MENU,
+ SMALL_TOOLBAR,
+ LARGE_TOOLBAR,
+ BUTTON,
+ DND,
+ DIALOG
+ }
+
+ void gtk_init(int argc, String[] argv);
+ void gtk_main();
+ Pointer gtk_menu_new();
+ Pointer gtk_image_menu_item_new_with_label(String label);
+ Pointer gtk_separator_menu_item_new();
+ void gtk_menu_item_set_submenu(Pointer menu_item, Pointer submenu);
+ void gtk_image_menu_item_set_image(Pointer image_menu_item, Pointer image);
+ void gtk_image_menu_item_set_always_show_image(Pointer image_menu_item, int always_show);
+ void gtk_menu_item_set_label(Pointer menu_item, String label);
+ void gtk_menu_shell_append(Pointer menu_shell, Pointer child);
+ void gtk_widget_set_sensitive(Pointer widget, int sesitive);
+ void gtk_widget_show_all(Pointer widget);
+ void gtk_widget_destroy(Pointer widget);
+ Pointer gtk_check_menu_item_new_with_label(String label);
+ int gtk_check_menu_item_get_active(Pointer check_menu_item);
+ void gtk_check_menu_item_set_active(Pointer check_menu_item, int is_active);
+
+ void gdk_threads_enter();
+ void gdk_threads_leave();
+
+ Pointer gdk_pixbuf_new_from_data(Pointer data, int colorspace, int has_alpha,
+ int bits_per_sample, int width, int height, int rowstride,
+ Pointer destroy_fn, Pointer destroy_fn_data);
+ Pointer gtk_image_new_from_pixbuf(Pointer pixbuf);
+}
diff --git a/src/net/java/sip/communicator/impl/osdependent/systemtray/awt/AWTMouseAdapter.java b/src/net/java/sip/communicator/impl/osdependent/systemtray/awt/AWTMouseAdapter.java
new file mode 100644
index 0000000..eb4a773
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/osdependent/systemtray/awt/AWTMouseAdapter.java
@@ -0,0 +1,124 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.osdependent.systemtray.awt;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+import javax.swing.event.*;
+
+import org.jitsi.util.*;
+
+/**
+ * Extended mouse adapter to show the JPopupMenu in Java 6. Based on: <a href=
+ * "https://community.oracle.com/blogs/ixmal/2006/05/03/using-jpopupmenu-trayicon">
+ * Using JPopupMenu in TrayIcon Blog</a> and <a href=
+ * "https://community.oracle.com/blogs/alexfromsun/2008/02/14/jtrayicon-update">
+ * JTrayIcon update Blog</a>.
+ *
+ * Use a hidden JWindow (JDialog for Windows) to manage the JPopupMenu.
+ *
+ * @author Damien Roth
+ */
+class AWTMouseAdapter
+ extends MouseAdapter
+{
+ private JPopupMenu popup = null;
+ private Window hiddenWindow = null;
+
+ public AWTMouseAdapter(JPopupMenu p)
+ {
+ this.popup = p;
+ this.popup.addPopupMenuListener(new PopupMenuListener()
+ {
+ public void popupMenuWillBecomeVisible(PopupMenuEvent e)
+ {}
+
+ public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
+ {
+ if (hiddenWindow != null)
+ {
+ hiddenWindow.dispose();
+ hiddenWindow = null;
+ }
+ }
+
+ public void popupMenuCanceled(PopupMenuEvent e)
+ {
+ if (hiddenWindow != null)
+ {
+ hiddenWindow.dispose();
+ hiddenWindow = null;
+ }
+ }
+ });
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e)
+ {
+ showPopupMenu(e);
+ }
+
+ @Override
+ public void mousePressed(MouseEvent e)
+ {
+ showPopupMenu(e);
+ }
+
+ private void showPopupMenu(MouseEvent e)
+ {
+ if (e.isPopupTrigger() && popup != null)
+ {
+ if (hiddenWindow == null)
+ {
+ if (OSUtils.IS_WINDOWS)
+ {
+ hiddenWindow = new JDialog((Frame) null);
+ ((JDialog) hiddenWindow).setUndecorated(true);
+ }
+ else
+ hiddenWindow = new JWindow((Frame) null);
+
+ hiddenWindow.setAlwaysOnTop(true);
+ Dimension size = popup.getPreferredSize();
+
+ Point centerPoint = GraphicsEnvironment
+ .getLocalGraphicsEnvironment()
+ .getCenterPoint();
+
+ if(e.getY() > centerPoint.getY())
+ hiddenWindow
+ .setLocation(e.getX(), e.getY() - size.height);
+ else
+ hiddenWindow
+ .setLocation(e.getX(), e.getY());
+
+ hiddenWindow.setVisible(true);
+
+ popup.show(
+ ((RootPaneContainer)hiddenWindow).getContentPane(),
+ 0, 0);
+
+ // popup works only for focused windows
+ hiddenWindow.toFront();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/osdependent/systemtray/awt/AWTSystemTray.java b/src/net/java/sip/communicator/impl/osdependent/systemtray/awt/AWTSystemTray.java
new file mode 100644
index 0000000..1f211c7
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/osdependent/systemtray/awt/AWTSystemTray.java
@@ -0,0 +1,78 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.osdependent.systemtray.awt;
+
+import java.awt.*;
+
+import javax.swing.*;
+
+import org.jitsi.util.*;
+
+import net.java.sip.communicator.impl.osdependent.systemtray.SystemTray;
+import net.java.sip.communicator.impl.osdependent.systemtray.TrayIcon;
+
+/**
+ * Wrapper of the AWT SystemTray class.
+ */
+public class AWTSystemTray
+ extends SystemTray
+{
+ private final java.awt.SystemTray impl;
+
+ /**
+ * Creates a new instance of this class.
+ */
+ public AWTSystemTray()
+ {
+ impl = java.awt.SystemTray.getSystemTray();
+ }
+
+ @Override
+ public void addTrayIcon(TrayIcon trayIcon)
+ throws IllegalArgumentException
+ {
+ try
+ {
+ impl.add(((AWTTrayIcon) trayIcon).getImpl());
+ }
+ catch (AWTException e)
+ {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ @Override
+ public TrayIcon createTrayIcon(ImageIcon icon, String tooltip,
+ Object popup)
+ {
+ return new AWTTrayIcon(icon.getImage(), tooltip, popup);
+ }
+
+ @Override
+ public boolean useSwingPopupMenu()
+ {
+ // enable swing for Java 1.6 except for the mac version
+ return !OSUtils.IS_MAC;
+ }
+
+ @Override
+ public boolean supportsDynamicMenu()
+ {
+ return true;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/osdependent/systemtray/awt/AWTTrayIcon.java b/src/net/java/sip/communicator/impl/osdependent/systemtray/awt/AWTTrayIcon.java
new file mode 100644
index 0000000..2fa0318
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/osdependent/systemtray/awt/AWTTrayIcon.java
@@ -0,0 +1,131 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.osdependent.systemtray.awt;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.impl.osdependent.systemtray.TrayIcon;
+
+/**
+ * Wrapper of the AWT TrayIcon class.
+ */
+public class AWTTrayIcon
+ implements TrayIcon
+{
+ private final java.awt.TrayIcon impl;
+
+ /**
+ * Creates a new instance of this class.
+ *
+ * @param image the <tt>Image</tt> to be used
+ * @param tooltip the string to be used as tooltip text; if the value is
+ * <tt>null</tt> no tooltip is shown
+ * @param popup the menu to be used for the tray icon's popup menu; if the
+ * value is <tt>null</tt> no popup menu is shown
+ */
+ public AWTTrayIcon(Image image, String tooltip,
+ Object popup)
+ {
+ if (popup instanceof JPopupMenu)
+ {
+ impl = new java.awt.TrayIcon(image, tooltip);
+ impl.addMouseListener(new AWTMouseAdapter((JPopupMenu)popup));
+ }
+ else if (popup instanceof PopupMenu)
+ {
+ impl = new java.awt.TrayIcon(image, tooltip, (PopupMenu)popup);
+ }
+ else if (popup == null)
+ {
+ impl = new java.awt.TrayIcon(image, tooltip);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Invalid popup menu type");
+ }
+ }
+
+ public void setDefaultAction(final Object menuItem)
+ {
+ // clear all previous listeners
+ ActionListener[] previous = impl.getActionListeners();
+ for (ActionListener l : previous)
+ {
+ impl.removeActionListener(l);
+ }
+
+ // get the new handlers
+ final ActionListener[] listeners;
+ if (menuItem instanceof JMenuItem)
+ {
+ listeners = ((JMenuItem) menuItem).getActionListeners();
+ }
+ else if (menuItem instanceof MenuItem)
+ {
+ listeners = ((MenuItem) menuItem).getActionListeners();
+ }
+ else
+ {
+ return;
+ }
+
+ // create a custom handler to fake that the source is the menu item
+ impl.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ for (ActionListener l : listeners)
+ {
+ l.actionPerformed(new ActionEvent(menuItem,
+ e.getID(), e.getActionCommand()));
+ }
+ }
+ });
+ }
+
+ public void addBalloonActionListener(ActionListener listener)
+ {
+ // java.awt.TrayIcon doesn't support addBalloonActionListener()
+ }
+
+ public void displayMessage(String caption, String text,
+ java.awt.TrayIcon.MessageType messageType)
+ throws NullPointerException
+ {
+ impl.displayMessage(caption, text, messageType);
+ }
+
+ public void setIcon(ImageIcon icon) throws NullPointerException
+ {
+ impl.setImage(icon.getImage());
+ }
+
+ public void setIconAutoSize(boolean autoSize)
+ {
+ impl.setImageAutoSize(autoSize);
+ }
+
+ java.awt.TrayIcon getImpl()
+ {
+ return impl;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/osdependent/windows/ImageConverter.java b/src/net/java/sip/communicator/impl/osdependent/windows/ImageConverter.java
new file mode 100644
index 0000000..99754d3
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/osdependent/windows/ImageConverter.java
@@ -0,0 +1,172 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright 2000-2016 JetBrains s.r.o.
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */package net.java.sip.communicator.impl.osdependent.windows;
+
+import java.awt.image.*;
+import java.nio.*;
+
+import com.sun.jna.*;
+import com.sun.jna.platform.win32.*;
+import com.sun.jna.platform.win32.WinDef.*;
+
+/**
+ * Image conversion utilities.
+ *
+ * Parts of this code are based on AppIcon.java from IntelliJ community.
+ * Licensed under Apache 2.0, Copyright 2000-2016 JetBrains s.r.o.
+ */
+public class ImageConverter
+{
+ /**
+ * Converts the <tt>BufferedImage</tt> to an ICONDIR structure.
+ * @param src The source image to convert
+ * @return an ICONDIR structure with the data of the passed source image
+ */
+ public static byte[] writeTransparentIcoImage(BufferedImage src)
+ {
+ int bitCount = 32;
+
+ int scanline_size = (bitCount * src.getWidth() + 7) / 8;
+ if ((scanline_size % 4) != 0)
+ scanline_size += 4 - (scanline_size % 4); // pad scanline to 4 byte
+ // size.
+ int t_scanline_size = (src.getWidth() + 7) / 8;
+ if ((t_scanline_size % 4) != 0)
+ t_scanline_size += 4 - (t_scanline_size % 4); // pad scanline to 4
+ // byte size.
+ int imageSize = 40 + src.getHeight() * scanline_size
+ + src.getHeight() * t_scanline_size;
+
+ // sizeof(ICONDIR)
+ // + sizeof(ICONDIRENTRY)
+ // + (sizeof(BITMAPINFOHEADER)+data)
+ ByteBuffer bos = ByteBuffer.allocate(6 + 16 + imageSize);
+ bos.order(ByteOrder.LITTLE_ENDIAN);
+
+ // ICONDIR
+ bos.putShort((short) 0); // reserved
+ bos.putShort((short) 1); // 1=ICO, 2=CUR
+ bos.putShort((short) 1); // count
+
+ // ICONDIRENTRY
+ int iconDirEntryWidth = src.getWidth();
+ int iconDirEntryHeight = src.getHeight();
+ if (iconDirEntryWidth > 255 || iconDirEntryHeight > 255)
+ {
+ iconDirEntryWidth = 0;
+ iconDirEntryHeight = 0;
+ }
+ bos.put((byte) iconDirEntryWidth);
+ bos.put((byte) iconDirEntryHeight);
+ bos.put((byte) 0);
+ bos.put((byte) 0); // reserved
+ bos.putShort((short) 1); // color planes
+ bos.putShort((short) bitCount);
+ bos.putInt(imageSize);
+ bos.putInt(22); // image offset
+
+ // BITMAPINFOHEADER
+ bos.putInt(40); // size
+ bos.putInt(src.getWidth());
+ bos.putInt(2 * src.getHeight());
+ bos.putShort((short) 1); // planes
+ bos.putShort((short) bitCount);
+ bos.putInt(0); // compression
+ bos.putInt(0); // image size
+ bos.putInt(0); // x pixels per meter
+ bos.putInt(0); // y pixels per meter
+ bos.putInt(0); // colors used, 0 = (1 << bitCount) (ignored)
+ bos.putInt(0); // colors important
+
+ int bit_cache = 0;
+ int bits_in_cache = 0;
+ int row_padding = scanline_size - (bitCount * src.getWidth() + 7) / 8;
+ for (int y = src.getHeight() - 1; y >= 0; y--)
+ {
+ for (int x = 0; x < src.getWidth(); x++)
+ {
+ int argb = src.getRGB(x, y);
+
+ bos.put((byte) (0xff & argb));
+ bos.put((byte) (0xff & (argb >> 8)));
+ bos.put((byte) (0xff & (argb >> 16)));
+ bos.put((byte) (0xff & (argb >> 24)));
+ }
+
+ for (int x = 0; x < row_padding; x++)
+ bos.put((byte) 0);
+ }
+
+ int t_row_padding = t_scanline_size - (src.getWidth() + 7) / 8;
+ for (int y = src.getHeight() - 1; y >= 0; y--)
+ {
+ for (int x = 0; x < src.getWidth(); x++)
+ {
+ int argb = src.getRGB(x, y);
+ int alpha = 0xff & (argb >> 24);
+ bit_cache <<= 1;
+ if (alpha == 0)
+ bit_cache |= 1;
+ bits_in_cache++;
+ if (bits_in_cache >= 8)
+ {
+ bos.put((byte) (0xff & bit_cache));
+ bit_cache = 0;
+ bits_in_cache = 0;
+ }
+ }
+
+ if (bits_in_cache > 0)
+ {
+ bit_cache <<= (8 - bits_in_cache);
+ bos.put((byte) (0xff & bit_cache));
+ bit_cache = 0;
+ bits_in_cache = 0;
+ }
+
+ for (int x = 0; x < t_row_padding; x++)
+ bos.put((byte) 0);
+ }
+
+ byte[] result = new byte[bos.position()];
+ System.arraycopy(bos.array(), 0, result, 0, bos.position());
+ return result;
+ }
+
+ /**
+ * Converts an ICONDIR ico to an HICON handle
+ * @param ico the image data
+ * @return A Windows HICON handle
+ */
+ public static HICON createIcon(byte[] ico)
+ {
+ Memory buffer = new Memory(ico.length);
+ buffer.write(0, ico, 0, ico.length);
+ int nSize = 100;
+ int offset = User32Ex.INSTANCE.LookupIconIdFromDirectoryEx(buffer, true,
+ nSize, nSize, 0);
+ if (offset != 0)
+ {
+ return User32Ex.INSTANCE.CreateIconFromResourceEx(
+ buffer.share(offset), new WinDef.DWORD(0), true,
+ new WinDef.DWORD(0x00030000), nSize, nSize, 0);
+ }
+
+ return null;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/osdependent/windows/TaskBarList3.java b/src/net/java/sip/communicator/impl/osdependent/windows/TaskBarList3.java
new file mode 100644
index 0000000..a21cd8f
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/osdependent/windows/TaskBarList3.java
@@ -0,0 +1,150 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.osdependent.windows;
+
+import java.awt.*;
+import java.awt.image.*;
+
+import org.jitsi.util.*;
+
+import com.sun.jna.*;
+import com.sun.jna.platform.win32.*;
+import com.sun.jna.platform.win32.COM.*;
+import com.sun.jna.platform.win32.Guid.*;
+import com.sun.jna.platform.win32.WinDef.*;
+import com.sun.jna.platform.win32.WinNT.*;
+import com.sun.jna.ptr.*;
+
+/**
+ * JNA wrapper for the ITaskBarList3 COM interface.
+ * https://msdn.microsoft.com/en-us/library/dd391696(v=vs.85).aspx
+ *
+ * @author Ingo Bauersachs
+ */
+public class TaskBarList3
+ extends Unknown
+{
+ private static final GUID CLSID_TaskbarList =
+ new GUID("{56FDF344-FD6D-11d0-958A-006097C9A090}");
+
+ private static final GUID IID_ITaskbarList3 =
+ new GUID("{ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}");
+
+ private static TaskBarList3 instance;
+
+ /**
+ * Gets the ITaskBarList3 interface and initializes it with HrInit
+ * @return A ready to use TaskBarList3 object.
+ * @throws COMException when the interface could not be accessed
+ */
+ public static TaskBarList3 getInstance()
+ {
+ if (instance == null && OSUtils.IS_WINDOWS)
+ {
+ Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, 0);
+ PointerByReference p = new PointerByReference();
+ WinNT.HRESULT hr =
+ Ole32.INSTANCE.CoCreateInstance(CLSID_TaskbarList, Pointer.NULL,
+ ObjBase.CLSCTX_ALL, IID_ITaskbarList3, p);
+ COMUtils.checkRC(hr);
+ instance = new TaskBarList3(p.getValue());
+ }
+
+ return instance;
+ }
+
+ private TaskBarList3(Pointer p)
+ {
+ super(p);
+ HrInit();
+ }
+
+ // VTable
+ // ------
+ // IUnknown:
+ // 0: AddRef
+ // 1: QueryInterface
+ // 2: Release
+ //
+ // ITaskBarList:
+ // 3: HrInit
+ // 4: AddTab
+ // 5: DeleteTab
+ // 6: ActivateTab
+ // 7: SetActiveAlt
+ //
+ // ITaskBarList2
+ // 8: MarkFullscreenWindow
+ //
+ // ITaskBarList3:
+ // 9: SetProgressValue
+ // 10: SetProgressState
+ // 11: RegisterTab
+ // 12: UnregisterTab
+ // 13: SetTabOrder
+ // 14: SetTabActive
+ // 15: ThumbBarAddButtons
+ // 16: ThumbBarAddButtons
+ // 17: ThumbBarSetImageList
+ // 18: SetOverlayIcon
+ // 19: SetThumbnailTooltip
+ // 20: SetThumbnailClip
+ //
+ // ITaskbarList4:
+ // 21: SetTabProperties
+
+ /**
+ * https://msdn.microsoft.com/en-us/library/bb774650(v=vs.85).aspx
+ */
+ private void HrInit()
+ {
+ int hr = this._invokeNativeInt(3, new Object[]
+ { this.getPointer() });
+ COMUtils.checkRC(new HRESULT(hr));
+ }
+
+ /**
+ * https://msdn.microsoft.com/en-us/library/dd391696(v=vs.85).aspx
+ */
+ private void SetOverlayIcon(HWND hwnd, HICON hIcon, String pszDescription)
+ {
+ int hr = this._invokeNativeInt(18, new Object[]
+ { this.getPointer(), hwnd, hIcon, pszDescription });
+ COMUtils.checkRC(new HRESULT(hr));
+ }
+
+ /**
+ * Sets an overlay image to the taskbar icon.
+ * @param frame The window that should receive the overlay
+ * @param image The overlay image, can be <tt>null</tt> to clear the overlay
+ * @param description An optional tooltip text, can be <tt>null</tt>
+ */
+ public void SetOverlayIcon(Component frame, BufferedImage image,
+ String description)
+ {
+ HICON ico = null;
+ if (image != null)
+ {
+ byte[] iconBytes = ImageConverter.writeTransparentIcoImage(image);
+ ico = ImageConverter.createIcon(iconBytes);
+ }
+
+ HWND hwnd = new HWND(Native.getComponentPointer(frame));
+ SetOverlayIcon(hwnd, ico, description);
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/osdependent/windows/User32Ex.java b/src/net/java/sip/communicator/impl/osdependent/windows/User32Ex.java
new file mode 100644
index 0000000..59f3a7a
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/osdependent/windows/User32Ex.java
@@ -0,0 +1,47 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.osdependent.windows;
+
+import com.sun.jna.*;
+import com.sun.jna.platform.win32.*;
+import com.sun.jna.win32.*;
+
+/**
+ * Extension to missing user32 Windows APIs
+ *
+ * @author Ingo Bauersachs
+ */
+interface User32Ex
+ extends StdCallLibrary
+{
+ User32Ex INSTANCE = (User32Ex) Native.loadLibrary("user32", User32Ex.class,
+ W32APIOptions.DEFAULT_OPTIONS);
+
+ /**
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/ms648074(v=vs.85).aspx
+ */
+ int LookupIconIdFromDirectoryEx(Memory presbits, boolean fIcon,
+ int cxDesired, int cyDesired, int Flags);
+
+ /**
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/ms648061(v=vs.85).aspx
+ */
+ WinDef.HICON CreateIconFromResourceEx(Pointer pbIconBits,
+ WinDef.DWORD cbIconBits, boolean fIcon, WinDef.DWORD dwVersion,
+ int cxDesired, int cyDesired, int uFlags);
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingConfigurationImpl.java b/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingConfigurationImpl.java
index b26b11a..978c74c 100644
--- a/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingConfigurationImpl.java
+++ b/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingConfigurationImpl.java
@@ -60,6 +60,10 @@ public class PacketLoggingConfigurationImpl
configService.getBoolean(
PACKET_LOGGING_ICE4J_ENABLED_PROPERTY_NAME,
isIce4JLoggingEnabled()));
+ super.setArbitraryLoggingEnabled(
+ configService.getBoolean(
+ PACKET_LOGGING_ARBITRARY_ENABLED_PROPERTY_NAME,
+ isArbitraryLoggingEnabled()));
super.setLimit(
configService.getLong(
PACKET_LOGGING_FILE_SIZE_PROPERTY_NAME,
diff --git a/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingServiceImpl.java b/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingServiceImpl.java
index 788e8db..1e459f1 100644
--- a/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingServiceImpl.java
+++ b/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingServiceImpl.java
@@ -20,6 +20,7 @@ package net.java.sip.communicator.impl.packetlogging;
import java.io.*;
import java.util.*;
+import com.google.common.collect.*;
import net.java.sip.communicator.util.*;
import org.jitsi.service.fileaccess.*;
@@ -41,6 +42,14 @@ public class PacketLoggingServiceImpl
= Logger.getLogger(PacketLoggingServiceImpl.class);
/**
+ * The max size of the <tt>EvictingQueue</tt> that the saver thread
+ * is using.
+ *
+ * TODO this needs to be configurable eventually.
+ */
+ private static final int EVICTING_QUEUE_MAX_SIZE = 1000;
+
+ /**
* The OutputStream we are currently writing to.
*/
private FileOutputStream outputStream = null;
@@ -62,10 +71,17 @@ public class PacketLoggingServiceImpl
new byte[]{
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
- (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
- (byte)0x08, (byte)0x00
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
};
+ /** IEEE 802.3 EtherType for IPv4 */
+ private final static byte[] ipv4EtherType =
+ new byte[] { 0x08, 0x00 };
+
+ /** IEEE 802.3 EtherType for IPv6 */
+ private final static byte[] ipv6EtherType =
+ new byte[] { (byte)0x86, (byte)0xdd };
+
/**
* The fake ipv4 header we use as template.
*/
@@ -313,22 +329,22 @@ public class PacketLoggingServiceImpl
{
switch(protocol)
{
- case SIP:
- return cfg.isSipLoggingEnabled();
- case JABBER:
- return cfg.isJabberLoggingEnabled();
- case RTP:
- return cfg.isRTPLoggingEnabled();
- case ICE4J:
- return cfg.isIce4JLoggingEnabled();
- default:
- /*
- * It may seem like it was unnecessary to invoke
- * getConfiguration and isGlobalLoggingEnabled prior to
- * checking that the specified protocol is supported but,
- * actually, there are no other ProtocolName values.
- */
- return false;
+ case SIP:
+ return cfg.isSipLoggingEnabled();
+ case JABBER:
+ return cfg.isJabberLoggingEnabled();
+ case RTP:
+ return cfg.isRTPLoggingEnabled();
+ case ICE4J:
+ return cfg.isIce4JLoggingEnabled();
+ case ARBITRARY:
+ return cfg.isArbitraryLoggingEnabled();
+ default:
+ // It may seem like it was unnecessary to invoke
+ // getConfiguration and isGlobalLoggingEnabled prior to checking
+ // that the specified protocol is supported but, actually, there
+ // are no other ProtocolName values.
+ return false;
}
}
else
@@ -553,6 +569,7 @@ public class PacketLoggingServiceImpl
int tsSec = (int)(current/1000);
int tsUsec = (int)((current%1000) * 1000);
int feakHeaderLen = fakeEthernetHeader.length +
+ (isIPv4 ? ipv4EtherType : ipv6EtherType).length +
ipHeader.length + transportHeader.length;
int inclLen = packet.packetLength + feakHeaderLen;
int origLen = inclLen;
@@ -577,6 +594,7 @@ public class PacketLoggingServiceImpl
addInt(origLen);
outputStream.write(fakeEthernetHeader);
+ outputStream.write(isIPv4 ? ipv4EtherType : ipv6EtherType);
outputStream.write(ipHeader);
outputStream.write(transportHeader);
outputStream.write(
@@ -767,7 +785,8 @@ public class PacketLoggingServiceImpl
/**
* List of packets queued to be written in the file.
*/
- private final List<Packet> pktsToSave = new ArrayList<Packet>();
+ private final EvictingQueue<Packet> pktsToSave
+ = EvictingQueue.create(EVICTING_QUEUE_MAX_SIZE);
/**
* Initializes a new <tt>SaverThread</tt>.
@@ -803,7 +822,7 @@ public class PacketLoggingServiceImpl
continue;
}
- pktToSave = pktsToSave.remove(0);
+ pktToSave = pktsToSave.poll();
}
if(pktToSave != null)
@@ -842,6 +861,11 @@ public class PacketLoggingServiceImpl
*/
public synchronized void queuePacket(Packet packet)
{
+ if (EVICTING_QUEUE_MAX_SIZE - pktsToSave.size() == 0)
+ {
+ logger.warn("Queue is full, packets are being evicted.");
+ }
+
pktsToSave.add(packet);
notifyAll();
}
diff --git a/src/net/java/sip/communicator/impl/packetlogging/packetlogging.manifest.mf b/src/net/java/sip/communicator/impl/packetlogging/packetlogging.manifest.mf
index 374294f..2099f02 100644
--- a/src/net/java/sip/communicator/impl/packetlogging/packetlogging.manifest.mf
+++ b/src/net/java/sip/communicator/impl/packetlogging/packetlogging.manifest.mf
@@ -16,4 +16,5 @@ Import-Package: org.osgi.framework,
javax.swing,
javax.swing.border,
javax.swing.event,
- javax.swing.text
+ javax.swing.text,
+ com.google.common.collect
diff --git a/src/net/java/sip/communicator/impl/phonenumbers/PhoneNumberI18nServiceImpl.java b/src/net/java/sip/communicator/impl/phonenumbers/PhoneNumberI18nServiceImpl.java
index d1942b2..4d4d417 100644
--- a/src/net/java/sip/communicator/impl/phonenumbers/PhoneNumberI18nServiceImpl.java
+++ b/src/net/java/sip/communicator/impl/phonenumbers/PhoneNumberI18nServiceImpl.java
@@ -18,6 +18,9 @@
package net.java.sip.communicator.impl.phonenumbers;
import com.google.i18n.phonenumbers.*;
+import com.google.i18n.phonenumbers.PhoneNumberUtil.*;
+import com.google.i18n.phonenumbers.Phonenumber.*;
+
import net.java.sip.communicator.service.protocol.*;
import org.jitsi.service.configuration.*;
@@ -183,6 +186,33 @@ public class PhoneNumberI18nServiceImpl
}
/**
+ * Tries to format the passed phone number into the international format. If
+ * parsing fails or the string is not recognized as a valid phone number,
+ * the input is returned as is.
+ *
+ * @param phoneNumber The phone number to format.
+ * @return the formatted phone number in the international format.
+ */
+ public String formatForDisplay(String phoneNumber)
+ {
+ try
+ {
+ PhoneNumber pn = PhoneNumberUtil.getInstance().parse(phoneNumber,
+ System.getProperty("user.country"));
+ if (PhoneNumberUtil.getInstance().isPossibleNumber(pn))
+ {
+ return PhoneNumberUtil.getInstance().format(pn,
+ PhoneNumberFormat.INTERNATIONAL);
+ }
+ }
+ catch (NumberParseException e)
+ {
+ }
+
+ return phoneNumber;
+ }
+
+ /**
* Indicates if the given string is possibly a phone number.
*
* @param possibleNumber the string to be verified
diff --git a/src/net/java/sip/communicator/impl/protocol/dict/ContactDictImpl.java b/src/net/java/sip/communicator/impl/protocol/dict/ContactDictImpl.java
deleted file mode 100644
index 924c0f7..0000000
--- a/src/net/java/sip/communicator/impl/protocol/dict/ContactDictImpl.java
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.dict;
-
-import net.java.dict4j.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * An implementation of a Dict contact
- *
- * @author ROTH Damien
- * @author LITZELMANN Cedric
- */
-public class ContactDictImpl
- extends AbstractContact
-{
- private Logger logger = Logger.getLogger(ContactDictImpl.class);
-
- /**
- * Icon
- */
- private static byte[] icon = DictActivator.getResources()
- .getImageInBytes("service.protocol.dict.DICT_64x64");
-
- /**
- * The id of the contact.
- */
- private String contactID = null;
-
- /**
- * The provider that created us.
- */
- private ProtocolProviderServiceDictImpl parentProvider = null;
-
- /**
- * The group that belong to.
- */
- private ContactGroupDictImpl parentGroup = null;
-
- /**
- * The presence status of the contact.
- */
- private PresenceStatus presenceStatus = DictStatusEnum.ONLINE;
-
- /**
- * Determines whether this contact is persistent, i.e. member of the contact
- * list or whether it is here only temporarily.
- */
- private boolean isPersistent = true;
-
- /**
- * Determines whether the contact has been resolved (i.e. we have a
- * confirmation that it is still on the server contact list).
- */
- private boolean isResolved = true;
-
- /**
- * The string in a "humain readable and understandable representation" of
- * the dictionnaire. In brief this is a short description of the dictionary.
- */
- private String dictName = null;
-
- /**
- * Creates an instance of a meta contact with the specified string used
- * as a name and identifier.
- *
- * @param databaseCode The identifier of this contact (also used as a name).
- * @param parentProvider The provider that created us.
- */
- public ContactDictImpl(
- String databaseCode,
- ProtocolProviderServiceDictImpl parentProvider)
- {
- this.contactID = databaseCode;
- this.parentProvider = parentProvider;
- }
-
- /**
- * This method is only called when the contact is added to a new
- * <tt>ContactGroupDictImpl</tt> by the
- * <tt>ContactGroupDictImpl</tt> itself.
- *
- * @param newParentGroup the <tt>ContactGroupDictImpl</tt> that is now
- * parent of this <tt>ContactDictImpl</tt>
- */
- void setParentGroup(ContactGroupDictImpl newParentGroup)
- {
- this.parentGroup = newParentGroup;
- }
-
- /**
- * Returns a String that can be used for identifying the contact.
- *
- * @return a String id representing and uniquely identifying the contact.
- */
- public String getContactID()
- {
- return contactID;
- }
-
- /**
- * Returns a String that can be used for identifying the contact.
- *
- * @return a String id representing and uniquely identifying the contact.
- */
- public String getAddress()
- {
- return contactID;
- }
-
- /**
- * Returns a String that could be used by any user interacting modules
- * for referring to this contact.
- *
- * @return a String that can be used for referring to this contact when
- * interacting with the user.
- */
- public String getDisplayName()
- {
- if (dictName == null)
- {
- if (this.contactID.equals("*"))
- {
- this.dictName = DictActivator.getResources()
- .getI18NString("plugin.dictaccregwizz.ANY_DICTIONARY");
- }
- else if (this.contactID.equals("!"))
- {
- this.dictName = DictActivator.getResources()
- .getI18NString("plugin.dictaccregwizz.FIRST_MATCH");
- }
- else
- {
- try
- {
- this.dictName = this.parentProvider.getConnection()
- .getDictionaryName(this.contactID);
- }
- catch (DictException dx)
- {
- logger.error("Error while getting dictionary long name", dx);
- }
-
- if (this.dictName == null)
- this.dictName = this.contactID;
- }
- }
-
- return dictName;
- }
-
- /**
- * Returns a byte array containing an image (most often a photo or an
- * avatar) that the contact uses as a representation.
- *
- * @return byte[] an image representing the contact.
- */
- public byte[] getImage()
- {
- return icon;
- }
-
- /**
- * Returns the status of the contact.
- *
- * @return always DictStatusEnum.ONLINE.
- */
- public PresenceStatus getPresenceStatus()
- {
- return this.presenceStatus;
- }
-
- /**
- * Sets <tt>dictPresenceStatus</tt> as the PresenceStatus that this
- * contact is currently in.
- * @param dictPresenceStatus the <tt>DictPresenceStatus</tt>
- * currently valid for this contact.
- */
- public void setPresenceStatus(PresenceStatus dictPresenceStatus)
- {
- this.presenceStatus = dictPresenceStatus;
- }
-
- /**
- * Returns a reference to the protocol provider that created the contact.
- *
- * @return a refererence to an instance of the ProtocolProviderService
- */
- public ProtocolProviderService getProtocolProvider()
- {
- return parentProvider;
- }
-
- /**
- * Determines whether or not this contact represents our own identity.
- *
- * @return true in case this is a contact that represents ourselves and
- * false otherwise.
- */
- public boolean isLocal()
- {
- return false;
- }
-
- /**
- * Returns the group that contains this contact.
- * @return a reference to the <tt>ContactGroupDictImpl</tt> that
- * contains this contact.
- */
- public ContactGroup getParentContactGroup()
- {
- return this.parentGroup;
- }
-
- /**
- * Returns a string representation of this contact, containing most of its
- * representative details.
- *
- * @return a string representation of this contact.
- */
- @Override
- public String toString()
- {
- StringBuffer buff
- = new StringBuffer("ContactDictImpl[ DisplayName=")
- .append(getDisplayName()).append("]");
-
- return buff.toString();
- }
-
- /**
- * Determines whether or not this contact is being stored by the server.
- * Non persistent contacts are common in the case of simple, non-persistent
- * presence operation sets. They could however also be seen in persistent
- * presence operation sets when for example we have received an event
- * from someone not on our contact list. Non persistent contacts are
- * volatile even when coming from a persistent presence op. set. They would
- * only exist until the application is closed and will not be there next
- * time it is loaded.
- *
- * @return true if the contact is persistent and false otherwise.
- */
- public boolean isPersistent()
- {
- return isPersistent;
- }
-
- /**
- * Specifies whether or not this contact is being stored by the server.
- * Non persistent contacts are common in the case of simple, non-persistent
- * presence operation sets. They could however also be seen in persistent
- * presence operation sets when for example we have received an event
- * from someone not on our contact list. Non persistent contacts are
- * volatile even when coming from a persistent presence op. set. They would
- * only exist until the application is closed and will not be there next
- * time it is loaded.
- *
- * @param isPersistent true if the contact is persistent and false
- * otherwise.
- */
- public void setPersistent(boolean isPersistent)
- {
- this.isPersistent = isPersistent;
- }
-
-
- /**
- * Returns null as no persistent data is required and the contact address is
- * sufficient for restoring the contact.
- * <p>
- * @return null as no such data is needed.
- */
- public String getPersistentData()
- {
- return null;
- }
-
- /**
- * Determines whether or not this contact has been resolved against the
- * server. Unresolved contacts are used when initially loading a contact
- * list that has been stored in a local file until the presence operation
- * set has managed to retrieve all the contact list from the server and has
- * properly mapped contacts to their on-line buddies.
- *
- * @return true if the contact has been resolved (mapped against a buddy)
- * and false otherwise.
- */
- public boolean isResolved()
- {
- return isResolved;
- }
-
- /**
- * Return the current status message of this contact.
- *
- * @return null as the protocol has currently no support of status messages
- */
- public String getStatusMessage()
- {
- return null;
- }
-
- /**
- * Makes the contact resolved or unresolved.
- *
- * @param resolved true to make the contact resolved; false to
- * make it unresolved
- */
- public void setResolved(boolean resolved)
- {
- this.isResolved = resolved;
- }
-
- /**
- * Returns the persistent presence operation set that this contact belongs
- * to.
- *
- * @return the <tt>OperationSetPersistentPresenceGibberishImpl</tt> that
- * this contact belongs to.
- */
- public OperationSetPersistentPresenceDictImpl
- getParentPresenceOperationSet()
- {
- return (OperationSetPersistentPresenceDictImpl) parentProvider
- .getOperationSet(OperationSetPersistentPresence.class);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/dict/ContactGroupDictImpl.java b/src/net/java/sip/communicator/impl/protocol/dict/ContactGroupDictImpl.java
deleted file mode 100644
index e52ce96..0000000
--- a/src/net/java/sip/communicator/impl/protocol/dict/ContactGroupDictImpl.java
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.dict;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * A simple, straightforward implementation of a dict ContactGroup. Since
- * the Dict protocol is not a real one, we simply store all group details
- * in class fields. You should know that when implementing a real protocol,
- * the contact group implementation would rather encapsulate group objects from
- * the protocol stack and group property values should be returned by consulting
- * the encapsulated object.
- *
- * @author ROTH Damien
- * @author LITZELMANN Cedric
- */
-public class ContactGroupDictImpl
- implements ContactGroup
-{
-
- /**
- * The name of this Dict contact group.
- */
- private String groupName = null;
-
- /**
- * The list of this group's members.
- */
- private List<Contact> contacts = new ArrayList<Contact>();
-
- /**
- * The list of sub groups belonging to this group.
- */
- private List<ContactGroup> subGroups = new ArrayList<ContactGroup>();
-
- /**
- * The group that this group belongs to (or null if this is the root group).
- */
- private ContactGroupDictImpl parentGroup = null;
-
- /**
- * Determines whether this group is really in the contact list or whether
- * it is here only temporarily and will be gone next time we restart.
- */
- private boolean isPersistent = true;
-
- /**
- * The protocol provider that created us.
- */
- private ProtocolProviderServiceDictImpl parentProvider = null;
-
- /**
- * Determines whether this group has been resolved on the server.
- * Unresolved groups are groups that were available on previous runs and
- * that the meta contact list has stored. During all next runs, when
- * bootstrapping, the meta contact list would create these groups as
- * unresolved. Once a protocol provider implementation confirms that the
- * groups are still on the server, it would issue an event indicating that
- * the groups are now resolved.
- */
- private boolean isResolved = true;
-
- /**
- * An id uniquely identifying the group. For many protocols this could be
- * the group name itself.
- */
- private String uid = null;
- private static final String UID_SUFFIX = ".uid";
-
- /**
- * Creates a ContactGroupDictImpl with the specified name.
- *
- * @param groupName the name of the group.
- * @param parentProvider the protocol provider that created this group.
- */
- public ContactGroupDictImpl(
- String groupName,
- ProtocolProviderServiceDictImpl parentProvider)
- {
- this.groupName = groupName;
- this.uid = groupName + UID_SUFFIX;
- this.parentProvider = parentProvider;
- }
-
- /**
- * Determines whether the group may contain subgroups or not.
- *
- * @return always true in this implementation.
- */
- public boolean canContainSubgroups()
- {
- return true;
- }
-
- /**
- * Returns the protocol provider that this group belongs to.
- * @return a regerence to the ProtocolProviderService instance that this
- * ContactGroup belongs to.
- */
- public ProtocolProviderService getProtocolProvider()
- {
- return parentProvider;
- }
-
- /**
- * Returns an Iterator over all contacts, member of this
- * <tt>ContactGroup</tt>.
- *
- * @return a java.util.Iterator over all contacts inside this
- * <tt>ContactGroup</tt>
- */
- public Iterator<Contact> contacts()
- {
- return contacts.iterator();
- }
-
- /**
- * Adds the specified contact to this group.
- * @param contactToAdd the ContactDictImpl to add to this group.
- */
- public void addContact(ContactDictImpl contactToAdd)
- {
- this.contacts.add(contactToAdd);
- contactToAdd.setParentGroup(this);
- }
-
- /**
- * Returns the number of <tt>Contact</tt> members of this
- * <tt>ContactGroup</tt>
- *
- * @return an int indicating the number of <tt>Contact</tt>s, members of
- * this <tt>ContactGroup</tt>.
- */
- public int countContacts()
- {
- return contacts.size();
- }
-
- /**
- * Returns the number of subgroups contained by this
- * <tt>ContactGroup</tt>.
- *
- * @return the number of subGroups currently added to this group.
- */
- public int countSubgroups()
- {
- return subGroups.size();
- }
-
- /**
- * Adds the specified contact group to the contained by this group.
- * @param subgroup the ContactGroupDictImpl to add as a subgroup to this group.
- */
- public void addSubgroup(ContactGroupDictImpl subgroup)
- {
- this.subGroups.add(subgroup);
- subgroup.setParentGroup(this);
- }
-
- /**
- * Sets the group that is the new parent of this group
- * @param parent ContactGroupDictImpl
- */
- void setParentGroup(ContactGroupDictImpl parent)
- {
- this.parentGroup = parent;
- }
-
- /**
- * Returns the contact group that currently contains this group or null if
- * this is the root contact group.
- * @return the contact group that currently contains this group or null if
- * this is the root contact group.
- */
- public ContactGroup getParentContactGroup()
- {
- return this.parentGroup;
- }
-
- /**
- * Removes the specified contact group from the this group's subgroups.
- * @param subgroup the ContactGroupDictImpl subgroup to remove.
- */
- public void removeSubGroup(ContactGroupDictImpl subgroup)
- {
- this.subGroups.remove(subgroup);
- subgroup.setParentGroup(null);
- }
-
- /**
- * Returns the group that is parent of the specified dictGroup or null
- * if no parent was found.
- * @param dictGroup the group whose parent we're looking for.
- * @return the ContactGroupDictImpl instance that dictGroup
- * belongs to or null if no parent was found.
- */
- public ContactGroupDictImpl findGroupParent(ContactGroupDictImpl dictGroup)
- {
- if ( subGroups.contains(dictGroup) )
- return this;
-
- Iterator<ContactGroup> subGroupsIter = subgroups();
- while (subGroupsIter.hasNext())
- {
- ContactGroupDictImpl subgroup
- = (ContactGroupDictImpl) subGroupsIter.next();
-
- ContactGroupDictImpl parent
- = subgroup.findGroupParent(dictGroup);
-
- if(parent != null)
- return parent;
- }
- return null;
- }
-
- /**
- * Returns the group that is parent of the specified dictContact or
- * null if no parent was found.
- *
- * @param dictContact the contact whose parent we're looking for.
- * @return the ContactGroupDictImpl instance that dictContact
- * belongs to or <tt>null</tt> if no parent was found.
- */
- public ContactGroupDictImpl findContactParent(
- ContactDictImpl dictContact)
- {
- if ( contacts.contains(dictContact) )
- return this;
-
- Iterator<ContactGroup> subGroupsIter = subgroups();
- while (subGroupsIter.hasNext())
- {
- ContactGroupDictImpl subgroup
- = (ContactGroupDictImpl) subGroupsIter.next();
-
- ContactGroupDictImpl parent
- = subgroup.findContactParent(dictContact);
-
- if(parent != null)
- return parent;
- }
- return null;
- }
-
-
-
- /**
- * Returns the <tt>Contact</tt> with the specified address or identifier.
- *
- * @param id the addres or identifier of the <tt>Contact</tt> we are
- * looking for.
- * @return the <tt>Contact</tt> with the specified id or address.
- */
- public Contact getContact(String id)
- {
- Iterator<Contact> contactsIter = contacts();
- while (contactsIter.hasNext())
- {
- ContactDictImpl contact = (ContactDictImpl) contactsIter.next();
- if (contact.getAddress().equals(id))
- return contact;
-
- }
- return null;
- }
-
- /**
- * Returns the subgroup with the specified index.
- *
- * @param index the index of the <tt>ContactGroup</tt> to retrieve.
- * @return the <tt>ContactGroup</tt> with the specified index.
- */
- public ContactGroup getGroup(int index)
- {
- return subGroups.get(index);
- }
-
- /**
- * Returns the subgroup with the specified name.
- *
- * @param groupName the name of the <tt>ContactGroup</tt> to retrieve.
- * @return the <tt>ContactGroup</tt> with the specified index.
- */
- public ContactGroup getGroup(String groupName)
- {
- Iterator<ContactGroup> groupsIter = subgroups();
- while (groupsIter.hasNext())
- {
- ContactGroupDictImpl contactGroup
- = (ContactGroupDictImpl) groupsIter.next();
- if (contactGroup.getGroupName().equals(groupName))
- return contactGroup;
-
- }
- return null;
-
- }
-
- /**
- * Returns the name of this group.
- *
- * @return a String containing the name of this group.
- */
- public String getGroupName()
- {
- return this.groupName;
- }
-
- /**
- * Sets this group a new name.
- * @param newGrpName a String containing the new name of this group.
- */
- public void setGroupName(String newGrpName)
- {
- this.groupName = newGrpName;
- }
-
- /**
- * Returns an iterator over the sub groups that this
- * <tt>ContactGroup</tt> contains.
- *
- * @return a java.util.Iterator over the <tt>ContactGroup</tt> children
- * of this group (i.e. subgroups).
- */
- public Iterator<ContactGroup> subgroups()
- {
- return subGroups.iterator();
- }
-
- /**
- * Removes the specified contact from this group.
- * @param contact the ContactDictImpl to remove from this group
- */
- public void removeContact(ContactDictImpl contact)
- {
- this.contacts.remove(contact);
- }
-
- /**
- * Returns the contact with the specified id or null if no such contact
- * exists.
- * @param id the id of the contact we're looking for.
- * @return ContactDictImpl
- */
- public ContactDictImpl findContactByID(String id)
- {
- //first go through the contacts that are direct children.
- Iterator<Contact> contactsIter = contacts();
-
- while(contactsIter.hasNext())
- {
- ContactDictImpl mContact = (ContactDictImpl)contactsIter.next();
-
- if( mContact.getAddress().equals(id) )
- return mContact;
- }
-
- //if we didn't find it here, let's try in the subougroups
- Iterator<ContactGroup> groupsIter = subgroups();
-
- while( groupsIter.hasNext() )
- {
- ContactGroupDictImpl mGroup = (ContactGroupDictImpl)groupsIter.next();
-
- ContactDictImpl mContact = mGroup.findContactByID(id);
-
- if (mContact != null)
- return mContact;
- }
-
- return null;
- }
-
-
- /**
- * Returns a String representation of this group and the contacts it
- * contains (may turn out to be a relatively long string).
- * @return a String representing this group and its child contacts.
- */
- @Override
- public String toString()
- {
-
- StringBuffer buff = new StringBuffer(getGroupName());
- buff.append(".subGroups=" + countSubgroups() + ":\n");
-
- Iterator<ContactGroup> subGroups = subgroups();
- while (subGroups.hasNext())
- {
- ContactGroupDictImpl group = (ContactGroupDictImpl)subGroups.next();
- buff.append(group.toString());
- if (subGroups.hasNext())
- buff.append("\n");
- }
-
- buff.append("\nChildContacts="+countContacts()+":[");
-
- Iterator<Contact> contacts = contacts();
- while (contacts.hasNext())
- {
- ContactDictImpl contact = (ContactDictImpl) contacts.next();
- buff.append(contact.toString());
- if(contacts.hasNext())
- buff.append(", ");
- }
- return buff.append("]").toString();
- }
-
- /**
- * Specifies whether or not this contact group is being stored by the server.
- * Non persistent contact groups are common in the case of simple,
- * non-persistent presence operation sets. They could however also be seen
- * in persistent presence operation sets when for example we have received
- * an event from someone not on our contact list and the contact that we
- * associated with that user is placed in a non persistent group. Non
- * persistent contact groups are volatile even when coming from a persistent
- * presence op. set. They would only exist until the application is closed
- * and will not be there next time it is loaded.
- *
- * @param isPersistent true if the contact group is to be persistent and
- * false otherwise.
- */
- public void setPersistent(boolean isPersistent)
- {
- this.isPersistent = isPersistent;
- }
-
- /**
- * Determines whether or not this contact group is being stored by the
- * server. Non persistent contact groups exist for the sole purpose of
- * containing non persistent contacts.
- * @return true if the contact group is persistent and false otherwise.
- */
- public boolean isPersistent()
- {
- return isPersistent;
- }
-
- /**
- * Returns null as no persistent data is required and the contact address is
- * sufficient for restoring the contact.
- * <p>
- * @return null as no such data is needed.
- */
- public String getPersistentData()
- {
- return null;
- }
-
- /**
- * Determines whether or not this contact has been resolved against the
- * server. Unresolved contacts are used when initially loading a contact
- * list that has been stored in a local file until the presence operation
- * set has managed to retrieve all the contact list from the server and has
- * properly mapped contacts to their on-line buddies.
- * @return true if the contact has been resolved (mapped against a buddy)
- * and false otherwise.
- */
- public boolean isResolved()
- {
- return isResolved;
- }
-
- /**
- * Makes the group resolved or unresolved.
- *
- * @param resolved true to make the group resolved; false to
- * make it unresolved
- */
- public void setResolved(boolean resolved)
- {
- this.isResolved = resolved;
- }
-
- /**
- * Returns a <tt>String</tt> that uniquely represnets the group inside
- * the current protocol. The string MUST be persistent (it must not change
- * across connections or runs of the application). In many cases (Jabber,
- * ICQ) the string may match the name of the group as these protocols
- * only allow a single level of contact groups and there is no danger of
- * having the same name twice in the same contact list. Other protocols
- * (no examples come to mind but that doesn't bother me ;) ) may be
- * supporting mutilple levels of grooups so it might be possible for group
- * A and group B to both contain groups named C. In such cases the
- * implementation must find a way to return a unique identifier in this
- * method and this UID should never change for a given group.
- *
- * @return a String representing this group in a unique and persistent
- * way.
- */
- public String getUID()
- {
- return uid;
- }
-
- /**
- * Ugly but tricky conversion method.
- * @param uid the uid we'd like to get a name from
- * @return the name of the group with the specified <tt>uid</tt>.
- */
- static String createNameFromUID(String uid)
- {
- return uid.substring(0, uid.length() - (UID_SUFFIX.length()));
- }
-
- /**
- * Indicates whether some other object is "equal to" this one which in terms
- * of contact groups translates to having the equal names and matching
- * subgroups and child contacts. The resolved status of contactgroups and
- * contacts is deliberately ignored so that groups and/or contacts would
- * be assumed equal even if it differs.
- * <p>
- * @param obj the reference object with which to compare.
- * @return <code>true</code> if this contact group has the equal child
- * contacts and subgroups to those of the <code>obj</code> argument.
- */
- @Override
- public boolean equals(Object obj)
- {
- if(obj == null
- || !(obj instanceof ContactGroupDictImpl))
- return false;
-
- ContactGroupDictImpl dictGroup
- = (ContactGroupDictImpl)obj;
-
- if( ! dictGroup.getGroupName().equals(getGroupName())
- || ! dictGroup.getUID().equals(getUID())
- || dictGroup.countContacts() != countContacts()
- || dictGroup.countSubgroups() != countSubgroups())
- return false;
-
- //traverse child contacts
- Iterator<Contact> theirContacts = dictGroup.contacts();
-
- while(theirContacts.hasNext())
- {
- ContactDictImpl theirContact
- = (ContactDictImpl)theirContacts.next();
-
- ContactDictImpl ourContact
- = (ContactDictImpl)getContact(theirContact.getAddress());
-
- if(ourContact == null
- || !ourContact.equals(theirContact))
- return false;
- }
-
- //traverse subgroups
- Iterator<ContactGroup> theirSubgroups = dictGroup.subgroups();
-
- while(theirSubgroups.hasNext())
- {
- ContactGroupDictImpl theirSubgroup
- = (ContactGroupDictImpl)theirSubgroups.next();
-
- ContactGroupDictImpl ourSubgroup
- = (ContactGroupDictImpl)getGroup(
- theirSubgroup.getGroupName());
-
- if(ourSubgroup == null
- || !ourSubgroup.equals(theirSubgroup))
- return false;
- }
-
- return true;
- }
-}
-
diff --git a/src/net/java/sip/communicator/impl/protocol/dict/DictAccountID.java b/src/net/java/sip/communicator/impl/protocol/dict/DictAccountID.java
deleted file mode 100644
index 538ae71..0000000
--- a/src/net/java/sip/communicator/impl/protocol/dict/DictAccountID.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.dict;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * The Dict implementation of a sip-communicator account id.
- * @author LITZELMANN Cedric
- * @author ROTH Damien
- */
-public class DictAccountID
- extends AccountID
-{
- /**
- * Creates an account id from the specified id and account properties.
- *
- * @param userID the user identifier correspnding to the account
- * @param accountProperties any other properties necessary for the account.
- */
- DictAccountID(String userID, Map<String, String> accountProperties)
- {
- super(userID, accountProperties, ProtocolNames.DICT, "dict.org");
- }
-
- /**
- * Returns the dict server adress
- * @return the dict server adress
- */
- public String getHost()
- {
- return getAccountPropertyString(ProtocolProviderFactory.SERVER_ADDRESS);
- }
-
- /**
- * Returns the dict server port
- * @return the dict server port
- */
- public int getPort()
- {
- return Integer
- .parseInt(getAccountPropertyString(ProtocolProviderFactory.SERVER_PORT));
- }
-
- /**
- * Returns the selected strategy
- * @return the selected strategy
- */
- public String getStrategy()
- {
- return getAccountPropertyString(ProtocolProviderFactory.STRATEGY);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/dict/DictActivator.java b/src/net/java/sip/communicator/impl/protocol/dict/DictActivator.java
deleted file mode 100644
index b5976c7..0000000
--- a/src/net/java/sip/communicator/impl/protocol/dict/DictActivator.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.dict;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.resources.*;
-import org.osgi.framework.*;
-
-/**
- * Loads the Dict provider factory and registers its services in the OSGI
- * bundle context.
- *
- * @author ROTH Damien
- * @author LITZELMANN Cedric
- */
-public class DictActivator
- implements BundleActivator
-{
- private static final Logger logger = Logger.getLogger(DictActivator.class);
-
- /**
- * The currently valid bundle context.
- */
- private static BundleContext bundleContext = null;
-
- private ServiceRegistration dictPpFactoryServReg = null;
- private static ProtocolProviderFactoryDictImpl
- dictProviderFactory = null;
-
- private static ResourceManagementService resourceService;
-
- /**
- * Called when this bundle is started. In here we'll export the
- * dict ProtocolProviderFactory implementation so that it could be
- * possible to register accounts with it in SIP Communicator.
- *
- * @param context The execution context of the bundle being started.
- * @throws Exception If this method throws an exception, this bundle is
- * marked as stopped and the Framework will remove this bundle's
- * listeners, unregister all services registered by this bundle, and
- * release all services used by this bundle.
- */
- public void start(BundleContext context)
- throws Exception
- {
- bundleContext = context;
-
- Hashtable<String,String> hashtable = new Hashtable<String,String>();
- hashtable.put(ProtocolProviderFactory.PROTOCOL, ProtocolNames.DICT);
-
- dictProviderFactory = new ProtocolProviderFactoryDictImpl();
-
- //reg the dict provider factory.
- dictPpFactoryServReg = context.registerService(
- ProtocolProviderFactory.class.getName(),
- dictProviderFactory,
- hashtable);
-
- if (logger.isInfoEnabled())
- logger.info("DICT protocol implementation [STARTED].");
- }
-
- /**
- * Returns a reference to the bundle context that we were started with.
- * @return a reference to the BundleContext instance that we were started
- * witn.
- */
- public static BundleContext getBundleContext()
- {
- return bundleContext;
- }
-
- /**
- * Called when this bundle is stopped so the Framework can perform the
- * bundle-specific activities necessary to stop the bundle.
- *
- * @param context The execution context of the bundle being stopped.
- * @throws Exception If this method throws an exception, the bundle is
- * still marked as stopped, and the Framework will remove the bundle's
- * listeners, unregister all services registered by the bundle, and
- * release all services used by the bundle.
- */
- public void stop(BundleContext context)
- throws Exception
- {
-
- dictProviderFactory.stop();
- dictPpFactoryServReg.unregister();
-
- if (logger.isInfoEnabled())
- logger.info("DICT protocol implementation [STOPPED].");
- }
-
- /**
- * Returns a reference to the protocol provider factory that we have
- * registered.
- * @return a reference to the <tt>ProtocolProviderFactoryDictImpl</tt>
- * instance that we have registered from this package.
- */
- public static ProtocolProviderFactoryDictImpl getProtocolProviderFactory()
- {
- return dictProviderFactory;
- }
-
-
- /**
- * Returns the <tt>ResourceManagementService</tt>.
- *
- * @return the <tt>ResourceManagementService</tt>.
- */
- public static ResourceManagementService getResources()
- {
- if (resourceService == null)
- {
- ServiceReference serviceReference = bundleContext
- .getServiceReference(ResourceManagementService.class.getName());
-
- if(serviceReference == null)
- return null;
-
- resourceService = (ResourceManagementService) bundleContext
- .getService(serviceReference);
- }
-
- return resourceService;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/dict/DictStatusEnum.java b/src/net/java/sip/communicator/impl/protocol/dict/DictStatusEnum.java
deleted file mode 100644
index 87086f7..0000000
--- a/src/net/java/sip/communicator/impl/protocol/dict/DictStatusEnum.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.dict;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * An implementation of <tt>PresenceStatus</tt> that enumerates all states that
- * a Dict contact can fall into.
- *
- * @author ROTH Damien
- * @author LITZELMANN Cedric
- */
-public class DictStatusEnum
- extends PresenceStatus
-{
-
- /**
- * Indicates an Offline status or status with 0 connectivity.
- */
- public static final DictStatusEnum OFFLINE
- = new DictStatusEnum(
- 0, "Offline",
- DictActivator.getResources()
- .getImageInBytes("service.protocol.dict.OFFLINE_STATUS_ICON"));
-
- /**
- * The Online status. Indicate that the user is able and willing to
- * communicate.
- */
- public static final DictStatusEnum ONLINE
- = new DictStatusEnum(
- 65, "Online",
- DictActivator.getResources()
- .getImageInBytes("service.protocol.dict.DICT_16x16"));
-
- /**
- * Initialize the list of supported status states.
- */
- private static List<PresenceStatus> supportedStatusSet = new LinkedList<PresenceStatus>();
- static
- {
- supportedStatusSet.add(OFFLINE);
- supportedStatusSet.add(ONLINE);
- }
-
- /**
- * Creates an instance of <tt>RssPresneceStatus</tt> with the
- * specified parameters.
- * @param status the connectivity level of the new presence status instance
- * @param statusName the name of the presence status.
- * @param statusIcon the icon associated with this status
- */
- private DictStatusEnum(int status,
- String statusName,
- byte[] statusIcon)
- {
- super(status, statusName, statusIcon);
- }
-
- /**
- * Returns an iterator over all status instances supproted by the rss
- * provider.
- * @return an <tt>Iterator</tt> over all status instances supported by the
- * rss provider.
- */
- static Iterator<PresenceStatus> supportedStatusSet()
- {
- return supportedStatusSet.iterator();
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/dict/MessageDictImpl.java b/src/net/java/sip/communicator/impl/protocol/dict/MessageDictImpl.java
deleted file mode 100644
index 5b95dd4..0000000
--- a/src/net/java/sip/communicator/impl/protocol/dict/MessageDictImpl.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.dict;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * Very simple message implementation for the Dict protocol.
- *
- * @author ROTH Damien
- * @author LITZELMANN Cedric
- * @author Lubomir Marinov
- */
-public class MessageDictImpl
- extends AbstractMessage
-{
-
- /**
- * Creates a message instance according to the specified parameters.
- *
- * @param content the message body
- * @param contentType message content type or null for text/plain
- * @param contentEncoding message encoding or null for UTF8
- * @param subject the subject of the message or null for no subject.
- */
- public MessageDictImpl(String content, String contentType,
- String contentEncoding, String subject)
- {
- super(content, contentType, contentEncoding, subject);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/dict/OperationSetBasicInstantMessagingDictImpl.java b/src/net/java/sip/communicator/impl/protocol/dict/OperationSetBasicInstantMessagingDictImpl.java
deleted file mode 100644
index f1f4973..0000000
--- a/src/net/java/sip/communicator/impl/protocol/dict/OperationSetBasicInstantMessagingDictImpl.java
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.dict;
-
-import java.util.*;
-
-import net.java.dict4j.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Instant messaging functionalities for the Dict protocol.
- *
- * @author ROTH Damien
- * @author LITZELMANN Cedric
- */
-public class OperationSetBasicInstantMessagingDictImpl
- extends AbstractOperationSetBasicInstantMessaging
- implements RegistrationStateChangeListener
-{
- /**
- * The currently valid persistent presence operation set.
- */
- private OperationSetPersistentPresenceDictImpl opSetPersPresence = null;
-
- /**
- * The protocol provider that created us.
- */
- private ProtocolProviderServiceDictImpl parentProvider = null;
-
- private DictAccountID accountID;
-
- /**
- * Creates an instance of this operation set keeping a reference to the
- * parent protocol provider and presence operation set.
- *
- * @param provider The provider instance that creates us.
- * @param opSetPersPresence the currently valid
- * <tt>OperationSetPersistentPresenceDictImpl</tt> instance.
- */
- public OperationSetBasicInstantMessagingDictImpl(
- ProtocolProviderServiceDictImpl provider,
- OperationSetPersistentPresenceDictImpl opSetPersPresence)
- {
- this.opSetPersPresence = opSetPersPresence;
- this.parentProvider = provider;
- this.accountID = (DictAccountID) provider.getAccountID();
-
- parentProvider.addRegistrationStateChangeListener(this);
- }
-
- @Override
- public Message createMessage(String content)
- {
- return new MessageDictImpl(content, HTML_MIME_TYPE,
- DEFAULT_MIME_ENCODING, null);
- }
-
- @Override
- public Message createMessage(String content, String contentType,
- String encoding, String subject)
- {
- return new MessageDictImpl(content, contentType, encoding, subject);
- }
-
- /**
- * Sends the <tt>message</tt> to the destination indicated by the
- * <tt>to</tt> contact.
- *
- * @param to the <tt>Contact</tt> to send <tt>message</tt> to
- * @param message the <tt>Message</tt> to send.
- * @throws IllegalStateException if the underlying ICQ stack is not
- * registered and initialized.
- * @throws IllegalArgumentException if <tt>to</tt> is not an instance
- * belonging to the underlying implementation.
- */
- public void sendInstantMessage(Contact to, Message message)
- throws IllegalStateException,
- IllegalArgumentException
- {
- if( !(to instanceof ContactDictImpl) )
- {
- throw new IllegalArgumentException(
- "The specified contact is not a Dict contact."
- + to);
- }
-
- // Remove all html tags from the message
- message = createMessage(Html2Text.extractText(message.getContent()));
-
- // Display the queried word
- fireMessageDelivered(message, to);
-
- this.submitDictQuery((ContactDictImpl) to, message);
- }
-
- /**
- * Determines whether the protocol provider (or the protocol itself) supports
- * sending and receiving offline messages. Most often this method would
- * return true for protocols that support offline messages and false for
- * those that don't. It is however possible for a protocol to support these
- * messages and yet have a particular account that does not (i.e. feature
- * not enabled on the protocol server). In cases like this it is possible
- * for this method to return true even when offline messaging is not
- * supported, and then have the sendMessage method throw an
- * OperationFailedException with code - OFFLINE_MESSAGES_NOT_SUPPORTED.
- *
- * @return <tt>true</tt> if the protocol supports offline messages and
- * <tt>false</tt> otherwise.
- */
- public boolean isOfflineMessagingSupported()
- {
- return false;
- }
-
- /**
- * Determines whether the protocol supports the supplied content type.
- *
- * @param contentType the type we want to check
- * @return <tt>true</tt> if the protocol supports it and
- * <tt>false</tt> otherwise.
- */
- public boolean isContentTypeSupported(String contentType)
- {
- if(contentType.equals(DEFAULT_MIME_TYPE))
- return true;
- else if(contentType.equals(HTML_MIME_TYPE))
- return true;
- else
- return false;
- }
-
- /**
- * Returns the protocol provider that this operation set belongs to.
- *
- * @return a reference to the <tt>ProtocolProviderServiceDictImpl</tt>
- * instance that this operation set belongs to.
- */
- public ProtocolProviderServiceDictImpl getParentProvider()
- {
- return this.parentProvider;
- }
-
- /**
- * Returns a reference to the presence operation set instance used by our
- * source provider.
- *
- * @return a reference to the <tt>OperationSetPersistentPresenceDictImpl</tt>
- * instance used by this provider.
- */
- public OperationSetPersistentPresenceDictImpl getOpSetPersPresence()
- {
- return this.opSetPersPresence;
- }
-
- /**
- * The method is called by the ProtocolProvider whenever a change in the
- * registration state of the corresponding provider has occurred.
- *
- * @param evt ProviderStatusChangeEvent the event describing the status
- * change.
- */
- public void registrationStateChanged(RegistrationStateChangeEvent evt)
- {
-
- }
-
-
- /**
- * Create, execute and display a query to a dictionary (ContactDictImpl)
- *
- * @param dictContact the contact containing the database name
- * @param message the message containing the word
- */
- private void submitDictQuery(ContactDictImpl dictContact, Message message)
- {
- Message msg = this.createMessage("");
-
- String database = dictContact.getContactID();
- DictConnection conn = this.parentProvider.getConnection();
- boolean doMatch = false;
-
- String word;
-
- // Formatting the query message, if the word as one or more spaces we
- // put it between quotes to prevent errors
- word = message.getContent().replace("\"", "").trim();
- if (word.indexOf(' ') > 0)
- {
- word = "\"" + word + "\"";
- }
-
- // Try to get the definition of the work
- try
- {
- List<Definition> definitions = conn.define(database, word);
- msg = this.createMessage(retrieveDefine(definitions, word));
- }
- catch(DictException dx)
- {
- if (dx.getErrorCode() == DictReturnCode.NO_MATCH)
- { // No word found, we are going to try the match command
- doMatch = true;
- }
- else
- { // Otherwise we display the error returned by the server
- msg = this.createMessage(manageException(dx, database));
- }
- }
-
- if (doMatch)
- {
- // Trying the match command
- try
- {
- List<MatchWord> matchWords = conn.match(database, word,
- this.accountID.getStrategy());
- msg = this.createMessage(retrieveMatch(matchWords, word));
- }
- catch(DictException dx)
- {
- msg = this.createMessage(manageException(dx, database));
- }
- }
-
- // Send message
- fireMessageReceived(msg, dictContact);
- }
-
- /**
- * Generate the display of the results of the Define command
- *
- * @param data the result of the Define command
- * @param word the queried word
- * @return the formatted result
- */
- private String retrieveDefine(List<Definition> data, String word)
- {
- StringBuffer res = new StringBuffer();
- Definition def;
-
- for (int i=0; i<data.size(); i++)
- {
- def = data.get(i);
-
- if(i != 0 && data.size() > 0)
- {
- res.append("<hr>");
- }
- res.append(def.getDefinition().replaceAll("\n", "<br>"))
- .append("<div align=\"right\"><font size=\"-2\">-- From ")
- .append(def.getDictionary())
- .append("</font></div>");
- }
-
- String result = res.toString();
- result = formatResult(result, "\\\\", "<em>", "</em>");
- result = formatResult(result, "[\\[\\]]", "<cite>", "</cite>");
- result = formatResult(result, "[\\{\\}]", "<strong>", "</strong>");
- result = formatWordDefined(result, word);
-
- return result;
- }
-
- /**
- * Makes a stronger emphasis for the word defined.
- * @param result The text containing the definition of the word.
- * @param word The word defined to display with bold font. For this we
- * had the strong HTML tag.
- * @return Returns the result text with an strong emphasis of all
- * the occurences of the word defined.
- */
- private String formatWordDefined(String result, String word)
- {
- String tmpWord;
-
- tmpWord = word.toUpperCase();
- result = result.replaceAll("\\b" + tmpWord + "\\b", "<strong>" + tmpWord + "</strong>");
- tmpWord = word.toLowerCase();
- result = result.replaceAll("\\b" + tmpWord + "\\b", "<strong>" + tmpWord + "</strong>");
- if(tmpWord.length() > 1)
- {
- tmpWord = tmpWord.substring(0, 1).toUpperCase() + tmpWord.substring(1);
- result = result.replaceAll("\\b" + tmpWord + "\\b", "<strong>" + tmpWord + "</strong>");
- }
-
- return result;
- }
-
- /**
- * Remplaces special characters into HTML tags to make some emphasis.
- * @param result The text containing the definition of the word.
- * @param regex The special character to replace with HTML tags.
- * @param startTag The start HTML tag to use.
- * @param endTag The end HTML tag to use.
- * @return The result with all special characters replaced by HTML
- * tags.
- */
- private String formatResult(String result, String regex, String startTag, String endTag)
- {
- String[] tmp = result.split(regex);
- String res = "";
-
- for(int i = 0; i < (tmp.length - 1); i += 2)
- {
- res += tmp[i] + startTag + tmp[i+1] + endTag;
- }
- if((tmp.length % 2) != 0)
- {
- res += tmp[tmp.length - 1];
- }
- return res;
- }
-
- /**
- * Generate the display of the results of the Match command
- *
- * @param data the result of the Match command
- * @param word the queried word
- * @return the formatted result
- */
- private String retrieveMatch(List<MatchWord> data, String word)
- {
- StringBuffer result = new StringBuffer();
- boolean isStart = true;
-
- result.append(DictActivator.getResources()
- .getI18NString("plugin.dictaccregwizz.MATCH_RESULT", new String[] {word}));
-
- for (int i=0; i<data.size(); i++)
- {
- if (isStart)
- isStart = false;
- else
- result.append(", ");
-
- result.append(data.get(i).getWord());
- }
-
- return result.toString();
- }
-
- /**
- * Manages the return exception of a dict query.
- *
- * @param dix The exception returned by the adapter
- * @param database The dictionary used
- * @return Exception message
- */
- private String manageException(DictException dix, String database)
- {
- int errorCode = dix.getErrorCode();
-
- // We change the text only for exception 550 (invalid dictionary) and 551 (invalid strategy)
- if (errorCode == DictReturnCode.INVALID_DATABASE)
- {
- return DictActivator.getResources()
- .getI18NString("plugin.dictaccregwizz.INVALID_DATABASE", new String[] {database});
- }
- else if (errorCode == DictReturnCode.INVALID_STRATEGY)
- {
- return DictActivator.getResources()
- .getI18NString("plugin.dictaccregwizz.INVALID_STRATEGY");
- }
- else if (errorCode == DictReturnCode.NO_MATCH)
- {
- return DictActivator.getResources()
- .getI18NString("plugin.dictaccregwizz.NO_MATCH");
- }
-
- return dix.getMessage();
- }
-
- /**
- * Sends the <tt>message</tt> to the destination indicated by the
- * <tt>to</tt>. Resources are not supported by this operation set
- * implementation.
- *
- * @param to the <tt>Contact</tt> to send <tt>message</tt> to
- * @param toResource the resource to which the message should be send
- * @param message the <tt>Message</tt> to send.
- * @throws java.lang.IllegalStateException if the underlying ICQ stack is
- * not registered and initialized.
- * @throws java.lang.IllegalArgumentException if <tt>to</tt> is not an
- * instance belonging to the underlying implementation.
- */
- @Override
- public void sendInstantMessage( Contact to,
- ContactResource toResource,
- Message message)
- throws IllegalStateException,
- IllegalArgumentException
- {
- sendInstantMessage(to, message);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/dict/OperationSetPersistentPresenceDictImpl.java b/src/net/java/sip/communicator/impl/protocol/dict/OperationSetPersistentPresenceDictImpl.java
deleted file mode 100644
index 8184fe9..0000000
--- a/src/net/java/sip/communicator/impl/protocol/dict/OperationSetPersistentPresenceDictImpl.java
+++ /dev/null
@@ -1,988 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.dict;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * A Dict implementation of a persistent presence operation set. In order
- * to simulate server persistence, this operation set would simply accept all
- * unresolved contacts and resolve them immediately. A real world protocol
- * implementation would save it on a server using methods provided by the
- * protocol stack.
- *
- * @author ROTH Damien
- * @author LITZELMANN Cedric
- */
-public class OperationSetPersistentPresenceDictImpl
- extends AbstractOperationSetPersistentPresence<ProtocolProviderServiceDictImpl>
-{
- private static final Logger logger =
- Logger.getLogger(OperationSetPersistentPresenceDictImpl.class);
-
- /**
- * The root of the dict contact list.
- */
- private ContactGroupDictImpl contactListRoot = null;
-
- /**
- * The currently active status message.
- */
- private String statusMessage = "Default Status Message";
-
- /**
- * Our presence status.
- */
- private PresenceStatus presenceStatus = DictStatusEnum.ONLINE;
-
- /**
- * The <tt>AuthorizationHandler</tt> instance that we'd have to transmit
- * authorization requests to for approval.
- */
- private AuthorizationHandler authorizationHandler = null;
-
- /**
- * Creates an instance of this operation set keeping a reference to the
- * specified parent <tt>provider</tt>.
- * @param provider the ProtocolProviderServiceDictImpl instance that
- * created us.
- */
- public OperationSetPersistentPresenceDictImpl(
- ProtocolProviderServiceDictImpl provider)
- {
- super(provider);
-
- contactListRoot = new ContactGroupDictImpl("RootGroup", provider);
-
- //add our unregistration listener
- parentProvider.addRegistrationStateChangeListener(
- new UnregistrationListener());
- }
-
- /**
- * Creates a group with the specified name and parent in the server
- * stored contact list.
- *
- * @param parent the group where the new group should be created
- * @param groupName the name of the new group to create.
- */
- public void createServerStoredContactGroup(ContactGroup parent,
- String groupName)
- {
- ContactGroupDictImpl newGroup
- = new ContactGroupDictImpl(groupName, parentProvider);
-
- ((ContactGroupDictImpl)parent).addSubgroup(newGroup);
-
- this.fireServerStoredGroupEvent(
- newGroup, ServerStoredGroupEvent.GROUP_CREATED_EVENT);
- }
-
- /**
- * A Dict Provider method to use for fast filling of a contact list.
- *
- * @param contactGroup the group to add
- */
- public void addDictGroup(ContactGroupDictImpl contactGroup)
- {
- contactListRoot.addSubgroup(contactGroup);
- }
-
- /**
- * A Dict Provider method to use for fast filling of a contact list.
- * This method would add both the group and fire an event.
- *
- * @param parent the group where <tt>contactGroup</tt> should be added.
- * @param contactGroup the group to add
- */
- public void addDictGroupAndFireEvent(
- ContactGroupDictImpl parent
- , ContactGroupDictImpl contactGroup)
- {
- parent.addSubgroup(contactGroup);
-
- this.fireServerStoredGroupEvent(
- contactGroup, ServerStoredGroupEvent.GROUP_CREATED_EVENT);
- }
-
-
- /**
- * Returns a reference to the contact with the specified ID in case we
- * have a subscription for it and null otherwise/
- *
- * @param contactID a String identifier of the contact which we're
- * seeking a reference of.
- * @return a reference to the Contact with the specified
- * <tt>contactID</tt> or null if we don't have a subscription for the
- * that identifier.
- */
- public Contact findContactByID(String contactID)
- {
- return contactListRoot.findContactByID(contactID);
- }
-
- /**
- * Sets the specified status message.
- * @param statusMessage a String containing the new status message.
- */
- public void setStatusMessage(String statusMessage)
- {
- this.statusMessage = statusMessage;
- }
-
- /**
- * Returns the status message that was last set through
- * setCurrentStatusMessage.
- *
- * @return the last status message that we have requested and the aim
- * server has confirmed.
- */
- public String getCurrentStatusMessage()
- {
- return statusMessage;
- }
-
- /**
- * Returns the protocol specific contact instance representing the local
- * user.
- *
- * @return the Contact (address, phone number, or uin) that the Provider
- * implementation is communicating on behalf of.
- */
- public Contact getLocalContact()
- {
- return null;
- }
-
- /**
- * Returns a PresenceStatus instance representing the state this provider
- * is currently in.
- *
- * @return the PresenceStatus last published by this provider.
- */
- public PresenceStatus getPresenceStatus()
- {
- return presenceStatus;
- }
-
- /**
- * Returns the root group of the server stored contact list.
- *
- * @return the root ContactGroup for the ContactList stored by this
- * service.
- */
- public ContactGroup getServerStoredContactListRoot()
- {
- return contactListRoot;
- }
-
- /**
- * Returns the set of PresenceStatus objects that a user of this service
- * may request the provider to enter.
- *
- * @return Iterator a PresenceStatus array containing "enterable" status
- * instances.
- */
- public Iterator<PresenceStatus> getSupportedStatusSet()
- {
- return DictStatusEnum.supportedStatusSet();
- }
-
- /**
- * Removes the specified contact from its current parent and places it
- * under <tt>newParent</tt>.
- *
- * @param contactToMove the <tt>Contact</tt> to move
- * @param newParent the <tt>ContactGroup</tt> where <tt>Contact</tt>
- * would be placed.
- */
- public void moveContactToGroup(Contact contactToMove,
- ContactGroup newParent)
- {
- ContactDictImpl dictContact
- = (ContactDictImpl)contactToMove;
-
- ContactGroupDictImpl parentDictGroup
- = findContactParent(dictContact);
-
- parentDictGroup.removeContact(dictContact);
-
- //if this is a volatile contact then we haven't really subscribed to
- //them so we'd need to do so here
- if(!dictContact.isPersistent())
- {
- //first tell everyone that the volatile contact was removed
- fireSubscriptionEvent(dictContact
- , parentDictGroup
- , SubscriptionEvent.SUBSCRIPTION_REMOVED);
-
- try
- {
- //now subscribe
- this.subscribe(newParent, contactToMove.getAddress());
-
- //now tell everyone that we've added the contact
- fireSubscriptionEvent(dictContact
- , newParent
- , SubscriptionEvent.SUBSCRIPTION_CREATED);
- }
- catch (Exception ex)
- {
- logger.error("Failed to move contact "
- + dictContact.getAddress()
- , ex);
- }
- }
- else
- {
- ( (ContactGroupDictImpl) newParent)
- .addContact(dictContact);
-
- fireSubscriptionMovedEvent(contactToMove
- , parentDictGroup
- , newParent);
- }
- }
-
- /**
- * Requests the provider to enter into a status corresponding to the
- * specified paramters.
- *
- * @param status the PresenceStatus as returned by
- * getRequestableStatusSet
- * @param statusMessage the message that should be set as the reason to
- * enter that status
- * @throws IllegalArgumentException if the status requested is not a
- * valid PresenceStatus supported by this provider.
- * @throws IllegalStateException if the provider is not currently
- * registered.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * publishing the status fails due to a network error.
- */
- public void publishPresenceStatus(PresenceStatus status,
- String statusMessage) throws
- IllegalArgumentException, IllegalStateException,
- OperationFailedException
- {
- PresenceStatus oldPresenceStatus = this.presenceStatus;
- this.presenceStatus = status;
- this.statusMessage = statusMessage;
-
- this.fireProviderStatusChangeEvent(oldPresenceStatus);
-
- //since we are not a real protocol, we set the contact presence status
- //ourselves and make them have the same status as ours.
- changePresenceStatusForAllContacts( getServerStoredContactListRoot()
- , getPresenceStatus());
-
- //now check whether we are in someone else's contact list and modify
- //our status there
- List<Contact> contacts = findContactsPointingToUs();
-
- Iterator<Contact> contactsIter = contacts.iterator();
- while (contactsIter.hasNext())
- {
- ContactDictImpl contact
- = (ContactDictImpl) contactsIter.next();
-
- PresenceStatus oldStatus = contact.getPresenceStatus();
- contact.setPresenceStatus(status);
- contact.getParentPresenceOperationSet()
- .fireContactPresenceStatusChangeEvent(
- contact
- , contact.getParentContactGroup()
- , oldStatus);
-
- }
- }
-
-
-
- /**
- * Get the PresenceStatus for a particular contact.
- *
- * @param contactIdentifier the identifier of the contact whose status
- * we're interested in.
- * @return PresenceStatus the <tt>PresenceStatus</tt> of the specified
- * <tt>contact</tt>
- * @throws IllegalArgumentException if <tt>contact</tt> is not a contact
- * known to the underlying protocol provider
- * @throws IllegalStateException if the underlying protocol provider is
- * not registered/signed on a public service.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * retrieving the status fails due to errors experienced during
- * network communication
- */
- public PresenceStatus queryContactStatus(String contactIdentifier) throws
- IllegalArgumentException, IllegalStateException,
- OperationFailedException
- {
- return findContactByID(contactIdentifier).getPresenceStatus();
- }
-
- /**
- * Sets the presence status of <tt>contact</tt> to <tt>newStatus</tt>.
- *
- * @param contact the <tt>ContactDictImpl</tt> whose status we'd like
- * to set.
- * @param newStatus the new status we'd like to set to <tt>contact</tt>.
- */
- private void changePresenceStatusForContact(
- ContactDictImpl contact
- , PresenceStatus newStatus)
- {
- PresenceStatus oldStatus = contact.getPresenceStatus();
- contact.setPresenceStatus(newStatus);
-
- fireContactPresenceStatusChangeEvent(
- contact, findContactParent(contact), oldStatus);
- }
-
- /**
- * Sets the presence status of all <tt>contact</tt>s in our contact list
- * (except those that correspond to another provider registered with SC)
- * to <tt>newStatus</tt>.
- *
- * @param newStatus the new status we'd like to set to <tt>contact</tt>.
- * @param parent the group in which we'd have to update the status of all
- * direct and indirect child contacts.
- */
- private void changePresenceStatusForAllContacts(ContactGroup parent,
- PresenceStatus newStatus)
- {
- //first set the status for contacts in this group
- Iterator<Contact> childContacts = parent.contacts();
-
- while(childContacts.hasNext())
- {
- ContactDictImpl contact
- = (ContactDictImpl)childContacts.next();
-
- if(findProviderForDictUserID(contact.getAddress()) != null)
- {
- //this is a contact corresponding to another SIP Communicator
- //provider so we won't change it's status here.
- continue;
- }
- PresenceStatus oldStatus = contact.getPresenceStatus();
- contact.setPresenceStatus(newStatus);
-
- fireContactPresenceStatusChangeEvent(
- contact, parent, oldStatus);
- }
-
- //now call this method recursively for all subgroups
- Iterator<ContactGroup> subgroups = parent.subgroups();
-
- while(subgroups.hasNext())
- {
- ContactGroup subgroup = subgroups.next();
- changePresenceStatusForAllContacts(subgroup, newStatus);
- }
- }
-
- /**
- * Returns the group that is parent of the specified dictGroup or null
- * if no parent was found.
- * @param dictGroup the group whose parent we're looking for.
- * @return the ContactGroupDictImpl instance that dictGroup
- * belongs to or null if no parent was found.
- */
- public ContactGroupDictImpl findGroupParent(
- ContactGroupDictImpl dictGroup)
- {
- return contactListRoot.findGroupParent(dictGroup);
- }
-
- /**
- * Returns the group that is parent of the specified dictContact or
- * null if no parent was found.
- * @param dictContact the contact whose parent we're looking for.
- * @return the ContactGroupDictImpl instance that dictContact
- * belongs to or null if no parent was found.
- */
- public ContactGroupDictImpl findContactParent(
- ContactDictImpl dictContact)
- {
- return (ContactGroupDictImpl)dictContact
- .getParentContactGroup();
- }
-
-
- /**
- * Removes the specified group from the server stored contact list.
- *
- * @param group the group to remove.
- *
- * @throws IllegalArgumentException if <tt>group</tt> was not found in this
- * protocol's contact list.
- */
- public void removeServerStoredContactGroup(ContactGroup group)
- throws IllegalArgumentException
- {
- ContactGroupDictImpl dictGroup
- = (ContactGroupDictImpl)group;
-
- ContactGroupDictImpl parent = findGroupParent(dictGroup);
-
- if(parent == null){
- throw new IllegalArgumentException(
- "group " + group
- + " does not seem to belong to this protocol's contact list.");
- }
-
- parent.removeSubGroup(dictGroup);
-
- this.fireServerStoredGroupEvent(
- dictGroup, ServerStoredGroupEvent.GROUP_REMOVED_EVENT);
- }
-
- /**
- * Renames the specified group from the server stored contact list.
- *
- * @param group the group to rename.
- * @param newName the new name of the group.
- */
- public void renameServerStoredContactGroup(ContactGroup group,
- String newName)
- {
- ((ContactGroupDictImpl)group).setGroupName(newName);
-
- this.fireServerStoredGroupEvent(
- group, ServerStoredGroupEvent.GROUP_RENAMED_EVENT);
- }
-
- /**
- * Handler for incoming authorization requests.
- *
- * @param handler an instance of an AuthorizationHandler for
- * authorization requests coming from other users requesting
- * permission add us to their contact list.
- */
- public void setAuthorizationHandler(AuthorizationHandler handler)
- {
- this.authorizationHandler = handler;
- }
-
- /**
- * Persistently adds a subscription for the presence status of the
- * contact corresponding to the specified contactIdentifier and indicates
- * that it should be added to the specified group of the server stored
- * contact list.
- *
- * @param parent the parent group of the server stored contact list
- * where the contact should be added. <p>
- * @param contactIdentifier the contact whose status updates we are
- * subscribing for.
- * @throws IllegalArgumentException if <tt>contact</tt> or
- * <tt>parent</tt> are not a contact known to the underlying protocol
- * provider.
- * @throws IllegalStateException if the underlying protocol provider is
- * not registered/signed on a public service.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * subscribing fails due to errors experienced during network
- * communication
- */
- public void subscribe(ContactGroup parent, String contactIdentifier) throws
- IllegalArgumentException, IllegalStateException,
- OperationFailedException
- {
- ContactDictImpl contact = new ContactDictImpl(
- contactIdentifier
- , parentProvider);
-
- ((ContactGroupDictImpl)parent).addContact(contact);
-
- fireSubscriptionEvent(contact,
- parent,
- SubscriptionEvent.SUBSCRIPTION_CREATED);
-
- //notify presence listeners for the status change.
- fireContactPresenceStatusChangeEvent(contact
- , parent
- , DictStatusEnum.ONLINE);
- }
-
-
- /**
- * Depending on whether <tt>contact</tt> corresponds to another protocol
- * provider installed in sip-communicator, this method would either deliver
- * it to that provider or simulate a corresponding request from the
- * destination contact and make return a response after it has received
- * one If the destination contact matches us, then we'll ask the user to
- * act upon the request, and return the response.
- *
- * @param request the authorization request that we'd like to deliver to the
- * destination <tt>contact</tt>.
- * @param contact the <tt>Contact</tt> to notify
- *
- * @return the <tt>AuthorizationResponse</tt> that has been given or
- * generated in response to <tt>request</tt>.
- */
- private AuthorizationResponse deliverAuthorizationRequest(
- AuthorizationRequest request,
- Contact contact)
- {
- String userID = contact.getAddress();
-
- //if the user id is our own id, then this request is being routed to us
- //from another instance of the dict provider.
- if (userID.equals(this.parentProvider.getAccountID().getUserID()))
- {
- //check who is the provider sending the message
- String sourceUserID = contact.getProtocolProvider()
- .getAccountID().getUserID();
-
- //check whether they are in our contact list
- Contact from = findContactByID(sourceUserID);
-
- //and if not - add them there as volatile.
- if (from == null)
- {
- from = createVolatileContact(sourceUserID);
- }
-
- //and now handle the request.
- return authorizationHandler.processAuthorisationRequest(
- request, from);
- }
- else
- {
- //if userID is not our own, try a check whether another provider
- //has that id and if yes - deliver the request to them.
- ProtocolProviderServiceDictImpl dictProvider
- = this.findProviderForDictUserID(userID);
- if (dictProvider != null)
- {
- OperationSetPersistentPresenceDictImpl opSetPersPresence
- = (OperationSetPersistentPresenceDictImpl)
- dictProvider.getOperationSet(
- OperationSetPersistentPresence.class);
- return opSetPersPresence
- .deliverAuthorizationRequest(request, contact);
- }
- else
- {
- //if we got here then "to" is simply someone in our contact
- //list so let's just simulate a reciproce request and generate
- //a response accordingly.
-
- //pretend that the remote contact is asking for authorization
- authorizationHandler.processAuthorisationRequest(
- request, contact);
-
- //and now pretend that the remote contact has granted us
- //authorization
- return new AuthorizationResponse(AuthorizationResponse.ACCEPT
- , "You are welcome!");
- }
- }
- }
-
- /**
- * Adds a subscription for the presence status of the contact
- * corresponding to the specified contactIdentifier.
- *
- * @param contactIdentifier the identifier of the contact whose status
- * updates we are subscribing for. <p>
- * @throws IllegalArgumentException if <tt>contact</tt> is not a contact
- * known to the underlying protocol provider
- * @throws IllegalStateException if the underlying protocol provider is
- * not registered/signed on a public service.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * subscribing fails due to errors experienced during network
- * communication
- */
- public void subscribe(String contactIdentifier) throws
- IllegalArgumentException, IllegalStateException,
- OperationFailedException
- {
- //subscribe(contactListRoot, contactIdentifier);
-
- }
-
- /**
- * Removes a subscription for the presence status of the specified
- * contact.
- *
- * @param contact the contact whose status updates we are unsubscribing
- * from.
- * @throws IllegalArgumentException if <tt>contact</tt> is not a contact
- * known to the underlying protocol provider
- * @throws IllegalStateException if the underlying protocol provider is
- * not registered/signed on a public service.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * unsubscribing fails due to errors experienced during network
- * communication
- */
- public void unsubscribe(Contact contact) throws IllegalArgumentException,
- IllegalStateException, OperationFailedException
- {
- ContactGroupDictImpl parentGroup
- = (ContactGroupDictImpl)((ContactDictImpl)contact)
- .getParentContactGroup();
-
- parentGroup.removeContact((ContactDictImpl)contact);
-
- fireSubscriptionEvent(contact,
- ((ContactDictImpl)contact).getParentContactGroup()
- , SubscriptionEvent.SUBSCRIPTION_REMOVED);
- }
-
- /**
- * Creates and returns a unresolved contact from the specified
- * <tt>address</tt> and <tt>persistentData</tt>. The method will not try
- * to establish a network connection and resolve the newly created Contact
- * against the server. The protocol provider may will later try and resolve
- * the contact. When this happens the corresponding event would notify
- * interested subscription listeners.
- *
- * @param address an identifier of the contact that we'll be creating.
- * @param persistentData a String returned Contact's getPersistentData()
- * method during a previous run and that has been persistently stored
- * locally.
- * @return the unresolved <tt>Contact</tt> created from the specified
- * <tt>address</tt> and <tt>persistentData</tt>
- */
- public Contact createUnresolvedContact(String address,
- String persistentData)
- {
- return createUnresolvedContact(address
- , persistentData
- , getServerStoredContactListRoot());
- }
-
- /**
- * Creates and returns a unresolved contact from the specified
- * <tt>address</tt> and <tt>persistentData</tt>. The method will not try
- * to establish a network connection and resolve the newly created Contact
- * against the server. The protocol provider may will later try and resolve
- * the contact. When this happens the corresponding event would notify
- * interested subscription listeners.
- *
- * @param address an identifier of the contact that we'll be creating.
- * @param persistentData a String returned Contact's getPersistentData()
- * method during a previous run and that has been persistently stored
- * locally.
- * @param parent the group where the unresolved contact is
- * supposed to belong to.
- *
- * @return the unresolved <tt>Contact</tt> created from the specified
- * <tt>address</tt> and <tt>persistentData</tt>
- */
- public Contact createUnresolvedContact(String address,
- String persistentData,
- ContactGroup parent)
- {
-
- ContactDictImpl contact = new ContactDictImpl(
- address
- , parentProvider);
- contact.setResolved(false);
-
- ( (ContactGroupDictImpl) parent).addContact(contact);
-
- fireSubscriptionEvent(contact,
- parent,
- SubscriptionEvent.SUBSCRIPTION_CREATED);
-
- //since we don't have any server, we'll simply resolve the contact
- //ourselves as if we've just received an event from the server telling
- //us that it has been resolved.
- contact.setResolved(true);
- fireSubscriptionEvent(contact, parent, SubscriptionEvent.SUBSCRIPTION_RESOLVED);
-
- //since we are not a real protocol, we set the contact presence status
- //ourselves
- changePresenceStatusForContact( contact, getPresenceStatus());
-
- return contact;
- }
-
- /**
- * Looks for a dict protocol provider registered for a user id matching
- * <tt>dictUserID</tt>.
- *
- * @param dictUserID the ID of the Dict user whose corresponding
- * protocol provider we'd like to find.
- * @return ProtocolProviderServiceDictImpl a dict protocol
- * provider registered for a user with id <tt>dictUserID</tt> or null
- * if there is no such protocol provider.
- */
- public ProtocolProviderServiceDictImpl
- findProviderForDictUserID(String dictUserID)
- {
- BundleContext bc = DictActivator.getBundleContext();
-
- String osgiQuery = "(&"
- + "(" + ProtocolProviderFactory.PROTOCOL
- + "=Dict)"
- + "(" + ProtocolProviderFactory.USER_ID
- + "=" + dictUserID + ")"
- + ")";
-
- ServiceReference[] refs = null;
- try
- {
- refs = bc.getServiceReferences(
- ProtocolProviderService.class.getName()
- ,osgiQuery);
- }
- catch (InvalidSyntaxException ex)
- {
- logger.error("Failed to execute the following osgi query: "
- + osgiQuery
- , ex);
- }
-
- if(refs != null && refs.length > 0)
- {
- return (ProtocolProviderServiceDictImpl)bc.getService(refs[0]);
- }
-
- return null;
- }
-
- /**
- * Looks for dict protocol providers that have added us to their
- * contact list and returns list of all contacts representing us in these
- * providers.
- *
- * @return a list of all contacts in other providers' contact lists that
- * point to us.
- */
- public List<Contact> findContactsPointingToUs()
- {
- List<Contact> contacts = new LinkedList<Contact>();
- BundleContext bc = DictActivator.getBundleContext();
-
- String osgiQuery =
- "(" + ProtocolProviderFactory.PROTOCOL
- + "=Dict)";
-
- ServiceReference[] refs = null;
- try
- {
- refs = bc.getServiceReferences(
- ProtocolProviderService.class.getName()
- ,osgiQuery);
- }
- catch (InvalidSyntaxException ex)
- {
- logger.error("Failed to execute the following osgi query: "
- + osgiQuery
- , ex);
- }
-
- for (int i =0; refs != null && i < refs.length; i++)
- {
- ProtocolProviderServiceDictImpl gibProvider
- = (ProtocolProviderServiceDictImpl)bc.getService(refs[i]);
-
- OperationSetPersistentPresenceDictImpl opSetPersPresence
- = (OperationSetPersistentPresenceDictImpl)gibProvider
- .getOperationSet(OperationSetPersistentPresence.class);
-
- Contact contact = opSetPersPresence.findContactByID(
- parentProvider.getAccountID().getUserID());
-
- if (contact != null)
- contacts.add(contact);
- }
-
- return contacts;
- }
-
-
- /**
- * Creates and returns a unresolved contact group from the specified
- * <tt>address</tt> and <tt>persistentData</tt>. The method will not try
- * to establish a network connection and resolve the newly created
- * <tt>ContactGroup</tt> against the server or the contact itself. The
- * protocol provider will later resolve the contact group. When this happens
- * the corresponding event would notify interested subscription listeners.
- *
- * @param groupUID an identifier, returned by ContactGroup's getGroupUID,
- * that the protocol provider may use in order to create the group.
- * @param persistentData a String returned ContactGroups's
- * getPersistentData() method during a previous run and that has been
- * persistently stored locally.
- * @param parentGroup the group under which the new group is to be created
- * or null if this is group directly underneath the root.
- * @return the unresolved <tt>ContactGroup</tt> created from the specified
- * <tt>uid</tt> and <tt>persistentData</tt>
- */
- public ContactGroup createUnresolvedContactGroup(String groupUID,
- String persistentData, ContactGroup parentGroup)
- {
- ContactGroupDictImpl newGroup
- = new ContactGroupDictImpl(
- ContactGroupDictImpl.createNameFromUID(groupUID)
- , parentProvider);
- newGroup.setResolved(false);
-
- //if parent is null then we're adding under root.
- if(parentGroup == null)
- parentGroup = getServerStoredContactListRoot();
-
- ((ContactGroupDictImpl)parentGroup).addSubgroup(newGroup);
-
- this.fireServerStoredGroupEvent(
- newGroup, ServerStoredGroupEvent.GROUP_CREATED_EVENT);
-
- return newGroup;
- }
-
- private class UnregistrationListener
- implements RegistrationStateChangeListener
- {
- /**
- * The method is called by a ProtocolProvider implementation whenver
- * a change in the registration state of the corresponding provider had
- * occurred. The method is particularly interested in events stating
- * that the dict provider has unregistered so that it would fire
- * status change events for all contacts in our buddy list.
- *
- * @param evt ProviderStatusChangeEvent the event describing the status
- * change.
- */
- public void registrationStateChanged(RegistrationStateChangeEvent evt)
- {
- if (! evt.getNewState().equals(RegistrationState.UNREGISTERED)
- && !evt.getNewState().equals(RegistrationState.AUTHENTICATION_FAILED)
- && !evt.getNewState().equals(RegistrationState.CONNECTION_FAILED))
- {
- return;
- }
-
- //send event notifications saying that all our buddies are
- //offline. The icq protocol does not implement top level buddies
- //nor subgroups for top level groups so a simple nested loop
- //would be enough.
- Iterator<ContactGroup> groupsIter = getServerStoredContactListRoot()
- .subgroups();
- while (groupsIter.hasNext())
- {
- ContactGroupDictImpl group
- = (ContactGroupDictImpl) groupsIter.next();
-
- Iterator<Contact> contactsIter = group.contacts();
-
- while (contactsIter.hasNext())
- {
- ContactDictImpl contact
- = (ContactDictImpl) contactsIter.next();
-
- PresenceStatus oldContactStatus
- = contact.getPresenceStatus();
-
- if (!oldContactStatus.isOnline())
- continue;
-
- contact.setPresenceStatus(DictStatusEnum.OFFLINE);
-
- fireContactPresenceStatusChangeEvent(
- contact
- , contact.getParentContactGroup()
- , oldContactStatus);
- }
- }
- }
- }
-
- /**
- * Returns the volatile group or null if this group has not yet been
- * created.
- *
- * @return a volatile group existing in our contact list or <tt>null</tt>
- * if such a group has not yet been created.
- */
- private ContactGroupDictImpl getNonPersistentGroup()
- {
- for (int i = 0
- ; i < getServerStoredContactListRoot().countSubgroups()
- ; i++)
- {
- ContactGroupDictImpl gr =
- (ContactGroupDictImpl)getServerStoredContactListRoot()
- .getGroup(i);
-
- if(!gr.isPersistent())
- return gr;
- }
-
- return null;
- }
-
-
- /**
- * Creates a non persistent contact for the specified address. This would
- * also create (if necessary) a group for volatile contacts that would not
- * be added to the server stored contact list. This method would have no
- * effect on the server stored contact list.
- *
- * @param contactAddress the address of the volatile contact we'd like to
- * create.
- * @return the newly created volatile contact.
- */
- public ContactDictImpl createVolatileContact(String contactAddress)
- {
- //First create the new volatile contact;
- ContactDictImpl newVolatileContact
- = new ContactDictImpl(contactAddress
- , this.parentProvider);
- newVolatileContact.setPersistent(false);
-
-
- //Check whether a volatile group already exists and if not create
- //one
- ContactGroupDictImpl theVolatileGroup = getNonPersistentGroup();
-
-
- //if the parent volatile group is null then we create it
- if (theVolatileGroup == null)
- {
- theVolatileGroup = new ContactGroupDictImpl(
- DictActivator.getResources().getI18NString(
- "service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME")
- , parentProvider);
- theVolatileGroup.setResolved(false);
- theVolatileGroup.setPersistent(false);
-
- this.contactListRoot.addSubgroup(theVolatileGroup);
-
- fireServerStoredGroupEvent(theVolatileGroup
- , ServerStoredGroupEvent.GROUP_CREATED_EVENT);
- }
-
- //now add the volatile contact instide it
- theVolatileGroup.addContact(newVolatileContact);
- fireSubscriptionEvent(newVolatileContact
- , theVolatileGroup
- , SubscriptionEvent.SUBSCRIPTION_CREATED);
-
- return newVolatileContact;
- }
-
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/dict/ProtocolIconDictImpl.java b/src/net/java/sip/communicator/impl/protocol/dict/ProtocolIconDictImpl.java
deleted file mode 100644
index 4f09f22..0000000
--- a/src/net/java/sip/communicator/impl/protocol/dict/ProtocolIconDictImpl.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.dict;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * Represents the Dict protocol icon. Implements the <tt>ProtocolIcon</tt>
- * interface in order to provide a Dict logo image in two different sizes.
- *
- * @author ROTH Damien
- * @author LITZELMANN Cedric
- */
-public class ProtocolIconDictImpl
- implements ProtocolIcon
-{
- /**
- * A hash table containing the protocol icon in different sizes.
- */
- private static Hashtable<String,byte[]> iconsTable
- = new Hashtable<String,byte[]>();
- static
- {
- iconsTable.put(ProtocolIcon.ICON_SIZE_16x16,
- DictActivator.getResources()
- .getImageInBytes("service.protocol.dict.DICT_16x16"));
-
- iconsTable.put(ProtocolIcon.ICON_SIZE_32x32,
- DictActivator.getResources()
- .getImageInBytes("service.protocol.dict.DICT_32x32"));
-
- iconsTable.put(ProtocolIcon.ICON_SIZE_48x48,
- DictActivator.getResources()
- .getImageInBytes("service.protocol.dict.DICT_48x48"));
-
- iconsTable.put(ProtocolIcon.ICON_SIZE_64x64,
- DictActivator.getResources()
- .getImageInBytes("service.protocol.dict.DICT_64x64"));
- }
-
- /**
- * A hash table containing the path to the protocol icon in different sizes.
- */
- private static Hashtable<String, String> iconPathsTable
- = new Hashtable<String, String>();
- static
- {
- iconPathsTable.put(ProtocolIcon.ICON_SIZE_16x16,
- DictActivator.getResources()
- .getImagePath("service.protocol.dict.DICT_16x16"));
-
- iconPathsTable.put(ProtocolIcon.ICON_SIZE_32x32,
- DictActivator.getResources()
- .getImagePath("service.protocol.dict.DICT_32x32"));
-
- iconPathsTable.put(ProtocolIcon.ICON_SIZE_48x48,
- DictActivator.getResources()
- .getImagePath("service.protocol.dict.DICT_48x48"));
-
- iconPathsTable.put(ProtocolIcon.ICON_SIZE_64x64,
- DictActivator.getResources()
- .getImagePath("service.protocol.dict.DICT_64x64"));
- }
-
- /**
- * Implements the <tt>ProtocolIcon.getSupportedSizes()</tt> method. Returns
- * an iterator to a set containing the supported icon sizes.
- * @return Returns an iterator to a set containing the supported icon sizes
- */
- public Iterator<String> getSupportedSizes()
- {
- return iconsTable.keySet().iterator();
- }
-
- /**
- * Returns TRUE if an icon with the given size is supported, FALSE otherwise.
- * @param iconSize The size of the icon, that we want to know if it is
- * supported.
- * @return Returns true if the size is supported. False otherwise.
- */
- public boolean isSizeSupported(String iconSize)
- {
- return iconsTable.containsKey(iconSize);
- }
-
- /**
- * Returns the icon image in the given size.
- * @param iconSize The icon size one of ICON_SIZE_XXX constants
- * @return Returns a byte[] containing the pixels of the icon for the given
- * size.
- */
- public byte[] getIcon(String iconSize)
- {
- return iconsTable.get(iconSize);
- }
-
- /**
- * Returns a path to the icon with the given size.
- * @param iconSize the size of the icon we're looking for
- * @return the path to the icon with the given size
- */
- public String getIconPath(String iconSize)
- {
- return iconPathsTable.get(iconSize);
- }
-
- /**
- * Returns the icon image used to represent the protocol connecting state.
- * @return Returns the icon image used to represent the protocol connecting
- * state.
- */
- public byte[] getConnectingIcon()
- {
- return iconsTable.get(ProtocolIcon.ICON_SIZE_16x16);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/dict/ProtocolProviderFactoryDictImpl.java b/src/net/java/sip/communicator/impl/protocol/dict/ProtocolProviderFactoryDictImpl.java
deleted file mode 100644
index d7eaf30..0000000
--- a/src/net/java/sip/communicator/impl/protocol/dict/ProtocolProviderFactoryDictImpl.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.dict;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.contactlist.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * The Dict protocol provider factory creates instances of the Dict
- * protocol provider service. One Service instance corresponds to one account.
- *
- * @author ROTH Damien
- * @author LITZELMANN Cedric
- */
-public class ProtocolProviderFactoryDictImpl
- extends ProtocolProviderFactory
-{
- private static final Logger logger
- = Logger.getLogger(ProtocolProviderFactoryDictImpl.class);
-
- /**
- * Creates an instance of the ProtocolProviderFactoryDictImpl.
- */
- public ProtocolProviderFactoryDictImpl()
- {
- super(DictActivator.getBundleContext(), ProtocolNames.DICT);
- }
-
- /**
- * Initializaed and creates an account corresponding to the specified
- * accountProperties and registers the resulting ProtocolProvider in the
- * <tt>context</tt> BundleContext parameter.
- *
- * @param userIDStr The user identifier uniquely representing the newly
- * created account within the protocol namespace.
- * @param accountProperties a set of protocol (or implementation)
- * specific properties defining the new account.
- * @return the AccountID of the newly created account.
- */
- @Override
- public AccountID installAccount( String userIDStr,
- Map<String, String> accountProperties)
- {
- BundleContext context = DictActivator.getBundleContext();
- if (context == null)
- {
- throw new NullPointerException("The specified BundleContext was null");
- }
- if (userIDStr == null)
- {
- throw new NullPointerException("The specified AccountID was null");
- }
- if (accountProperties == null)
- {
- throw new NullPointerException("The specified property map was null");
- }
-
- accountProperties.put(USER_ID, userIDStr);
-
- AccountID accountID = new DictAccountID(userIDStr, accountProperties);
-
- //make sure we haven't seen this account id before.
- if (registeredAccounts.containsKey(accountID))
- {
- throw new IllegalStateException("An account for id " + userIDStr + " was already installed!");
- }
-
- //first store the account and only then load it as the load generates
- //an osgi event, the osgi event triggers (through the UI) a call to the
- //ProtocolProviderService.register() method and it needs to acces
- //the configuration service and check for a stored password.
- this.storeAccount(accountID, false);
-
- accountID = loadAccount(accountProperties);
-
- // Creates the dict contact group.
- this.createGroup();
- // Creates the default conatct for this dict server.
- this.createDefaultContact(accountID);
-
- return accountID;
- }
-
- @Override
- protected AccountID createAccountID(String userID, Map<String, String> accountProperties)
- {
- return new DictAccountID(userID, accountProperties);
- }
-
- @Override
- protected ProtocolProviderService createService(String userID,
- AccountID accountID)
- {
- ProtocolProviderServiceDictImpl service =
- new ProtocolProviderServiceDictImpl();
-
- service.initialize(userID, accountID);
- return service;
- }
-
- /**
- * Creates a group for the dict contacts
- */
- private void createGroup()
- {
- // Get MetaContactListService
- BundleContext bundleContext = getBundleContext();
- ServiceReference<MetaContactListService> mfcServiceRef
- = bundleContext.getServiceReference(MetaContactListService.class);
-
- MetaContactListService mcl = bundleContext.getService(mfcServiceRef);
-
- try
- {
- String groupName = DictActivator.getResources()
- .getI18NString("service.protocol.DICTIONARIES");
-
- mcl.createMetaContactGroup(mcl.getRoot(), groupName);
- }
- catch (MetaContactListException ex)
- {
- int errorCode = ex.getErrorCode();
- if (errorCode != MetaContactListException.CODE_GROUP_ALREADY_EXISTS_ERROR)
- {
- logger.error(ex);
- }
- }
- }
-
- /**
- * Creates a default contact for the new DICT server.
- * @param accountID The accountID of the dict protocol provider for which we
- * want to add a default contact.
- */
- private void createDefaultContact(AccountID accountID)
- {
- // Gets the MetaContactListService.
- BundleContext bundleContext = getBundleContext();
- ServiceReference<MetaContactListService> mfcServiceRef
- = bundleContext.getServiceReference(MetaContactListService.class);
- MetaContactListService mcl = bundleContext.getService(mfcServiceRef);
-
- // Gets the ProtocolProviderService.
- ServiceReference<ProtocolProviderService> serRef
- = getProviderForAccount(accountID);
- ProtocolProviderService protocolProvider
- = DictActivator.getBundleContext().getService(serRef);
-
- // Gets group name
- String groupName = DictActivator.getResources()
- .getI18NString("service.protocol.DICTIONARIES");
-
- // Gets contact name
- String contactName = DictActivator.getResources()
- .getI18NString("plugin.dictaccregwizz.ANY_DICTIONARY_FORM",
- new String[] {accountID.getUserID()});
-
- // Gets the MetaContactGroup for the "dictionaries" group.
- MetaContactGroup group = mcl.getRoot().getMetaContactSubgroup(groupName);
-
- // Sets the default contact identifier to "*" corresponding to "all the
- // dictionaries" available on the server (cf. RFC-2229).
- String dict_uin = "*";
- // Create the default contact.
- mcl.createMetaContact(protocolProvider, group, dict_uin);
- // Rename the default contact.
- mcl.renameMetaContact(
- group.getMetaContact(protocolProvider, dict_uin),
- contactName);
- }
-
- @Override
- public void modifyAccount(
- ProtocolProviderService protocolProvider,
- Map<String, String> accountProperties)
- throws NullPointerException
- {
- // TODO Auto-generated method stub
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/dict/ProtocolProviderServiceDictImpl.java b/src/net/java/sip/communicator/impl/protocol/dict/ProtocolProviderServiceDictImpl.java
deleted file mode 100644
index aa9ef50..0000000
--- a/src/net/java/sip/communicator/impl/protocol/dict/ProtocolProviderServiceDictImpl.java
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.dict;
-
-import net.java.dict4j.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.version.*;
-import org.osgi.framework.*;
-
-/**
- * A Dict implementation of the ProtocolProviderService.
- *
- * @author ROTH Damien
- * @author LITZELMANN Cedric
- */
-public class ProtocolProviderServiceDictImpl
- extends AbstractProtocolProviderService
-{
- private static final Logger logger
- = Logger.getLogger(ProtocolProviderServiceDictImpl.class);
-
- /**
- * The name of this protocol.
- */
- public static final String DICT_PROTOCOL_NAME = "Dict";
-
- /**
- * The id of the account that this protocol provider represents.
- */
- private DictAccountID accountID = null;
-
- /**
- * We use this to lock access to initialization.
- */
- private Object initializationLock = new Object();
-
- /**
- * Indicates whether or not the provider is initialized and ready for use.
- */
- private boolean isInitialized = false;
-
- /**
- * The logo corresponding to the gibberish protocol.
- */
- private ProtocolIconDictImpl dictIcon = new ProtocolIconDictImpl();
-
- /**
- * The registration state that we are currently in. Note that in a real
- * world protocol implementation this field won't exist and the registration
- * state would be retrieved from the protocol stack.
- */
- private RegistrationState currentRegistrationState
- = RegistrationState.UNREGISTERED;
-
- /**
- * the <tt>DictConnection</tt> opened by this provider
- */
- private DictConnection dictConnection;
-
- /**
- * The default constructor for the Dict protocol provider.
- */
- public ProtocolProviderServiceDictImpl()
- {
- if (logger.isTraceEnabled())
- logger.trace("Creating a Dict provider.");
- }
-
- /**
- * Initializes the service implementation, and puts it in a sate where it
- * could interoperate with other services. It is strongly recomended that
- * properties in this Map be mapped to property names as specified by
- * <tt>AccountProperties</tt>.
- *
- * @param userID the user id of the gibberish account we're currently
- * initializing
- * @param accountID the identifier of the account that this protocol
- * provider represents.
- *
- * @see net.java.sip.communicator.service.protocol.AccountID
- */
- protected void initialize(String userID,
- AccountID accountID)
- {
- synchronized(initializationLock)
- {
- this.accountID = (DictAccountID) accountID;
-
- this.dictConnection = new DictConnection(this.accountID.getHost(),
- this.accountID.getPort());
- this.dictConnection.setClientName(getSCVersion());
-
- //initialize the presence operationset
- OperationSetPersistentPresenceDictImpl persistentPresence =
- new OperationSetPersistentPresenceDictImpl(this);
-
- addSupportedOperationSet(
- OperationSetPersistentPresence.class,
- persistentPresence);
- //register it once again for those that simply need presence and
- //won't be smart enough to check for a persistent presence
- //alternative
- addSupportedOperationSet(
- OperationSetPresence.class,
- persistentPresence);
-
- //initialize the IM operation set
- addSupportedOperationSet(
- OperationSetBasicInstantMessaging.class,
- new OperationSetBasicInstantMessagingDictImpl(
- this,
- persistentPresence));
-
- //initialize the typing notifications operation set
- /*OperationSetTypingNotifications typingNotifications =
- new OperationSetTypingNotificationsDictImpl(
- this, persistentPresence);
-
- supportedOperationSets.put(
- OperationSetTypingNotifications.class.getName(),
- typingNotifications);
- */
- isInitialized = true;
- }
- }
-
- /**
- * Returns the <tt>DictConnection</tt> opened by this provider
- * @return the <tt>DictConnection</tt> opened by this provider
- */
- public DictConnection getConnection()
- {
- return this.dictConnection;
- }
-
- /**
- * Returns the AccountID that uniquely identifies the account represented
- * by this instance of the ProtocolProviderService.
- *
- * @return the id of the account represented by this provider.
- */
- public AccountID getAccountID()
- {
- return accountID;
- }
-
- /**
- * Returns the short name of the protocol that the implementation of this
- * provider is based upon (like SIP, Jabber, ICQ/AIM, or others for
- * example).
- *
- * @return a String containing the short name of the protocol this
- * service is implementing (most often that would be a name in
- * ProtocolNames).
- */
- public String getProtocolName()
- {
- return DICT_PROTOCOL_NAME;
- }
-
- /**
- * Returns the dict protocol icon.
- * @return the dict protocol icon
- */
- public ProtocolIcon getProtocolIcon()
- {
- return this.dictIcon;
- }
-
- /**
- * Returns the state of the registration of this protocol provider with
- * the corresponding registration service.
- *
- * @return ProviderRegistrationState
- */
- public RegistrationState getRegistrationState()
- {
- return currentRegistrationState;
- }
-
- /**
- * Starts the registration process.
- *
- * @param authority the security authority that will be used for
- * resolving any security challenges that may be returned during the
- * registration or at any moment while wer're registered.
- * @throws OperationFailedException with the corresponding code it the
- * registration fails for some reason (e.g. a networking error or an
- * implementation problem).
- */
- public void register(SecurityAuthority authority)
- throws OperationFailedException
- {
- // Try to connect to the server
- boolean connected = connect();
-
- if (connected)
- {
- fireRegistrationStateChanged(
- getRegistrationState(),
- RegistrationState.REGISTERED,
- RegistrationStateChangeEvent.REASON_USER_REQUEST,
- null);
- currentRegistrationState = RegistrationState.REGISTERED;
- }
- else
- {
- fireRegistrationStateChanged(
- getRegistrationState(),
- RegistrationState.CONNECTION_FAILED,
- RegistrationStateChangeEvent.REASON_SERVER_NOT_FOUND,
- null);
- currentRegistrationState = RegistrationState.UNREGISTERED;
- }
- }
-
- /**
- * Checks if the connection to the dict server is open
- * @return TRUE if the connection is open - FALSE otherwise
- */
- private boolean connect()
- {
- if (this.dictConnection.isConnected())
- {
- return true;
- }
-
- try
- {
- return this.dictConnection.isAvailable();
- }
- catch (DictException dx)
- {
- if (logger.isInfoEnabled())
- logger.info(dx);
- }
-
- return false;
- }
-
- /**
- * Makes the service implementation close all open sockets and release
- * any resources that it might have taken and prepare for
- * shutdown/garbage collection.
- */
- public void shutdown()
- {
- if(!isInitialized)
- {
- return;
- }
- if (logger.isTraceEnabled())
- logger.trace("Killing the Dict Protocol Provider for account "
- + this.accountID.getUserID());
-
- closeConnection();
-
- if(isRegistered())
- {
- try
- {
- //do the unregistration
- unregister();
- }
- catch (OperationFailedException ex)
- {
- //we're shutting down so we need to silence the exception here
- logger.error(
- "Failed to properly unregister before shutting down. "
- + getAccountID()
- , ex);
- }
- }
-
- isInitialized = false;
- }
-
- /**
- * Ends the registration of this protocol provider with the current
- * registration service.
- *
- * @throws OperationFailedException with the corresponding code it the
- * registration fails for some reason (e.g. a networking error or an
- * implementation problem).
- */
- public void unregister()
- throws OperationFailedException
- {
- closeConnection();
-
- fireRegistrationStateChanged(
- getRegistrationState(),
- RegistrationState.UNREGISTERED,
- RegistrationStateChangeEvent.REASON_USER_REQUEST,
- null);
- }
-
- /**
- * DICT has no support for secure transport.
- */
- public boolean isSignalingTransportSecure()
- {
- return false;
- }
-
- /**
- * Returns the "transport" protocol of this instance used to carry the
- * control channel for the current protocol service.
- *
- * @return The "transport" protocol of this instance: TCP.
- */
- public TransportProtocol getTransportProtocol()
- {
- return TransportProtocol.TCP;
- }
-
- /**
- * Close the connection to the server
- */
- private void closeConnection()
- {
- try
- {
- this.dictConnection.close();
- }
- catch (DictException dx)
- {
- if (logger.isInfoEnabled())
- logger.info(dx);
- }
- }
-
- /**
- * Returns the current version of SIP-Communicator
- * @return the current version of SIP-Communicator
- */
- private String getSCVersion()
- {
- BundleContext bc = DictActivator.getBundleContext();
- ServiceReference vsr = bc.getServiceReference(VersionService.class.getName());
-
- VersionService vs = (VersionService) bc.getService(vsr);
- return vs.getCurrentVersion().toString();
-
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/dict/dict.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/dict/dict.provider.manifest.mf
deleted file mode 100644
index d764657..0000000
--- a/src/net/java/sip/communicator/impl/protocol/dict/dict.provider.manifest.mf
+++ /dev/null
@@ -1,15 +0,0 @@
-Bundle-Activator: net.java.sip.communicator.impl.protocol.dict.DictActivator
-Bundle-Name: Dict Protocol Provider
-Bundle-Description: A bundle providing support for the Dict protocol.
-Bundle-Vendor: jitsi.org
-Bundle-Version: 1.0.0
-Bundle-SymbolicName: net.java.sip.communicator.protocol.dict
-Import-Package: org.osgi.framework,
- org.jitsi.service.version,
- net.java.sip.communicator.service.contactlist,
- org.jitsi.service.configuration,
- org.jitsi.service.resources, net.java.sip.communicator.service.resources,
- net.java.sip.communicator.util,
- net.java.sip.communicator.service.protocol,
- net.java.sip.communicator.service.protocol.event,
-Export-Package: net.java.dict4j
diff --git a/src/net/java/sip/communicator/impl/protocol/gibberish/ContactGroupGibberishImpl.java b/src/net/java/sip/communicator/impl/protocol/gibberish/ContactGroupGibberishImpl.java
index 2a95493..8528267 100644
--- a/src/net/java/sip/communicator/impl/protocol/gibberish/ContactGroupGibberishImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/gibberish/ContactGroupGibberishImpl.java
@@ -577,4 +577,29 @@ public class ContactGroupGibberishImpl
return true;
}
+
+ @Override
+ public int hashCode()
+ {
+ List<Object> objects = new ArrayList<Object>();
+ objects.add(getGroupName());
+ objects.add(getUID());
+ objects.add(countContacts());
+ objects.add(countSubgroups());
+
+ //traverse child contacts
+ for (Contact c : contacts)
+ {
+ objects.add(c.getAddress());
+ }
+
+
+ //traverse subgroups
+ for (ContactGroup g : subGroups)
+ {
+ objects.add(g.getGroupName());
+ }
+
+ return Objects.hash(objects.toArray());
+ }
}
diff --git a/src/net/java/sip/communicator/impl/protocol/icq/icq.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/icq/icq.provider.manifest.mf
index da47277..959ae6d 100644
--- a/src/net/java/sip/communicator/impl/protocol/icq/icq.provider.manifest.mf
+++ b/src/net/java/sip/communicator/impl/protocol/icq/icq.provider.manifest.mf
@@ -13,5 +13,4 @@ Import-Package: org.osgi.framework,
net.java.sip.communicator.service.dns,
net.java.sip.communicator.service.protocol,
net.java.sip.communicator.service.protocol.icqconstants,
- net.java.sip.communicator.service.protocol.aimconstants,
net.java.sip.communicator.service.protocol.event
diff --git a/src/net/java/sip/communicator/impl/protocol/irc/OperationSetMultiUserChatIrcImpl.java b/src/net/java/sip/communicator/impl/protocol/irc/OperationSetMultiUserChatIrcImpl.java
index 6b09978..7a1c2b3 100644
--- a/src/net/java/sip/communicator/impl/protocol/irc/OperationSetMultiUserChatIrcImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/irc/OperationSetMultiUserChatIrcImpl.java
@@ -275,7 +275,7 @@ public class OperationSetMultiUserChatIrcImpl
*/
protected ChatRoomIrcImpl getChatRoom(final String chatRoomName)
{
- return (ChatRoomIrcImpl) this.chatRoomCache.get(chatRoomName);
+ return this.chatRoomCache.get(chatRoomName);
}
/**
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/AnonymousLoginStrategy.java b/src/net/java/sip/communicator/impl/protocol/jabber/AnonymousLoginStrategy.java
index c955100..b62d01a 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/AnonymousLoginStrategy.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/AnonymousLoginStrategy.java
@@ -70,7 +70,7 @@ public class AnonymousLoginStrategy
}
@Override
- public boolean login(XMPPConnection connection, String userName,
+ public boolean login(Connection connection, String userName,
String resource)
throws XMPPException
{
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/CallJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/CallJabberImpl.java
index e23481a..3987ea8 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/CallJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/CallJabberImpl.java
@@ -311,7 +311,7 @@ public class CallJabberImpl
contentRequest.addChannel(remoteChannelRequest);
}
- XMPPConnection connection = protocolProvider.getConnection();
+ Connection connection = protocolProvider.getConnection();
PacketCollector packetCollector
= connection.createPacketCollector(
new PacketIDFilter(conferenceRequest.getPacketID()));
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerJabberImpl.java
index 64eb5fa..c257202 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerJabberImpl.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,1647 +15,1644 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.protocol.jabber;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import net.java.sip.communicator.impl.protocol.jabber.extensions.colibri.*;
-import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
-import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.ContentPacketExtension.SendersEnum;
-import net.java.sip.communicator.impl.protocol.jabber.jinglesdp.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.neomedia.*;
-import org.jivesoftware.smack.*;
-import org.jivesoftware.smack.filter.*;
-import org.jivesoftware.smack.packet.*;
-import org.jivesoftware.smack.util.*;
-import org.jivesoftware.smackx.packet.*;
-
-/**
- * Implements a Jabber <tt>CallPeer</tt>.
- *
- * @author Emil Ivov
- * @author Lyubomir Marinov
- * @author Boris Grozev
- */
-public class CallPeerJabberImpl
- extends AbstractCallPeerJabberGTalkImpl
- <CallJabberImpl, CallPeerMediaHandlerJabberImpl, JingleIQ>
-{
- /**
- * The <tt>Logger</tt> used by the <tt>CallPeerJabberImpl</tt> class and its
- * instances for logging output.
- */
- private static final Logger logger
- = Logger.getLogger(CallPeerJabberImpl.class);
-
- /**
- * If the call is cancelled before session-initiate is sent.
- */
- private boolean cancelled = false;
-
- /**
- * Synchronization object for candidates available.
- */
- private final Object candSyncRoot = new Object();
-
- /**
- * If the content-add does not contains candidates.
- */
- private boolean contentAddWithNoCands = false;
-
- /**
- * If we have processed the session initiate.
- */
- private boolean sessionInitiateProcessed = false;
-
- /**
- * Synchronization object. Synchronization object? Wow, who would have
- * thought! ;) Would be great to have a word on what we are syncing with it
- */
- private final Object sessionInitiateSyncRoot = new Object();
-
- /**
- * Synchronization object for SID.
- */
- private final Object sidSyncRoot = new Object();
-
- /**
- * The current value of the 'senders' field of the audio content in the
- * Jingle session with this <tt>CallPeer</tt>.
- * <tt>null</tt> should be interpreted as 'both', which is the default in
- * Jingle if the XML attribute is missing.
- */
- private SendersEnum audioSenders = SendersEnum.none;
-
- /**
- * The current value of the 'senders' field of the video content in the
- * Jingle session with this <tt>CallPeer</tt>.
- * <tt>null</tt> should be interpreted as 'both', which is the default in
- * Jingle if the XML attribute is missing.
- */
- private SendersEnum videoSenders = SendersEnum.none;
-
- /**
- * Creates a new call peer with address <tt>peerAddress</tt>.
- *
- * @param peerAddress the Jabber address of the new call peer.
- * @param owningCall the call that contains this call peer.
- */
- public CallPeerJabberImpl(String peerAddress,
- CallJabberImpl owningCall)
- {
- super(peerAddress, owningCall);
-
- setMediaHandler(new CallPeerMediaHandlerJabberImpl(this));
- }
-
- /**
- * Creates a new call peer with address <tt>peerAddress</tt>.
- *
- * @param peerAddress the Jabber address of the new call peer.
- * @param owningCall the call that contains this call peer.
- * @param sessionIQ The session-initiate <tt>JingleIQ</tt> which was
- * received from <tt>peerAddress</tt> and caused the creation of this
- * <tt>CallPeerJabberImpl</tt>
- */
- public CallPeerJabberImpl(String peerAddress,
- CallJabberImpl owningCall,
- JingleIQ sessionIQ)
- {
- this(peerAddress, owningCall);
- this.sessionInitIQ = sessionIQ;
- }
-
- /**
- * Send a session-accept <tt>JingleIQ</tt> to this <tt>CallPeer</tt>
- * @throws OperationFailedException if we fail to create or send the
- * response.
- */
- public synchronized void answer()
- throws OperationFailedException
- {
- Iterable<ContentPacketExtension> answer;
- CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
-
- try
- {
- mediaHandler
- .getTransportManager()
- .wrapupConnectivityEstablishment();
- answer = mediaHandler.generateSessionAccept();
- for (ContentPacketExtension c : answer)
- setSenders(getMediaType(c), c.getSenders());
- }
- catch(Exception exc)
- {
- logger.info("Failed to answer an incoming call", exc);
-
- //send an error response
- String reasonText = "Error: " + exc.getMessage();
- JingleIQ errResp
- = JinglePacketFactory.createSessionTerminate(
- sessionInitIQ.getTo(),
- sessionInitIQ.getFrom(),
- sessionInitIQ.getSID(),
- Reason.FAILED_APPLICATION,
- reasonText);
-
- setState(CallPeerState.FAILED, reasonText);
- getProtocolProvider().getConnection().sendPacket(errResp);
- return;
- }
-
- JingleIQ response
- = JinglePacketFactory.createSessionAccept(
- sessionInitIQ.getTo(),
- sessionInitIQ.getFrom(),
- getSID(),
- answer);
-
- //send the packet first and start the stream later in case the media
- //relay needs to see it before letting hole punching techniques through.
- getProtocolProvider().getConnection().sendPacket(response);
-
- try
- {
- mediaHandler.start();
- }
- catch(UndeclaredThrowableException e)
- {
- Throwable exc = e.getUndeclaredThrowable();
-
- logger.info("Failed to establish a connection", exc);
-
- //send an error response
- String reasonText = "Error: " + exc.getMessage();
- JingleIQ errResp
- = JinglePacketFactory.createSessionTerminate(
- sessionInitIQ.getTo(),
- sessionInitIQ.getFrom(),
- sessionInitIQ.getSID(),
- Reason.GENERAL_ERROR,
- reasonText);
-
- setState(CallPeerState.FAILED, reasonText);
- getProtocolProvider().getConnection().sendPacket(errResp);
- return;
- }
-
- //tell everyone we are connected so that the audio notifications would
- //stop
- setState(CallPeerState.CONNECTED);
- }
-
- /**
- * Returns the session ID of the Jingle session associated with this call.
- *
- * @return the session ID of the Jingle session associated with this call.
- */
- @Override
- public String getSID()
- {
- return sessionInitIQ != null ? sessionInitIQ.getSID() : null;
- }
-
- /**
- * Returns the IQ ID of the Jingle session-initiate packet associated with
- * this call.
- *
- * @return the IQ ID of the Jingle session-initiate packet associated with
- * this call.
- */
- public JingleIQ getSessionIQ()
- {
- return sessionInitIQ;
- }
-
- /**
- * Ends the call with this <tt>CallPeer</tt>. Depending on the state
- * of the peer the method would send a CANCEL, BYE, or BUSY_HERE message
- * and set the new state to DISCONNECTED.
- *
- * @param failed indicates if the hangup is following to a call failure or
- * simply a disconnect
- * @param reasonText the text, if any, to be set on the
- * <tt>ReasonPacketExtension</tt> as the value of its
- * @param reasonOtherExtension the <tt>PacketExtension</tt>, if any, to be
- * set on the <tt>ReasonPacketExtension</tt> as the value of its
- * <tt>otherExtension</tt> property
- */
- public void hangup(boolean failed,
- String reasonText,
- PacketExtension reasonOtherExtension)
- {
- CallPeerState prevPeerState = getState();
-
- // do nothing if the call is already ended
- if (CallPeerState.DISCONNECTED.equals(prevPeerState)
- || CallPeerState.FAILED.equals(prevPeerState))
- {
- if (logger.isDebugEnabled())
- logger.debug("Ignoring a request to hangup a call peer "
- + "that is already DISCONNECTED");
- return;
- }
-
- setState(
- failed ? CallPeerState.FAILED : CallPeerState.DISCONNECTED,
- reasonText);
-
- JingleIQ responseIQ = null;
-
- if (prevPeerState.equals(CallPeerState.CONNECTED)
- || CallPeerState.isOnHold(prevPeerState))
- {
- responseIQ = JinglePacketFactory.createBye(
- getProtocolProvider().getOurJID(), peerJID, getSID());
- }
- else if (CallPeerState.CONNECTING.equals(prevPeerState)
- || CallPeerState.CONNECTING_WITH_EARLY_MEDIA.equals(prevPeerState)
- || CallPeerState.ALERTING_REMOTE_SIDE.equals(prevPeerState))
- {
- String jingleSID = getSID();
-
- if(jingleSID == null)
- {
- synchronized(sidSyncRoot)
- {
- // we cancelled the call too early because the jingleSID
- // is null (i.e. the session-initiate has not been created)
- // and no need to send the session-terminate
- cancelled = true;
- return;
- }
- }
-
- responseIQ = JinglePacketFactory.createCancel(
- getProtocolProvider().getOurJID(), peerJID, getSID());
- }
- else if (prevPeerState.equals(CallPeerState.INCOMING_CALL))
- {
- responseIQ = JinglePacketFactory.createBusy(
- getProtocolProvider().getOurJID(), peerJID, getSID());
- }
- else if (prevPeerState.equals(CallPeerState.BUSY)
- || prevPeerState.equals(CallPeerState.FAILED))
- {
- // For FAILED and BUSY we only need to update CALL_STATUS
- // as everything else has been done already.
- }
- else
- {
- logger.info("Could not determine call peer state!");
- }
-
- if (responseIQ != null)
- {
- if (reasonOtherExtension != null)
- {
- ReasonPacketExtension reason
- = (ReasonPacketExtension)
- responseIQ.getExtension(
- ReasonPacketExtension.ELEMENT_NAME,
- ReasonPacketExtension.NAMESPACE);
-
- if (reason != null)
- {
- reason.setOtherExtension(reasonOtherExtension);
- }
- else if(reasonOtherExtension instanceof ReasonPacketExtension)
- {
- responseIQ.setReason(
- (ReasonPacketExtension)reasonOtherExtension);
- }
- }
-
- getProtocolProvider().getConnection().sendPacket(responseIQ);
- }
- }
-
- /**
- * Creates and sends a session-initiate {@link JingleIQ}.
- *
- * @param sessionInitiateExtensions a collection of additional and optional
- * <tt>PacketExtension</tt>s to be added to the <tt>session-initiate</tt>
- * {@link JingleIQ} which is to initiate the session with this
- * <tt>CallPeerJabberImpl</tt>
- * @throws OperationFailedException exception
- */
- protected synchronized void initiateSession(
- Iterable<PacketExtension> sessionInitiateExtensions)
- throws OperationFailedException
- {
- initiator = false;
-
- //Create the media description that we'd like to send to the other side.
- List<ContentPacketExtension> offer
- = getMediaHandler().createContentList();
-
- ProtocolProviderServiceJabberImpl protocolProvider
- = getProtocolProvider();
-
- synchronized(sidSyncRoot)
- {
- sessionInitIQ
- = JinglePacketFactory.createSessionInitiate(
- protocolProvider.getOurJID(),
- this.peerJID,
- JingleIQ.generateSID(),
- offer);
-
- if(cancelled)
- {
- // we cancelled the call too early so no need to send the
- // session-initiate to peer
- getMediaHandler().getTransportManager().close();
- return;
- }
- }
-
- if (sessionInitiateExtensions != null)
- {
- for (PacketExtension sessionInitiateExtension
- : sessionInitiateExtensions)
- {
- sessionInitIQ.addExtension(sessionInitiateExtension);
- }
- }
-
- protocolProvider.getConnection().sendPacket(sessionInitIQ);
- }
-
- /**
- * Notifies this instance that a specific <tt>ColibriConferenceIQ</tt> has
- * been received. This <tt>CallPeerJabberImpl</tt> uses the part of the
- * information provided in the specified <tt>conferenceIQ</tt> which
- * concerns it only.
- *
- * @param conferenceIQ the <tt>ColibriConferenceIQ</tt> which has been
- * received
- */
- void processColibriConferenceIQ(ColibriConferenceIQ conferenceIQ)
- {
- /*
- * CallPeerJabberImpl does not itself/directly know the specifics
- * related to the channels allocated on the Jitsi Videobridge server.
- * The channels contain transport and media-related information so
- * forward the notification to CallPeerMediaHandlerJabberImpl.
- */
- getMediaHandler().processColibriConferenceIQ(conferenceIQ);
- }
-
- /**
- * Processes the content-accept {@link JingleIQ}.
- *
- * @param content The {@link JingleIQ} that contains content that remote
- * peer has accepted
- */
- public void processContentAccept(JingleIQ content)
- {
- List<ContentPacketExtension> contents = content.getContentList();
- CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
-
- try
- {
- mediaHandler
- .getTransportManager()
- .wrapupConnectivityEstablishment();
- mediaHandler.processAnswer(contents);
- for (ContentPacketExtension c : contents)
- setSenders(getMediaType(c), c.getSenders());
- }
- catch (Exception e)
- {
- logger.warn("Failed to process a content-accept", e);
-
- // Send an error response.
- String reason = "Error: " + e.getMessage();
- JingleIQ errResp
- = JinglePacketFactory.createSessionTerminate(
- getProtocolProvider().getOurJID(),
- peerJID,
- sessionInitIQ.getSID(),
- Reason.INCOMPATIBLE_PARAMETERS,
- reason);
-
- setState(CallPeerState.FAILED, reason);
- getProtocolProvider().getConnection().sendPacket(errResp);
- return;
- }
-
- mediaHandler.start();
- }
-
- /**
- * Processes the content-add {@link JingleIQ}.
- *
- * @param content The {@link JingleIQ} that contains content that remote
- * peer wants to be added
- */
- public void processContentAdd(final JingleIQ content)
- {
- CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
- List<ContentPacketExtension> contents = content.getContentList();
- Iterable<ContentPacketExtension> answerContents;
- JingleIQ contentIQ;
- boolean noCands = false;
- MediaStream oldVideoStream = mediaHandler.getStream(MediaType.VIDEO);
-
- if(logger.isInfoEnabled())
- logger.info("Looking for candidates in content-add.");
- try
- {
- if(!contentAddWithNoCands)
- {
- mediaHandler.processOffer(contents);
-
- /*
- * Gingle transport will not put candidate in session-initiate
- * and content-add.
- */
- for(ContentPacketExtension c : contents)
- {
- if(JingleUtils.getFirstCandidate(c, 1) == null)
- {
- contentAddWithNoCands = true;
- noCands = true;
- }
- }
- }
-
- // if no candidates are present, launch a new Thread which will
- // process and wait for the connectivity establishment (otherwise
- // the existing thread will be blocked and thus cannot receive
- // transport-info with candidates
- if(noCands)
- {
- new Thread()
- {
- @Override
- public void run()
- {
- try
- {
- synchronized(candSyncRoot)
- {
- candSyncRoot.wait();
- }
- }
- catch(InterruptedException e)
- {
- }
-
- processContentAdd(content);
- contentAddWithNoCands = false;
- }
- }.start();
- if(logger.isInfoEnabled())
- logger.info("No candidates found in content-add, started "
- + "new thread.");
- return;
- }
-
- mediaHandler
- .getTransportManager()
- .wrapupConnectivityEstablishment();
- if(logger.isInfoEnabled())
- logger.info("Wrapping up connectivity establishment");
- answerContents = mediaHandler.generateSessionAccept();
- contentIQ = null;
- }
- catch(Exception e)
- {
- logger.warn("Exception occurred", e);
-
- answerContents = null;
- contentIQ
- = JinglePacketFactory.createContentReject(
- getProtocolProvider().getOurJID(),
- this.peerJID,
- getSID(),
- answerContents);
- }
-
- if(contentIQ == null)
- {
- /* send content-accept */
- contentIQ
- = JinglePacketFactory.createContentAccept(
- getProtocolProvider().getOurJID(),
- this.peerJID,
- getSID(),
- answerContents);
- for (ContentPacketExtension c : answerContents)
- setSenders(getMediaType(c), c.getSenders());
- }
-
- getProtocolProvider().getConnection().sendPacket(contentIQ);
- mediaHandler.start();
-
- /*
- * If a remote peer turns her video on in a conference which is hosted
- * by the local peer and the local peer is not streaming her local
- * video, reinvite the other remote peers to enable RTP translation.
- */
- if (oldVideoStream == null)
- {
- MediaStream newVideoStream
- = mediaHandler.getStream(MediaType.VIDEO);
-
- if ((newVideoStream != null)
- && mediaHandler.isRTPTranslationEnabled(MediaType.VIDEO))
- {
- try
- {
- getCall().modifyVideoContent();
- }
- catch (OperationFailedException ofe)
- {
- logger.error("Failed to enable RTP translation", ofe);
- }
- }
- }
- }
-
- /**
- * Processes the content-modify {@link JingleIQ}.
- *
- * @param content The {@link JingleIQ} that contains content that remote
- * peer wants to be modified
- */
- public void processContentModify(JingleIQ content)
- {
- ContentPacketExtension ext = content.getContentList().get(0);
- MediaType mediaType = getMediaType(ext);
-
- try
- {
- boolean modify
- = (ext.getFirstChildOfType(RtpDescriptionPacketExtension.class)
- != null);
-
- getMediaHandler().reinitContent(ext.getName(), ext, modify);
-
- setSenders(mediaType, ext.getSenders());
-
- if (MediaType.VIDEO.equals(mediaType))
- getCall().modifyVideoContent();
- }
- catch(Exception e)
- {
- logger.info("Failed to process an incoming content-modify", e);
-
- // Send an error response.
- String reason = "Error: " + e.getMessage();
- JingleIQ errResp
- = JinglePacketFactory.createSessionTerminate(
- getProtocolProvider().getOurJID(),
- peerJID,
- sessionInitIQ.getSID(),
- Reason.INCOMPATIBLE_PARAMETERS,
- reason);
-
- setState(CallPeerState.FAILED, reason);
- getProtocolProvider().getConnection().sendPacket(errResp);
- return;
- }
- }
-
- /**
- * Processes the content-reject {@link JingleIQ}.
- *
- * @param content The {@link JingleIQ}
- */
- public void processContentReject(JingleIQ content)
- {
- if(content.getContentList().isEmpty())
- {
- //send an error response;
- JingleIQ errResp = JinglePacketFactory.createSessionTerminate(
- sessionInitIQ.getTo(), sessionInitIQ.getFrom(),
- sessionInitIQ.getSID(), Reason.INCOMPATIBLE_PARAMETERS,
- "Error: content rejected");
-
- setState(CallPeerState.FAILED, "Error: content rejected");
- getProtocolProvider().getConnection().sendPacket(errResp);
- return;
- }
- }
-
- /**
- * Processes the content-remove {@link JingleIQ}.
- *
- * @param content The {@link JingleIQ} that contains content that remote
- * peer wants to be removed
- */
- public void processContentRemove(JingleIQ content)
- {
- List<ContentPacketExtension> contents = content.getContentList();
- boolean videoContentRemoved = false;
-
- if (!contents.isEmpty())
- {
- CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
-
- for(ContentPacketExtension c : contents)
- {
- mediaHandler.removeContent(c.getName());
-
- MediaType mediaType = getMediaType(c);
- setSenders(mediaType, SendersEnum.none);
-
- if (MediaType.VIDEO.equals(mediaType))
- videoContentRemoved = true;
- }
-
- /*
- * TODO XEP-0166: Jingle says: If the content-remove results in zero
- * content definitions for the session, the entity that receives the
- * content-remove SHOULD send a session-terminate action to the
- * other party (since a session with no content definitions is
- * void).
- */
- }
-
- if (videoContentRemoved)
- {
- // removing of the video content might affect the other sessions
- // in the call
- try
- {
- getCall().modifyVideoContent();
- }
- catch (Exception e)
- {
- logger.warn("Failed to update Jingle sessions");
- }
- }
- }
-
- /**
- * Processes a session-accept {@link JingleIQ}.
- *
- * @param sessionInitIQ The session-accept {@link JingleIQ} to process.
- */
- public void processSessionAccept(JingleIQ sessionInitIQ)
- {
- this.sessionInitIQ = sessionInitIQ;
-
- CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
- List<ContentPacketExtension> answer = sessionInitIQ.getContentList();
-
- try
- {
- mediaHandler
- .getTransportManager()
- .wrapupConnectivityEstablishment();
- mediaHandler.processAnswer(answer);
- for (ContentPacketExtension c : answer)
- setSenders(getMediaType(c), c.getSenders());
- }
- catch(Exception exc)
- {
- if (logger.isInfoEnabled())
- logger.info("Failed to process a session-accept", exc);
-
- //send an error response;
- JingleIQ errResp = JinglePacketFactory.createSessionTerminate(
- sessionInitIQ.getTo(), sessionInitIQ.getFrom(),
- sessionInitIQ.getSID(), Reason.INCOMPATIBLE_PARAMETERS,
- exc.getClass().getName() + ": " + exc.getMessage());
-
- setState(CallPeerState.FAILED, "Error: " + exc.getMessage());
- getProtocolProvider().getConnection().sendPacket(errResp);
- return;
- }
-
- //tell everyone we are connected so that the audio notifications would
- //stop
- setState(CallPeerState.CONNECTED);
-
- mediaHandler.start();
-
- /*
- * If video was added to the call after we sent the session-initiate
- * to this peer, it needs to be added to this peer's session with a
- * content-add.
- */
- sendModifyVideoContent();
- }
-
- /**
- * Handles the specified session <tt>info</tt> packet according to its
- * content.
- *
- * @param info the {@link SessionInfoPacketExtension} that we just received.
- */
- public void processSessionInfo(SessionInfoPacketExtension info)
- {
- switch (info.getType())
- {
- case ringing:
- setState(CallPeerState.ALERTING_REMOTE_SIDE);
- break;
- case hold:
- getMediaHandler().setRemotelyOnHold(true);
- reevalRemoteHoldStatus();
- break;
- case unhold:
- case active:
- getMediaHandler().setRemotelyOnHold(false);
- reevalRemoteHoldStatus();
- break;
- default:
- logger.warn("Received SessionInfoPacketExtension of unknown type");
- }
- }
-
- /**
- * Processes the session initiation {@link JingleIQ} that we were created
- * with, passing its content to the media handler and then sends either a
- * "session-info/ringing" or a "session-terminate" response.
- *
- * @param sessionInitIQ The {@link JingleIQ} that created the session that
- * we are handling here.
- */
- protected synchronized void processSessionInitiate(JingleIQ sessionInitIQ)
- {
- // Do initiate the session.
- this.sessionInitIQ = sessionInitIQ;
- this.initiator = true;
-
- // This is the SDP offer that came from the initial session-initiate.
- // Contrary to SIP, we are guaranteed to have content because XEP-0166
- // says: "A session consists of at least one content type at a time."
- List<ContentPacketExtension> offer = sessionInitIQ.getContentList();
-
- try
- {
- getMediaHandler().processOffer(offer);
-
- CoinPacketExtension coin = null;
-
- for(PacketExtension ext : sessionInitIQ.getExtensions())
- {
- if(ext.getElementName().equals(
- CoinPacketExtension.ELEMENT_NAME))
- {
- coin = (CoinPacketExtension)ext;
- break;
- }
- }
-
- /* does the call peer acts as a conference focus ? */
- if(coin != null)
- {
- setConferenceFocus(Boolean.parseBoolean(
- (String)coin.getAttribute("isfocus")));
- }
- }
- catch(Exception ex)
- {
- logger.info("Failed to process an incoming session initiate", ex);
-
- //send an error response;
- String reasonText = "Error: " + ex.getMessage();
- JingleIQ errResp
- = JinglePacketFactory.createSessionTerminate(
- sessionInitIQ.getTo(),
- sessionInitIQ.getFrom(),
- sessionInitIQ.getSID(),
- Reason.INCOMPATIBLE_PARAMETERS,
- reasonText);
-
- setState(CallPeerState.FAILED, reasonText);
- getProtocolProvider().getConnection().sendPacket(errResp);
- return;
- }
-
- // If we do not get the info about the remote peer yet. Get it right
- // now.
- if(this.getDiscoveryInfo() == null)
- {
- String calleeURI = sessionInitIQ.getFrom();
- retrieveDiscoveryInfo(calleeURI);
- }
-
- //send a ringing response
- if (logger.isTraceEnabled())
- logger.trace("will send ringing response: ");
-
- getProtocolProvider().getConnection().sendPacket(
- JinglePacketFactory.createRinging(sessionInitIQ));
-
- synchronized(sessionInitiateSyncRoot)
- {
- sessionInitiateProcessed = true;
- sessionInitiateSyncRoot.notify();
- }
-
- //if this is a 3264 initiator, let's give them an early peek at our
- //answer so that they could start ICE (SIP-2-Jingle gateways won't
- //be able to send their candidates unless they have this)
- DiscoverInfo discoverInfo = getDiscoveryInfo();
- if ((discoverInfo != null)
- && discoverInfo.containsFeature(
- ProtocolProviderServiceJabberImpl.URN_IETF_RFC_3264))
- {
- getProtocolProvider().getConnection().sendPacket(
- JinglePacketFactory.createDescriptionInfo(
- sessionInitIQ.getTo(),
- sessionInitIQ.getFrom(),
- sessionInitIQ.getSID(),
- getMediaHandler().getLocalContentList()));
- }
- }
-
- /**
- * Puts this peer into a {@link CallPeerState#DISCONNECTED}, indicating a
- * reason to the user, if there is one.
- *
- * @param jingleIQ the {@link JingleIQ} that's terminating our session.
- */
- public void processSessionTerminate(JingleIQ jingleIQ)
- {
- String reasonStr = "Call ended by remote side.";
- ReasonPacketExtension reasonExt = jingleIQ.getReason();
-
- if(reasonExt != null)
- {
- Reason reason = reasonExt.getReason();
-
- if(reason != null)
- reasonStr += " Reason: " + reason.toString() + ".";
-
- String text = reasonExt.getText();
-
- if(text != null)
- reasonStr += " " + text;
- }
-
- setState(CallPeerState.DISCONNECTED, reasonStr);
- }
-
- /**
- * Processes a specific "XEP-0251: Jingle Session Transfer"
- * <tt>transfer</tt> packet (extension).
- *
- * @param transfer the "XEP-0251: Jingle Session Transfer" transfer packet
- * (extension) to process
- * @throws OperationFailedException if anything goes wrong while processing
- * the specified <tt>transfer</tt> packet (extension)
- */
- public void processTransfer(TransferPacketExtension transfer)
- throws OperationFailedException
- {
- String attendantAddress = transfer.getFrom();
-
- if (attendantAddress == null)
- {
- throw new OperationFailedException(
- "Session transfer must contain a \'from\' attribute value.",
- OperationFailedException.ILLEGAL_ARGUMENT);
- }
-
- String calleeAddress = transfer.getTo();
-
- if (calleeAddress == null)
- {
- throw new OperationFailedException(
- "Session transfer must contain a \'to\' attribute value.",
- OperationFailedException.ILLEGAL_ARGUMENT);
- }
-
- // Checks if the transfer remote peer is contained by the roster of this
- // account.
- Roster roster = getProtocolProvider().getConnection().getRoster();
- if(!roster.contains(StringUtils.parseBareAddress(calleeAddress)))
- {
- String failedMessage =
- "Transfer impossible:\n"
- + "Account roster does not contain transfer peer: "
- + StringUtils.parseBareAddress(calleeAddress);
- setState(CallPeerState.FAILED, failedMessage);
- logger.info(failedMessage);
- }
-
- OperationSetBasicTelephonyJabberImpl basicTelephony
- = (OperationSetBasicTelephonyJabberImpl)
- getProtocolProvider()
- .getOperationSet(OperationSetBasicTelephony.class);
- CallJabberImpl calleeCall = new CallJabberImpl(basicTelephony);
- TransferPacketExtension calleeTransfer = new TransferPacketExtension();
- String sid = transfer.getSID();
-
- calleeTransfer.setFrom(attendantAddress);
- if (sid != null)
- {
- calleeTransfer.setSID(sid);
- calleeTransfer.setTo(calleeAddress);
- }
- basicTelephony.createOutgoingCall(
- calleeCall,
- calleeAddress,
- Arrays.asList(new PacketExtension[] { calleeTransfer }));
- }
-
- /**
- * Processes the <tt>transport-info</tt> {@link JingleIQ}.
- *
- * @param jingleIQ the <tt>transport-info</tt> {@link JingleIQ} to process
- */
- public void processTransportInfo(JingleIQ jingleIQ)
- {
- /*
- * The transport-info action is used to exchange transport candidates so
- * it only concerns the mediaHandler.
- */
- try
- {
- if(isInitiator())
- {
- synchronized(sessionInitiateSyncRoot)
- {
- if(!sessionInitiateProcessed)
- {
- try
- {
- sessionInitiateSyncRoot.wait();
- }
- catch(InterruptedException e)
- {
- }
- }
- }
- }
-
- getMediaHandler().processTransportInfo(
- jingleIQ.getContentList());
- }
- catch (OperationFailedException ofe)
- {
- logger.warn("Failed to process an incoming transport-info", ofe);
-
- //send an error response
- String reasonText = "Error: " + ofe.getMessage();
- JingleIQ errResp
- = JinglePacketFactory.createSessionTerminate(
- getProtocolProvider().getOurJID(),
- peerJID,
- sessionInitIQ.getSID(),
- Reason.GENERAL_ERROR,
- reasonText);
-
- setState(CallPeerState.FAILED, reasonText);
- getProtocolProvider().getConnection().sendPacket(errResp);
-
- return;
- }
-
- synchronized(candSyncRoot)
- {
- candSyncRoot.notify();
- }
- }
-
- /**
- * Puts the <tt>CallPeer</tt> represented by this instance on or off hold.
- *
- * @param onHold <tt>true</tt> to have the <tt>CallPeer</tt> put on hold;
- * <tt>false</tt>, otherwise
- *
- * @throws OperationFailedException if we fail to construct or send the
- * INVITE request putting the remote side on/off hold.
- */
- public void putOnHold(boolean onHold)
- throws OperationFailedException
- {
- CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
-
- mediaHandler.setLocallyOnHold(onHold);
-
- SessionInfoType type;
-
- if(onHold)
- type = SessionInfoType.hold;
- else
- {
- type = SessionInfoType.unhold;
- getMediaHandler().reinitAllContents();
- }
-
- //we are now on hold and need to realize this before potentially
- //spoiling it all with an exception while sending the packet :).
- reevalLocalHoldStatus();
-
- JingleIQ onHoldIQ = JinglePacketFactory.createSessionInfo(
- getProtocolProvider().getOurJID(),
- peerJID,
- getSID(),
- type);
-
- getProtocolProvider().getConnection().sendPacket(onHoldIQ);
- }
-
- /**
- * Send a <tt>content-add</tt> to add video setup.
- */
- private void sendAddVideoContent()
- {
- List<ContentPacketExtension> contents;
-
- try
- {
- contents = getMediaHandler().createContentList(MediaType.VIDEO);
- }
- catch(Exception exc)
- {
- logger.warn("Failed to gather content for video type", exc);
- return;
- }
-
- ProtocolProviderServiceJabberImpl protocolProvider
- = getProtocolProvider();
- JingleIQ contentIQ
- = JinglePacketFactory.createContentAdd(
- protocolProvider.getOurJID(),
- this.peerJID,
- getSID(),
- contents);
-
- protocolProvider.getConnection().sendPacket(contentIQ);
- }
-
- /**
- * Sends a <tt>content</tt> message to reflect changes in the setup such as
- * the local peer/user becoming a conference focus.
- */
- public void sendCoinSessionInfo()
- {
- JingleIQ sessionInfoIQ
- = JinglePacketFactory.createSessionInfo(
- getProtocolProvider().getOurJID(),
- this.peerJID,
- getSID());
- CoinPacketExtension coinExt
- = new CoinPacketExtension(getCall().isConferenceFocus());
-
- sessionInfoIQ.addExtension(coinExt);
- getProtocolProvider().getConnection().sendPacket(sessionInfoIQ);
- }
-
- /**
- * Returns the <tt>MediaDirection</tt> that should be set for the content
- * of type <tt>mediaType</tt> in the Jingle session for this
- * <tt>CallPeer</tt>.
- * If we are the focus of a conference and are doing RTP translation,
- * takes into account the other <tt>CallPeer</tt>s in the <tt>Call</tt>.
- *
- * @param mediaType the <tt>MediaType</tt> for which to return the
- * <tt>MediaDirection</tt>
- * @return the <tt>MediaDirection</tt> that should be used for the content
- * of type <tt>mediaType</tt> in the Jingle session for this
- * <tt>CallPeer</tt>.
- */
- private MediaDirection getDirectionForJingle(MediaType mediaType)
- {
- MediaDirection direction = MediaDirection.INACTIVE;
- CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
-
- // If we are streaming media, the direction should allow sending
- if ( (MediaType.AUDIO == mediaType &&
- mediaHandler.isLocalAudioTransmissionEnabled()) ||
- (MediaType.VIDEO == mediaType &&
- isLocalVideoStreaming()))
- direction = direction.or(MediaDirection.SENDONLY);
-
- // If we are receiving media from this CallPeer, the direction should
- // allow receiving
- SendersEnum senders = getSenders(mediaType);
- if (senders == null || senders == SendersEnum.both ||
- (isInitiator() && senders == SendersEnum.initiator) ||
- (!isInitiator() && senders == SendersEnum.responder))
- direction = direction.or(MediaDirection.RECVONLY);
-
- // If we are the focus of a conference and we are receiving media from
- // another CallPeer in the same Call, the direction should allow sending
- CallJabberImpl call = getCall();
- if (call != null && call.isConferenceFocus())
- {
- for (CallPeerJabberImpl peer : call.getCallPeerList())
- {
- if (peer != this)
- {
- senders = peer.getSenders(mediaType);
- if (senders == null || senders == SendersEnum.both ||
- (peer.isInitiator()
- && senders == SendersEnum.initiator) ||
- (!peer.isInitiator()
- && senders == SendersEnum.responder))
- {
- direction = direction.or(MediaDirection.SENDONLY);
- break;
- }
- }
- }
- }
-
- return direction;
- }
-
- /**
- * Send, if necessary, a jingle <tt>content</tt> message to reflect change
- * in video setup. Whether the jingle session should have a video content,
- * and if so, the value of the <tt>senders</tt> field is determined
- * based on whether we are streaming local video and, if we are the focus
- * of a conference, on the other peers in the conference.
- * The message can be content-modify if video content exists (and the
- * <tt>senders</tt> field changes), content-add or content-remove.
- *
- * @return <tt>true</tt> if a jingle <tt>content</tt> message was sent.
- */
- public boolean sendModifyVideoContent()
- {
- CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
- MediaDirection direction = getDirectionForJingle(MediaType.VIDEO);
-
- ContentPacketExtension remoteContent
- = mediaHandler.getLocalContent(MediaType.VIDEO.toString());
-
- if (remoteContent == null)
- {
- if (direction == MediaDirection.INACTIVE)
- {
- // no video content, none needed
- return false;
- }
- else
- {
- if (getState() == CallPeerState.CONNECTED)
- {
- if (logger.isInfoEnabled())
- logger.info("Adding video content for " + this);
- sendAddVideoContent();
- return true;
- }
- return false;
- }
- }
- else
- {
- if (direction == MediaDirection.INACTIVE)
- {
- sendRemoveVideoContent();
- return true;
- }
- }
-
- SendersEnum senders = getSenders(MediaType.VIDEO);
- if (senders == null)
- senders = SendersEnum.both;
-
- SendersEnum newSenders = SendersEnum.none;
- if (MediaDirection.SENDRECV == direction)
- newSenders = SendersEnum.both;
- else if (MediaDirection.RECVONLY == direction)
- newSenders = isInitiator()
- ? SendersEnum.initiator : SendersEnum.responder;
- else if (MediaDirection.SENDONLY == direction)
- newSenders = isInitiator()
- ? SendersEnum.responder : SendersEnum.initiator;
-
- /*
- * Send Content-Modify
- */
- ContentPacketExtension ext = new ContentPacketExtension();
- String remoteContentName = remoteContent.getName();
-
- ext.setSenders(newSenders);
- ext.setCreator(remoteContent.getCreator());
- ext.setName(remoteContentName);
-
- if (newSenders != senders)
- {
- if (logger.isInfoEnabled())
- logger.info("Sending content modify, senders: "
- + senders + "->" + newSenders);
- ProtocolProviderServiceJabberImpl protocolProvider
- = getProtocolProvider();
- JingleIQ contentIQ
- = JinglePacketFactory.createContentModify(
- protocolProvider.getOurJID(),
- this.peerJID,
- getSID(),
- ext);
-
- protocolProvider.getConnection().sendPacket(contentIQ);
- }
-
- try
- {
- mediaHandler.reinitContent(remoteContentName, ext, false);
- mediaHandler.start();
- }
- catch(Exception e)
- {
- logger.warn("Exception occurred during media reinitialization", e);
- }
-
- return (newSenders != senders);
- }
-
- /**
- * Send a <tt>content</tt> message to reflect change in video setup (start
- * or stop).
- */
- public void sendModifyVideoResolutionContent()
- {
- CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
- ContentPacketExtension remoteContent
- = mediaHandler.getRemoteContent(MediaType.VIDEO.toString());
- ContentPacketExtension content;
-
- logger.info("send modify-content to change resolution");
-
- // send content-modify with RTP description
-
- // create content list with resolution
- try
- {
- content = mediaHandler.createContentForMedia(MediaType.VIDEO);
- }
- catch (Exception e)
- {
- logger.warn("Failed to gather content for video type", e);
- return;
- }
-
- // if we are only receiving video senders is null
- SendersEnum senders = remoteContent.getSenders();
-
- if (senders != null)
- content.setSenders(senders);
-
- ProtocolProviderServiceJabberImpl protocolProvider
- = getProtocolProvider();
- JingleIQ contentIQ
- = JinglePacketFactory.createContentModify(
- protocolProvider.getOurJID(),
- this.peerJID,
- getSID(),
- content);
-
- protocolProvider.getConnection().sendPacket(contentIQ);
-
- try
- {
- mediaHandler.reinitContent(remoteContent.getName(), content, false);
- mediaHandler.start();
- }
- catch(Exception e)
- {
- logger.warn("Exception occurred when media reinitialization", e);
- }
- }
-
- /**
- * Send a <tt>content-remove</tt> to remove video setup.
- */
- private void sendRemoveVideoContent()
- {
- CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
-
- ContentPacketExtension content = new ContentPacketExtension();
- ContentPacketExtension remoteContent
- = mediaHandler.getRemoteContent(MediaType.VIDEO.toString());
- if (remoteContent == null)
- return;
- String remoteContentName = remoteContent.getName();
-
- content.setName(remoteContentName);
- content.setCreator(remoteContent.getCreator());
- content.setSenders(remoteContent.getSenders());
-
- ProtocolProviderServiceJabberImpl protocolProvider
- = getProtocolProvider();
- JingleIQ contentIQ
- = JinglePacketFactory.createContentRemove(
- protocolProvider.getOurJID(),
- this.peerJID,
- getSID(),
- Arrays.asList(content));
-
- protocolProvider.getConnection().sendPacket(contentIQ);
- mediaHandler.removeContent(remoteContentName);
- setSenders(MediaType.VIDEO, SendersEnum.none);
- }
-
- /**
- * Sends local candidate addresses from the local peer to the remote peer
- * using the <tt>transport-info</tt> {@link JingleIQ}.
- *
- * @param contents the local candidate addresses to be sent from the local
- * peer to the remote peer using the <tt>transport-info</tt>
- * {@link JingleIQ}
- */
- protected void sendTransportInfo(Iterable<ContentPacketExtension> contents)
- {
- // if the call is canceled, do not start sending candidates in
- // transport-info
- if(cancelled)
- return;
-
- JingleIQ transportInfo = new JingleIQ();
-
- for (ContentPacketExtension content : contents)
- transportInfo.addContent(content);
-
- ProtocolProviderServiceJabberImpl protocolProvider
- = getProtocolProvider();
-
- transportInfo.setAction(JingleAction.TRANSPORT_INFO);
- transportInfo.setFrom(protocolProvider.getOurJID());
- transportInfo.setSID(getSID());
- transportInfo.setTo(getAddress());
- transportInfo.setType(IQ.Type.SET);
-
- PacketCollector collector
- = protocolProvider.getConnection().createPacketCollector(
- new PacketIDFilter(transportInfo.getPacketID()));
-
- protocolProvider.getConnection().sendPacket(transportInfo);
- collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
- collector.cancel();
- }
-
- @Override
- public void setState(CallPeerState newState, String reason, int reasonCode)
- {
- CallPeerState oldState = getState();
- try
- {
- /*
- * We need to dispose of the transport manager before the
- * 'call' field is set to null, because if Jitsi Videobridge is in
- * use, it (the call) is needed in order to expire the
- * Videobridge channels.
- */
- if (CallPeerState.DISCONNECTED.equals(newState)
- || CallPeerState.FAILED.equals(newState))
- getMediaHandler().getTransportManager().close();
- }
- finally
- {
- super.setState(newState, reason, reasonCode);
- }
-
- if (CallPeerState.isOnHold(oldState)
- && CallPeerState.CONNECTED.equals(newState))
- {
- try
- {
- getCall().modifyVideoContent();
- }
- catch (OperationFailedException ofe)
- {
- logger.error("Failed to update call video state after " +
- "'hold' status removed for "+this);
- }
- }
- }
-
- /**
- * Transfer (in the sense of call transfer) this <tt>CallPeer</tt> to a
- * specific callee address which may optionally be participating in an
- * active <tt>Call</tt>.
- *
- * @param to the address of the callee to transfer this <tt>CallPeer</tt> to
- * @param sid the Jingle session ID of the active <tt>Call</tt> between the
- * local peer and the callee in the case of attended transfer; <tt>null</tt>
- * in the case of unattended transfer
- * @throws OperationFailedException if something goes wrong
- */
- protected void transfer(String to, String sid)
- throws OperationFailedException
- {
- JingleIQ transferSessionInfo = new JingleIQ();
- ProtocolProviderServiceJabberImpl protocolProvider
- = getProtocolProvider();
-
- transferSessionInfo.setAction(JingleAction.SESSION_INFO);
- transferSessionInfo.setFrom(protocolProvider.getOurJID());
- transferSessionInfo.setSID(getSID());
- transferSessionInfo.setTo(getAddress());
- transferSessionInfo.setType(IQ.Type.SET);
-
- TransferPacketExtension transfer = new TransferPacketExtension();
-
- // Attended transfer.
- if (sid != null)
- {
- /*
- * Not really sure what the value of the "from" attribute of the
- * "transfer" element should be but the examples in "XEP-0251:
- * Jingle Session Transfer" has it in the case of attended transfer.
- */
- transfer.setFrom(protocolProvider.getOurJID());
- transfer.setSID(sid);
-
- // Puts on hold the 2 calls before making the attended transfer.
- OperationSetBasicTelephonyJabberImpl basicTelephony
- = (OperationSetBasicTelephonyJabberImpl)
- protocolProvider.getOperationSet(
- OperationSetBasicTelephony.class);
- CallPeerJabberImpl callPeer = basicTelephony.getActiveCallPeer(sid);
- if(callPeer != null)
- {
- if(!CallPeerState.isOnHold(callPeer.getState()))
- {
- callPeer.putOnHold(true);
- }
- }
-
- if(!CallPeerState.isOnHold(this.getState()))
- {
- this.putOnHold(true);
- }
- }
- transfer.setTo(to);
-
- transferSessionInfo.addExtension(transfer);
-
- Connection connection = protocolProvider.getConnection();
- PacketCollector collector = connection.createPacketCollector(
- new PacketIDFilter(transferSessionInfo.getPacketID()));
- protocolProvider.getConnection().sendPacket(transferSessionInfo);
-
- Packet result
- = collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
-
- if(result == null)
- {
- // Log the failed transfer call and notify the user.
- throw new OperationFailedException(
- "No response to the \"transfer\" request.",
- OperationFailedException.ILLEGAL_ARGUMENT);
- }
- else if (((IQ) result).getType() != IQ.Type.RESULT)
- {
- // Log the failed transfer call and notify the user.
- throw new OperationFailedException(
- "Remote peer does not manage call \"transfer\"."
- + "Response to the \"transfer\" request is: "
- + ((IQ) result).getType(),
- OperationFailedException.ILLEGAL_ARGUMENT);
- }
- else
- {
- String message = ((sid == null) ? "Unattended" : "Attended")
- + " transfer to: "
- + to;
- // Implements the SIP behavior: once the transfer is accepted, the
- // current call is closed.
- hangup(
- false,
- message,
- new ReasonPacketExtension(Reason.SUCCESS,
- message,
- new TransferredPacketExtension()));
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public String getEntity()
- {
- return getAddress();
- }
-
- /**
- * {@inheritDoc}
- *
- * In Jingle there isn't an actual "direction" parameter. We use the
- * <tt>senders</tt> field to calculate the direction.
- */
- @Override
- public MediaDirection getDirection(MediaType mediaType)
- {
- SendersEnum senders = getSenders(mediaType);
-
- if (senders == SendersEnum.none)
- {
- return MediaDirection.INACTIVE;
- }
- else if (senders == null || senders == SendersEnum.both)
- {
- return MediaDirection.SENDRECV;
- }
- else if (senders == SendersEnum.initiator)
- {
- return
- isInitiator()
- ? MediaDirection.RECVONLY
- : MediaDirection.SENDONLY;
- }
- else //senders == SendersEnum.responder
- {
- return
- isInitiator()
- ? MediaDirection.SENDONLY
- : MediaDirection.RECVONLY;
- }
- }
-
- /**
- * Gets the current value of the <tt>senders</tt> field of the content with
- * name <tt>mediaType</tt> in the Jingle session with this
- * <tt>CallPeer</tt>.
- *
- * @param mediaType the <tt>MediaType</tt> for which to get the current
- * value of the <tt>senders</tt> field.
- * @return the current value of the <tt>senders</tt> field of the content
- * with name <tt>mediaType</tt> in the Jingle session with this
- * <tt>CallPeer</tt>.
- */
- public SendersEnum getSenders(MediaType mediaType)
- {
- switch (mediaType)
- {
- case AUDIO:
- return audioSenders;
- case DATA:
- /*
- * FIXME DATA has been introduced as a MediaType but explicit
- * support for DATA content has not been added yet.
- */
- return SendersEnum.none;
- case VIDEO:
- return videoSenders;
- default:
- throw new IllegalArgumentException("mediaType");
- }
- }
-
- /**
- * Set the current value of the <tt>senders</tt> field of the content with
- * name <tt>mediaType</tt> in the Jingle session with this <tt>CallPeer</tt>
- * @param mediaType the <tt>MediaType</tt> for which to get the current
- * value of the <tt>senders</tt> field.
- * @param senders the value to set
- */
- public void setSenders(MediaType mediaType, SendersEnum senders)
- {
- if (mediaType == null)
- return;
- else if (MediaType.AUDIO.equals(mediaType))
- this.audioSenders = senders;
- else if (MediaType.VIDEO.equals(mediaType))
- this.videoSenders = senders;
- else
- throw new IllegalArgumentException("mediaType");
- }
-
- /**
- * Gets the <tt>MediaType</tt> of <tt>content</tt>. If <tt>content</tt>
- * does not have a <tt>description</tt> child and therefore not
- * <tt>MediaType</tt> can be associated with it, tries to take the
- * <tt>MediaType</tt> from the session's already established contents with
- * the same name as <tt>content</tt>
- * @param content the <tt>ContentPacketExtention</tt> for which to get the
- * <tt>MediaType</tt>
- * @return the <tt>MediaType</tt> of <tt>content</tt>.
- */
- public MediaType getMediaType(ContentPacketExtension content)
- {
- String contentName = content.getName();
- if (contentName == null)
- return null;
-
- MediaType mediaType = JingleUtils.getMediaType(content);
- if (mediaType == null)
- {
- CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
- for (MediaType m : MediaType.values())
- {
- ContentPacketExtension sessionContent
- = mediaHandler.getRemoteContent(m.toString());
- if (sessionContent == null)
- sessionContent = mediaHandler.getLocalContent(m.toString());
-
- if (sessionContent != null
- && contentName.equals(sessionContent.getName()))
- {
- mediaType = m;
- break;
- }
- }
- }
-
- return mediaType;
- }
-}
+package net.java.sip.communicator.impl.protocol.jabber;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import net.java.sip.communicator.impl.protocol.jabber.extensions.colibri.*;
+import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
+import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.ContentPacketExtension.SendersEnum;
+import net.java.sip.communicator.impl.protocol.jabber.jinglesdp.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.neomedia.*;
+import org.jivesoftware.smack.*;
+import org.jivesoftware.smack.filter.*;
+import org.jivesoftware.smack.packet.*;
+import org.jivesoftware.smack.util.*;
+import org.jivesoftware.smackx.packet.*;
+
+/**
+ * Implements a Jabber <tt>CallPeer</tt>.
+ *
+ * @author Emil Ivov
+ * @author Lyubomir Marinov
+ * @author Boris Grozev
+ */
+public class CallPeerJabberImpl
+ extends AbstractCallPeerJabberGTalkImpl
+ <CallJabberImpl, CallPeerMediaHandlerJabberImpl, JingleIQ>
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>CallPeerJabberImpl</tt> class and its
+ * instances for logging output.
+ */
+ private static final Logger logger
+ = Logger.getLogger(CallPeerJabberImpl.class);
+
+ /**
+ * If the call is cancelled before session-initiate is sent.
+ */
+ private boolean cancelled = false;
+
+ /**
+ * Synchronization object for candidates available.
+ */
+ private final Object candSyncRoot = new Object();
+
+ /**
+ * If the content-add does not contains candidates.
+ */
+ private boolean contentAddWithNoCands = false;
+
+ /**
+ * If we have processed the session initiate.
+ */
+ private boolean sessionInitiateProcessed = false;
+
+ /**
+ * Synchronization object. Synchronization object? Wow, who would have
+ * thought! ;) Would be great to have a word on what we are syncing with it
+ */
+ private final Object sessionInitiateSyncRoot = new Object();
+
+ /**
+ * Synchronization object for SID.
+ */
+ private final Object sidSyncRoot = new Object();
+
+ /**
+ * The current value of the 'senders' field of the audio content in the
+ * Jingle session with this <tt>CallPeer</tt>.
+ * <tt>null</tt> should be interpreted as 'both', which is the default in
+ * Jingle if the XML attribute is missing.
+ */
+ private SendersEnum audioSenders = SendersEnum.none;
+
+ /**
+ * The current value of the 'senders' field of the video content in the
+ * Jingle session with this <tt>CallPeer</tt>.
+ * <tt>null</tt> should be interpreted as 'both', which is the default in
+ * Jingle if the XML attribute is missing.
+ */
+ private SendersEnum videoSenders = SendersEnum.none;
+
+ /**
+ * Creates a new call peer with address <tt>peerAddress</tt>.
+ *
+ * @param peerAddress the Jabber address of the new call peer.
+ * @param owningCall the call that contains this call peer.
+ */
+ public CallPeerJabberImpl(String peerAddress,
+ CallJabberImpl owningCall)
+ {
+ super(peerAddress, owningCall);
+
+ setMediaHandler(new CallPeerMediaHandlerJabberImpl(this));
+ }
+
+ /**
+ * Creates a new call peer with address <tt>peerAddress</tt>.
+ *
+ * @param peerAddress the Jabber address of the new call peer.
+ * @param owningCall the call that contains this call peer.
+ * @param sessionIQ The session-initiate <tt>JingleIQ</tt> which was
+ * received from <tt>peerAddress</tt> and caused the creation of this
+ * <tt>CallPeerJabberImpl</tt>
+ */
+ public CallPeerJabberImpl(String peerAddress,
+ CallJabberImpl owningCall,
+ JingleIQ sessionIQ)
+ {
+ this(peerAddress, owningCall);
+ this.sessionInitIQ = sessionIQ;
+ }
+
+ /**
+ * Send a session-accept <tt>JingleIQ</tt> to this <tt>CallPeer</tt>
+ * @throws OperationFailedException if we fail to create or send the
+ * response.
+ */
+ public synchronized void answer()
+ throws OperationFailedException
+ {
+ Iterable<ContentPacketExtension> answer;
+ CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
+
+ try
+ {
+ mediaHandler
+ .getTransportManager()
+ .wrapupConnectivityEstablishment();
+ answer = mediaHandler.generateSessionAccept();
+ for (ContentPacketExtension c : answer)
+ setSenders(getMediaType(c), c.getSenders());
+ }
+ catch(Exception exc)
+ {
+ logger.info("Failed to answer an incoming call", exc);
+
+ //send an error response
+ String reasonText = "Error: " + exc.getMessage();
+ JingleIQ errResp
+ = JinglePacketFactory.createSessionTerminate(
+ sessionInitIQ.getTo(),
+ sessionInitIQ.getFrom(),
+ sessionInitIQ.getSID(),
+ Reason.FAILED_APPLICATION,
+ reasonText);
+
+ setState(CallPeerState.FAILED, reasonText);
+ getProtocolProvider().getConnection().sendPacket(errResp);
+ return;
+ }
+
+ JingleIQ response
+ = JinglePacketFactory.createSessionAccept(
+ sessionInitIQ.getTo(),
+ sessionInitIQ.getFrom(),
+ getSID(),
+ answer);
+
+ //send the packet first and start the stream later in case the media
+ //relay needs to see it before letting hole punching techniques through.
+ getProtocolProvider().getConnection().sendPacket(response);
+
+ try
+ {
+ mediaHandler.start();
+ }
+ catch(UndeclaredThrowableException e)
+ {
+ Throwable exc = e.getUndeclaredThrowable();
+
+ logger.info("Failed to establish a connection", exc);
+
+ //send an error response
+ String reasonText = "Error: " + exc.getMessage();
+ JingleIQ errResp
+ = JinglePacketFactory.createSessionTerminate(
+ sessionInitIQ.getTo(),
+ sessionInitIQ.getFrom(),
+ sessionInitIQ.getSID(),
+ Reason.GENERAL_ERROR,
+ reasonText);
+
+ setState(CallPeerState.FAILED, reasonText);
+ getProtocolProvider().getConnection().sendPacket(errResp);
+ return;
+ }
+
+ //tell everyone we are connected so that the audio notifications would
+ //stop
+ setState(CallPeerState.CONNECTED);
+ }
+
+ /**
+ * Returns the session ID of the Jingle session associated with this call.
+ *
+ * @return the session ID of the Jingle session associated with this call.
+ */
+ @Override
+ public String getSID()
+ {
+ return sessionInitIQ != null ? sessionInitIQ.getSID() : null;
+ }
+
+ /**
+ * Returns the IQ ID of the Jingle session-initiate packet associated with
+ * this call.
+ *
+ * @return the IQ ID of the Jingle session-initiate packet associated with
+ * this call.
+ */
+ public JingleIQ getSessionIQ()
+ {
+ return sessionInitIQ;
+ }
+
+ /**
+ * Ends the call with this <tt>CallPeer</tt>. Depending on the state
+ * of the peer the method would send a CANCEL, BYE, or BUSY_HERE message
+ * and set the new state to DISCONNECTED.
+ *
+ * @param failed indicates if the hangup is following to a call failure or
+ * simply a disconnect
+ * @param reasonText the text, if any, to be set on the
+ * <tt>ReasonPacketExtension</tt> as the value of its
+ * @param reasonOtherExtension the <tt>PacketExtension</tt>, if any, to be
+ * set on the <tt>ReasonPacketExtension</tt> as the value of its
+ * <tt>otherExtension</tt> property
+ */
+ public void hangup(boolean failed,
+ String reasonText,
+ PacketExtension reasonOtherExtension)
+ {
+ CallPeerState prevPeerState = getState();
+
+ // do nothing if the call is already ended
+ if (CallPeerState.DISCONNECTED.equals(prevPeerState)
+ || CallPeerState.FAILED.equals(prevPeerState))
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Ignoring a request to hangup a call peer "
+ + "that is already DISCONNECTED");
+ return;
+ }
+
+ setState(
+ failed ? CallPeerState.FAILED : CallPeerState.DISCONNECTED,
+ reasonText);
+
+ JingleIQ responseIQ = null;
+
+ if (prevPeerState.equals(CallPeerState.CONNECTED)
+ || CallPeerState.isOnHold(prevPeerState))
+ {
+ responseIQ = JinglePacketFactory.createBye(
+ getProtocolProvider().getOurJID(), peerJID, getSID());
+ }
+ else if (CallPeerState.CONNECTING.equals(prevPeerState)
+ || CallPeerState.CONNECTING_WITH_EARLY_MEDIA.equals(prevPeerState)
+ || CallPeerState.ALERTING_REMOTE_SIDE.equals(prevPeerState))
+ {
+ String jingleSID = getSID();
+
+ if(jingleSID == null)
+ {
+ synchronized(sidSyncRoot)
+ {
+ // we cancelled the call too early because the jingleSID
+ // is null (i.e. the session-initiate has not been created)
+ // and no need to send the session-terminate
+ cancelled = true;
+ return;
+ }
+ }
+
+ responseIQ = JinglePacketFactory.createCancel(
+ getProtocolProvider().getOurJID(), peerJID, getSID());
+ }
+ else if (prevPeerState.equals(CallPeerState.INCOMING_CALL))
+ {
+ responseIQ = JinglePacketFactory.createBusy(
+ getProtocolProvider().getOurJID(), peerJID, getSID());
+ }
+ else if (prevPeerState.equals(CallPeerState.BUSY)
+ || prevPeerState.equals(CallPeerState.FAILED))
+ {
+ // For FAILED and BUSY we only need to update CALL_STATUS
+ // as everything else has been done already.
+ }
+ else
+ {
+ logger.info("Could not determine call peer state!");
+ }
+
+ if (responseIQ != null)
+ {
+ if (reasonOtherExtension != null)
+ {
+ ReasonPacketExtension reason
+ = (ReasonPacketExtension)
+ responseIQ.getExtension(
+ ReasonPacketExtension.ELEMENT_NAME,
+ ReasonPacketExtension.NAMESPACE);
+
+ if (reason != null)
+ {
+ reason.setOtherExtension(reasonOtherExtension);
+ }
+ else if(reasonOtherExtension instanceof ReasonPacketExtension)
+ {
+ responseIQ.setReason(
+ (ReasonPacketExtension)reasonOtherExtension);
+ }
+ }
+
+ getProtocolProvider().getConnection().sendPacket(responseIQ);
+ }
+ }
+
+ /**
+ * Creates and sends a session-initiate {@link JingleIQ}.
+ *
+ * @param sessionInitiateExtensions a collection of additional and optional
+ * <tt>PacketExtension</tt>s to be added to the <tt>session-initiate</tt>
+ * {@link JingleIQ} which is to initiate the session with this
+ * <tt>CallPeerJabberImpl</tt>
+ * @throws OperationFailedException exception
+ */
+ protected synchronized void initiateSession(
+ Iterable<PacketExtension> sessionInitiateExtensions)
+ throws OperationFailedException
+ {
+ initiator = false;
+
+ //Create the media description that we'd like to send to the other side.
+ List<ContentPacketExtension> offer
+ = getMediaHandler().createContentList();
+
+ ProtocolProviderServiceJabberImpl protocolProvider
+ = getProtocolProvider();
+
+ synchronized(sidSyncRoot)
+ {
+ sessionInitIQ
+ = JinglePacketFactory.createSessionInitiate(
+ protocolProvider.getOurJID(),
+ this.peerJID,
+ JingleIQ.generateSID(),
+ offer);
+
+ if(cancelled)
+ {
+ // we cancelled the call too early so no need to send the
+ // session-initiate to peer
+ getMediaHandler().getTransportManager().close();
+ return;
+ }
+ }
+
+ if (sessionInitiateExtensions != null)
+ {
+ for (PacketExtension sessionInitiateExtension
+ : sessionInitiateExtensions)
+ {
+ sessionInitIQ.addExtension(sessionInitiateExtension);
+ }
+ }
+
+ protocolProvider.getConnection().sendPacket(sessionInitIQ);
+ }
+
+ /**
+ * Notifies this instance that a specific <tt>ColibriConferenceIQ</tt> has
+ * been received. This <tt>CallPeerJabberImpl</tt> uses the part of the
+ * information provided in the specified <tt>conferenceIQ</tt> which
+ * concerns it only.
+ *
+ * @param conferenceIQ the <tt>ColibriConferenceIQ</tt> which has been
+ * received
+ */
+ void processColibriConferenceIQ(ColibriConferenceIQ conferenceIQ)
+ {
+ /*
+ * CallPeerJabberImpl does not itself/directly know the specifics
+ * related to the channels allocated on the Jitsi Videobridge server.
+ * The channels contain transport and media-related information so
+ * forward the notification to CallPeerMediaHandlerJabberImpl.
+ */
+ getMediaHandler().processColibriConferenceIQ(conferenceIQ);
+ }
+
+ /**
+ * Processes the content-accept {@link JingleIQ}.
+ *
+ * @param content The {@link JingleIQ} that contains content that remote
+ * peer has accepted
+ */
+ public void processContentAccept(JingleIQ content)
+ {
+ List<ContentPacketExtension> contents = content.getContentList();
+ CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
+
+ try
+ {
+ mediaHandler
+ .getTransportManager()
+ .wrapupConnectivityEstablishment();
+ mediaHandler.processAnswer(contents);
+ for (ContentPacketExtension c : contents)
+ setSenders(getMediaType(c), c.getSenders());
+ }
+ catch (Exception e)
+ {
+ logger.warn("Failed to process a content-accept", e);
+
+ // Send an error response.
+ String reason = "Error: " + e.getMessage();
+ JingleIQ errResp
+ = JinglePacketFactory.createSessionTerminate(
+ getProtocolProvider().getOurJID(),
+ peerJID,
+ sessionInitIQ.getSID(),
+ Reason.INCOMPATIBLE_PARAMETERS,
+ reason);
+
+ setState(CallPeerState.FAILED, reason);
+ getProtocolProvider().getConnection().sendPacket(errResp);
+ return;
+ }
+
+ mediaHandler.start();
+ }
+
+ /**
+ * Processes the content-add {@link JingleIQ}.
+ *
+ * @param content The {@link JingleIQ} that contains content that remote
+ * peer wants to be added
+ */
+ public void processContentAdd(final JingleIQ content)
+ {
+ CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
+ List<ContentPacketExtension> contents = content.getContentList();
+ Iterable<ContentPacketExtension> answerContents;
+ JingleIQ contentIQ;
+ boolean noCands = false;
+ MediaStream oldVideoStream = mediaHandler.getStream(MediaType.VIDEO);
+
+ if(logger.isInfoEnabled())
+ logger.info("Looking for candidates in content-add.");
+ try
+ {
+ if(!contentAddWithNoCands)
+ {
+ mediaHandler.processOffer(contents);
+
+ /*
+ * Gingle transport will not put candidate in session-initiate
+ * and content-add.
+ */
+ for(ContentPacketExtension c : contents)
+ {
+ if(JingleUtils.getFirstCandidate(c, 1) == null)
+ {
+ contentAddWithNoCands = true;
+ noCands = true;
+ }
+ }
+ }
+
+ // if no candidates are present, launch a new Thread which will
+ // process and wait for the connectivity establishment (otherwise
+ // the existing thread will be blocked and thus cannot receive
+ // transport-info with candidates
+ if(noCands)
+ {
+ new Thread()
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ synchronized(candSyncRoot)
+ {
+ candSyncRoot.wait();
+ }
+ }
+ catch(InterruptedException e)
+ {
+ }
+
+ processContentAdd(content);
+ contentAddWithNoCands = false;
+ }
+ }.start();
+ if(logger.isInfoEnabled())
+ logger.info("No candidates found in content-add, started "
+ + "new thread.");
+ return;
+ }
+
+ mediaHandler
+ .getTransportManager()
+ .wrapupConnectivityEstablishment();
+ if(logger.isInfoEnabled())
+ logger.info("Wrapping up connectivity establishment");
+ answerContents = mediaHandler.generateSessionAccept();
+ contentIQ = null;
+ }
+ catch(Exception e)
+ {
+ logger.warn("Exception occurred", e);
+
+ answerContents = null;
+ contentIQ
+ = JinglePacketFactory.createContentReject(
+ getProtocolProvider().getOurJID(),
+ this.peerJID,
+ getSID(),
+ answerContents);
+ }
+
+ if(contentIQ == null)
+ {
+ /* send content-accept */
+ contentIQ
+ = JinglePacketFactory.createContentAccept(
+ getProtocolProvider().getOurJID(),
+ this.peerJID,
+ getSID(),
+ answerContents);
+ for (ContentPacketExtension c : answerContents)
+ setSenders(getMediaType(c), c.getSenders());
+ }
+
+ getProtocolProvider().getConnection().sendPacket(contentIQ);
+ mediaHandler.start();
+
+ /*
+ * If a remote peer turns her video on in a conference which is hosted
+ * by the local peer and the local peer is not streaming her local
+ * video, reinvite the other remote peers to enable RTP translation.
+ */
+ if (oldVideoStream == null)
+ {
+ MediaStream newVideoStream
+ = mediaHandler.getStream(MediaType.VIDEO);
+
+ if ((newVideoStream != null)
+ && mediaHandler.isRTPTranslationEnabled(MediaType.VIDEO))
+ {
+ try
+ {
+ getCall().modifyVideoContent();
+ }
+ catch (OperationFailedException ofe)
+ {
+ logger.error("Failed to enable RTP translation", ofe);
+ }
+ }
+ }
+ }
+
+ /**
+ * Processes the content-modify {@link JingleIQ}.
+ *
+ * @param content The {@link JingleIQ} that contains content that remote
+ * peer wants to be modified
+ */
+ public void processContentModify(JingleIQ content)
+ {
+ ContentPacketExtension ext = content.getContentList().get(0);
+ MediaType mediaType = getMediaType(ext);
+
+ try
+ {
+ boolean modify
+ = (ext.getFirstChildOfType(RtpDescriptionPacketExtension.class)
+ != null);
+
+ getMediaHandler().reinitContent(ext.getName(), ext, modify);
+
+ setSenders(mediaType, ext.getSenders());
+
+ if (MediaType.VIDEO.equals(mediaType))
+ getCall().modifyVideoContent();
+ }
+ catch(Exception e)
+ {
+ logger.info("Failed to process an incoming content-modify", e);
+
+ // Send an error response.
+ String reason = "Error: " + e.getMessage();
+ JingleIQ errResp
+ = JinglePacketFactory.createSessionTerminate(
+ getProtocolProvider().getOurJID(),
+ peerJID,
+ sessionInitIQ.getSID(),
+ Reason.INCOMPATIBLE_PARAMETERS,
+ reason);
+
+ setState(CallPeerState.FAILED, reason);
+ getProtocolProvider().getConnection().sendPacket(errResp);
+ return;
+ }
+ }
+
+ /**
+ * Processes the content-reject {@link JingleIQ}.
+ *
+ * @param content The {@link JingleIQ}
+ */
+ public void processContentReject(JingleIQ content)
+ {
+ if(content.getContentList().isEmpty())
+ {
+ //send an error response;
+ JingleIQ errResp = JinglePacketFactory.createSessionTerminate(
+ sessionInitIQ.getTo(), sessionInitIQ.getFrom(),
+ sessionInitIQ.getSID(), Reason.INCOMPATIBLE_PARAMETERS,
+ "Error: content rejected");
+
+ setState(CallPeerState.FAILED, "Error: content rejected");
+ getProtocolProvider().getConnection().sendPacket(errResp);
+ return;
+ }
+ }
+
+ /**
+ * Processes the content-remove {@link JingleIQ}.
+ *
+ * @param content The {@link JingleIQ} that contains content that remote
+ * peer wants to be removed
+ */
+ public void processContentRemove(JingleIQ content)
+ {
+ List<ContentPacketExtension> contents = content.getContentList();
+ boolean videoContentRemoved = false;
+
+ if (!contents.isEmpty())
+ {
+ CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
+
+ for(ContentPacketExtension c : contents)
+ {
+ mediaHandler.removeContent(c.getName());
+
+ MediaType mediaType = getMediaType(c);
+ setSenders(mediaType, SendersEnum.none);
+
+ if (MediaType.VIDEO.equals(mediaType))
+ videoContentRemoved = true;
+ }
+
+ /*
+ * TODO XEP-0166: Jingle says: If the content-remove results in zero
+ * content definitions for the session, the entity that receives the
+ * content-remove SHOULD send a session-terminate action to the
+ * other party (since a session with no content definitions is
+ * void).
+ */
+ }
+
+ if (videoContentRemoved)
+ {
+ // removing of the video content might affect the other sessions
+ // in the call
+ try
+ {
+ getCall().modifyVideoContent();
+ }
+ catch (Exception e)
+ {
+ logger.warn("Failed to update Jingle sessions");
+ }
+ }
+ }
+
+ /**
+ * Processes a session-accept {@link JingleIQ}.
+ *
+ * @param sessionInitIQ The session-accept {@link JingleIQ} to process.
+ */
+ public void processSessionAccept(JingleIQ sessionInitIQ)
+ {
+ this.sessionInitIQ = sessionInitIQ;
+
+ CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
+ List<ContentPacketExtension> answer = sessionInitIQ.getContentList();
+
+ try
+ {
+ mediaHandler
+ .getTransportManager()
+ .wrapupConnectivityEstablishment();
+ mediaHandler.processAnswer(answer);
+ for (ContentPacketExtension c : answer)
+ setSenders(getMediaType(c), c.getSenders());
+ }
+ catch(Exception exc)
+ {
+ if (logger.isInfoEnabled())
+ logger.info("Failed to process a session-accept", exc);
+
+ //send an error response;
+ JingleIQ errResp = JinglePacketFactory.createSessionTerminate(
+ sessionInitIQ.getTo(), sessionInitIQ.getFrom(),
+ sessionInitIQ.getSID(), Reason.INCOMPATIBLE_PARAMETERS,
+ exc.getClass().getName() + ": " + exc.getMessage());
+
+ setState(CallPeerState.FAILED, "Error: " + exc.getMessage());
+ getProtocolProvider().getConnection().sendPacket(errResp);
+ return;
+ }
+
+ //tell everyone we are connected so that the audio notifications would
+ //stop
+ setState(CallPeerState.CONNECTED);
+
+ mediaHandler.start();
+
+ /*
+ * If video was added to the call after we sent the session-initiate
+ * to this peer, it needs to be added to this peer's session with a
+ * content-add.
+ */
+ sendModifyVideoContent();
+ }
+
+ /**
+ * Handles the specified session <tt>info</tt> packet according to its
+ * content.
+ *
+ * @param info the {@link SessionInfoPacketExtension} that we just received.
+ */
+ public void processSessionInfo(SessionInfoPacketExtension info)
+ {
+ switch (info.getType())
+ {
+ case ringing:
+ setState(CallPeerState.ALERTING_REMOTE_SIDE);
+ break;
+ case hold:
+ getMediaHandler().setRemotelyOnHold(true);
+ reevalRemoteHoldStatus();
+ break;
+ case unhold:
+ case active:
+ getMediaHandler().setRemotelyOnHold(false);
+ reevalRemoteHoldStatus();
+ break;
+ default:
+ logger.warn("Received SessionInfoPacketExtension of unknown type");
+ }
+ }
+
+ /**
+ * Processes the session initiation {@link JingleIQ} that we were created
+ * with, passing its content to the media handler and then sends either a
+ * "session-info/ringing" or a "session-terminate" response.
+ *
+ * @param sessionInitIQ The {@link JingleIQ} that created the session that
+ * we are handling here.
+ */
+ protected synchronized void processSessionInitiate(JingleIQ sessionInitIQ)
+ {
+ // Do initiate the session.
+ this.sessionInitIQ = sessionInitIQ;
+ this.initiator = true;
+
+ // This is the SDP offer that came from the initial session-initiate.
+ // Contrary to SIP, we are guaranteed to have content because XEP-0166
+ // says: "A session consists of at least one content type at a time."
+ List<ContentPacketExtension> offer = sessionInitIQ.getContentList();
+
+ try
+ {
+ getMediaHandler().processOffer(offer);
+
+ CoinPacketExtension coin = null;
+
+ for(PacketExtension ext : sessionInitIQ.getExtensions())
+ {
+ if(ext.getElementName().equals(
+ CoinPacketExtension.ELEMENT_NAME))
+ {
+ coin = (CoinPacketExtension)ext;
+ break;
+ }
+ }
+
+ /* does the call peer acts as a conference focus ? */
+ if(coin != null)
+ {
+ setConferenceFocus(Boolean.parseBoolean(
+ (String)coin.getAttribute("isfocus")));
+ }
+ }
+ catch(Exception ex)
+ {
+ logger.info("Failed to process an incoming session initiate", ex);
+
+ //send an error response;
+ String reasonText = "Error: " + ex.getMessage();
+ JingleIQ errResp
+ = JinglePacketFactory.createSessionTerminate(
+ sessionInitIQ.getTo(),
+ sessionInitIQ.getFrom(),
+ sessionInitIQ.getSID(),
+ Reason.INCOMPATIBLE_PARAMETERS,
+ reasonText);
+
+ setState(CallPeerState.FAILED, reasonText);
+ getProtocolProvider().getConnection().sendPacket(errResp);
+ return;
+ }
+
+ // If we do not get the info about the remote peer yet. Get it right
+ // now.
+ if(this.getDiscoveryInfo() == null)
+ {
+ String calleeURI = sessionInitIQ.getFrom();
+ retrieveDiscoveryInfo(calleeURI);
+ }
+
+ //send a ringing response
+ if (logger.isTraceEnabled())
+ logger.trace("will send ringing response: ");
+
+ getProtocolProvider().getConnection().sendPacket(
+ JinglePacketFactory.createRinging(sessionInitIQ));
+
+ synchronized(sessionInitiateSyncRoot)
+ {
+ sessionInitiateProcessed = true;
+ sessionInitiateSyncRoot.notify();
+ }
+
+ //if this is a 3264 initiator, let's give them an early peek at our
+ //answer so that they could start ICE (SIP-2-Jingle gateways won't
+ //be able to send their candidates unless they have this)
+ DiscoverInfo discoverInfo = getDiscoveryInfo();
+ if ((discoverInfo != null)
+ && discoverInfo.containsFeature(
+ ProtocolProviderServiceJabberImpl.URN_IETF_RFC_3264))
+ {
+ getProtocolProvider().getConnection().sendPacket(
+ JinglePacketFactory.createDescriptionInfo(
+ sessionInitIQ.getTo(),
+ sessionInitIQ.getFrom(),
+ sessionInitIQ.getSID(),
+ getMediaHandler().getLocalContentList()));
+ }
+ }
+
+ /**
+ * Puts this peer into a {@link CallPeerState#DISCONNECTED}, indicating a
+ * reason to the user, if there is one.
+ *
+ * @param jingleIQ the {@link JingleIQ} that's terminating our session.
+ */
+ public void processSessionTerminate(JingleIQ jingleIQ)
+ {
+ String reasonStr = "Call ended by remote side.";
+ ReasonPacketExtension reasonExt = jingleIQ.getReason();
+
+ if(reasonExt != null)
+ {
+ Reason reason = reasonExt.getReason();
+
+ if(reason != null)
+ reasonStr += " Reason: " + reason.toString() + ".";
+
+ String text = reasonExt.getText();
+
+ if(text != null)
+ reasonStr += " " + text;
+ }
+
+ setState(CallPeerState.DISCONNECTED, reasonStr);
+ }
+
+ /**
+ * Processes a specific "XEP-0251: Jingle Session Transfer"
+ * <tt>transfer</tt> packet (extension).
+ *
+ * @param transfer the "XEP-0251: Jingle Session Transfer" transfer packet
+ * (extension) to process
+ * @throws OperationFailedException if anything goes wrong while processing
+ * the specified <tt>transfer</tt> packet (extension)
+ */
+ public void processTransfer(TransferPacketExtension transfer)
+ throws OperationFailedException
+ {
+ String attendantAddress = transfer.getFrom();
+
+ if (attendantAddress == null)
+ {
+ throw new OperationFailedException(
+ "Session transfer must contain a \'from\' attribute value.",
+ OperationFailedException.ILLEGAL_ARGUMENT);
+ }
+
+ String calleeAddress = transfer.getTo();
+
+ if (calleeAddress == null)
+ {
+ throw new OperationFailedException(
+ "Session transfer must contain a \'to\' attribute value.",
+ OperationFailedException.ILLEGAL_ARGUMENT);
+ }
+
+ // Checks if the transfer remote peer is contained by the roster of this
+ // account.
+ Roster roster = getProtocolProvider().getConnection().getRoster();
+ if(!roster.contains(StringUtils.parseBareAddress(calleeAddress)))
+ {
+ String failedMessage =
+ "Transfer impossible:\n"
+ + "Account roster does not contain transfer peer: "
+ + StringUtils.parseBareAddress(calleeAddress);
+ setState(CallPeerState.FAILED, failedMessage);
+ logger.info(failedMessage);
+ }
+
+ OperationSetBasicTelephonyJabberImpl basicTelephony
+ = (OperationSetBasicTelephonyJabberImpl)
+ getProtocolProvider()
+ .getOperationSet(OperationSetBasicTelephony.class);
+ CallJabberImpl calleeCall = new CallJabberImpl(basicTelephony);
+ TransferPacketExtension calleeTransfer = new TransferPacketExtension();
+ String sid = transfer.getSID();
+
+ calleeTransfer.setFrom(attendantAddress);
+ if (sid != null)
+ {
+ calleeTransfer.setSID(sid);
+ calleeTransfer.setTo(calleeAddress);
+ }
+ basicTelephony.createOutgoingCall(
+ calleeCall,
+ calleeAddress,
+ Arrays.asList(new PacketExtension[] { calleeTransfer }));
+ }
+
+ /**
+ * Processes the <tt>transport-info</tt> {@link JingleIQ}.
+ *
+ * @param jingleIQ the <tt>transport-info</tt> {@link JingleIQ} to process
+ */
+ public void processTransportInfo(JingleIQ jingleIQ)
+ {
+ /*
+ * The transport-info action is used to exchange transport candidates so
+ * it only concerns the mediaHandler.
+ */
+ try
+ {
+ if(isInitiator())
+ {
+ synchronized(sessionInitiateSyncRoot)
+ {
+ if(!sessionInitiateProcessed)
+ {
+ try
+ {
+ sessionInitiateSyncRoot.wait();
+ }
+ catch(InterruptedException e)
+ {
+ }
+ }
+ }
+ }
+
+ getMediaHandler().processTransportInfo(
+ jingleIQ.getContentList());
+ }
+ catch (OperationFailedException ofe)
+ {
+ logger.warn("Failed to process an incoming transport-info", ofe);
+
+ //send an error response
+ String reasonText = "Error: " + ofe.getMessage();
+ JingleIQ errResp
+ = JinglePacketFactory.createSessionTerminate(
+ getProtocolProvider().getOurJID(),
+ peerJID,
+ sessionInitIQ.getSID(),
+ Reason.GENERAL_ERROR,
+ reasonText);
+
+ setState(CallPeerState.FAILED, reasonText);
+ getProtocolProvider().getConnection().sendPacket(errResp);
+
+ return;
+ }
+
+ synchronized(candSyncRoot)
+ {
+ candSyncRoot.notify();
+ }
+ }
+
+ /**
+ * Puts the <tt>CallPeer</tt> represented by this instance on or off hold.
+ *
+ * @param onHold <tt>true</tt> to have the <tt>CallPeer</tt> put on hold;
+ * <tt>false</tt>, otherwise
+ *
+ * @throws OperationFailedException if we fail to construct or send the
+ * INVITE request putting the remote side on/off hold.
+ */
+ public void putOnHold(boolean onHold)
+ throws OperationFailedException
+ {
+ CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
+
+ mediaHandler.setLocallyOnHold(onHold);
+
+ SessionInfoType type;
+
+ if(onHold)
+ type = SessionInfoType.hold;
+ else
+ {
+ type = SessionInfoType.unhold;
+ getMediaHandler().reinitAllContents();
+ }
+
+ //we are now on hold and need to realize this before potentially
+ //spoiling it all with an exception while sending the packet :).
+ reevalLocalHoldStatus();
+
+ JingleIQ onHoldIQ = JinglePacketFactory.createSessionInfo(
+ getProtocolProvider().getOurJID(),
+ peerJID,
+ getSID(),
+ type);
+
+ getProtocolProvider().getConnection().sendPacket(onHoldIQ);
+ }
+
+ /**
+ * Send a <tt>content-add</tt> to add video setup.
+ */
+ private void sendAddVideoContent()
+ {
+ List<ContentPacketExtension> contents;
+
+ try
+ {
+ contents = getMediaHandler().createContentList(MediaType.VIDEO);
+ }
+ catch(Exception exc)
+ {
+ logger.warn("Failed to gather content for video type", exc);
+ return;
+ }
+
+ ProtocolProviderServiceJabberImpl protocolProvider
+ = getProtocolProvider();
+ JingleIQ contentIQ
+ = JinglePacketFactory.createContentAdd(
+ protocolProvider.getOurJID(),
+ this.peerJID,
+ getSID(),
+ contents);
+
+ protocolProvider.getConnection().sendPacket(contentIQ);
+ }
+
+ /**
+ * Sends a <tt>content</tt> message to reflect changes in the setup such as
+ * the local peer/user becoming a conference focus.
+ */
+ public void sendCoinSessionInfo()
+ {
+ JingleIQ sessionInfoIQ
+ = JinglePacketFactory.createSessionInfo(
+ getProtocolProvider().getOurJID(),
+ this.peerJID,
+ getSID());
+ CoinPacketExtension coinExt
+ = new CoinPacketExtension(getCall().isConferenceFocus());
+
+ sessionInfoIQ.addExtension(coinExt);
+ getProtocolProvider().getConnection().sendPacket(sessionInfoIQ);
+ }
+
+ /**
+ * Returns the <tt>MediaDirection</tt> that should be set for the content
+ * of type <tt>mediaType</tt> in the Jingle session for this
+ * <tt>CallPeer</tt>.
+ * If we are the focus of a conference and are doing RTP translation,
+ * takes into account the other <tt>CallPeer</tt>s in the <tt>Call</tt>.
+ *
+ * @param mediaType the <tt>MediaType</tt> for which to return the
+ * <tt>MediaDirection</tt>
+ * @return the <tt>MediaDirection</tt> that should be used for the content
+ * of type <tt>mediaType</tt> in the Jingle session for this
+ * <tt>CallPeer</tt>.
+ */
+ private MediaDirection getDirectionForJingle(MediaType mediaType)
+ {
+ MediaDirection direction = MediaDirection.INACTIVE;
+ CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
+
+ // If we are streaming media, the direction should allow sending
+ if ( (MediaType.AUDIO == mediaType &&
+ mediaHandler.isLocalAudioTransmissionEnabled()) ||
+ (MediaType.VIDEO == mediaType &&
+ isLocalVideoStreaming()))
+ direction = direction.or(MediaDirection.SENDONLY);
+
+ // If we are receiving media from this CallPeer, the direction should
+ // allow receiving
+ SendersEnum senders = getSenders(mediaType);
+ if (senders == null || senders == SendersEnum.both ||
+ (isInitiator() && senders == SendersEnum.initiator) ||
+ (!isInitiator() && senders == SendersEnum.responder))
+ direction = direction.or(MediaDirection.RECVONLY);
+
+ // If we are the focus of a conference and we are receiving media from
+ // another CallPeer in the same Call, the direction should allow sending
+ CallJabberImpl call = getCall();
+ if (call != null && call.isConferenceFocus())
+ {
+ for (CallPeerJabberImpl peer : call.getCallPeerList())
+ {
+ if (peer != this)
+ {
+ senders = peer.getSenders(mediaType);
+ if (senders == null || senders == SendersEnum.both ||
+ (peer.isInitiator()
+ && senders == SendersEnum.initiator) ||
+ (!peer.isInitiator()
+ && senders == SendersEnum.responder))
+ {
+ direction = direction.or(MediaDirection.SENDONLY);
+ break;
+ }
+ }
+ }
+ }
+
+ return direction;
+ }
+
+ /**
+ * Send, if necessary, a jingle <tt>content</tt> message to reflect change
+ * in video setup. Whether the jingle session should have a video content,
+ * and if so, the value of the <tt>senders</tt> field is determined
+ * based on whether we are streaming local video and, if we are the focus
+ * of a conference, on the other peers in the conference.
+ * The message can be content-modify if video content exists (and the
+ * <tt>senders</tt> field changes), content-add or content-remove.
+ *
+ * @return <tt>true</tt> if a jingle <tt>content</tt> message was sent.
+ */
+ public boolean sendModifyVideoContent()
+ {
+ CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
+ MediaDirection direction = getDirectionForJingle(MediaType.VIDEO);
+
+ ContentPacketExtension remoteContent
+ = mediaHandler.getLocalContent(MediaType.VIDEO.toString());
+
+ if (remoteContent == null)
+ {
+ if (direction == MediaDirection.INACTIVE)
+ {
+ // no video content, none needed
+ return false;
+ }
+ else
+ {
+ if (getState() == CallPeerState.CONNECTED)
+ {
+ if (logger.isInfoEnabled())
+ logger.info("Adding video content for " + this);
+ sendAddVideoContent();
+ return true;
+ }
+ return false;
+ }
+ }
+ else
+ {
+ if (direction == MediaDirection.INACTIVE)
+ {
+ sendRemoveVideoContent();
+ return true;
+ }
+ }
+
+ SendersEnum senders = getSenders(MediaType.VIDEO);
+ if (senders == null)
+ senders = SendersEnum.both;
+
+ SendersEnum newSenders = SendersEnum.none;
+ if (MediaDirection.SENDRECV == direction)
+ newSenders = SendersEnum.both;
+ else if (MediaDirection.RECVONLY == direction)
+ newSenders = isInitiator()
+ ? SendersEnum.initiator : SendersEnum.responder;
+ else if (MediaDirection.SENDONLY == direction)
+ newSenders = isInitiator()
+ ? SendersEnum.responder : SendersEnum.initiator;
+
+ /*
+ * Send Content-Modify
+ */
+ ContentPacketExtension ext = new ContentPacketExtension();
+ String remoteContentName = remoteContent.getName();
+
+ ext.setSenders(newSenders);
+ ext.setCreator(remoteContent.getCreator());
+ ext.setName(remoteContentName);
+
+ if (newSenders != senders)
+ {
+ if (logger.isInfoEnabled())
+ logger.info("Sending content modify, senders: "
+ + senders + "->" + newSenders);
+ ProtocolProviderServiceJabberImpl protocolProvider
+ = getProtocolProvider();
+ JingleIQ contentIQ
+ = JinglePacketFactory.createContentModify(
+ protocolProvider.getOurJID(),
+ this.peerJID,
+ getSID(),
+ ext);
+
+ protocolProvider.getConnection().sendPacket(contentIQ);
+ }
+
+ try
+ {
+ mediaHandler.reinitContent(remoteContentName, ext, false);
+ mediaHandler.start();
+ }
+ catch(Exception e)
+ {
+ logger.warn("Exception occurred during media reinitialization", e);
+ }
+
+ return (newSenders != senders);
+ }
+
+ /**
+ * Send a <tt>content</tt> message to reflect change in video setup (start
+ * or stop).
+ */
+ public void sendModifyVideoResolutionContent()
+ {
+ CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
+ ContentPacketExtension remoteContent
+ = mediaHandler.getRemoteContent(MediaType.VIDEO.toString());
+ ContentPacketExtension content;
+
+ logger.info("send modify-content to change resolution");
+
+ // send content-modify with RTP description
+
+ // create content list with resolution
+ try
+ {
+ content = mediaHandler.createContentForMedia(MediaType.VIDEO);
+ }
+ catch (Exception e)
+ {
+ logger.warn("Failed to gather content for video type", e);
+ return;
+ }
+
+ // if we are only receiving video senders is null
+ SendersEnum senders = remoteContent.getSenders();
+
+ if (senders != null)
+ content.setSenders(senders);
+
+ ProtocolProviderServiceJabberImpl protocolProvider
+ = getProtocolProvider();
+ JingleIQ contentIQ
+ = JinglePacketFactory.createContentModify(
+ protocolProvider.getOurJID(),
+ this.peerJID,
+ getSID(),
+ content);
+
+ protocolProvider.getConnection().sendPacket(contentIQ);
+
+ try
+ {
+ mediaHandler.reinitContent(remoteContent.getName(), content, false);
+ mediaHandler.start();
+ }
+ catch(Exception e)
+ {
+ logger.warn("Exception occurred when media reinitialization", e);
+ }
+ }
+
+ /**
+ * Send a <tt>content-remove</tt> to remove video setup.
+ */
+ private void sendRemoveVideoContent()
+ {
+ CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
+
+ ContentPacketExtension content = new ContentPacketExtension();
+ ContentPacketExtension remoteContent
+ = mediaHandler.getRemoteContent(MediaType.VIDEO.toString());
+ if (remoteContent == null)
+ return;
+ String remoteContentName = remoteContent.getName();
+
+ content.setName(remoteContentName);
+ content.setCreator(remoteContent.getCreator());
+ content.setSenders(remoteContent.getSenders());
+
+ ProtocolProviderServiceJabberImpl protocolProvider
+ = getProtocolProvider();
+ JingleIQ contentIQ
+ = JinglePacketFactory.createContentRemove(
+ protocolProvider.getOurJID(),
+ this.peerJID,
+ getSID(),
+ Arrays.asList(content));
+
+ protocolProvider.getConnection().sendPacket(contentIQ);
+ mediaHandler.removeContent(remoteContentName);
+ setSenders(MediaType.VIDEO, SendersEnum.none);
+ }
+
+ /**
+ * Sends local candidate addresses from the local peer to the remote peer
+ * using the <tt>transport-info</tt> {@link JingleIQ}.
+ *
+ * @param contents the local candidate addresses to be sent from the local
+ * peer to the remote peer using the <tt>transport-info</tt>
+ * {@link JingleIQ}
+ */
+ protected void sendTransportInfo(Iterable<ContentPacketExtension> contents)
+ {
+ // if the call is canceled, do not start sending candidates in
+ // transport-info
+ if(cancelled)
+ return;
+
+ JingleIQ transportInfo = new JingleIQ();
+
+ for (ContentPacketExtension content : contents)
+ transportInfo.addContent(content);
+
+ ProtocolProviderServiceJabberImpl protocolProvider
+ = getProtocolProvider();
+
+ transportInfo.setAction(JingleAction.TRANSPORT_INFO);
+ transportInfo.setFrom(protocolProvider.getOurJID());
+ transportInfo.setSID(getSID());
+ transportInfo.setTo(getAddress());
+ transportInfo.setType(IQ.Type.SET);
+
+ PacketCollector collector
+ = protocolProvider.getConnection().createPacketCollector(
+ new PacketIDFilter(transportInfo.getPacketID()));
+
+ protocolProvider.getConnection().sendPacket(transportInfo);
+ collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+ collector.cancel();
+ }
+
+ @Override
+ public void setState(CallPeerState newState, String reason, int reasonCode)
+ {
+ CallPeerState oldState = getState();
+ try
+ {
+ /*
+ * We need to dispose of the transport manager before the
+ * 'call' field is set to null, because if Jitsi Videobridge is in
+ * use, it (the call) is needed in order to expire the
+ * Videobridge channels.
+ */
+ if (CallPeerState.DISCONNECTED.equals(newState)
+ || CallPeerState.FAILED.equals(newState))
+ getMediaHandler().getTransportManager().close();
+ }
+ finally
+ {
+ super.setState(newState, reason, reasonCode);
+ }
+
+ if (CallPeerState.isOnHold(oldState)
+ && CallPeerState.CONNECTED.equals(newState))
+ {
+ try
+ {
+ getCall().modifyVideoContent();
+ }
+ catch (OperationFailedException ofe)
+ {
+ logger.error("Failed to update call video state after " +
+ "'hold' status removed for "+this);
+ }
+ }
+ }
+
+ /**
+ * Transfer (in the sense of call transfer) this <tt>CallPeer</tt> to a
+ * specific callee address which may optionally be participating in an
+ * active <tt>Call</tt>.
+ *
+ * @param to the address of the callee to transfer this <tt>CallPeer</tt> to
+ * @param sid the Jingle session ID of the active <tt>Call</tt> between the
+ * local peer and the callee in the case of attended transfer; <tt>null</tt>
+ * in the case of unattended transfer
+ * @throws OperationFailedException if something goes wrong
+ */
+ protected void transfer(String to, String sid)
+ throws OperationFailedException
+ {
+ JingleIQ transferSessionInfo = new JingleIQ();
+ ProtocolProviderServiceJabberImpl protocolProvider
+ = getProtocolProvider();
+
+ transferSessionInfo.setAction(JingleAction.SESSION_INFO);
+ transferSessionInfo.setFrom(protocolProvider.getOurJID());
+ transferSessionInfo.setSID(getSID());
+ transferSessionInfo.setTo(getAddress());
+ transferSessionInfo.setType(IQ.Type.SET);
+
+ TransferPacketExtension transfer = new TransferPacketExtension();
+
+ // Attended transfer.
+ if (sid != null)
+ {
+ /*
+ * Not really sure what the value of the "from" attribute of the
+ * "transfer" element should be but the examples in "XEP-0251:
+ * Jingle Session Transfer" has it in the case of attended transfer.
+ */
+ transfer.setFrom(protocolProvider.getOurJID());
+ transfer.setSID(sid);
+
+ // Puts on hold the 2 calls before making the attended transfer.
+ OperationSetBasicTelephonyJabberImpl basicTelephony
+ = (OperationSetBasicTelephonyJabberImpl)
+ protocolProvider.getOperationSet(
+ OperationSetBasicTelephony.class);
+ CallPeerJabberImpl callPeer = basicTelephony.getActiveCallPeer(sid);
+ if(callPeer != null)
+ {
+ if(!CallPeerState.isOnHold(callPeer.getState()))
+ {
+ callPeer.putOnHold(true);
+ }
+ }
+
+ if(!CallPeerState.isOnHold(this.getState()))
+ {
+ this.putOnHold(true);
+ }
+ }
+ transfer.setTo(to);
+
+ transferSessionInfo.addExtension(transfer);
+
+ Connection connection = protocolProvider.getConnection();
+ PacketCollector collector = connection.createPacketCollector(
+ new PacketIDFilter(transferSessionInfo.getPacketID()));
+ protocolProvider.getConnection().sendPacket(transferSessionInfo);
+
+ Packet result
+ = collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
+
+ if(result == null)
+ {
+ // Log the failed transfer call and notify the user.
+ throw new OperationFailedException(
+ "No response to the \"transfer\" request.",
+ OperationFailedException.ILLEGAL_ARGUMENT);
+ }
+ else if (((IQ) result).getType() != IQ.Type.RESULT)
+ {
+ // Log the failed transfer call and notify the user.
+ throw new OperationFailedException(
+ "Remote peer does not manage call \"transfer\"."
+ + "Response to the \"transfer\" request is: "
+ + ((IQ) result).getType(),
+ OperationFailedException.ILLEGAL_ARGUMENT);
+ }
+ else
+ {
+ String message = ((sid == null) ? "Unattended" : "Attended")
+ + " transfer to: "
+ + to;
+ // Implements the SIP behavior: once the transfer is accepted, the
+ // current call is closed.
+ hangup(
+ false,
+ message,
+ new ReasonPacketExtension(Reason.SUCCESS,
+ message,
+ new TransferredPacketExtension()));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEntity()
+ {
+ return getAddress();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * In Jingle there isn't an actual "direction" parameter. We use the
+ * <tt>senders</tt> field to calculate the direction.
+ */
+ @Override
+ public MediaDirection getDirection(MediaType mediaType)
+ {
+ SendersEnum senders = getSenders(mediaType);
+
+ if (senders == SendersEnum.none)
+ {
+ return MediaDirection.INACTIVE;
+ }
+ else if (senders == null || senders == SendersEnum.both)
+ {
+ return MediaDirection.SENDRECV;
+ }
+ else if (senders == SendersEnum.initiator)
+ {
+ return
+ isInitiator()
+ ? MediaDirection.RECVONLY
+ : MediaDirection.SENDONLY;
+ }
+ else //senders == SendersEnum.responder
+ {
+ return
+ isInitiator()
+ ? MediaDirection.SENDONLY
+ : MediaDirection.RECVONLY;
+ }
+ }
+
+ /**
+ * Gets the current value of the <tt>senders</tt> field of the content with
+ * name <tt>mediaType</tt> in the Jingle session with this
+ * <tt>CallPeer</tt>.
+ *
+ * @param mediaType the <tt>MediaType</tt> for which to get the current
+ * value of the <tt>senders</tt> field.
+ * @return the current value of the <tt>senders</tt> field of the content
+ * with name <tt>mediaType</tt> in the Jingle session with this
+ * <tt>CallPeer</tt>.
+ */
+ public SendersEnum getSenders(MediaType mediaType)
+ {
+ switch (mediaType)
+ {
+ case AUDIO:
+ return audioSenders;
+ case VIDEO:
+ return videoSenders;
+ default:
+ return SendersEnum.none;
+ }
+ }
+
+ /**
+ * Set the current value of the <tt>senders</tt> field of the content with
+ * name <tt>mediaType</tt> in the Jingle session with this <tt>CallPeer</tt>
+ * @param mediaType the <tt>MediaType</tt> for which to get the current
+ * value of the <tt>senders</tt> field.
+ * @param senders the value to set
+ */
+ public void setSenders(MediaType mediaType, SendersEnum senders)
+ {
+ switch(mediaType)
+ {
+ case AUDIO:
+ this.audioSenders = senders;
+ break;
+ case VIDEO:
+ this.videoSenders = senders;
+ break;
+ default:
+ throw new IllegalArgumentException("mediaType");
+ }
+ }
+
+ /**
+ * Gets the <tt>MediaType</tt> of <tt>content</tt>. If <tt>content</tt>
+ * does not have a <tt>description</tt> child and therefore not
+ * <tt>MediaType</tt> can be associated with it, tries to take the
+ * <tt>MediaType</tt> from the session's already established contents with
+ * the same name as <tt>content</tt>
+ * @param content the <tt>ContentPacketExtention</tt> for which to get the
+ * <tt>MediaType</tt>
+ * @return the <tt>MediaType</tt> of <tt>content</tt>.
+ */
+ public MediaType getMediaType(ContentPacketExtension content)
+ {
+ String contentName = content.getName();
+ if (contentName == null)
+ return null;
+
+ MediaType mediaType = JingleUtils.getMediaType(content);
+ if (mediaType == null)
+ {
+ CallPeerMediaHandlerJabberImpl mediaHandler = getMediaHandler();
+ for (MediaType m : MediaType.values())
+ {
+ ContentPacketExtension sessionContent
+ = mediaHandler.getRemoteContent(m.toString());
+ if (sessionContent == null)
+ sessionContent = mediaHandler.getLocalContent(m.toString());
+
+ if (sessionContent != null
+ && contentName.equals(sessionContent.getName()))
+ {
+ mediaType = m;
+ break;
+ }
+ }
+ }
+
+ return mediaType;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java
index 2c8845d..979d696 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java
@@ -937,19 +937,18 @@ public class CallPeerMediaHandlerJabberImpl
if (supportedTransports != null
&& supportedTransports.length > 0)
{
- for (int i = 0; i < supportedTransports.length; i++)
+ for(String supportedTransport : supportedTransports)
{
if (ProtocolProviderServiceJabberImpl.
URN_XMPP_JINGLE_ICE_UDP_1.
- equals(supportedTransports[i]))
+ equals(supportedTransport))
{
- transportManager
- = new IceUdpTransportManager(peer);
+ transportManager = new IceUdpTransportManager(peer);
break;
}
else if (ProtocolProviderServiceJabberImpl.
- URN_XMPP_JINGLE_RAW_UDP_0.
- equals(supportedTransports[i]))
+ URN_XMPP_JINGLE_RAW_UDP_0.
+ equals(supportedTransport))
{
transportManager
= new RawUdpTransportManager(peer);
@@ -1117,12 +1116,11 @@ public class CallPeerMediaHandlerJabberImpl
List<Component> visualComponents
= new LinkedList<Component>();
- for (int i = 0; i < remoteSSRCs.length; i++)
+ for(int remoteSSRC : remoteSSRCs)
{
- int remoteSSRC = remoteSSRCs[i];
Component visualComponent
- = videoStream.getVisualComponent(
- 0xFFFFFFFFL & remoteSSRC);
+ = videoStream.getVisualComponent(
+ 0xFFFFFFFFL & remoteSSRC);
if (visualComponent != null)
visualComponents.add(visualComponent);
@@ -1605,7 +1603,7 @@ public class CallPeerMediaHandlerJabberImpl
{
List<MediaFormat> fmts = supportedFormats;
- if(fmts.size() > 0)
+ if(!fmts.isEmpty())
{
MediaFormat fmt = fmts.get(0);
@@ -2108,21 +2106,17 @@ public class CallPeerMediaHandlerJabberImpl
* TODO The transportManager is going to be changed so it may need to be
* disposed of prior to the change.
*/
-
- if (xmlns.equals(
- ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_ICE_UDP_1))
+ switch (xmlns)
{
- transportManager = new IceUdpTransportManager(peer);
- }
- else if (xmlns.equals(
- ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_RAW_UDP_0))
- {
- transportManager = new RawUdpTransportManager(peer);
- }
- else
- {
- throw new IllegalArgumentException(
- "Unsupported Jingle transport " + xmlns);
+ case ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_ICE_UDP_1:
+ transportManager = new IceUdpTransportManager(peer);
+ break;
+ case ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_RAW_UDP_0:
+ transportManager = new RawUdpTransportManager(peer);
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported Jingle " +
+ "transport " + xmlns);
}
synchronized(transportManagerSyncRoot)
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ChatRoomJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ChatRoomJabberImpl.java
index 8a6f3ed..6c4c358 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/ChatRoomJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/ChatRoomJabberImpl.java
@@ -609,7 +609,7 @@ public class ChatRoomJabberImpl
this.provider.getConnection().addPacketListener(
presenceListener,
new AndFilter(
- new FromMatchesFilter(multiUserChat.getRoom()),
+ FromMatchesFilter.create(multiUserChat.getRoom()),
new PacketTypeFilter(
org.jivesoftware.smack.packet.Presence.class)));
if(password == null)
@@ -868,7 +868,7 @@ public class ChatRoomJabberImpl
clearCachedConferenceDescriptionList();
- XMPPConnection connection = this.provider.getConnection();
+ Connection connection = this.provider.getConnection();
try
{
// if we are already disconnected
@@ -1896,6 +1896,23 @@ public class ChatRoomJabberImpl
}
/**
+ * Removes given <tt>PacketExtension</tt> from the MUC presence and
+ * publishes it immediately.
+ * @param extension the <tt>PacketExtension</tt> to be removed from the MUC
+ * presence.
+ */
+ public void removePresenceExtension(PacketExtension extension)
+ {
+ if (lastPresenceSent != null)
+ {
+ setPacketExtension(
+ lastPresenceSent, null, extension.getNamespace());
+
+ provider.getConnection().sendPacket(lastPresenceSent);
+ }
+ }
+
+ /**
* Returns the ids of the users that has the member role in the room.
* When the room is member only, this are the users allowed to join.
* @return the ids of the users that has the member role in the room.
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java b/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java
index 1f4e3d8..c3c852c 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java
@@ -58,11 +58,21 @@ public class IceUdpTransportManager
= Logger.getLogger(IceUdpTransportManager.class);
/**
+ * Default STUN server address.
+ */
+ protected static final String DEFAULT_STUN_SERVER_ADDRESS = "stun.jitsi.net";
+
+ /**
+ * Default STUN server port.
+ */
+ protected static final int DEFAULT_STUN_SERVER_PORT = 3478;
+
+ /**
* The ICE <tt>Component</tt> IDs in their common order used, for example,
* by <tt>DefaultStreamConnector</tt>, <tt>MediaStreamTarget</tt>.
*/
private static final int[] COMPONENT_IDS
- = new int[] { Component.RTP, Component.RTCP };
+ = new int[] { Component.RTP, Component.RTCP };
/**
* This is where we keep our answer between the time we get the offer and
@@ -76,15 +86,6 @@ public class IceUdpTransportManager
*/
protected final Agent iceAgent;
- /**
- * Default STUN server address.
- */
- protected static final String DEFAULT_STUN_SERVER_ADDRESS = "stun.jitsi.net";
-
- /**
- * Default STUN server port.
- */
- protected static final int DEFAULT_STUN_SERVER_PORT = 3478;
/**
* Creates a new instance of this transport manager, binding it to the
@@ -156,7 +157,10 @@ public class IceUdpTransportManager
// in case user has canceled the login window
if(credentials == null)
+ {
+ logger.info("Credentials were null. User has most likely canceled the login operation");
return null;
+ }
//extract the password the user passed us.
char[] pass = credentials.getPassword();
@@ -164,7 +168,10 @@ public class IceUdpTransportManager
// the user didn't provide us a password (i.e. canceled the
// operation)
if(pass == null)
+ {
+ logger.info("Password was null. User has most likely canceled the login operation");
return null;
+ }
password = new String(pass);
if (credentials.isPasswordPersistent())
@@ -390,28 +397,29 @@ public class IceUdpTransportManager
for (int i = 0; i < COMPONENT_IDS.length; i++)
{
Component component = stream.getComponent(COMPONENT_IDS[i]);
-
- if (component != null)
+ if (component == null)
{
- CandidatePair selectedPair = component.getSelectedPair();
-
- if (selectedPair != null)
- {
- DatagramSocket streamConnectorSocket
- = selectedPair.getLocalCandidate().
- getDatagramSocket();
+ continue;
+ }
- if (streamConnectorSocket != null)
- {
- streamConnectorSockets[i] = streamConnectorSocket;
- streamConnectorSocketCount++;
- }
- }
+ DatagramSocket streamConnectorSocket = component.getSocket();
+ if (streamConnectorSocket != null)
+ {
+ streamConnectorSockets[i] = streamConnectorSocket;
+ streamConnectorSocketCount++;
+ logger.trace("Added a streamConnectorSocket to the array " +
+ "StreamConnectorSocket and increased " +
+ "the count of streamConnectorSocketCount by one to " +
+ streamConnectorSocketCount);
}
}
+
if (streamConnectorSocketCount > 0)
+ {
return streamConnectorSockets;
+ }
}
+
return null;
}
@@ -742,20 +750,25 @@ public class IceUdpTransportManager
ex);
}
- //let's now update the next port var as best we can: we would assume
- //that all local candidates are bound on the same port and set it
- //to the one just above. if the assumption is wrong the next bind
- //would simply include one more bind retry.
+ // Attempt to minimize subsequent bind retries: see if we have allocated
+ // any ports from the dynamic range, and if so update the port tracker.
+ // Do NOT update the port tracker with non-dynamic ports (e.g. 4443
+ // coming from TCP) because this will force it to revert back it its
+ // configured min port. When maxPort is reached, allocation will begin
+ // from minPort again, so we don't have to worry about wraps.
try
{
- portTracker.setNextPort(
- 1
- + stream
- .getComponent(Component.RTCP)
- .getLocalCandidates()
- .get(0)
- .getTransportAddress()
- .getPort());
+ int maxAllocatedPort = getMaxAllocatedPort(
+ stream,
+ portTracker.getMinPort(),
+ portTracker.getMaxPort());
+
+ if(maxAllocatedPort > 0)
+ {
+ int nextPort = 1 + maxAllocatedPort;
+ portTracker.setNextPort(nextPort);
+ logger.debug("Updating the port tracker min port: " + nextPort);
+ }
}
catch(Throwable t)
{
@@ -768,6 +781,48 @@ public class IceUdpTransportManager
}
/**
+ * @return the highest local port used by any of the local candidates of
+ * {@code iceStream}, which falls in the range [{@code min}, {@code max}].
+ */
+ private int getMaxAllocatedPort(IceMediaStream iceStream, int min, int max)
+ {
+ return
+ Math.max(
+ getMaxAllocatedPort(
+ iceStream.getComponent(Component.RTP),
+ min, max),
+ getMaxAllocatedPort(
+ iceStream.getComponent(Component.RTCP),
+ min, max));
+ }
+
+ /**
+ * @return the highest local port used by any of the local candidates of
+ * {@code component}, which falls in the range [{@code min}, {@code max}].
+ */
+ private int getMaxAllocatedPort(Component component, int min, int max)
+ {
+ int maxAllocatedPort = -1;
+
+ if (component != null)
+ {
+ for (LocalCandidate candidate : component.getLocalCandidates())
+ {
+ int candidatePort = candidate.getTransportAddress().getPort();
+
+ if (min <= candidatePort
+ && candidatePort <= max
+ && maxAllocatedPort < candidatePort)
+ {
+ maxAllocatedPort = candidatePort;
+ }
+ }
+ }
+
+ return maxAllocatedPort;
+ }
+
+ /**
* Simply returns the list of local candidates that we gathered during the
* harvest.
*
@@ -898,8 +953,12 @@ public class IceUdpTransportManager
= transport.getChildExtensionsOfType(
CandidatePacketExtension.class);
- if (iceAgentStateIsRunning && (candidates.size() == 0))
+ if (iceAgentStateIsRunning && candidates.isEmpty())
+ {
+ logger.info("connectivity establishment has not been started " +
+ "because candidate list is empty");
return false;
+ }
String media = e.getKey();
IceMediaStream stream = iceAgent.getStream(media);
@@ -938,6 +997,12 @@ public class IceUdpTransportManager
if (candidate.getGeneration() != generation)
continue;
+ if (candidate.getIP() == null || "".equals(candidate.getIP()))
+ {
+ logger.warn("Skipped ICE candidate with empty IP");
+ continue;
+ }
+
Component component
= stream.getComponent(candidate.getComponent());
String relAddr;
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/InfoRetreiver.java b/src/net/java/sip/communicator/impl/protocol/jabber/InfoRetreiver.java
index a0387df..c3137ad 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/InfoRetreiver.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/InfoRetreiver.java
@@ -151,7 +151,7 @@ public class InfoRetreiver
List<GenericDetail> result = new LinkedList<GenericDetail>();
try
{
- XMPPConnection connection = jabberProvider.getConnection();
+ Connection connection = jabberProvider.getConnection();
if(connection == null || !connection.isAuthenticated())
return null;
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/JabberLoginStrategy.java b/src/net/java/sip/communicator/impl/protocol/jabber/JabberLoginStrategy.java
index 438ea1b..de7578c 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/JabberLoginStrategy.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/JabberLoginStrategy.java
@@ -61,7 +61,7 @@ public interface JabberLoginStrategy
* @param resource the XMPP resource
* @return true to continue connecting, false to abort
*/
- public boolean login(XMPPConnection connection, String userName,
+ public boolean login(Connection connection, String userName,
String resource)
throws XMPPException;
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesCandidate.java b/src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesCandidate.java
index 0ea9a54..f2473dd 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesCandidate.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesCandidate.java
@@ -87,7 +87,7 @@ public class JingleNodesCandidate
* @return the <tt>RelayedCandidateDatagramSocket</tt> of this
* <tt>RelayedCandidate</tt>
*/
- public synchronized JingleNodesCandidateDatagramSocket
+ private synchronized JingleNodesCandidateDatagramSocket
getRelayedCandidateDatagramSocket()
{
if (jingleNodesCandidateDatagramSocket == null)
@@ -113,7 +113,7 @@ public class JingleNodesCandidate
* <tt>Candidate</tt>
*/
@Override
- public IceSocketWrapper getIceSocketWrapper()
+ protected IceSocketWrapper getCandidateIceSocketWrapper()
{
if (socket == null)
{
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesHarvester.java b/src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesHarvester.java
index bb7d31b..d29be03 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesHarvester.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesHarvester.java
@@ -36,7 +36,7 @@ import org.xmpp.jnodes.smack.*;
* @author Sebastien Vincent
*/
public class JingleNodesHarvester
- extends CandidateHarvester
+ extends AbstractCandidateHarvester
{
/**
* The <tt>Logger</tt> used by the <tt>JingleNodesHarvester</tt> class and
@@ -125,7 +125,7 @@ public class JingleNodesHarvester
}
}
- if (ciq != null && ciq.getRemoteport() > 0)
+ if (ciq != null)
{
ip = ciq.getHost();
port = ciq.getRemoteport();
@@ -136,6 +136,22 @@ public class JingleNodesHarvester
" local port: " + ciq.getLocalport());
}
+ if (ip == null || ciq.getRemoteport() == 0)
+ {
+ logger.warn("JN relay ignored because ip was null or port 0");
+ return candidates;
+ }
+
+ // Drop the scope or interface name if the relay sends it
+ // along in its IPv6 address. The scope/ifname is only valid on the
+ // host that owns the IP and we don't need it here.
+ int scopeIndex = ip.indexOf('%');
+ if (scopeIndex > 0)
+ {
+ logger.warn("Dropping scope from assumed IPv6 address " + ip);
+ ip = ip.substring(0, scopeIndex);
+ }
+
/* RTP */
TransportAddress relayedAddress = new TransportAddress(ip, port,
Transport.UDP);
@@ -160,6 +176,7 @@ public class JingleNodesHarvester
candidates.add(local);
}
}
+
return candidates;
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/LoginByClientCertificateStrategy.java b/src/net/java/sip/communicator/impl/protocol/jabber/LoginByClientCertificateStrategy.java
index 09c9462..4825e01 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/LoginByClientCertificateStrategy.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/LoginByClientCertificateStrategy.java
@@ -116,7 +116,7 @@ class LoginByClientCertificateStrategy
* accepted.
* @throws XMPPException
*/
- public boolean login(XMPPConnection connection, String userName,
+ public boolean login(Connection connection, String userName,
String resource)
throws XMPPException
{
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/LoginByPasswordStrategy.java b/src/net/java/sip/communicator/impl/protocol/jabber/LoginByPasswordStrategy.java
index 43fc8a4..7034221 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/LoginByPasswordStrategy.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/LoginByPasswordStrategy.java
@@ -115,7 +115,7 @@ public class LoginByPasswordStrategy
* @return always true.
* @throws XMPPException
*/
- public boolean login(XMPPConnection connection, String userName,
+ public boolean login(Connection connection, String userName,
String resource)
throws XMPPException
{
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/MobileIndicator.java b/src/net/java/sip/communicator/impl/protocol/jabber/MobileIndicator.java
index 926848c..8c801c6 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/MobileIndicator.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/MobileIndicator.java
@@ -222,11 +222,13 @@ public class MobileIndicator
/**
* Caps for user has been changed.
* @param user the user (full JID)
+ * @param fullJids a list of all resources of the user (full JIDs)
* @param node the entity caps node#ver
* @param online indicates if the user for which we're notified is online
*/
@Override
- public void userCapsNodeAdded(String user, String node, boolean online)
+ public void userCapsNodeAdded(String user, ArrayList<String> fullJids,
+ String node, boolean online)
{
updateMobileIndicatorUsingCaps(user);
}
@@ -234,11 +236,13 @@ public class MobileIndicator
/**
* Caps for user has been changed.
* @param user the user (full JID)
+ * @param fullJids a list of all resources of the user (full JIDs)
* @param node the entity caps node#ver
* @param online indicates if the user for which we're notified is online
*/
@Override
- public void userCapsNodeRemoved(String user, String node, boolean online)
+ public void userCapsNodeRemoved(String user, ArrayList<String> fullJids,
+ String node, boolean online)
{
updateMobileIndicatorUsingCaps(user);
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java
index 42a3916..2f35fef 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java
@@ -815,6 +815,17 @@ public class OperationSetBasicInstantMessagingJabberImpl
ForwardedPacketExtension.class);
if(extensions.isEmpty())
return;
+
+ // according to xep-0280 all carbons should come from
+ // our bare jid
+ if (!msg.getFrom().equals(
+ StringUtils.parseBareAddress(
+ jabberProvider.getOurJID())))
+ {
+ logger.info("Received a carbon copy with wrong from!");
+ return;
+ }
+
ForwardedPacketExtension forwardedExt = extensions.get(0);
msg = forwardedExt.getMessage();
if(msg == null || msg.getBody() == null)
@@ -1109,7 +1120,7 @@ public class OperationSetBasicInstantMessagingJabberImpl
NewMailNotificationIQ.NAMESPACE,
new NewMailNotificationProvider());
- XMPPConnection connection = jabberProvider.getConnection();
+ Connection connection = jabberProvider.getConnection();
connection.addPacketListener(
new MailboxIQListener(), new PacketTypeFilter(MailboxIQ.class));
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java
index cc36936..78027c0 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java
@@ -280,7 +280,10 @@ public class OperationSetBasicTelephonyJabberImpl
Iterable<PacketExtension> sessionInitiateExtensions)
throws OperationFailedException
{
- return createOutgoingCall(call, calleeAddress, null, null);
+ if (calleeAddress.contains("/"))
+ return createOutgoingCall(call, calleeAddress, calleeAddress, null);
+ else
+ return createOutgoingCall(call, calleeAddress, null, null);
}
/**
@@ -774,7 +777,7 @@ public class OperationSetBasicTelephonyJabberImpl
*/
private void unsubscribeForJinglePackets()
{
- XMPPConnection connection = protocolProvider.getConnection();
+ Connection connection = protocolProvider.getConnection();
if(connection != null)
connection.removePacketListener(this);
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetContactCapabilitiesJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetContactCapabilitiesJabberImpl.java
index 0a6edfe..59cc17c 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetContactCapabilitiesJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetContactCapabilitiesJabberImpl.java
@@ -26,7 +26,7 @@ import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
import org.jivesoftware.smack.packet.*;
-import org.jivesoftware.smack.util.StringUtils;
+import org.jivesoftware.smack.util.*;
/**
* Represents an <tt>OperationSet</tt> to query the <tt>OperationSet</tt>s
@@ -52,6 +52,19 @@ public class OperationSetContactCapabilitiesJabberImpl
= Logger.getLogger(OperationSetContactCapabilitiesJabberImpl.class);
/**
+ * The name of the property used to control whether to use
+ * all resources to show capabilities
+ */
+ public static final String PROP_XMPP_USE_ALL_RESOURCES_FOR_CAPABILITIES =
+ "net.java.sip.communicator.XMPP_USE_ALL_RESOURCES_FOR_CAPABILITIES";
+
+ /**
+ * The default value for the capabilities setting
+ */
+ public static final boolean USE_ALL_RESOURCES_FOR_CAPABILITIES_DEFAULT =
+ true;
+
+ /**
* The list of <tt>OperationSet</tt> capabilities presumed to be supported
* by a <tt>Contact</tt> when it is offline.
*/
@@ -276,6 +289,42 @@ public class OperationSetContactCapabilitiesJabberImpl
}
/**
+ * Gets the largest set of <tt>OperationSet</tt>s supported from a
+ * list of full JIDs. The returned <tt>OperationSet</tt>s are considered
+ * by the associated protocol provider to capabilities possessed by the
+ * specified <tt>contact</tt>.
+ *
+ * @param fullJids a list of full JIDs in which to find the resource with
+ * the most capabilities.
+ * @return the <tt>Map</tt> listing the most <tt>OperationSet</tt>s
+ * considered by the associated protocol provider to be supported by the
+ * specified <tt>contact</tt> (i.e. to be possessed as capabilities).
+ * Each supported <tt>OperationSet</tt> capability is represented by a
+ * <tt>Map.Entry</tt> with key equal to the <tt>OperationSet</tt> class
+ * name and value equal to the respective <tt>OperationSet</tt> instance
+ */
+ protected Map<String, OperationSet> getLargestSupportedOperationSet(
+ ArrayList<String> fullJids)
+ {
+ Map<String, OperationSet> supportedOperationSets =
+ new HashMap<String, OperationSet>();
+ if (fullJids!=null)
+ {
+ for (String fullJid : fullJids)
+ {
+ Map<String, OperationSet> newSupportedOperationSets=
+ getSupportedOperationSets(fullJid, true);
+ if (newSupportedOperationSets.size()>
+ supportedOperationSets.size())
+ {
+ supportedOperationSets = newSupportedOperationSets;
+ }
+ }
+ }
+ return supportedOperationSets;
+ }
+
+ /**
* Gets the <tt>OperationSet</tt> corresponding to the specified
* <tt>Class</tt> and supported by the specified <tt>Contact</tt>. If the
* returned value is non-<tt>null</tt>, it indicates that the
@@ -387,17 +436,19 @@ public class OperationSetContactCapabilitiesJabberImpl
* record for a specific user about the caps node the user has.
*
* @param user the user (full JID)
+ * @param fullJids a list of all resources of the user (full JIDs)
* @param node the entity caps node#ver
* @param online indicates if the user is currently online
* @see UserCapsNodeListener#userCapsNodeAdded(String, String, boolean)
*/
- public void userCapsNodeAdded(String user, String node, boolean online)
+ public void userCapsNodeAdded(String user, ArrayList<String> fullJids,
+ String node, boolean online)
{
/*
* It doesn't matter to us whether a caps node has been added or removed
* for the specified user because we report all changes.
*/
- userCapsNodeRemoved(user, node, online);
+ userCapsNodeChanged(user, fullJids, node, online);
}
/**
@@ -405,45 +456,86 @@ public class OperationSetContactCapabilitiesJabberImpl
* record for a specific user about the caps node the user has.
*
* @param user the user (full JID)
+ * @param fullJids a list of all resources of the user (full JIDs)
+ * @param node the entity caps node#ver
+ * @param online indicates if the user is currently online
+ * @see UserCapsNodeListener#userCapsNodeAdded(String, String, boolean)
+ */
+ public void userCapsNodeRemoved(String user, ArrayList<String> fullJids,
+ String node, boolean online)
+ {
+ /*
+ * It doesn't matter to us whether a caps node has been added or removed
+ * for the specified user because we report all changes.
+ */
+ userCapsNodeChanged(user, fullJids, node, online);
+ }
+
+ /**
+ * Notifies this listener that an <tt>EntityCapsManager</tt> has changed a
+ * record for a specific user about the caps node the user has.
+ *
+ * @param user the user (full JID)
+ * @param fullJids a list of all resources of the user (full JIDs)
* @param node the entity caps node#ver
* @param online indicates if the given user is online
- * @see UserCapsNodeListener#userCapsNodeRemoved(String, String, boolean)
*/
- public void userCapsNodeRemoved(String user, String node, boolean online)
+ public void userCapsNodeChanged(String user, ArrayList<String> fullJids,
+ String node, boolean online)
{
OperationSetPresence opsetPresence
- = parentProvider.getOperationSet(OperationSetPresence.class);
-
- if (opsetPresence != null)
- {
- String jid = StringUtils.parseBareAddress(user);
- Contact contact = opsetPresence.findContactByID(jid);
-
- // If the contact isn't null and is online we try to discover the
- // new set of operation sets and to notify interested parties.
- // Otherwise we ignore the event.
- if (contact != null)
+ = parentProvider.getOperationSet(OperationSetPresence.class);
+ if (opsetPresence != null) {
+ if(JabberActivator.getConfigurationService()
+ .getBoolean(
+ PROP_XMPP_USE_ALL_RESOURCES_FOR_CAPABILITIES,
+ USE_ALL_RESOURCES_FOR_CAPABILITIES_DEFAULT)
+ && !fullJids.isEmpty())
{
- if(online)
+ String bareJid = StringUtils.parseBareAddress(user);
+ Contact contact = opsetPresence.findContactByID(bareJid);
+ if (contact != null)
{
- // when going online we have received a presence
- // and make sure we discover this particular jid
- // for getSupportedOperationSets
fireContactCapabilitiesEvent(
contact,
- ContactCapabilitiesEvent.SUPPORTED_OPERATION_SETS_CHANGED,
- getSupportedOperationSets(user,
- online));
+ ContactCapabilitiesEvent.
+ SUPPORTED_OPERATION_SETS_CHANGED,
+ getLargestSupportedOperationSet(fullJids));
}
- else
+ }
+ else
+ {
+ String jid = StringUtils.parseBareAddress(user);
+ Contact contact = opsetPresence.findContactByID(jid);
+
+ // If the contact isn't null and is online we try to discover
+ // the new set of operation sets and to notify interested
+ // parties. Otherwise we ignore the event.
+ if (contact != null)
{
- // when offline, we use the contact, and selecting
- // the most connected jid
- // for getSupportedOperationSets
- fireContactCapabilitiesEvent(
- contact,
- ContactCapabilitiesEvent.SUPPORTED_OPERATION_SETS_CHANGED,
- getSupportedOperationSets(contact));
+ if(online)
+ {
+ // when going online we have received a presence
+ // and make sure we discover this particular jid
+ // for getSupportedOperationSets
+ fireContactCapabilitiesEvent(
+ contact,
+ ContactCapabilitiesEvent.
+ SUPPORTED_OPERATION_SETS_CHANGED,
+ getSupportedOperationSets(user,
+ online));
+ }
+ else
+ {
+ // when offline, we use the contact, and selecting
+ // the most connected jid
+ // for getSupportedOperationSets
+ fireContactCapabilitiesEvent(
+ contact,
+ ContactCapabilitiesEvent.
+ SUPPORTED_OPERATION_SETS_CHANGED,
+ getSupportedOperationSets(contact));
+ }
}
}
}
@@ -460,7 +552,8 @@ public class OperationSetContactCapabilitiesJabberImpl
{
// If the user goes offline we ensure to remove the caps node.
if (capsManager != null
- && evt.getNewStatus().getStatus() < PresenceStatus.ONLINE_THRESHOLD)
+ && evt.getNewStatus().getStatus() < PresenceStatus.ONLINE_THRESHOLD
+ && !evt.isResourceChanged())
{
capsManager.removeContactCapsNode(evt.getSourceContact());
}
@@ -469,31 +562,59 @@ public class OperationSetContactCapabilitiesJabberImpl
/**
* Fires event that contact capabilities has changed.
* @param user the user to search for its contact.
+ * @param fullJids a list of all resources of the user (full JIDs)
*/
- public void fireContactCapabilitiesChanged(String user)
+ public void fireContactCapabilitiesChanged(String user,
+ ArrayList<String> fullJids)
{
- OperationSetPresence opsetPresence
+ if(!JabberActivator.getConfigurationService()
+ .getBoolean(
+ PROP_XMPP_USE_ALL_RESOURCES_FOR_CAPABILITIES,
+ USE_ALL_RESOURCES_FOR_CAPABILITIES_DEFAULT)
+ || fullJids.isEmpty())
+ {
+ OperationSetPresence opsetPresence
= parentProvider.getOperationSet(OperationSetPresence.class);
- if (opsetPresence != null)
+ if (opsetPresence != null)
+ {
+ String userID = StringUtils.parseBareAddress(user);
+ Contact contact = opsetPresence.findContactByID(userID);
+
+ // this called by received discovery info for particular jid
+ // so we use its online and opsets for this particular jid
+ boolean online = false;
+ Presence presence = parentProvider.getConnection().getRoster()
+ .getPresence(user);
+ if(presence != null)
+ online = presence.isAvailable();
+
+ if(contact != null)
+ {
+ fireContactCapabilitiesEvent(
+ contact,
+ ContactCapabilitiesEvent.
+ SUPPORTED_OPERATION_SETS_CHANGED,
+ getSupportedOperationSets(user, online));
+ }
+ }
+ }
+ else
{
- String userID = StringUtils.parseBareAddress(user);
- Contact contact = opsetPresence.findContactByID(userID);
-
- // this called by received discovery info for particular jid
- // so we use its online and opsets for this particular jid
- boolean online = false;
- Presence presence = parentProvider.getConnection().getRoster()
- .getPresence(user);
- if(presence != null)
- online = presence.isAvailable();
-
- if(contact != null)
+ OperationSetPresence opsetPresence
+ = parentProvider.getOperationSet(OperationSetPresence.class);
+ if (opsetPresence != null)
{
- fireContactCapabilitiesEvent(
- contact,
- ContactCapabilitiesEvent.SUPPORTED_OPERATION_SETS_CHANGED,
- getSupportedOperationSets(user, online));
+ String bareJid = StringUtils.parseBareAddress(user);
+ Contact contact = opsetPresence.findContactByID(bareJid);
+ if(contact != null)
+ {
+ fireContactCapabilitiesEvent(
+ contact,
+ ContactCapabilitiesEvent.
+ SUPPORTED_OPERATION_SETS_CHANGED,
+ getLargestSupportedOperationSet(fullJids));
+ }
}
}
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetJitsiMeetToolsJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetJitsiMeetToolsJabberImpl.java
index 0fb6979..7ea4453 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetJitsiMeetToolsJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetJitsiMeetToolsJabberImpl.java
@@ -72,6 +72,16 @@ public class OperationSetJitsiMeetToolsJabberImpl
* {@inheritDoc}
*/
@Override
+ public void removePresenceExtension(ChatRoom chatRoom,
+ PacketExtension extension)
+ {
+ ((ChatRoomJabberImpl)chatRoom).removePresenceExtension(extension);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public void setPresenceStatus(ChatRoom chatRoom, String statusMessage)
{
((ChatRoomJabberImpl)chatRoom).publishPresenceStatus(statusMessage);
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetMultiUserChatJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetMultiUserChatJabberImpl.java
index 80bbb4e..cf53906 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetMultiUserChatJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetMultiUserChatJabberImpl.java
@@ -471,10 +471,10 @@ public class OperationSetMultiUserChatJabberImpl
* Almost all <tt>MultiUserChat</tt> methods require an xmpp connection
* param so I added this method only for the sake of utility.
*
- * @return the XMPPConnection currently in use by the jabber provider or
+ * @return the XMPP connection currently in use by the jabber provider or
* null if jabber provider has yet to be initialized.
*/
- private XMPPConnection getXmppConnection()
+ private Connection getXmppConnection()
{
return (jabberProvider == null)
? null
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java
index 69c168c..c502824 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java
@@ -691,7 +691,7 @@ public class OperationSetPersistentPresenceJabberImpl
*/
assertConnected();
- XMPPConnection xmppConnection = parentProvider.getConnection();
+ Connection xmppConnection = parentProvider.getConnection();
if (xmppConnection == null)
{
@@ -1124,7 +1124,7 @@ public class OperationSetPersistentPresenceJabberImpl
ssContactList.cleanup();
- XMPPConnection connection = parentProvider.getConnection();
+ Connection connection = parentProvider.getConnection();
if(connection != null)
{
connection.removePacketListener(subscribtionPacketListener);
@@ -1528,6 +1528,19 @@ public class OperationSetPersistentPresenceJabberImpl
o2, parentProvider).getStatus()
- jabberStatusToPresenceStatus(
o1, parentProvider).getStatus();
+ // We have run out of "logical" ways to order
+ // the presences inside the TreeSet. We have
+ // make sure we are consinstent with equals.
+ // We do this by comparing the unique resource
+ // names. If this evaluates to 0 again, then we
+ // can safely assume this presence object
+ // represents the same resource and by that the
+ // same client.
+ if(res == 0)
+ {
+ res = o1.getFrom().compareTo(
+ o2.getFrom());
+ }
}
return res;
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java
index e81b43a..e5b83e7 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,585 +15,585 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.protocol.jabber;
-
-import java.util.*;
-
-import net.java.sip.communicator.impl.protocol.jabber.extensions.coin.*;
-import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.service.protocol.media.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.util.xml.*;
-import org.jivesoftware.smack.*;
-import org.jivesoftware.smack.filter.*;
-import org.jivesoftware.smack.packet.*;
-import org.jivesoftware.smack.packet.IQ.Type;
-import org.jivesoftware.smack.util.*;
-import org.jivesoftware.smackx.packet.*;
-
-/**
- * Implements <tt>OperationSetTelephonyConferencing</tt> for Jabber.
- *
- * @author Lyubomir Marinov
- * @author Sebastien Vincent
- * @author Boris Grozev
- * @author Pawel Domas
- */
-public class OperationSetTelephonyConferencingJabberImpl
- extends AbstractOperationSetTelephonyConferencing<
- ProtocolProviderServiceJabberImpl,
- OperationSetBasicTelephonyJabberImpl,
- CallJabberImpl,
- CallPeerJabberImpl,
- String>
- implements RegistrationStateChangeListener,
- PacketListener,
- PacketFilter
-
-{
- /**
- * The <tt>Logger</tt> used by the
- * <tt>OperationSetTelephonyConferencingJabberImpl</tt> class and its
- * instances for logging output.
- */
- private static final Logger logger
- = Logger.getLogger(OperationSetTelephonyConferencingJabberImpl.class);
-
- /**
- * The minimum interval in milliseconds between COINs sent to a single
- * <tt>CallPeer</tt>.
- */
- private static final int COIN_MIN_INTERVAL = 200;
-
- /**
- * Property used to disable COIN notifications.
- */
- public static final String DISABLE_COIN_PROP_NAME
- = "net.java.sip.communicator.impl.protocol.jabber.DISABLE_COIN";
-
- /**
- * Synchronization object.
- */
- private final Object lock = new Object();
-
- /**
- * Field indicates whether COIN notification are disabled or not.
- */
- private boolean isCoinDisabled = false;
-
- /**
- * Initializes a new <tt>OperationSetTelephonyConferencingJabberImpl</tt>
- * instance which is to provide telephony conferencing services for the
- * specified Jabber <tt>ProtocolProviderService</tt> implementation.
- *
- * @param parentProvider the Jabber <tt>ProtocolProviderService</tt>
- * implementation which has requested the creation of the new instance and
- * for which the new instance is to provide telephony conferencing services
- */
- public OperationSetTelephonyConferencingJabberImpl(
- ProtocolProviderServiceJabberImpl parentProvider)
- {
- super(parentProvider);
-
- this.isCoinDisabled
- = JabberActivator.getConfigurationService()
- .getBoolean(DISABLE_COIN_PROP_NAME, false);
- }
-
- /**
- * Notifies all <tt>CallPeer</tt>s associated with a specific <tt>Call</tt>
- * about changes in the telephony conference-related information. In
- * contrast, {@link #notifyAll()} notifies all <tt>CallPeer</tt>s associated
- * with the telephony conference in which a specific <tt>Call</tt> is
- * participating.
- *
- * @param call the <tt>Call</tt> whose <tt>CallPeer</tt>s are to be notified
- * about changes in the telephony conference-related information
- */
- @Override
- protected void notifyCallPeers(Call call)
- {
- if (!isCoinDisabled && call.isConferenceFocus())
- {
- synchronized (lock)
- {
- // send conference-info to all CallPeers of the specified call.
- for (Iterator<? extends CallPeer> i = call.getCallPeers();
- i.hasNext();)
- {
- notify(i.next());
- }
- }
- }
- }
-
- /**
- * Notifies a specific <tt>CallPeer</tt> about changes in the telephony
- * conference-related information.
- *
- * @param callPeer the <tt>CallPeer</tt> to notify.
- */
- private void notify(CallPeer callPeer)
- {
- if(!(callPeer instanceof CallPeerJabberImpl))
- return;
-
- //Don't send COINs to peers with might not be ready to accept COINs yet
- CallPeerState peerState = callPeer.getState();
- if (peerState == CallPeerState.CONNECTING
- || peerState == CallPeerState.UNKNOWN
- || peerState == CallPeerState.INITIATING_CALL
- || peerState == CallPeerState.DISCONNECTED
- || peerState == CallPeerState.FAILED)
- return;
-
- final CallPeerJabberImpl callPeerJabber = (CallPeerJabberImpl)callPeer;
-
- final long timeSinceLastCoin = System.currentTimeMillis()
- - callPeerJabber.getLastConferenceInfoSentTimestamp();
- if (timeSinceLastCoin < COIN_MIN_INTERVAL)
- {
- if (callPeerJabber.isConfInfoScheduled())
- return;
-
- logger.info("Scheduling to send a COIN to " + callPeerJabber);
- callPeerJabber.setConfInfoScheduled(true);
- new Thread(new Runnable(){
- @Override
- public void run()
- {
- try
- {
- Thread.sleep(1 + COIN_MIN_INTERVAL - timeSinceLastCoin);
- }
- catch (InterruptedException ie) {}
-
- OperationSetTelephonyConferencingJabberImpl.this
- .notify(callPeerJabber);
- }
- }).start();
-
- return;
- }
-
- // check that callPeer supports COIN before sending him a
- // conference-info
- String to = getBasicTelephony().getFullCalleeURI(callPeer.getAddress());
-
- // XXX if this generates actual disco#info requests we might want to
- // cache it.
- try
- {
- DiscoverInfo discoverInfo
- = parentProvider.getDiscoveryManager().discoverInfo(to);
-
- if (!discoverInfo.containsFeature(
- ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_COIN))
- {
- logger.info(callPeer.getAddress() + " does not support COIN");
- callPeerJabber.setConfInfoScheduled(false);
- return;
- }
- }
- catch (XMPPException xmppe)
- {
- logger.warn("Failed to retrieve DiscoverInfo for " + to, xmppe);
- }
-
- ConferenceInfoDocument currentConfInfo
- = getCurrentConferenceInfo(callPeerJabber);
- ConferenceInfoDocument lastSentConfInfo
- = callPeerJabber.getLastConferenceInfoSent();
-
- ConferenceInfoDocument diff;
-
- if (lastSentConfInfo == null)
- diff = currentConfInfo;
- else
- diff = getConferenceInfoDiff(lastSentConfInfo, currentConfInfo);
-
- if (diff != null)
- {
- int newVersion
- = lastSentConfInfo == null
- ? 1
- : lastSentConfInfo.getVersion() + 1;
- diff.setVersion(newVersion);
-
- IQ iq = getConferenceInfo(callPeerJabber, diff);
-
- if (iq != null)
- {
- parentProvider.getConnection().sendPacket(iq);
-
- // We save currentConfInfo, because it is of state "full", while
- // diff could be a partial
- currentConfInfo.setVersion(newVersion);
- callPeerJabber.setLastConferenceInfoSent(currentConfInfo);
- callPeerJabber.setLastConferenceInfoSentTimestamp(
- System.currentTimeMillis());
- }
- }
- callPeerJabber.setConfInfoScheduled(false);
- }
-
- /**
- * Generates the conference-info IQ to be sent to a specific
- * <tt>CallPeer</tt> in order to notify it of the current state of the
- * conference managed by the local peer.
- *
- * @param callPeer the <tt>CallPeer</tt> to generate conference-info XML for
- * @param confInfo the <tt>ConferenceInformationDocument</tt> which is to be
- * included in the IQ
- * @return the conference-info IQ to be sent to the specified
- * <tt>callPeer</tt> in order to notify it of the current state of the
- * conference managed by the local peer
- */
- private IQ getConferenceInfo(CallPeerJabberImpl callPeer,
- final ConferenceInfoDocument confInfo)
- {
- String callPeerSID = callPeer.getSID();
-
- if (callPeerSID == null)
- return null;
-
- IQ iq = new IQ(){
- @Override
- public String getChildElementXML()
- {
- return confInfo.toXml();
- }
- };
-
- CallJabberImpl call = callPeer.getCall();
-
- iq.setFrom(call.getProtocolProvider().getOurJID());
- iq.setTo(callPeer.getAddress());
- iq.setType(Type.SET);
-
- return iq;
- }
-
- /**
- * Implementation of method <tt>registrationStateChange</tt> from
- * interface RegistrationStateChangeListener for setting up (or down)
- * our <tt>JingleManager</tt> when an <tt>XMPPConnection</tt> is available
- *
- * @param evt the event received
- */
- @Override
- public void registrationStateChanged(RegistrationStateChangeEvent evt)
- {
- super.registrationStateChanged(evt);
-
- RegistrationState registrationState = evt.getNewState();
-
- if (RegistrationState.REGISTERED.equals(registrationState))
- {
- if(logger.isDebugEnabled())
- logger.debug("Subscribes to Coin packets");
- subscribeForCoinPackets();
- }
- else if (RegistrationState.UNREGISTERED.equals(registrationState))
- {
- if(logger.isDebugEnabled())
- logger.debug("Unsubscribes to Coin packets");
- unsubscribeForCoinPackets();
- }
- }
-
- /**
- * Creates a new outgoing <tt>Call</tt> into which conference callees are to
- * be invited by this <tt>OperationSetTelephonyConferencing</tt>.
- *
- * @return a new outgoing <tt>Call</tt> into which conference callees are to
- * be invited by this <tt>OperationSetTelephonyConferencing</tt>
- * @throws OperationFailedException if anything goes wrong
- */
- @Override
- protected CallJabberImpl createOutgoingCall()
- throws OperationFailedException
- {
- return new CallJabberImpl(getBasicTelephony());
- }
-
- /**
- * {@inheritDoc}
- *
- * Implements the protocol-dependent part of the logic of inviting a callee
- * to a <tt>Call</tt>. The protocol-independent part of that logic is
- * implemented by
- * {@link AbstractOperationSetTelephonyConferencing#inviteCalleeToCall(String,Call)}.
- */
- @Override
- protected CallPeer doInviteCalleeToCall(
- String calleeAddress,
- CallJabberImpl call)
- throws OperationFailedException
- {
- return
- getBasicTelephony().createOutgoingCall(
- call,
- calleeAddress,
- Arrays.asList(
- new PacketExtension[]
- {
- new CoinPacketExtension(true)
- }));
- }
-
- /**
- * Parses a <tt>String</tt> value which represents a callee address
- * specified by the user into an object which is to actually represent the
- * callee during the invitation to a conference <tt>Call</tt>.
- *
- * @param calleeAddressString a <tt>String</tt> value which represents a
- * callee address to be parsed into an object which is to actually represent
- * the callee during the invitation to a conference <tt>Call</tt>
- * @return an object which is to actually represent the specified
- * <tt>calleeAddressString</tt> during the invitation to a conference
- * <tt>Call</tt>
- * @throws OperationFailedException if parsing the specified
- * <tt>calleeAddressString</tt> fails
- */
- @Override
- protected String parseAddressString(String calleeAddressString)
- throws OperationFailedException
- {
- return getBasicTelephony().getFullCalleeURI(calleeAddressString);
- }
-
- /**
- * Subscribes us to notifications about incoming Coin packets.
- */
- private void subscribeForCoinPackets()
- {
- parentProvider.getConnection().addPacketListener(this, this);
- }
-
- /**
- * Unsubscribes us from notifications about incoming Coin packets.
- */
- private void unsubscribeForCoinPackets()
- {
- XMPPConnection connection = parentProvider.getConnection();
-
- if (connection != null)
- connection.removePacketListener(this);
- }
-
- /**
- * Tests whether or not the specified packet should be handled by this
- * operation set. This method is called by smack prior to packet delivery
- * and it would only accept <tt>CoinIQ</tt>s.
- *
- * @param packet the packet to test.
- * @return true if and only if <tt>packet</tt> passes the filter.
- */
- public boolean accept(Packet packet)
- {
- return (packet instanceof CoinIQ);
- }
-
- /**
- * Handles incoming jingle packets and passes them to the corresponding
- * method based on their action.
- *
- * @param packet the packet to process.
- */
- public void processPacket(Packet packet)
- {
- CoinIQ coinIQ = (CoinIQ) packet;
- String errorMessage = null;
-
- //first ack all "set" requests.
- IQ.Type type = coinIQ.getType();
- if (type == IQ.Type.SET)
- {
- IQ ack = IQ.createResultIQ(coinIQ);
-
- parentProvider.getConnection().sendPacket(ack);
- }
- else if(type == IQ.Type.ERROR)
- {
- XMPPError error = coinIQ.getError();
- if(error != null)
- {
- String msg = error.getMessage();
- errorMessage = ((msg != null)? (msg + " ") : "")
- + "Error code: " + error.getCode();
- }
-
- logger.error("Received error in COIN packet. "+errorMessage);
- }
-
- String sid = coinIQ.getSID();
-
- if (sid != null)
- {
- CallPeerJabberImpl callPeer
- = getBasicTelephony().getActiveCallsRepository().findCallPeer(
- sid);
-
-
- if (callPeer != null)
- {
- if(type == IQ.Type.ERROR)
- {
- callPeer.fireConferenceMemberErrorEvent(errorMessage);
- return;
- }
-
- if (logger.isDebugEnabled())
- logger.debug("Processing COIN from " + coinIQ.getFrom()
- + " (version=" + coinIQ.getVersion() + ")");
-
- handleCoin(callPeer, coinIQ);
- }
- }
- }
-
- /**
- * Handles a specific <tt>CoinIQ</tt> sent from a specific
- * <tt>CallPeer</tt>.
- *
- * @param callPeer the <tt>CallPeer</tt> from which the specified
- * <tt>CoinIQ</tt> was sent
- * @param coinIQ the <tt>CoinIQ</tt> which was sent from the specified
- * <tt>callPeer</tt>
- */
- private void handleCoin(CallPeerJabberImpl callPeer, CoinIQ coinIQ)
- {
- try
- {
- setConferenceInfoXML(callPeer, coinIQ.getChildElementXML());
- }
- catch (XMLException e)
- {
- logger.error("Could not handle received COIN from " + callPeer
- + ": " + coinIQ);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * For COINs (XEP-0298), we use the attributes of the
- * <tt>conference-info</tt> element to piggyback a Jingle SID. This is
- * temporary and should be removed once we choose a better way to pass the
- * SID.
- */
- @Override
- protected ConferenceInfoDocument getCurrentConferenceInfo(
- MediaAwareCallPeer<?,?,?> callPeer)
- {
- ConferenceInfoDocument confInfo
- = super.getCurrentConferenceInfo(callPeer);
-
- if (callPeer instanceof CallPeerJabberImpl
- && confInfo != null)
- {
- confInfo.setSid(((CallPeerJabberImpl)callPeer).getSID());
- }
- return confInfo;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected String getLocalEntity(CallPeer callPeer)
- {
- JingleIQ sessionIQ = ((CallPeerJabberImpl)callPeer).getSessionIQ();
- String from = sessionIQ.getFrom();
- String chatRoomName = StringUtils.parseBareAddress(from);
- OperationSetMultiUserChatJabberImpl opSetMUC
- = (OperationSetMultiUserChatJabberImpl)
- parentProvider.getOperationSet(OperationSetMultiUserChat.class);
- ChatRoom room = null;
- if(opSetMUC != null)
- room = opSetMUC.getChatRoom(chatRoomName);
-
- if(room != null)
- return "xmpp:" + chatRoomName + "/" + room.getUserNickname();
-
- return "xmpp:" + parentProvider.getOurJID();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected String getLocalDisplayName()
- {
- return null;
- }
-
- /**
- * {@inheritDoc}
- *
- * The URI of the returned <tt>ConferenceDescription</tt> is the occupant
- * JID with which we have joined the room.
- *
- * If a Videobridge is available for our <tt>ProtocolProviderService</tt>
- * we use it. TODO: this should be relaxed when we refactor the Videobridge
- * implementation, so that any Videobridge (on any protocol provider) can
- * be used.
- */
- @Override
- public ConferenceDescription setupConference(final ChatRoom chatRoom)
- {
- OperationSetVideoBridge videoBridge
- = parentProvider.getOperationSet(OperationSetVideoBridge.class);
- boolean isVideobridge = (videoBridge != null) && videoBridge.isActive();
-
- CallJabberImpl call = new CallJabberImpl(getBasicTelephony());
- call.setAutoAnswer(true);
-
- String uri = "xmpp:" + chatRoom.getIdentifier() +
- "/" + chatRoom.getUserNickname();
-
- ConferenceDescription cd
- = new ConferenceDescription(uri, call.getCallID());
-
- call.addCallChangeListener(new CallChangeListener()
- {
- @Override
- public void callStateChanged(CallChangeEvent ev)
- {
- if(CallState.CALL_ENDED.equals(ev.getNewValue()))
- chatRoom.publishConference(null, null);
- }
-
- @Override
- public void callPeerRemoved(CallPeerEvent ev)
- {
- }
-
- @Override
- public void callPeerAdded(CallPeerEvent ev)
- {
- }
- });
- if (isVideobridge)
- {
- call.setConference(new MediaAwareCallConference(true));
-
- //For Jitsi Videobridge we set the transports to RAW-UDP, otherwise
- //we leave them empty (meaning both RAW-UDP and ICE could be used)
- cd.addTransport(
- ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_RAW_UDP_0);
- }
-
- if (logger.isInfoEnabled())
- {
- logger.info("Setup a conference with uri=" + uri + " and callid=" +
- call.getCallID() + ". Videobridge in use: " + isVideobridge);
- }
-
- return cd;
- }
-}
+package net.java.sip.communicator.impl.protocol.jabber;
+
+import java.util.*;
+
+import net.java.sip.communicator.impl.protocol.jabber.extensions.coin.*;
+import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.service.protocol.media.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.util.xml.*;
+import org.jivesoftware.smack.*;
+import org.jivesoftware.smack.filter.*;
+import org.jivesoftware.smack.packet.*;
+import org.jivesoftware.smack.packet.IQ.Type;
+import org.jivesoftware.smack.util.*;
+import org.jivesoftware.smackx.packet.*;
+
+/**
+ * Implements <tt>OperationSetTelephonyConferencing</tt> for Jabber.
+ *
+ * @author Lyubomir Marinov
+ * @author Sebastien Vincent
+ * @author Boris Grozev
+ * @author Pawel Domas
+ */
+public class OperationSetTelephonyConferencingJabberImpl
+ extends AbstractOperationSetTelephonyConferencing<
+ ProtocolProviderServiceJabberImpl,
+ OperationSetBasicTelephonyJabberImpl,
+ CallJabberImpl,
+ CallPeerJabberImpl,
+ String>
+ implements RegistrationStateChangeListener,
+ PacketListener,
+ PacketFilter
+
+{
+ /**
+ * The <tt>Logger</tt> used by the
+ * <tt>OperationSetTelephonyConferencingJabberImpl</tt> class and its
+ * instances for logging output.
+ */
+ private static final Logger logger
+ = Logger.getLogger(OperationSetTelephonyConferencingJabberImpl.class);
+
+ /**
+ * The minimum interval in milliseconds between COINs sent to a single
+ * <tt>CallPeer</tt>.
+ */
+ private static final int COIN_MIN_INTERVAL = 200;
+
+ /**
+ * Property used to disable COIN notifications.
+ */
+ public static final String DISABLE_COIN_PROP_NAME
+ = "net.java.sip.communicator.impl.protocol.jabber.DISABLE_COIN";
+
+ /**
+ * Synchronization object.
+ */
+ private final Object lock = new Object();
+
+ /**
+ * Field indicates whether COIN notification are disabled or not.
+ */
+ private boolean isCoinDisabled = false;
+
+ /**
+ * Initializes a new <tt>OperationSetTelephonyConferencingJabberImpl</tt>
+ * instance which is to provide telephony conferencing services for the
+ * specified Jabber <tt>ProtocolProviderService</tt> implementation.
+ *
+ * @param parentProvider the Jabber <tt>ProtocolProviderService</tt>
+ * implementation which has requested the creation of the new instance and
+ * for which the new instance is to provide telephony conferencing services
+ */
+ public OperationSetTelephonyConferencingJabberImpl(
+ ProtocolProviderServiceJabberImpl parentProvider)
+ {
+ super(parentProvider);
+
+ this.isCoinDisabled
+ = JabberActivator.getConfigurationService()
+ .getBoolean(DISABLE_COIN_PROP_NAME, false);
+ }
+
+ /**
+ * Notifies all <tt>CallPeer</tt>s associated with a specific <tt>Call</tt>
+ * about changes in the telephony conference-related information. In
+ * contrast, {@link #notifyAll()} notifies all <tt>CallPeer</tt>s associated
+ * with the telephony conference in which a specific <tt>Call</tt> is
+ * participating.
+ *
+ * @param call the <tt>Call</tt> whose <tt>CallPeer</tt>s are to be notified
+ * about changes in the telephony conference-related information
+ */
+ @Override
+ protected void notifyCallPeers(Call call)
+ {
+ if (!isCoinDisabled && call.isConferenceFocus())
+ {
+ synchronized (lock)
+ {
+ // send conference-info to all CallPeers of the specified call.
+ for (Iterator<? extends CallPeer> i = call.getCallPeers();
+ i.hasNext();)
+ {
+ notify(i.next());
+ }
+ }
+ }
+ }
+
+ /**
+ * Notifies a specific <tt>CallPeer</tt> about changes in the telephony
+ * conference-related information.
+ *
+ * @param callPeer the <tt>CallPeer</tt> to notify.
+ */
+ private void notify(CallPeer callPeer)
+ {
+ if(!(callPeer instanceof CallPeerJabberImpl))
+ return;
+
+ //Don't send COINs to peers with might not be ready to accept COINs yet
+ CallPeerState peerState = callPeer.getState();
+ if (peerState == CallPeerState.CONNECTING
+ || peerState == CallPeerState.UNKNOWN
+ || peerState == CallPeerState.INITIATING_CALL
+ || peerState == CallPeerState.DISCONNECTED
+ || peerState == CallPeerState.FAILED)
+ return;
+
+ final CallPeerJabberImpl callPeerJabber = (CallPeerJabberImpl)callPeer;
+
+ final long timeSinceLastCoin = System.currentTimeMillis()
+ - callPeerJabber.getLastConferenceInfoSentTimestamp();
+ if (timeSinceLastCoin < COIN_MIN_INTERVAL)
+ {
+ if (callPeerJabber.isConfInfoScheduled())
+ return;
+
+ logger.info("Scheduling to send a COIN to " + callPeerJabber);
+ callPeerJabber.setConfInfoScheduled(true);
+ new Thread(new Runnable(){
+ @Override
+ public void run()
+ {
+ try
+ {
+ Thread.sleep(1 + COIN_MIN_INTERVAL - timeSinceLastCoin);
+ }
+ catch (InterruptedException ie) {}
+
+ OperationSetTelephonyConferencingJabberImpl.this
+ .notify(callPeerJabber);
+ }
+ }).start();
+
+ return;
+ }
+
+ // check that callPeer supports COIN before sending him a
+ // conference-info
+ String to = getBasicTelephony().getFullCalleeURI(callPeer.getAddress());
+
+ // XXX if this generates actual disco#info requests we might want to
+ // cache it.
+ try
+ {
+ DiscoverInfo discoverInfo
+ = parentProvider.getDiscoveryManager().discoverInfo(to);
+
+ if (!discoverInfo.containsFeature(
+ ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_COIN))
+ {
+ logger.info(callPeer.getAddress() + " does not support COIN");
+ callPeerJabber.setConfInfoScheduled(false);
+ return;
+ }
+ }
+ catch (XMPPException xmppe)
+ {
+ logger.warn("Failed to retrieve DiscoverInfo for " + to, xmppe);
+ }
+
+ ConferenceInfoDocument currentConfInfo
+ = getCurrentConferenceInfo(callPeerJabber);
+ ConferenceInfoDocument lastSentConfInfo
+ = callPeerJabber.getLastConferenceInfoSent();
+
+ ConferenceInfoDocument diff;
+
+ if (lastSentConfInfo == null)
+ diff = currentConfInfo;
+ else
+ diff = getConferenceInfoDiff(lastSentConfInfo, currentConfInfo);
+
+ if (diff != null)
+ {
+ int newVersion
+ = lastSentConfInfo == null
+ ? 1
+ : lastSentConfInfo.getVersion() + 1;
+ diff.setVersion(newVersion);
+
+ IQ iq = getConferenceInfo(callPeerJabber, diff);
+
+ if (iq != null)
+ {
+ parentProvider.getConnection().sendPacket(iq);
+
+ // We save currentConfInfo, because it is of state "full", while
+ // diff could be a partial
+ currentConfInfo.setVersion(newVersion);
+ callPeerJabber.setLastConferenceInfoSent(currentConfInfo);
+ callPeerJabber.setLastConferenceInfoSentTimestamp(
+ System.currentTimeMillis());
+ }
+ }
+ callPeerJabber.setConfInfoScheduled(false);
+ }
+
+ /**
+ * Generates the conference-info IQ to be sent to a specific
+ * <tt>CallPeer</tt> in order to notify it of the current state of the
+ * conference managed by the local peer.
+ *
+ * @param callPeer the <tt>CallPeer</tt> to generate conference-info XML for
+ * @param confInfo the <tt>ConferenceInformationDocument</tt> which is to be
+ * included in the IQ
+ * @return the conference-info IQ to be sent to the specified
+ * <tt>callPeer</tt> in order to notify it of the current state of the
+ * conference managed by the local peer
+ */
+ private IQ getConferenceInfo(CallPeerJabberImpl callPeer,
+ final ConferenceInfoDocument confInfo)
+ {
+ String callPeerSID = callPeer.getSID();
+
+ if (callPeerSID == null)
+ return null;
+
+ IQ iq = new IQ(){
+ @Override
+ public String getChildElementXML()
+ {
+ return confInfo.toXml();
+ }
+ };
+
+ CallJabberImpl call = callPeer.getCall();
+
+ iq.setFrom(call.getProtocolProvider().getOurJID());
+ iq.setTo(callPeer.getAddress());
+ iq.setType(Type.SET);
+
+ return iq;
+ }
+
+ /**
+ * Implementation of method <tt>registrationStateChange</tt> from
+ * interface RegistrationStateChangeListener for setting up (or down)
+ * our <tt>JingleManager</tt> when an <tt>XMPPConnection</tt> is available
+ *
+ * @param evt the event received
+ */
+ @Override
+ public void registrationStateChanged(RegistrationStateChangeEvent evt)
+ {
+ super.registrationStateChanged(evt);
+
+ RegistrationState registrationState = evt.getNewState();
+
+ if (RegistrationState.REGISTERED.equals(registrationState))
+ {
+ if(logger.isDebugEnabled())
+ logger.debug("Subscribes to Coin packets");
+ subscribeForCoinPackets();
+ }
+ else if (RegistrationState.UNREGISTERED.equals(registrationState))
+ {
+ if(logger.isDebugEnabled())
+ logger.debug("Unsubscribes to Coin packets");
+ unsubscribeForCoinPackets();
+ }
+ }
+
+ /**
+ * Creates a new outgoing <tt>Call</tt> into which conference callees are to
+ * be invited by this <tt>OperationSetTelephonyConferencing</tt>.
+ *
+ * @return a new outgoing <tt>Call</tt> into which conference callees are to
+ * be invited by this <tt>OperationSetTelephonyConferencing</tt>
+ * @throws OperationFailedException if anything goes wrong
+ */
+ @Override
+ protected CallJabberImpl createOutgoingCall()
+ throws OperationFailedException
+ {
+ return new CallJabberImpl(getBasicTelephony());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Implements the protocol-dependent part of the logic of inviting a callee
+ * to a <tt>Call</tt>. The protocol-independent part of that logic is
+ * implemented by
+ * {@link AbstractOperationSetTelephonyConferencing#inviteCalleeToCall(String,Call)}.
+ */
+ @Override
+ protected CallPeer doInviteCalleeToCall(
+ String calleeAddress,
+ CallJabberImpl call)
+ throws OperationFailedException
+ {
+ return
+ getBasicTelephony().createOutgoingCall(
+ call,
+ calleeAddress,
+ Arrays.asList(
+ new PacketExtension[]
+ {
+ new CoinPacketExtension(true)
+ }));
+ }
+
+ /**
+ * Parses a <tt>String</tt> value which represents a callee address
+ * specified by the user into an object which is to actually represent the
+ * callee during the invitation to a conference <tt>Call</tt>.
+ *
+ * @param calleeAddressString a <tt>String</tt> value which represents a
+ * callee address to be parsed into an object which is to actually represent
+ * the callee during the invitation to a conference <tt>Call</tt>
+ * @return an object which is to actually represent the specified
+ * <tt>calleeAddressString</tt> during the invitation to a conference
+ * <tt>Call</tt>
+ * @throws OperationFailedException if parsing the specified
+ * <tt>calleeAddressString</tt> fails
+ */
+ @Override
+ protected String parseAddressString(String calleeAddressString)
+ throws OperationFailedException
+ {
+ return getBasicTelephony().getFullCalleeURI(calleeAddressString);
+ }
+
+ /**
+ * Subscribes us to notifications about incoming Coin packets.
+ */
+ private void subscribeForCoinPackets()
+ {
+ parentProvider.getConnection().addPacketListener(this, this);
+ }
+
+ /**
+ * Unsubscribes us from notifications about incoming Coin packets.
+ */
+ private void unsubscribeForCoinPackets()
+ {
+ Connection connection = parentProvider.getConnection();
+
+ if (connection != null)
+ connection.removePacketListener(this);
+ }
+
+ /**
+ * Tests whether or not the specified packet should be handled by this
+ * operation set. This method is called by smack prior to packet delivery
+ * and it would only accept <tt>CoinIQ</tt>s.
+ *
+ * @param packet the packet to test.
+ * @return true if and only if <tt>packet</tt> passes the filter.
+ */
+ public boolean accept(Packet packet)
+ {
+ return (packet instanceof CoinIQ);
+ }
+
+ /**
+ * Handles incoming jingle packets and passes them to the corresponding
+ * method based on their action.
+ *
+ * @param packet the packet to process.
+ */
+ public void processPacket(Packet packet)
+ {
+ CoinIQ coinIQ = (CoinIQ) packet;
+ String errorMessage = null;
+
+ //first ack all "set" requests.
+ IQ.Type type = coinIQ.getType();
+ if (type == IQ.Type.SET)
+ {
+ IQ ack = IQ.createResultIQ(coinIQ);
+
+ parentProvider.getConnection().sendPacket(ack);
+ }
+ else if(type == IQ.Type.ERROR)
+ {
+ XMPPError error = coinIQ.getError();
+ if(error != null)
+ {
+ String msg = error.getMessage();
+ errorMessage = ((msg != null)? (msg + " ") : "")
+ + "Error code: " + error.getCode();
+ }
+
+ logger.error("Received error in COIN packet. "+errorMessage);
+ }
+
+ String sid = coinIQ.getSID();
+
+ if (sid != null)
+ {
+ CallPeerJabberImpl callPeer
+ = getBasicTelephony().getActiveCallsRepository().findCallPeer(
+ sid);
+
+
+ if (callPeer != null)
+ {
+ if(type == IQ.Type.ERROR)
+ {
+ callPeer.fireConferenceMemberErrorEvent(errorMessage);
+ return;
+ }
+
+ if (logger.isDebugEnabled())
+ logger.debug("Processing COIN from " + coinIQ.getFrom()
+ + " (version=" + coinIQ.getVersion() + ")");
+
+ handleCoin(callPeer, coinIQ);
+ }
+ }
+ }
+
+ /**
+ * Handles a specific <tt>CoinIQ</tt> sent from a specific
+ * <tt>CallPeer</tt>.
+ *
+ * @param callPeer the <tt>CallPeer</tt> from which the specified
+ * <tt>CoinIQ</tt> was sent
+ * @param coinIQ the <tt>CoinIQ</tt> which was sent from the specified
+ * <tt>callPeer</tt>
+ */
+ private void handleCoin(CallPeerJabberImpl callPeer, CoinIQ coinIQ)
+ {
+ try
+ {
+ setConferenceInfoXML(callPeer, coinIQ.getChildElementXML());
+ }
+ catch (XMLException e)
+ {
+ logger.error("Could not handle received COIN from " + callPeer
+ + ": " + coinIQ);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For COINs (XEP-0298), we use the attributes of the
+ * <tt>conference-info</tt> element to piggyback a Jingle SID. This is
+ * temporary and should be removed once we choose a better way to pass the
+ * SID.
+ */
+ @Override
+ protected ConferenceInfoDocument getCurrentConferenceInfo(
+ MediaAwareCallPeer<?,?,?> callPeer)
+ {
+ ConferenceInfoDocument confInfo
+ = super.getCurrentConferenceInfo(callPeer);
+
+ if (callPeer instanceof CallPeerJabberImpl
+ && confInfo != null)
+ {
+ confInfo.setSid(((CallPeerJabberImpl)callPeer).getSID());
+ }
+ return confInfo;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getLocalEntity(CallPeer callPeer)
+ {
+ JingleIQ sessionIQ = ((CallPeerJabberImpl)callPeer).getSessionIQ();
+ String from = sessionIQ.getFrom();
+ String chatRoomName = StringUtils.parseBareAddress(from);
+ OperationSetMultiUserChatJabberImpl opSetMUC
+ = (OperationSetMultiUserChatJabberImpl)
+ parentProvider.getOperationSet(OperationSetMultiUserChat.class);
+ ChatRoom room = null;
+ if(opSetMUC != null)
+ room = opSetMUC.getChatRoom(chatRoomName);
+
+ if(room != null)
+ return "xmpp:" + chatRoomName + "/" + room.getUserNickname();
+
+ return "xmpp:" + parentProvider.getOurJID();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getLocalDisplayName()
+ {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * The URI of the returned <tt>ConferenceDescription</tt> is the occupant
+ * JID with which we have joined the room.
+ *
+ * If a Videobridge is available for our <tt>ProtocolProviderService</tt>
+ * we use it. TODO: this should be relaxed when we refactor the Videobridge
+ * implementation, so that any Videobridge (on any protocol provider) can
+ * be used.
+ */
+ @Override
+ public ConferenceDescription setupConference(final ChatRoom chatRoom)
+ {
+ OperationSetVideoBridge videoBridge
+ = parentProvider.getOperationSet(OperationSetVideoBridge.class);
+ boolean isVideobridge = (videoBridge != null) && videoBridge.isActive();
+
+ CallJabberImpl call = new CallJabberImpl(getBasicTelephony());
+ call.setAutoAnswer(true);
+
+ String uri = "xmpp:" + chatRoom.getIdentifier() +
+ "/" + chatRoom.getUserNickname();
+
+ ConferenceDescription cd
+ = new ConferenceDescription(uri, call.getCallID());
+
+ call.addCallChangeListener(new CallChangeListener()
+ {
+ @Override
+ public void callStateChanged(CallChangeEvent ev)
+ {
+ if(CallState.CALL_ENDED.equals(ev.getNewValue()))
+ chatRoom.publishConference(null, null);
+ }
+
+ @Override
+ public void callPeerRemoved(CallPeerEvent ev)
+ {
+ }
+
+ @Override
+ public void callPeerAdded(CallPeerEvent ev)
+ {
+ }
+ });
+ if (isVideobridge)
+ {
+ call.setConference(new MediaAwareCallConference(true));
+
+ //For Jitsi Videobridge we set the transports to RAW-UDP, otherwise
+ //we leave them empty (meaning both RAW-UDP and ICE could be used)
+ cd.addTransport(
+ ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_RAW_UDP_0);
+ }
+
+ if (logger.isInfoEnabled())
+ {
+ logger.info("Setup a conference with uri=" + uri + " and callid=" +
+ call.getCallID() + ". Videobridge in use: " + isVideobridge);
+ }
+
+ return cd;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetVideoBridgeImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetVideoBridgeImpl.java
index b7e13ea..5d3dd8b 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetVideoBridgeImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetVideoBridgeImpl.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,282 +15,282 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.protocol.jabber;
-
-import java.util.*;
-
-import net.java.sip.communicator.impl.protocol.jabber.extensions.colibri.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.service.protocol.media.*;
-import net.java.sip.communicator.util.*;
-
-import org.jivesoftware.smack.*;
-import org.jivesoftware.smack.filter.*;
-import org.jivesoftware.smack.packet.*;
-
-/**
- * Implements <tt>OperationSetVideoBridge</tt> for Jabber.
- *
- * @author Yana Stamcheva
- * @author Lyubomir Marinov
- */
-public class OperationSetVideoBridgeImpl
- implements OperationSetVideoBridge,
- PacketFilter,
- PacketListener,
- RegistrationStateChangeListener
-{
- /**
- * The <tt>Logger</tt> used by the <tt>OperationSetVideoBridgeImpl</tt>
- * class and its instances for logging output.
- */
- private static final Logger logger
- = Logger.getLogger(OperationSetVideoBridgeImpl.class);
-
- /**
- * The <tt>ProtocolProviderService</tt> implementation which initialized
- * this instance, owns it and is often referred to as its parent.
- */
- private final ProtocolProviderServiceJabberImpl protocolProvider;
-
- /**
- * Creates an instance of <tt>OperationSetVideoBridgeImpl</tt> by
- * specifying the parent <tt>ProtocolProviderService</tt> announcing this
- * operation set.
- *
- * @param protocolProvider the parent Jabber protocol provider
- */
- public OperationSetVideoBridgeImpl(
- ProtocolProviderServiceJabberImpl protocolProvider)
- {
- this.protocolProvider = protocolProvider;
- this.protocolProvider.addRegistrationStateChangeListener(this);
- }
-
- /**
- * Implements {@link PacketFilter}. Determines whether this instance is
- * interested in a specific {@link Packet}.
- * <tt>OperationSetVideoBridgeImpl</tt> returns <tt>true</tt> if the
- * specified <tt>packet</tt> is a {@link ColibriConferenceIQ}; otherwise,
- * <tt>false</tt>.
- *
- * @param packet the <tt>Packet</tt> to be determined whether this instance
- * is interested in it
- * @return <tt>true</tt> if the specified <tt>packet</tt> is a
- * <tt>ColibriConferenceIQ</tt>; otherwise, <tt>false</tt>
- */
- public boolean accept(Packet packet)
- {
- return (packet instanceof ColibriConferenceIQ);
- }
-
- /**
- * Creates a conference call with the specified callees as call peers via a
- * video bridge provided by the parent Jabber provider.
- *
- * @param callees the list of addresses that we should call
- * @return the newly created conference call containing all CallPeers
- * @throws OperationFailedException if establishing the conference call
- * fails
- * @throws OperationNotSupportedException if the provider does not have any
- * conferencing features.
- */
- public Call createConfCall(String[] callees)
- throws OperationFailedException,
- OperationNotSupportedException
- {
- return
- protocolProvider
- .getOperationSet(OperationSetTelephonyConferencing.class)
- .createConfCall(
- callees,
- new MediaAwareCallConference(true));
- }
-
- /**
- * Invites the callee represented by the specified uri to an already
- * existing call using a video bridge provided by the parent Jabber provider.
- * The difference between this method and createConfCall is that
- * inviteCalleeToCall allows a user to add new peers to an already
- * established conference.
- *
- * @param uri the callee to invite to an existing conf call.
- * @param call the call that we should invite the callee to.
- * @return the CallPeer object corresponding to the callee represented by
- * the specified uri.
- * @throws OperationFailedException if inviting the specified callee to the
- * specified call fails
- * @throws OperationNotSupportedException if allowing additional callees to
- * a pre-established call is not supported.
- */
- public CallPeer inviteCalleeToCall(String uri, Call call)
- throws OperationFailedException,
- OperationNotSupportedException
- {
- return
- protocolProvider
- .getOperationSet(OperationSetTelephonyConferencing.class)
- .inviteCalleeToCall(uri, call);
- }
-
- /**
- * Indicates if there's an active video bridge available at this moment. The
- * Jabber provider may announce support for video bridge, but it should not
- * be used for calling until it becomes actually active.
- *
- * @return <tt>true</tt> to indicate that there's currently an active
- * available video bridge, <tt>false</tt> - otherwise
- */
- public boolean isActive()
- {
- String jitsiVideobridge = protocolProvider.getJitsiVideobridge();
-
- return ((jitsiVideobridge != null) && (jitsiVideobridge.length() > 0));
- }
-
- /**
- * Notifies this instance that a specific <tt>ColibriConferenceIQ</tt> has
- * been received.
- *
- * @param conferenceIQ the <tt>ColibriConferenceIQ</tt> which has been
- * received
- */
- private void processColibriConferenceIQ(ColibriConferenceIQ conferenceIQ)
- {
- /*
- * The application is not a Jitsi Videobridge server, it is a client.
- * Consequently, the specified ColibriConferenceIQ is sent to it in
- * relation to the part of the application's functionality which makes
- * requests to a Jitsi Videobridge server i.e. CallJabberImpl.
- *
- * Additionally, the method processColibriConferenceIQ is presently tasked
- * with processing ColibriConferenceIQ requests only. They are SET IQs
- * sent by the Jitsi Videobridge server to notify the application about
- * updates in the states of (colibri) conferences organized by the
- * application.
- */
- if (IQ.Type.SET.equals(conferenceIQ.getType())
- && conferenceIQ.getID() != null)
- {
- OperationSetBasicTelephony<?> basicTelephony
- = protocolProvider.getOperationSet(
- OperationSetBasicTelephony.class);
-
- if (basicTelephony != null)
- {
- Iterator<? extends Call> i = basicTelephony.getActiveCalls();
-
- while (i.hasNext())
- {
- Call call = i.next();
-
- if (call instanceof CallJabberImpl)
- {
- CallJabberImpl callJabberImpl = (CallJabberImpl) call;
- MediaAwareCallConference conference
- = callJabberImpl.getConference();
-
- if ((conference != null)
- && conference.isJitsiVideobridge())
- {
- /*
- * TODO We may want to disallow rogue CallJabberImpl
- * instances which may throw an exception to prevent
- * the conferenceIQ from reaching the CallJabberImpl
- * instance which it was meant for.
- */
- if (callJabberImpl.processColibriConferenceIQ(
- conferenceIQ))
- break;
- }
- }
- }
- }
- }
- }
-
- /**
- * Implements {@link PacketListener}. Notifies this instance that a specific
- * {@link Packet} (which this instance has already expressed interest into
- * by returning <tt>true</tt> from {@link #accept(Packet)}) has been
- * received.
- *
- * @param packet the <tt>Packet</tt> which has been received and which this
- * instance is given a chance to process
- */
- public void processPacket(Packet packet)
- {
- /*
- * As we do elsewhere, acknowledge the receipt of the Packet first and
- * then go about our business with it.
- */
- IQ iq = (IQ) packet;
-
- if (iq.getType() == IQ.Type.SET)
- protocolProvider.getConnection().sendPacket(IQ.createResultIQ(iq));
-
- /*
- * Now that the acknowledging is out of the way, do go about our
- * business with the Packet.
- */
- ColibriConferenceIQ conferenceIQ = (ColibriConferenceIQ) iq;
- boolean interrupted = false;
-
- try
- {
- processColibriConferenceIQ(conferenceIQ);
- }
- catch (Throwable t)
- {
- logger.error(
- "An error occurred during the processing of a "
- + packet.getClass().getName() + " packet",
- t);
-
- if (t instanceof InterruptedException)
- {
- /*
- * We cleared the interrupted state of the current Thread by
- * catching the InterruptedException. However, we do not really
- * care whether the current Thread has been interrupted - we
- * caught the InterruptedException because we want to swallow
- * any Throwable. Consequently, we should better restore the
- * interrupted state.
- */
- interrupted = true;
- }
- else if (t instanceof ThreadDeath)
- throw (ThreadDeath) t;
- }
- if (interrupted)
- Thread.currentThread().interrupt();
- }
-
- /**
- * {@inheritDoc}
- *
- * Implements {@link RegistrationStateChangeListener}. Notifies this
- * instance that there has been a change in the <tt>RegistrationState</tt>
- * of {@link #protocolProvider}. Subscribes this instance to
- * {@link ColibriConferenceIQ}s as soon as <tt>protocolProvider</tt> is
- * registered and unsubscribes it as soon as <tt>protocolProvider</tt> is
- * unregistered.
- */
- public void registrationStateChanged(RegistrationStateChangeEvent ev)
- {
- RegistrationState registrationState = ev.getNewState();
-
- if (RegistrationState.REGISTERED.equals(registrationState))
- {
- protocolProvider.getConnection().addPacketListener(this, this);
- }
- else if (RegistrationState.UNREGISTERED.equals(registrationState))
- {
- XMPPConnection connection = protocolProvider.getConnection();
-
- if (connection != null)
- connection.removePacketListener(this);
- }
- }
-}
+package net.java.sip.communicator.impl.protocol.jabber;
+
+import java.util.*;
+
+import net.java.sip.communicator.impl.protocol.jabber.extensions.colibri.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.service.protocol.media.*;
+import net.java.sip.communicator.util.*;
+
+import org.jivesoftware.smack.*;
+import org.jivesoftware.smack.filter.*;
+import org.jivesoftware.smack.packet.*;
+
+/**
+ * Implements <tt>OperationSetVideoBridge</tt> for Jabber.
+ *
+ * @author Yana Stamcheva
+ * @author Lyubomir Marinov
+ */
+public class OperationSetVideoBridgeImpl
+ implements OperationSetVideoBridge,
+ PacketFilter,
+ PacketListener,
+ RegistrationStateChangeListener
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>OperationSetVideoBridgeImpl</tt>
+ * class and its instances for logging output.
+ */
+ private static final Logger logger
+ = Logger.getLogger(OperationSetVideoBridgeImpl.class);
+
+ /**
+ * The <tt>ProtocolProviderService</tt> implementation which initialized
+ * this instance, owns it and is often referred to as its parent.
+ */
+ private final ProtocolProviderServiceJabberImpl protocolProvider;
+
+ /**
+ * Creates an instance of <tt>OperationSetVideoBridgeImpl</tt> by
+ * specifying the parent <tt>ProtocolProviderService</tt> announcing this
+ * operation set.
+ *
+ * @param protocolProvider the parent Jabber protocol provider
+ */
+ public OperationSetVideoBridgeImpl(
+ ProtocolProviderServiceJabberImpl protocolProvider)
+ {
+ this.protocolProvider = protocolProvider;
+ this.protocolProvider.addRegistrationStateChangeListener(this);
+ }
+
+ /**
+ * Implements {@link PacketFilter}. Determines whether this instance is
+ * interested in a specific {@link Packet}.
+ * <tt>OperationSetVideoBridgeImpl</tt> returns <tt>true</tt> if the
+ * specified <tt>packet</tt> is a {@link ColibriConferenceIQ}; otherwise,
+ * <tt>false</tt>.
+ *
+ * @param packet the <tt>Packet</tt> to be determined whether this instance
+ * is interested in it
+ * @return <tt>true</tt> if the specified <tt>packet</tt> is a
+ * <tt>ColibriConferenceIQ</tt>; otherwise, <tt>false</tt>
+ */
+ public boolean accept(Packet packet)
+ {
+ return (packet instanceof ColibriConferenceIQ);
+ }
+
+ /**
+ * Creates a conference call with the specified callees as call peers via a
+ * video bridge provided by the parent Jabber provider.
+ *
+ * @param callees the list of addresses that we should call
+ * @return the newly created conference call containing all CallPeers
+ * @throws OperationFailedException if establishing the conference call
+ * fails
+ * @throws OperationNotSupportedException if the provider does not have any
+ * conferencing features.
+ */
+ public Call createConfCall(String[] callees)
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ return
+ protocolProvider
+ .getOperationSet(OperationSetTelephonyConferencing.class)
+ .createConfCall(
+ callees,
+ new MediaAwareCallConference(true));
+ }
+
+ /**
+ * Invites the callee represented by the specified uri to an already
+ * existing call using a video bridge provided by the parent Jabber provider.
+ * The difference between this method and createConfCall is that
+ * inviteCalleeToCall allows a user to add new peers to an already
+ * established conference.
+ *
+ * @param uri the callee to invite to an existing conf call.
+ * @param call the call that we should invite the callee to.
+ * @return the CallPeer object corresponding to the callee represented by
+ * the specified uri.
+ * @throws OperationFailedException if inviting the specified callee to the
+ * specified call fails
+ * @throws OperationNotSupportedException if allowing additional callees to
+ * a pre-established call is not supported.
+ */
+ public CallPeer inviteCalleeToCall(String uri, Call call)
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ return
+ protocolProvider
+ .getOperationSet(OperationSetTelephonyConferencing.class)
+ .inviteCalleeToCall(uri, call);
+ }
+
+ /**
+ * Indicates if there's an active video bridge available at this moment. The
+ * Jabber provider may announce support for video bridge, but it should not
+ * be used for calling until it becomes actually active.
+ *
+ * @return <tt>true</tt> to indicate that there's currently an active
+ * available video bridge, <tt>false</tt> - otherwise
+ */
+ public boolean isActive()
+ {
+ String jitsiVideobridge = protocolProvider.getJitsiVideobridge();
+
+ return ((jitsiVideobridge != null) && (jitsiVideobridge.length() > 0));
+ }
+
+ /**
+ * Notifies this instance that a specific <tt>ColibriConferenceIQ</tt> has
+ * been received.
+ *
+ * @param conferenceIQ the <tt>ColibriConferenceIQ</tt> which has been
+ * received
+ */
+ private void processColibriConferenceIQ(ColibriConferenceIQ conferenceIQ)
+ {
+ /*
+ * The application is not a Jitsi Videobridge server, it is a client.
+ * Consequently, the specified ColibriConferenceIQ is sent to it in
+ * relation to the part of the application's functionality which makes
+ * requests to a Jitsi Videobridge server i.e. CallJabberImpl.
+ *
+ * Additionally, the method processColibriConferenceIQ is presently tasked
+ * with processing ColibriConferenceIQ requests only. They are SET IQs
+ * sent by the Jitsi Videobridge server to notify the application about
+ * updates in the states of (colibri) conferences organized by the
+ * application.
+ */
+ if (IQ.Type.SET.equals(conferenceIQ.getType())
+ && conferenceIQ.getID() != null)
+ {
+ OperationSetBasicTelephony<?> basicTelephony
+ = protocolProvider.getOperationSet(
+ OperationSetBasicTelephony.class);
+
+ if (basicTelephony != null)
+ {
+ Iterator<? extends Call> i = basicTelephony.getActiveCalls();
+
+ while (i.hasNext())
+ {
+ Call call = i.next();
+
+ if (call instanceof CallJabberImpl)
+ {
+ CallJabberImpl callJabberImpl = (CallJabberImpl) call;
+ MediaAwareCallConference conference
+ = callJabberImpl.getConference();
+
+ if ((conference != null)
+ && conference.isJitsiVideobridge())
+ {
+ /*
+ * TODO We may want to disallow rogue CallJabberImpl
+ * instances which may throw an exception to prevent
+ * the conferenceIQ from reaching the CallJabberImpl
+ * instance which it was meant for.
+ */
+ if (callJabberImpl.processColibriConferenceIQ(
+ conferenceIQ))
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Implements {@link PacketListener}. Notifies this instance that a specific
+ * {@link Packet} (which this instance has already expressed interest into
+ * by returning <tt>true</tt> from {@link #accept(Packet)}) has been
+ * received.
+ *
+ * @param packet the <tt>Packet</tt> which has been received and which this
+ * instance is given a chance to process
+ */
+ public void processPacket(Packet packet)
+ {
+ /*
+ * As we do elsewhere, acknowledge the receipt of the Packet first and
+ * then go about our business with it.
+ */
+ IQ iq = (IQ) packet;
+
+ if (iq.getType() == IQ.Type.SET)
+ protocolProvider.getConnection().sendPacket(IQ.createResultIQ(iq));
+
+ /*
+ * Now that the acknowledging is out of the way, do go about our
+ * business with the Packet.
+ */
+ ColibriConferenceIQ conferenceIQ = (ColibriConferenceIQ) iq;
+ boolean interrupted = false;
+
+ try
+ {
+ processColibriConferenceIQ(conferenceIQ);
+ }
+ catch (Throwable t)
+ {
+ logger.error(
+ "An error occurred during the processing of a "
+ + packet.getClass().getName() + " packet",
+ t);
+
+ if (t instanceof InterruptedException)
+ {
+ /*
+ * We cleared the interrupted state of the current Thread by
+ * catching the InterruptedException. However, we do not really
+ * care whether the current Thread has been interrupted - we
+ * caught the InterruptedException because we want to swallow
+ * any Throwable. Consequently, we should better restore the
+ * interrupted state.
+ */
+ interrupted = true;
+ }
+ else if (t instanceof ThreadDeath)
+ throw (ThreadDeath) t;
+ }
+ if (interrupted)
+ Thread.currentThread().interrupt();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Implements {@link RegistrationStateChangeListener}. Notifies this
+ * instance that there has been a change in the <tt>RegistrationState</tt>
+ * of {@link #protocolProvider}. Subscribes this instance to
+ * {@link ColibriConferenceIQ}s as soon as <tt>protocolProvider</tt> is
+ * registered and unsubscribes it as soon as <tt>protocolProvider</tt> is
+ * unregistered.
+ */
+ public void registrationStateChanged(RegistrationStateChangeEvent ev)
+ {
+ RegistrationState registrationState = ev.getNewState();
+
+ if (RegistrationState.REGISTERED.equals(registrationState))
+ {
+ protocolProvider.getConnection().addPacketListener(this, this);
+ }
+ else if (RegistrationState.UNREGISTERED.equals(registrationState))
+ {
+ Connection connection = protocolProvider.getConnection();
+
+ if (connection != null)
+ connection.removePacketListener(this);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OutgoingFileTransferJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OutgoingFileTransferJabberImpl.java
index f38d0bc..b219d68 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/OutgoingFileTransferJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OutgoingFileTransferJabberImpl.java
@@ -248,7 +248,7 @@ public class OutgoingFileTransferJabberImpl
ThumbnailIQ thumbnailIQ = (ThumbnailIQ) packet;
String thumbnailIQCid = thumbnailIQ.getCid();
- XMPPConnection connection = protocolProvider.getConnection();
+ Connection connection = protocolProvider.getConnection();
if ((thumbnailIQCid != null)
&& thumbnailIQCid.equals(thumbnailElement.getCid()))
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderFactoryJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderFactoryJabberImpl.java
index 4f9fc5f..86666f3 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderFactoryJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderFactoryJabberImpl.java
@@ -21,6 +21,7 @@ import java.util.*;
import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.jabber.*;
import org.jivesoftware.smack.provider.*;
import org.jivesoftware.smack.util.*;
import org.osgi.framework.*;
@@ -46,7 +47,14 @@ public class ProtocolProviderFactoryJabberImpl
{
try
{
+
+ // Set the extension provider manager for classes that use
+ // it directly
ProviderManager.setInstance(new ProviderManagerExt());
+ // Set the Smack interop implementation for the classes that need
+ // to support Smackv4 interoperation
+ AbstractSmackInteroperabilityLayer.setImplementationClass(
+ SmackV3InteroperabilityLayer.class);
}
catch(Throwable t)
{
@@ -179,7 +187,7 @@ public class ProtocolProviderFactoryJabberImpl
ProtocolProviderServiceJabberImpl service =
new ProtocolProviderServiceJabberImpl();
- service.initialize(userID, accountID);
+ service.initialize(userID, (JabberAccountID) accountID);
return service;
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
index 2ea5c9c..47b9b75 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
@@ -32,6 +32,7 @@ import net.java.sip.communicator.impl.protocol.jabber.extensions.carbon.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.coin.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.colibri.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.inputevt.*;
+import net.java.sip.communicator.impl.protocol.jabber.extensions.jibri.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.jingleinfo.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.keepalive.*;
@@ -41,6 +42,7 @@ import net.java.sip.communicator.service.certificate.*;
import net.java.sip.communicator.service.dns.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.service.protocol.jabber.*;
import net.java.sip.communicator.service.protocol.jabberconstants.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.Logger;
@@ -152,6 +154,14 @@ public class ProtocolProviderServiceJabberImpl
public static final String URN_IETF_RFC_3264 = "urn:ietf:rfc:3264";
/**
+ * http://xmpp.org/extensions/xep-0092.html Software Version.
+ *
+ */
+ // Used in JVB
+ @SuppressWarnings("unused")
+ public static final String URN_XMPP_IQ_VERSION = "jabber:iq:version";
+
+ /**
* Jingle's Discovery Info URN for "XEP-0294: Jingle RTP Header Extensions
* Negotiation" support.
*/
@@ -211,7 +221,7 @@ public class ProtocolProviderServiceJabberImpl
/**
* Used to connect to a XMPP server.
*/
- private XMPPConnection connection;
+ private Connection connection;
/**
* The socket address of the XMPP server.
@@ -231,7 +241,7 @@ public class ProtocolProviderServiceJabberImpl
/**
* The identifier of the account that this provider represents.
*/
- private AccountID accountID = null;
+ private JabberAccountID accountID = null;
/**
* Used when we need to re-register
@@ -598,7 +608,7 @@ public class ProtocolProviderServiceJabberImpl
*/
public boolean isSignalingTransportSecure()
{
- return connection != null && connection.isUsingTLS();
+ return connection.isSecureConnection();
}
/**
@@ -613,7 +623,7 @@ public class ProtocolProviderServiceJabberImpl
if(connection != null && connection.isConnected())
{
// Transport using a secure connection.
- if(connection.isUsingTLS())
+ if(isSignalingTransportSecure())
{
return TransportProtocol.TLS;
}
@@ -1112,11 +1122,24 @@ public class ProtocolProviderServiceJabberImpl
JabberLoginStrategy loginStrategy)
throws XMPPException
{
- ConnectionConfiguration confConn = new ConnectionConfiguration(
- address.getAddress().getHostAddress(),
- address.getPort(),
- serviceName, proxy
- );
+ // BOSH or TCP ?
+ ConnectionConfiguration confConn;
+ String boshURL = accountID.getBoshUrl();
+ boolean isBosh = !org.jitsi.util.StringUtils.isNullOrEmpty(boshURL);
+
+ if (isBosh)
+ {
+ confConn = new BOSHConfiguration(serviceName);
+ ((BOSHConfiguration)confConn).setBoshUrl(boshURL);
+ }
+ else
+ {
+ confConn
+ = new ConnectionConfiguration(
+ address.getAddress().getHostAddress(),
+ address.getPort(),
+ serviceName, proxy);
+ }
// if we have OperationSetPersistentPresence skip sending initial
// presence while login is executed, the OperationSet will take care
@@ -1144,7 +1167,11 @@ public class ProtocolProviderServiceJabberImpl
disconnectAndCleanConnection();
}
- connection = new XMPPConnection(confConn);
+ connection
+ = isBosh
+ ? new XMPPBOSHConnection((BOSHConfiguration)confConn)
+ : new XMPPConnection(confConn);
+
this.address = address;
try
@@ -1194,13 +1221,16 @@ public class ProtocolProviderServiceJabberImpl
throw new XMPPException("Error creating custom trust manager", e);
}
- if(debugger == null)
+ // FIXME rework debugger to work with Connection if possible
+ if(debugger == null && connection instanceof XMPPConnection)
+ {
debugger = new SmackPacketDebugger();
- // sets the debugger
- debugger.setConnection(connection);
- connection.addPacketListener(debugger, null);
- connection.addPacketInterceptor(debugger, null);
+ // sets the debugger
+ debugger.setConnection((XMPPConnection) connection);
+ connection.addPacketListener(debugger, null);
+ connection.addPacketInterceptor(debugger, null);
+ }
connection.connect();
@@ -1247,9 +1277,10 @@ public class ProtocolProviderServiceJabberImpl
}
else
{
- if (connection.getSocket() instanceof SSLSocket)
+ final SSLSocket sslSocket = getSSLSocket();
+
+ if (sslSocket != null)
{
- final SSLSocket sslSocket = (SSLSocket) connection.getSocket();
StringBuilder buff = new StringBuilder();
buff.append("Chosen TLS protocol and algorithm:\n")
.append("Protocol: ").append(sslSocket.getSession()
@@ -1538,7 +1569,7 @@ public class ProtocolProviderServiceJabberImpl
* @see net.java.sip.communicator.service.protocol.AccountID
*/
protected void initialize(String screenname,
- AccountID accountID)
+ JabberAccountID accountID)
{
synchronized(initializationLock)
{
@@ -1732,6 +1763,12 @@ public class ProtocolProviderServiceJabberImpl
ColibriConferenceIQ.NAMESPACE,
new ColibriIQProvider());
+ providerManager.addIQProvider(
+ JibriIq.ELEMENT_NAME,
+ JibriIq.NAMESPACE,
+ new JibriIqProvider()
+ );
+
providerManager.addExtensionProvider(
ConferenceDescriptionPacketExtension.ELEMENT_NAME,
ConferenceDescriptionPacketExtension.NAMESPACE,
@@ -2025,11 +2062,98 @@ public class ProtocolProviderServiceJabberImpl
}
/**
- * Returns the <tt>XMPPConnection</tt>opened by this provider
- * @return a reference to the <tt>XMPPConnection</tt> last opened by this
+ * Validates the node part of a JID and returns an error message if
+ * applicable and a suggested correction.
+ *
+ * @param contactId the contact identifier to validate
+ * @param result Must be supplied as an empty a list. Implementors add
+ * items:
+ * <ol>
+ * <li>is the error message if applicable
+ * <li>a suggested correction. Index 1 is optional and can only
+ * be present if there was a validation failure.
+ * </ol>
+ * @return true if the contact id is valid, false otherwise
+ */
+ @Override
+ public boolean validateContactAddress(String contactId, List<String> result)
+ {
+ if (result == null)
+ {
+ throw new IllegalArgumentException("result must be an empty list");
+ }
+
+ result.clear();
+ try
+ {
+ contactId = contactId.trim();
+ if (contactId.length() == 0)
+ {
+ result.add(JabberActivator.getResources().getI18NString(
+ "impl.protocol.jabber.INVALID_ADDRESS", new String[]
+ { contactId }));
+ // no suggestion for an empty id
+ return false;
+ }
+
+ String user = contactId;
+ String remainder = "";
+ int at = contactId.indexOf('@');
+ if (at > -1)
+ {
+ user = contactId.substring(0, at);
+ remainder = contactId.substring(at);
+ }
+
+ // <conforming-char> ::= #x21 | [#x23-#x25] | [#x28-#x2E] |
+ // [#x30-#x39] | #x3B | #x3D | #x3F |
+ // [#x41-#x7E] | [#x80-#xD7FF] |
+ // [#xE000-#xFFFD] | [#x10000-#x10FFFF]
+ boolean valid = true;
+ String suggestion = "";
+ for (char c : user.toCharArray())
+ {
+ if (!(c == 0x21 || (c >= 0x23 && c <= 0x25)
+ || (c >= 0x28 && c <= 0x2e) || (c >= 0x30 && c <= 0x39)
+ || c == 0x3b || c == 0x3d || c == 0x3f
+ || (c >= 0x41 && c <= 0x7e) || (c >= 0x80 && c <= 0xd7ff)
+ || (c >= 0xe000 && c <= 0xfffd)))
+ {
+ valid = false;
+ }
+ else
+ {
+ suggestion += c;
+ }
+ }
+
+ if (!valid)
+ {
+ result.add(JabberActivator.getResources().getI18NString(
+ "impl.protocol.jabber.INVALID_ADDRESS", new String[]
+ { contactId }));
+ result.add(suggestion + remainder);
+ return false;
+ }
+
+ return true;
+ }
+ catch (Exception ex)
+ {
+ result.add(JabberActivator.getResources().getI18NString(
+ "impl.protocol.jabber.INVALID_ADDRESS", new String[]
+ { contactId }));
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the <tt>Connection</tt>opened by this provider
+ * @return a reference to the <tt>Connection</tt> last opened by this
* provider.
*/
- public XMPPConnection getConnection()
+ public Connection getConnection()
{
return connection;
}
@@ -2315,18 +2439,16 @@ public class ProtocolProviderServiceJabberImpl
*/
public boolean isFeatureListSupported(String jid, String... features)
{
- boolean isFeatureListSupported = true;
-
try
{
if(discoveryManager == null)
- return isFeatureListSupported;
+ return false;
DiscoverInfo featureInfo =
discoveryManager.discoverInfoNonBlocking(jid);
if(featureInfo == null)
- return isFeatureListSupported;
+ return false;
for (String feature : features)
{
@@ -2334,17 +2456,19 @@ public class ProtocolProviderServiceJabberImpl
{
// If one is not supported we return false and don't check
// the others.
- isFeatureListSupported = false;
- break;
+ return false;
}
}
+
+ return true;
}
catch (XMPPException e)
{
if (logger.isDebugEnabled())
logger.debug("Failed to retrive discovery info.", e);
}
- return isFeatureListSupported;
+
+ return false;
}
/**
@@ -2386,7 +2510,7 @@ public class ProtocolProviderServiceJabberImpl
*/
public String getFullJid(String bareJid)
{
- XMPPConnection connection = getConnection();
+ Connection connection = getConnection();
// when we are not connected there is no full jid
if (connection != null && connection.isConnected())
@@ -2590,12 +2714,21 @@ public class ProtocolProviderServiceJabberImpl
*/
public void startJingleNodesDiscovery()
{
+ if (!(connection instanceof XMPPConnection))
+ {
+ logger.warn(
+ "Jingle node discovery currently will work only with " +
+ "TCP XMPP connection");
+ return;
+ }
+
// Jingle Nodes Service Initialization
+ final XMPPConnection xmppConnection = (XMPPConnection) connection;
final JabberAccountIDImpl accID = (JabberAccountIDImpl)getAccountID();
- final SmackServiceNode service = new SmackServiceNode(connection,
- 60000);
+ final SmackServiceNode service
+ = new SmackServiceNode(xmppConnection, 60000);
// make sure SmackServiceNode will clean up when connection is closed
- connection.addConnectionListener(service);
+ xmppConnection.addConnectionListener(service);
for(JingleNodeDescriptor desc : accID.getJingleNodes())
{
@@ -2611,7 +2744,7 @@ public class ProtocolProviderServiceJabberImpl
new Thread(new JingleNodesServiceDiscovery(
service,
- connection,
+ xmppConnection,
accID,
jingleNodesSyncRoot))
.start();
@@ -2739,7 +2872,7 @@ public class ProtocolProviderServiceJabberImpl
*/
private void setTrafficClass()
{
- Socket s = connection.getSocket();
+ Socket s = getSocket();
if(s != null)
{
@@ -2774,7 +2907,7 @@ public class ProtocolProviderServiceJabberImpl
*/
public String getJitsiVideobridge()
{
- XMPPConnection connection = getConnection();
+ Connection connection = getConnection();
if (connection != null)
{
@@ -2865,21 +2998,23 @@ public class ProtocolProviderServiceJabberImpl
}
/**
+ * Obtains XMPP connection's socket.
+ * @return <tt>Socket</tt> instance used by the underlying XMPP connection
+ * or <tt>null</tt> if "non socket" type of transport is currently used.
+ */
+ private Socket getSocket()
+ {
+ return connection != null ? connection.getSocket() : null;
+ }
+
+ /**
* Return the SSL socket (if TLS used).
* @return The SSL socket or null if not used
*/
- public SSLSocket getSSLSocket()
+ SSLSocket getSSLSocket()
{
- final SSLSocket result;
- final Socket socket = connection.getSocket();
- if (socket instanceof SSLSocket)
- {
- result = (SSLSocket) socket;
- }
- else
- {
- result = null;
- }
- return result;
+ final Socket socket = getSocket();
+
+ return (socket instanceof SSLSocket) ? (SSLSocket) socket : null;
}
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/RawUdpTransportManager.java b/src/net/java/sip/communicator/impl/protocol/jabber/RawUdpTransportManager.java
index 0aa4fb6..4bd49a9 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/RawUdpTransportManager.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/RawUdpTransportManager.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,529 +15,529 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.protocol.jabber;
-
-import java.net.*;
-import java.util.*;
-
-import net.java.sip.communicator.impl.protocol.jabber.extensions.colibri.*;
-import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
-import net.java.sip.communicator.impl.protocol.jabber.jinglesdp.*;
-import net.java.sip.communicator.service.protocol.*;
-
-import org.jitsi.service.neomedia.*;
-import org.jivesoftware.smack.packet.*;
-
-/**
- * A {@link TransportManagerJabberImpl} implementation that would only gather a
- * single candidate pair (i.e. RTP and RTCP).
- *
- * @author Emil Ivov
- * @author Lyubomir Marinov
- * @author Hristo Terezov
- */
-public class RawUdpTransportManager
- extends TransportManagerJabberImpl
-{
- /**
- * The list of <tt>ContentPacketExtension</tt>s which represents the local
- * counterpart of the negotiation between the local and the remote peers.
- */
- private List<ContentPacketExtension> local;
-
- /**
- * The collection of <tt>ContentPacketExtension</tt>s which represents the
- * remote counterpart of the negotiation between the local and the remote
- * peers.
- */
- private final List<Iterable<ContentPacketExtension>> remotes
- = new LinkedList<Iterable<ContentPacketExtension>>();
-
- /**
- * Creates a new instance of this transport manager, binding it to the
- * specified peer.
- *
- * @param callPeer the {@link CallPeer} whose traffic we will be taking
- * care of.
- */
- public RawUdpTransportManager(CallPeerJabberImpl callPeer)
- {
- super(callPeer);
- }
-
- /**
- * {@inheritDoc}
- */
- protected PacketExtension createTransport(String media)
- throws OperationFailedException
- {
- MediaType mediaType = MediaType.parseString(media);
-
- return createTransport(mediaType, getStreamConnector(mediaType));
- }
-
- /**
- * Creates a raw UDP transport element according to a specific
- * <tt>StreamConnector</tt>.
- *
- * @param mediaType the <tt>MediaType</tt> of the <tt>MediaStream</tt> which
- * uses the specified <tt>connector</tt> or <tt>channel</tt>
- * @param connector the <tt>StreamConnector</tt> to be described within the
- * transport element
- * @return a {@link RawUdpTransportPacketExtension} containing the RTP and
- * RTCP candidates of the specified <tt>connector</tt>
- */
- private RawUdpTransportPacketExtension createTransport(
- MediaType mediaType,
- StreamConnector connector)
- {
- RawUdpTransportPacketExtension ourTransport
- = new RawUdpTransportPacketExtension();
- int generation = getCurrentGeneration();
-
- // create and add candidates that correspond to the stream connector
- // RTP
- CandidatePacketExtension rtpCand = new CandidatePacketExtension();
-
- rtpCand.setComponent(CandidatePacketExtension.RTP_COMPONENT_ID);
- rtpCand.setGeneration(generation);
- rtpCand.setID(getNextID());
- rtpCand.setType(CandidateType.host);
-
- DatagramSocket dataSocket = connector.getDataSocket();
-
- rtpCand.setIP(dataSocket.getLocalAddress().getHostAddress());
- rtpCand.setPort(dataSocket.getLocalPort());
-
- ourTransport.addCandidate(rtpCand);
-
- // RTCP
- CandidatePacketExtension rtcpCand = new CandidatePacketExtension();
-
- rtcpCand.setComponent(CandidatePacketExtension.RTCP_COMPONENT_ID);
- rtcpCand.setGeneration(generation);
- rtcpCand.setID(getNextID());
- rtcpCand.setType(CandidateType.host);
-
- DatagramSocket controlSocket = connector.getControlSocket();
-
- rtcpCand.setIP(controlSocket.getLocalAddress().getHostAddress());
- rtcpCand.setPort(controlSocket.getLocalPort());
-
- ourTransport.addCandidate(rtcpCand);
-
- return ourTransport;
- }
-
- /**
- * {@inheritDoc}
- */
- protected PacketExtension createTransportPacketExtension()
- {
- return new RawUdpTransportPacketExtension();
- }
-
- /**
- * Implements {@link TransportManagerJabberImpl#getStreamTarget(MediaType)}.
- * Gets the <tt>MediaStreamTarget</tt> to be used as the <tt>target</tt> of
- * the <tt>MediaStream</tt> with a specific <tt>MediaType</tt>.
- *
- * @param mediaType the <tt>MediaType</tt> of the <tt>MediaStream</tt> which
- * is to have its <tt>target</tt> set to the returned
- * <tt>MediaStreamTarget</tt>
- * @return the <tt>MediaStreamTarget</tt> to be used as the <tt>target</tt>
- * of the <tt>MediaStream</tt> with the specified <tt>MediaType</tt>
- * @see TransportManagerJabberImpl#getStreamTarget(MediaType)
- */
- @Override
- public MediaStreamTarget getStreamTarget(MediaType mediaType)
- {
- ColibriConferenceIQ.Channel channel
- = getColibriChannel(mediaType, true /* local */);
- MediaStreamTarget streamTarget = null;
-
- if (channel == null)
- {
- String media = mediaType.toString();
-
- for (Iterable<ContentPacketExtension> remote : remotes)
- {
- for (ContentPacketExtension content : remote)
- {
- RtpDescriptionPacketExtension rtpDescription
- = content.getFirstChildOfType(
- RtpDescriptionPacketExtension.class);
-
- if (media.equals(rtpDescription.getMedia()))
- {
- streamTarget
- = JingleUtils.extractDefaultTarget(content);
- break;
- }
- }
- }
- }
- else
- {
- IceUdpTransportPacketExtension transport = channel.getTransport();
-
- if (transport != null)
- streamTarget = JingleUtils.extractDefaultTarget(transport);
- if (streamTarget == null)
- {
- /*
- * For the purposes of compatibility with legacy Jitsi
- * Videobridge, support the channel attributes host, rtpPort and
- * rtcpPort.
- */
- @SuppressWarnings("deprecation")
- String host = channel.getHost();
-
- if (host != null)
- {
- @SuppressWarnings("deprecation")
- int rtpPort = channel.getRTPPort();
- @SuppressWarnings("deprecation")
- int rtcpPort = channel.getRTCPPort();
-
- streamTarget
- = new MediaStreamTarget(
- new InetSocketAddress(host, rtpPort),
- new InetSocketAddress(host, rtcpPort));
- }
- }
- }
- return streamTarget;
- }
-
- /**
- * Implements {@link TransportManagerJabberImpl#getXmlNamespace()}. Gets the
- * XML namespace of the Jingle transport implemented by this
- * <tt>TransportManagerJabberImpl</tt>.
- *
- * @return the XML namespace of the Jingle transport implemented by this
- * <tt>TransportManagerJabberImpl</tt>
- * @see TransportManagerJabberImpl#getXmlNamespace()
- */
- @Override
- public String getXmlNamespace()
- {
- return ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_RAW_UDP_0;
- }
-
- /**
- * Removes a content with a specific name from the transport-related part of
- * the session represented by this <tt>TransportManagerJabberImpl</tt> which
- * may have been reported through previous calls to the
- * <tt>startCandidateHarvest</tt> and
- * <tt>startConnectivityEstablishment</tt> methods.
- *
- * @param name the name of the content to be removed from the
- * transport-related part of the session represented by this
- * <tt>TransportManagerJabberImpl</tt>
- * @see TransportManagerJabberImpl#removeContent(String)
- */
- @Override
- public void removeContent(String name)
- {
- if (local != null)
- removeContent(local, name);
-
- removeRemoteContent(name);
- }
-
- /**
- * Removes a content with a specific name from the remote counterpart of the
- * negotiation between the local and the remote peers.
- *
- * @param name the name of the content to be removed from the remote
- * counterpart of the negotiation between the local and the remote peers
- */
- private void removeRemoteContent(String name)
- {
- for (Iterator<Iterable<ContentPacketExtension>> remoteIter
- = remotes.iterator();
- remoteIter.hasNext();)
- {
- Iterable<ContentPacketExtension> remote = remoteIter.next();
-
- /*
- * Once the remote content is removed, make sure that we are not
- * retaining sets which do not have any contents.
- */
- if ((removeContent(remote, name) != null)
- && !remote.iterator().hasNext())
- {
- remoteIter.remove();
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- protected PacketExtension startCandidateHarvest(
- ContentPacketExtension theirContent,
- ContentPacketExtension ourContent,
- TransportInfoSender transportInfoSender,
- String media)
- throws OperationFailedException
- {
- return createTransportForStartCandidateHarvest(media);
- }
-
- /**
- * Starts transport candidate harvest. This method should complete rapidly
- * and, in case of lengthy procedures like STUN/TURN/UPnP candidate harvests
- * are necessary, they should be executed in a separate thread. Candidate
- * harvest would then need to be concluded in the
- * {@link #wrapupCandidateHarvest()} method which would be called once we
- * absolutely need the candidates.
- *
- * @param theirOffer a media description offer that we've received from the
- * remote party and that we should use in case we need to know what
- * transports our peer is using.
- * @param ourAnswer the content descriptions that we should be adding our
- * transport lists to (although not necessarily in this very instance).
- * @param transportInfoSender the <tt>TransportInfoSender</tt> to be used by
- * this <tt>TransportManagerJabberImpl</tt> to send <tt>transport-info</tt>
- * <tt>JingleIQ</tt>s from the local peer to the remote peer if this
- * <tt>TransportManagerJabberImpl</tt> wishes to utilize
- * <tt>transport-info</tt>. Local candidate addresses sent by this
- * <tt>TransportManagerJabberImpl</tt> in <tt>transport-info</tt> are
- * expected to not be included in the result of
- * {@link #wrapupCandidateHarvest()}.
- *
- * @throws OperationFailedException if we fail to allocate a port number.
- * @see TransportManagerJabberImpl#startCandidateHarvest(List, List,
- * TransportInfoSender)
- */
- @Override
- public void startCandidateHarvest(
- List<ContentPacketExtension> theirOffer,
- List<ContentPacketExtension> ourAnswer,
- TransportInfoSender transportInfoSender)
- throws OperationFailedException
- {
- this.local = ourAnswer;
-
- super.startCandidateHarvest(theirOffer, ourAnswer, transportInfoSender);
- }
-
- /**
- * Overrides the super implementation in order to remember the remote
- * counterpart of the negotiation between the local and the remote peer for
- * subsequent calls to {@link #getStreamTarget(MediaType)}.
- *
- * @param remote the collection of <tt>ContentPacketExtension</tt>s which
- * represents the remote counterpart of the negotiation between the local
- * and the remote peer
- * @return <tt>true</tt> because <tt>RawUdpTransportManager</tt> does not
- * perform connectivity checks
- * @see TransportManagerJabberImpl#startConnectivityEstablishment(Iterable)
- */
- @Override
- public boolean startConnectivityEstablishment(
- Iterable<ContentPacketExtension> remote)
- {
- if ((remote != null) && !remotes.contains(remote))
- {
- /*
- * The state of the session in Jingle is maintained by each peer and
- * is modified by content-add and content-remove. The remotes field
- * of this RawUdpTransportManager represents the state of the
- * session with respect to the remote peer. When the remote peer
- * tells us about a specific set of contents, make sure that it is
- * the only record we will have with respect to the specified set of
- * contents.
- */
- for (ContentPacketExtension content : remote)
- removeRemoteContent(content.getName());
-
- remotes.add(remote);
- }
-
- return super.startConnectivityEstablishment(remote);
- }
-
- /**
- * Simply returns the list of local candidates that we gathered during the
- * harvest. This is a raw UDP transport manager so there's no real wrapping
- * up to do.
- *
- * @return the list of local candidates that we gathered during the harvest
- * @see TransportManagerJabberImpl#wrapupCandidateHarvest()
- */
- @Override
- public List<ContentPacketExtension> wrapupCandidateHarvest()
- {
- return local;
- }
-
- /**
- * Returns the extended type of the candidate selected if this transport
- * manager is using ICE.
- *
- * @param streamName The stream name (AUDIO, VIDEO);
- *
- * @return The extended type of the candidate selected if this transport
- * manager is using ICE. Otherwise, returns null.
- */
- @Override
- public String getICECandidateExtendedType(String streamName)
- {
- return null;
- }
-
- /**
- * Returns the current state of ICE processing.
- *
- * @return the current state of ICE processing.
- */
- @Override
- public String getICEState()
- {
- return null;
- }
-
- /**
- * Returns the ICE local host address.
- *
- * @param streamName The stream name (AUDIO, VIDEO);
- *
- * @return the ICE local host address if this transport
- * manager is using ICE. Otherwise, returns null.
- */
- @Override
- public InetSocketAddress getICELocalHostAddress(String streamName)
- {
- return null;
- }
-
- /**
- * Returns the ICE remote host address.
- *
- * @param streamName The stream name (AUDIO, VIDEO);
- *
- * @return the ICE remote host address if this transport
- * manager is using ICE. Otherwise, returns null.
- */
- @Override
- public InetSocketAddress getICERemoteHostAddress(String streamName)
- {
- return null;
- }
-
- /**
- * Returns the ICE local reflexive address (server or peer reflexive).
- *
- * @param streamName The stream name (AUDIO, VIDEO);
- *
- * @return the ICE local reflexive address. May be null if this transport
- * manager is not using ICE or if there is no reflexive address for the
- * local candidate used.
- */
- @Override
- public InetSocketAddress getICELocalReflexiveAddress(String streamName)
- {
- return null;
- }
-
- /**
- * Returns the ICE remote reflexive address (server or peer reflexive).
- *
- * @param streamName The stream name (AUDIO, VIDEO);
- *
- * @return the ICE remote reflexive address. May be null if this transport
- * manager is not using ICE or if there is no reflexive address for the
- * remote candidate used.
- */
- @Override
- public InetSocketAddress getICERemoteReflexiveAddress(String streamName)
- {
- return null;
- }
-
- /**
- * Returns the ICE local relayed address (server or peer relayed).
- *
- * @param streamName The stream name (AUDIO, VIDEO);
- *
- * @return the ICE local relayed address. May be null if this transport
- * manager is not using ICE or if there is no relayed address for the
- * local candidate used.
- */
- @Override
- public InetSocketAddress getICELocalRelayedAddress(String streamName)
- {
- return null;
- }
-
- /**
- * Returns the ICE remote relayed address (server or peer relayed).
- *
- * @param streamName The stream name (AUDIO, VIDEO);
- *
- * @return the ICE remote relayed address. May be null if this transport
- * manager is not using ICE or if there is no relayed address for the
- * remote candidate used.
- */
- @Override
- public InetSocketAddress getICERemoteRelayedAddress(String streamName)
- {
- return null;
- }
-
- /**
- * Returns the total harvesting time (in ms) for all harvesters.
- *
- * @return The total harvesting time (in ms) for all the harvesters. 0 if
- * the ICE agent is null, or if the agent has nevers harvested.
- */
- @Override
- public long getTotalHarvestingTime()
- {
- return 0;
- }
-
- /**
- * Returns the harvesting time (in ms) for the harvester given in parameter.
- *
- * @param harvesterName The class name if the harvester.
- *
- * @return The harvesting time (in ms) for the harvester given in parameter.
- * 0 if this harvester does not exists, if the ICE agent is null, or if the
- * agent has never harvested with this harvester.
- */
- @Override
- public long getHarvestingTime(String harvesterName)
- {
- return 0;
- }
-
- /**
- * Returns the number of harvesting for this agent.
- *
- * @return The number of harvesting for this agent.
- */
- @Override
- public int getNbHarvesting()
- {
- return 0;
- }
-
- /**
- * Returns the number of harvesting time for the harvester given in
- * parameter.
- *
- * @param harvesterName The class name if the harvester.
- *
- * @return The number of harvesting time for the harvester given in
- * parameter.
- */
- @Override
- public int getNbHarvesting(String harvesterName)
- {
- return 0;
- }
-}
+package net.java.sip.communicator.impl.protocol.jabber;
+
+import java.net.*;
+import java.util.*;
+
+import net.java.sip.communicator.impl.protocol.jabber.extensions.colibri.*;
+import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
+import net.java.sip.communicator.impl.protocol.jabber.jinglesdp.*;
+import net.java.sip.communicator.service.protocol.*;
+
+import org.jitsi.service.neomedia.*;
+import org.jivesoftware.smack.packet.*;
+
+/**
+ * A {@link TransportManagerJabberImpl} implementation that would only gather a
+ * single candidate pair (i.e. RTP and RTCP).
+ *
+ * @author Emil Ivov
+ * @author Lyubomir Marinov
+ * @author Hristo Terezov
+ */
+public class RawUdpTransportManager
+ extends TransportManagerJabberImpl
+{
+ /**
+ * The list of <tt>ContentPacketExtension</tt>s which represents the local
+ * counterpart of the negotiation between the local and the remote peers.
+ */
+ private List<ContentPacketExtension> local;
+
+ /**
+ * The collection of <tt>ContentPacketExtension</tt>s which represents the
+ * remote counterpart of the negotiation between the local and the remote
+ * peers.
+ */
+ private final List<Iterable<ContentPacketExtension>> remotes
+ = new LinkedList<Iterable<ContentPacketExtension>>();
+
+ /**
+ * Creates a new instance of this transport manager, binding it to the
+ * specified peer.
+ *
+ * @param callPeer the {@link CallPeer} whose traffic we will be taking
+ * care of.
+ */
+ public RawUdpTransportManager(CallPeerJabberImpl callPeer)
+ {
+ super(callPeer);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected PacketExtension createTransport(String media)
+ throws OperationFailedException
+ {
+ MediaType mediaType = MediaType.parseString(media);
+
+ return createTransport(mediaType, getStreamConnector(mediaType));
+ }
+
+ /**
+ * Creates a raw UDP transport element according to a specific
+ * <tt>StreamConnector</tt>.
+ *
+ * @param mediaType the <tt>MediaType</tt> of the <tt>MediaStream</tt> which
+ * uses the specified <tt>connector</tt> or <tt>channel</tt>
+ * @param connector the <tt>StreamConnector</tt> to be described within the
+ * transport element
+ * @return a {@link RawUdpTransportPacketExtension} containing the RTP and
+ * RTCP candidates of the specified <tt>connector</tt>
+ */
+ private RawUdpTransportPacketExtension createTransport(
+ MediaType mediaType,
+ StreamConnector connector)
+ {
+ RawUdpTransportPacketExtension ourTransport
+ = new RawUdpTransportPacketExtension();
+ int generation = getCurrentGeneration();
+
+ // create and add candidates that correspond to the stream connector
+ // RTP
+ CandidatePacketExtension rtpCand = new CandidatePacketExtension();
+
+ rtpCand.setComponent(CandidatePacketExtension.RTP_COMPONENT_ID);
+ rtpCand.setGeneration(generation);
+ rtpCand.setID(getNextID());
+ rtpCand.setType(CandidateType.host);
+
+ DatagramSocket dataSocket = connector.getDataSocket();
+
+ rtpCand.setIP(dataSocket.getLocalAddress().getHostAddress());
+ rtpCand.setPort(dataSocket.getLocalPort());
+
+ ourTransport.addCandidate(rtpCand);
+
+ // RTCP
+ CandidatePacketExtension rtcpCand = new CandidatePacketExtension();
+
+ rtcpCand.setComponent(CandidatePacketExtension.RTCP_COMPONENT_ID);
+ rtcpCand.setGeneration(generation);
+ rtcpCand.setID(getNextID());
+ rtcpCand.setType(CandidateType.host);
+
+ DatagramSocket controlSocket = connector.getControlSocket();
+
+ rtcpCand.setIP(controlSocket.getLocalAddress().getHostAddress());
+ rtcpCand.setPort(controlSocket.getLocalPort());
+
+ ourTransport.addCandidate(rtcpCand);
+
+ return ourTransport;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected PacketExtension createTransportPacketExtension()
+ {
+ return new RawUdpTransportPacketExtension();
+ }
+
+ /**
+ * Implements {@link TransportManagerJabberImpl#getStreamTarget(MediaType)}.
+ * Gets the <tt>MediaStreamTarget</tt> to be used as the <tt>target</tt> of
+ * the <tt>MediaStream</tt> with a specific <tt>MediaType</tt>.
+ *
+ * @param mediaType the <tt>MediaType</tt> of the <tt>MediaStream</tt> which
+ * is to have its <tt>target</tt> set to the returned
+ * <tt>MediaStreamTarget</tt>
+ * @return the <tt>MediaStreamTarget</tt> to be used as the <tt>target</tt>
+ * of the <tt>MediaStream</tt> with the specified <tt>MediaType</tt>
+ * @see TransportManagerJabberImpl#getStreamTarget(MediaType)
+ */
+ @Override
+ public MediaStreamTarget getStreamTarget(MediaType mediaType)
+ {
+ ColibriConferenceIQ.Channel channel
+ = getColibriChannel(mediaType, true /* local */);
+ MediaStreamTarget streamTarget = null;
+
+ if (channel == null)
+ {
+ String media = mediaType.toString();
+
+ for (Iterable<ContentPacketExtension> remote : remotes)
+ {
+ for (ContentPacketExtension content : remote)
+ {
+ RtpDescriptionPacketExtension rtpDescription
+ = content.getFirstChildOfType(
+ RtpDescriptionPacketExtension.class);
+
+ if (media.equals(rtpDescription.getMedia()))
+ {
+ streamTarget
+ = JingleUtils.extractDefaultTarget(content);
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ IceUdpTransportPacketExtension transport = channel.getTransport();
+
+ if (transport != null)
+ streamTarget = JingleUtils.extractDefaultTarget(transport);
+ if (streamTarget == null)
+ {
+ /*
+ * For the purposes of compatibility with legacy Jitsi
+ * Videobridge, support the channel attributes host, rtpPort and
+ * rtcpPort.
+ */
+ @SuppressWarnings("deprecation")
+ String host = channel.getHost();
+
+ if (host != null)
+ {
+ @SuppressWarnings("deprecation")
+ int rtpPort = channel.getRTPPort();
+ @SuppressWarnings("deprecation")
+ int rtcpPort = channel.getRTCPPort();
+
+ streamTarget
+ = new MediaStreamTarget(
+ new InetSocketAddress(host, rtpPort),
+ new InetSocketAddress(host, rtcpPort));
+ }
+ }
+ }
+ return streamTarget;
+ }
+
+ /**
+ * Implements {@link TransportManagerJabberImpl#getXmlNamespace()}. Gets the
+ * XML namespace of the Jingle transport implemented by this
+ * <tt>TransportManagerJabberImpl</tt>.
+ *
+ * @return the XML namespace of the Jingle transport implemented by this
+ * <tt>TransportManagerJabberImpl</tt>
+ * @see TransportManagerJabberImpl#getXmlNamespace()
+ */
+ @Override
+ public String getXmlNamespace()
+ {
+ return ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_RAW_UDP_0;
+ }
+
+ /**
+ * Removes a content with a specific name from the transport-related part of
+ * the session represented by this <tt>TransportManagerJabberImpl</tt> which
+ * may have been reported through previous calls to the
+ * <tt>startCandidateHarvest</tt> and
+ * <tt>startConnectivityEstablishment</tt> methods.
+ *
+ * @param name the name of the content to be removed from the
+ * transport-related part of the session represented by this
+ * <tt>TransportManagerJabberImpl</tt>
+ * @see TransportManagerJabberImpl#removeContent(String)
+ */
+ @Override
+ public void removeContent(String name)
+ {
+ if (local != null)
+ removeContent(local, name);
+
+ removeRemoteContent(name);
+ }
+
+ /**
+ * Removes a content with a specific name from the remote counterpart of the
+ * negotiation between the local and the remote peers.
+ *
+ * @param name the name of the content to be removed from the remote
+ * counterpart of the negotiation between the local and the remote peers
+ */
+ private void removeRemoteContent(String name)
+ {
+ for (Iterator<Iterable<ContentPacketExtension>> remoteIter
+ = remotes.iterator();
+ remoteIter.hasNext();)
+ {
+ Iterable<ContentPacketExtension> remote = remoteIter.next();
+
+ /*
+ * Once the remote content is removed, make sure that we are not
+ * retaining sets which do not have any contents.
+ */
+ if ((removeContent(remote, name) != null)
+ && !remote.iterator().hasNext())
+ {
+ remoteIter.remove();
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected PacketExtension startCandidateHarvest(
+ ContentPacketExtension theirContent,
+ ContentPacketExtension ourContent,
+ TransportInfoSender transportInfoSender,
+ String media)
+ throws OperationFailedException
+ {
+ return createTransportForStartCandidateHarvest(media);
+ }
+
+ /**
+ * Starts transport candidate harvest. This method should complete rapidly
+ * and, in case of lengthy procedures like STUN/TURN/UPnP candidate harvests
+ * are necessary, they should be executed in a separate thread. Candidate
+ * harvest would then need to be concluded in the
+ * {@link #wrapupCandidateHarvest()} method which would be called once we
+ * absolutely need the candidates.
+ *
+ * @param theirOffer a media description offer that we've received from the
+ * remote party and that we should use in case we need to know what
+ * transports our peer is using.
+ * @param ourAnswer the content descriptions that we should be adding our
+ * transport lists to (although not necessarily in this very instance).
+ * @param transportInfoSender the <tt>TransportInfoSender</tt> to be used by
+ * this <tt>TransportManagerJabberImpl</tt> to send <tt>transport-info</tt>
+ * <tt>JingleIQ</tt>s from the local peer to the remote peer if this
+ * <tt>TransportManagerJabberImpl</tt> wishes to utilize
+ * <tt>transport-info</tt>. Local candidate addresses sent by this
+ * <tt>TransportManagerJabberImpl</tt> in <tt>transport-info</tt> are
+ * expected to not be included in the result of
+ * {@link #wrapupCandidateHarvest()}.
+ *
+ * @throws OperationFailedException if we fail to allocate a port number.
+ * @see TransportManagerJabberImpl#startCandidateHarvest(List, List,
+ * TransportInfoSender)
+ */
+ @Override
+ public void startCandidateHarvest(
+ List<ContentPacketExtension> theirOffer,
+ List<ContentPacketExtension> ourAnswer,
+ TransportInfoSender transportInfoSender)
+ throws OperationFailedException
+ {
+ this.local = ourAnswer;
+
+ super.startCandidateHarvest(theirOffer, ourAnswer, transportInfoSender);
+ }
+
+ /**
+ * Overrides the super implementation in order to remember the remote
+ * counterpart of the negotiation between the local and the remote peer for
+ * subsequent calls to {@link #getStreamTarget(MediaType)}.
+ *
+ * @param remote the collection of <tt>ContentPacketExtension</tt>s which
+ * represents the remote counterpart of the negotiation between the local
+ * and the remote peer
+ * @return <tt>true</tt> because <tt>RawUdpTransportManager</tt> does not
+ * perform connectivity checks
+ * @see TransportManagerJabberImpl#startConnectivityEstablishment(Iterable)
+ */
+ @Override
+ public boolean startConnectivityEstablishment(
+ Iterable<ContentPacketExtension> remote)
+ {
+ if ((remote != null) && !remotes.contains(remote))
+ {
+ /*
+ * The state of the session in Jingle is maintained by each peer and
+ * is modified by content-add and content-remove. The remotes field
+ * of this RawUdpTransportManager represents the state of the
+ * session with respect to the remote peer. When the remote peer
+ * tells us about a specific set of contents, make sure that it is
+ * the only record we will have with respect to the specified set of
+ * contents.
+ */
+ for (ContentPacketExtension content : remote)
+ removeRemoteContent(content.getName());
+
+ remotes.add(remote);
+ }
+
+ return super.startConnectivityEstablishment(remote);
+ }
+
+ /**
+ * Simply returns the list of local candidates that we gathered during the
+ * harvest. This is a raw UDP transport manager so there's no real wrapping
+ * up to do.
+ *
+ * @return the list of local candidates that we gathered during the harvest
+ * @see TransportManagerJabberImpl#wrapupCandidateHarvest()
+ */
+ @Override
+ public List<ContentPacketExtension> wrapupCandidateHarvest()
+ {
+ return local;
+ }
+
+ /**
+ * Returns the extended type of the candidate selected if this transport
+ * manager is using ICE.
+ *
+ * @param streamName The stream name (AUDIO, VIDEO);
+ *
+ * @return The extended type of the candidate selected if this transport
+ * manager is using ICE. Otherwise, returns null.
+ */
+ @Override
+ public String getICECandidateExtendedType(String streamName)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the current state of ICE processing.
+ *
+ * @return the current state of ICE processing.
+ */
+ @Override
+ public String getICEState()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the ICE local host address.
+ *
+ * @param streamName The stream name (AUDIO, VIDEO);
+ *
+ * @return the ICE local host address if this transport
+ * manager is using ICE. Otherwise, returns null.
+ */
+ @Override
+ public InetSocketAddress getICELocalHostAddress(String streamName)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the ICE remote host address.
+ *
+ * @param streamName The stream name (AUDIO, VIDEO);
+ *
+ * @return the ICE remote host address if this transport
+ * manager is using ICE. Otherwise, returns null.
+ */
+ @Override
+ public InetSocketAddress getICERemoteHostAddress(String streamName)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the ICE local reflexive address (server or peer reflexive).
+ *
+ * @param streamName The stream name (AUDIO, VIDEO);
+ *
+ * @return the ICE local reflexive address. May be null if this transport
+ * manager is not using ICE or if there is no reflexive address for the
+ * local candidate used.
+ */
+ @Override
+ public InetSocketAddress getICELocalReflexiveAddress(String streamName)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the ICE remote reflexive address (server or peer reflexive).
+ *
+ * @param streamName The stream name (AUDIO, VIDEO);
+ *
+ * @return the ICE remote reflexive address. May be null if this transport
+ * manager is not using ICE or if there is no reflexive address for the
+ * remote candidate used.
+ */
+ @Override
+ public InetSocketAddress getICERemoteReflexiveAddress(String streamName)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the ICE local relayed address (server or peer relayed).
+ *
+ * @param streamName The stream name (AUDIO, VIDEO);
+ *
+ * @return the ICE local relayed address. May be null if this transport
+ * manager is not using ICE or if there is no relayed address for the
+ * local candidate used.
+ */
+ @Override
+ public InetSocketAddress getICELocalRelayedAddress(String streamName)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the ICE remote relayed address (server or peer relayed).
+ *
+ * @param streamName The stream name (AUDIO, VIDEO);
+ *
+ * @return the ICE remote relayed address. May be null if this transport
+ * manager is not using ICE or if there is no relayed address for the
+ * remote candidate used.
+ */
+ @Override
+ public InetSocketAddress getICERemoteRelayedAddress(String streamName)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the total harvesting time (in ms) for all harvesters.
+ *
+ * @return The total harvesting time (in ms) for all the harvesters. 0 if
+ * the ICE agent is null, or if the agent has nevers harvested.
+ */
+ @Override
+ public long getTotalHarvestingTime()
+ {
+ return 0;
+ }
+
+ /**
+ * Returns the harvesting time (in ms) for the harvester given in parameter.
+ *
+ * @param harvesterName The class name if the harvester.
+ *
+ * @return The harvesting time (in ms) for the harvester given in parameter.
+ * 0 if this harvester does not exists, if the ICE agent is null, or if the
+ * agent has never harvested with this harvester.
+ */
+ @Override
+ public long getHarvestingTime(String harvesterName)
+ {
+ return 0;
+ }
+
+ /**
+ * Returns the number of harvesting for this agent.
+ *
+ * @return The number of harvesting for this agent.
+ */
+ @Override
+ public int getNbHarvesting()
+ {
+ return 0;
+ }
+
+ /**
+ * Returns the number of harvesting time for the harvester given in
+ * parameter.
+ *
+ * @param harvesterName The class name if the harvester.
+ *
+ * @return The number of harvesting time for the harvester given in
+ * parameter.
+ */
+ @Override
+ public int getNbHarvesting(String harvesterName)
+ {
+ return 0;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ScServiceDiscoveryManager.java b/src/net/java/sip/communicator/impl/protocol/jabber/ScServiceDiscoveryManager.java
index 9fdbea5..de2ce3e 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/ScServiceDiscoveryManager.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/ScServiceDiscoveryManager.java
@@ -27,6 +27,7 @@ import net.java.sip.communicator.util.*;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.filter.*;
import org.jivesoftware.smack.packet.*;
+import org.jivesoftware.smack.util.*;
import org.jivesoftware.smackx.*;
import org.jivesoftware.smackx.packet.*;
@@ -79,9 +80,9 @@ public class ScServiceDiscoveryManager
private final ProtocolProviderService parentProvider;
/**
- * The {@link XMPPConnection} that this manager is responsible for.
+ * The {@link Connection} that this manager is responsible for.
*/
- private final XMPPConnection connection;
+ private final Connection connection;
/**
* A local copy that we keep in sync with {@link ServiceDiscoveryManager}'s
@@ -129,7 +130,7 @@ public class ScServiceDiscoveryManager
*/
public ScServiceDiscoveryManager(
ProtocolProviderService parentProvider,
- XMPPConnection connection,
+ Connection connection,
String[] featuresToRemove,
String[] featuresToAdd,
boolean cacheNonCaps)
@@ -791,7 +792,11 @@ public class ScServiceDiscoveryManager
// fire event
if(fireEvent && capabilitiesOpSet != null)
{
- capabilitiesOpSet.fireContactCapabilitiesChanged(entityID);
+ capabilitiesOpSet.fireContactCapabilitiesChanged(
+ entityID,
+ capsManager.getFullJidsByBareJid(
+ StringUtils.parseBareAddress(entityID))
+ );
}
}
catch(XMPPException ex)
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/SmackV3InteroperabilityLayer.java b/src/net/java/sip/communicator/impl/protocol/jabber/SmackV3InteroperabilityLayer.java
new file mode 100644
index 0000000..d5af26f
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/SmackV3InteroperabilityLayer.java
@@ -0,0 +1,91 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.protocol.jabber;
+
+import net.java.sip.communicator.service.protocol.jabber.*;
+import org.jivesoftware.smack.provider.*;
+
+/**
+ * Smack v3 interoperation layer
+ *
+ * @author Maksym Kulish
+ */
+public class SmackV3InteroperabilityLayer
+ extends AbstractSmackInteroperabilityLayer
+{
+
+ /**
+ * A SmackV3 ProviderManager instance
+ */
+ private ProviderManager providerManager = ProviderManager.getInstance();
+
+ /**
+ * A default constructor
+ */
+ public SmackV3InteroperabilityLayer() {}
+
+ /**
+ * Add <tt>PacketExtensionProvider</tt> to the list of known
+ * providers
+ *
+ * @param elementName The element name where the matching is happening
+ * @param namespace The XML namespace used in that element
+ * @param provider <tt>PacketExtensionProvider</tt> implementation to be
+ * used
+ */
+ @Override
+ public void addExtensionProvider(
+ String elementName, String namespace, Object provider)
+ {
+ providerManager.addExtensionProvider(elementName, namespace, provider);
+ }
+
+ /**
+ * Add <tt>IQProvider</tt> to the list of known
+ * providers
+ *
+ * @param elementName The element name where the matching is happening
+ * @param namespace The XML namespace used in that element
+ * @param provider <tt>IQProvider</tt> implementation to be
+ * used
+ */
+ @Override
+ public void addIQProvider(
+ String elementName, String namespace, Object provider)
+ {
+ providerManager.addIQProvider(elementName, namespace, provider);
+ }
+
+ /**
+ * Get the <tt>PacketExtensionProvider</tt> for given element name and XML
+ * namespace
+ *
+ * @param elementName The element name where the matching is happening
+ * @param namespace The XML namespace used in that element
+ * @return <tt>PacketExtensionProvider</tt> implementation to be
+ * used
+ */
+ @Override
+ public PacketExtensionProvider getExtensionProvider(
+ String elementName, String namespace)
+ {
+ return (PacketExtensionProvider)providerManager
+ .getExtensionProvider(elementName, namespace);
+ }
+
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/TransportManagerJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/TransportManagerJabberImpl.java
index f7f47c6..41e8c05 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/TransportManagerJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/TransportManagerJabberImpl.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,963 +15,963 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.protocol.jabber;
-
-import java.net.*;
-import java.util.*;
-
-import net.java.sip.communicator.impl.protocol.jabber.extensions.colibri.*;
-import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
-import net.java.sip.communicator.impl.protocol.jabber.jinglesdp.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.media.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.neomedia.*;
-import org.jivesoftware.smack.packet.*;
-
-/**
- * <tt>TransportManager</tt>s gather local candidates for incoming and outgoing
- * calls. Their work starts by calling a start method which, using the remote
- * peer's session description, would start the harvest. Calling a second wrapup
- * method would deliver the candidate harvest, possibly after blocking if it has
- * not yet completed.
- *
- * @author Emil Ivov
- * @author Lyubomir Marinov
- */
-public abstract class TransportManagerJabberImpl
- extends TransportManager<CallPeerJabberImpl>
-{
- /**
- * The <tt>Logger</tt> used by the <tt>TransportManagerJabberImpl</tt> class
- * and its instances to print debug messages.
- */
- private static final Logger logger
- = Logger.getLogger(TransportManagerJabberImpl.class);
-
- /**
- * The ID that we will be assigning to our next candidate. We use
- * <tt>int</tt>s for interoperability reasons (Emil: I believe that GTalk
- * uses <tt>int</tt>s. If that turns out not to be the case we can stop
- * using <tt>int</tt>s here if that's an issue).
- */
- private static int nextID = 1;
-
- /**
- * The information pertaining to the Jisti Videobridge conference which the
- * local peer represented by this instance is a focus of. It gives a view of
- * the whole Jitsi Videobridge conference managed by the associated
- * <tt>CallJabberImpl</tt> which provides information specific to this
- * <tt>TransportManager</tt> only.
- */
- private ColibriConferenceIQ colibri;
-
- /**
- * The generation of the candidates we are currently generating
- */
- private int currentGeneration = 0;
-
- /**
- * The indicator which determines whether this <tt>TransportManager</tt>
- * instance is responsible to establish the connectivity with the associated
- * Jitsi Videobridge (in case it is being employed at all).
- */
- boolean isEstablishingConnectivityWithJitsiVideobridge = false;
-
- /**
- * The indicator which determines whether this <tt>TransportManager</tt>
- * instance is yet to start establishing the connectivity with the
- * associated Jitsi Videobridge (in case it is being employed at all).
- */
- boolean startConnectivityEstablishmentWithJitsiVideobridge = false;
-
- /**
- * Creates a new instance of this transport manager, binding it to the
- * specified peer.
- *
- * @param callPeer the {@link CallPeer} whose traffic we will be taking
- * care of.
- */
- protected TransportManagerJabberImpl(CallPeerJabberImpl callPeer)
- {
- super(callPeer);
- }
-
- /**
- * Returns the <tt>InetAddress</tt> that is most likely to be to be used
- * as a next hop when contacting the specified <tt>destination</tt>. This is
- * an utility method that is used whenever we have to choose one of our
- * local addresses to put in the Via, Contact or (in the case of no
- * registrar accounts) From headers.
- *
- * @param peer the CallPeer that we would contact.
- *
- * @return the <tt>InetAddress</tt> that is most likely to be to be used
- * as a next hop when contacting the specified <tt>destination</tt>.
- *
- * @throws IllegalArgumentException if <tt>destination</tt> is not a valid
- * host/IP/FQDN
- */
- @Override
- protected InetAddress getIntendedDestination(CallPeerJabberImpl peer)
- {
- return peer.getProtocolProvider().getNextHop();
- }
-
- /**
- * Returns the ID that we will be assigning to the next candidate we create.
- *
- * @return the next ID to use with a candidate.
- */
- protected String getNextID()
- {
- int nextID;
-
- synchronized (TransportManagerJabberImpl.class)
- {
- nextID = TransportManagerJabberImpl.nextID++;
- }
- return Integer.toString(nextID);
- }
-
- /**
- * Gets the <tt>MediaStreamTarget</tt> to be used as the <tt>target</tt> of
- * the <tt>MediaStream</tt> with a specific <tt>MediaType</tt>.
- *
- * @param mediaType the <tt>MediaType</tt> of the <tt>MediaStream</tt> which
- * is to have its <tt>target</tt> set to the returned
- * <tt>MediaStreamTarget</tt>
- * @return the <tt>MediaStreamTarget</tt> to be used as the <tt>target</tt>
- * of the <tt>MediaStream</tt> with the specified <tt>MediaType</tt>
- */
- public abstract MediaStreamTarget getStreamTarget(MediaType mediaType);
-
- /**
- * Gets the XML namespace of the Jingle transport implemented by this
- * <tt>TransportManagerJabberImpl</tt>.
- *
- * @return the XML namespace of the Jingle transport implemented by this
- * <tt>TransportManagerJabberImpl</tt>
- */
- public abstract String getXmlNamespace();
-
- /**
- * Returns the generation that our current candidates belong to.
- *
- * @return the generation that we should assign to candidates that we are
- * currently advertising.
- */
- protected int getCurrentGeneration()
- {
- return currentGeneration;
- }
-
- /**
- * Increments the generation that we are assigning candidates.
- */
- protected void incrementGeneration()
- {
- currentGeneration++;
- }
-
- /**
- * Sends transport-related information received from the remote peer to the
- * associated Jiitsi Videobridge in order to update the (remote)
- * <tt>ColibriConferenceIQ.Channel</tt> associated with this
- * <tt>TransportManager</tt> instance.
- *
- * @param map a <tt>Map</tt> of media-IceUdpTransportPacketExtension pairs
- * which represents the transport-related information which has been
- * received from the remote peer and which is to be sent to the associated
- * Jitsi Videobridge
- */
- protected void sendTransportInfoToJitsiVideobridge(
- Map<String,IceUdpTransportPacketExtension> map)
- {
- CallPeerJabberImpl peer = getCallPeer();
- boolean initiator = !peer.isInitiator();
- ColibriConferenceIQ conferenceRequest = null;
-
- for (Map.Entry<String,IceUdpTransportPacketExtension> e
- : map.entrySet())
- {
- String media = e.getKey();
- MediaType mediaType = MediaType.parseString(media);
- ColibriConferenceIQ.Channel channel
- = getColibriChannel(mediaType, false /* remote */);
-
- if (channel != null)
- {
- IceUdpTransportPacketExtension transport;
-
- try
- {
- transport = cloneTransportAndCandidates(e.getValue());
- }
- catch (OperationFailedException ofe)
- {
- transport = null;
- }
- if (transport == null)
- continue;
-
- ColibriConferenceIQ.Channel channelRequest
- = new ColibriConferenceIQ.Channel();
-
- channelRequest.setID(channel.getID());
- channelRequest.setInitiator(initiator);
- channelRequest.setTransport(transport);
-
- if (conferenceRequest == null)
- {
- if (colibri == null)
- break;
- else
- {
- String id = colibri.getID();
-
- if ((id == null) || (id.length() == 0))
- break;
- else
- {
- conferenceRequest = new ColibriConferenceIQ();
- conferenceRequest.setID(id);
- conferenceRequest.setTo(colibri.getFrom());
- conferenceRequest.setType(IQ.Type.SET);
- }
- }
- }
- conferenceRequest.getOrCreateContent(media).addChannel(
- channelRequest);
- }
- }
- if (conferenceRequest != null)
- {
- peer.getProtocolProvider().getConnection().sendPacket(
- conferenceRequest);
- }
- }
-
- /**
- * Starts transport candidate harvest for a specific
- * <tt>ContentPacketExtension</tt> that we are going to offer or answer
- * with.
- *
- * @param theirContent the <tt>ContentPacketExtension</tt> offered by the
- * remote peer to which we are going to answer with <tt>ourContent</tt> or
- * <tt>null</tt> if <tt>ourContent</tt> will be an offer to the remote peer
- * @param ourContent the <tt>ContentPacketExtension</tt> for which transport
- * candidate harvest is to be started
- * @param transportInfoSender a <tt>TransportInfoSender</tt> if the
- * harvested transport candidates are to be sent in a
- * <tt>transport-info</tt> rather than in <tt>ourContent</tt>; otherwise,
- * <tt>null</tt>
- * @param media the media of the <tt>RtpDescriptionPacketExtension</tt>
- * child of <tt>ourContent</tt>
- * @return a <tt>PacketExtension</tt> to be added as a child to
- * <tt>ourContent</tt>; otherwise, <tt>null</tt>
- * @throws OperationFailedException if anything goes wrong while starting
- * transport candidate harvest for the specified <tt>ourContent</tt>
- */
- protected abstract PacketExtension startCandidateHarvest(
- ContentPacketExtension theirContent,
- ContentPacketExtension ourContent,
- TransportInfoSender transportInfoSender,
- String media)
- throws OperationFailedException;
-
- /**
- * Starts transport candidate harvest. This method should complete rapidly
- * and, in case of lengthy procedures like STUN/TURN/UPnP candidate harvests
- * are necessary, they should be executed in a separate thread. Candidate
- * harvest would then need to be concluded in the
- * {@link #wrapupCandidateHarvest()} method which would be called once we
- * absolutely need the candidates.
- *
- * @param theirOffer a media description offer that we've received from the
- * remote party and that we should use in case we need to know what
- * transports our peer is using.
- * @param ourAnswer the content descriptions that we should be adding our
- * transport lists to (although not necessarily in this very instance).
- * @param transportInfoSender the <tt>TransportInfoSender</tt> to be used by
- * this <tt>TransportManagerJabberImpl</tt> to send <tt>transport-info</tt>
- * <tt>JingleIQ</tt>s from the local peer to the remote peer if this
- * <tt>TransportManagerJabberImpl</tt> wishes to utilize
- * <tt>transport-info</tt>. Local candidate addresses sent by this
- * <tt>TransportManagerJabberImpl</tt> in <tt>transport-info</tt> are
- * expected to not be included in the result of
- * {@link #wrapupCandidateHarvest()}.
- *
- * @throws OperationFailedException if we fail to allocate a port number.
- */
- public void startCandidateHarvest(
- List<ContentPacketExtension> theirOffer,
- List<ContentPacketExtension> ourAnswer,
- TransportInfoSender transportInfoSender)
- throws OperationFailedException
- {
- CallPeerJabberImpl peer = getCallPeer();
- CallJabberImpl call = peer.getCall();
- boolean isJitsiVideobridge = call.getConference().isJitsiVideobridge();
- List<ContentPacketExtension> cpes
- = (theirOffer == null) ? ourAnswer : theirOffer;
-
- /*
- * If Jitsi Videobridge is to be used, determine which channels are to
- * be allocated and attempt to allocate them now.
- */
- if (isJitsiVideobridge)
- {
- Map<ContentPacketExtension,ContentPacketExtension> contentMap
- = new LinkedHashMap
- <ContentPacketExtension,ContentPacketExtension>();
-
- for (ContentPacketExtension cpe : cpes)
- {
- MediaType mediaType = JingleUtils.getMediaType(cpe);
-
- /*
- * The existence of a content for the mediaType and regardless
- * of the existence of channels in it signals that a channel
- * allocation request has already been sent for that mediaType.
- */
- if ((colibri == null)
- || (colibri.getContent(mediaType.toString()) == null))
- {
- ContentPacketExtension local, remote;
-
- if (cpes == ourAnswer)
- {
- local = cpe;
- remote
- = (theirOffer == null)
- ? null
- : findContentByName(theirOffer, cpe.getName());
- }
- else
- {
- local = findContentByName(ourAnswer, cpe.getName());
- remote = cpe;
- }
- contentMap.put(local, remote);
- }
- }
- if (!contentMap.isEmpty())
- {
- /*
- * We are about to request the channel allocations for the media
- * types found in contentMap. Regardless of the response, we do
- * not want to repeat these requests.
- */
- if (colibri == null)
- colibri = new ColibriConferenceIQ();
- for (Map.Entry<ContentPacketExtension,ContentPacketExtension> e
- : contentMap.entrySet())
- {
- ContentPacketExtension cpe = e.getValue();
-
- if (cpe == null)
- cpe = e.getKey();
-
- colibri.getOrCreateContent(
- JingleUtils.getMediaType(cpe).toString());
- }
-
- ColibriConferenceIQ conferenceResult
- = call.createColibriChannels(peer, contentMap);
-
- if (conferenceResult != null)
- {
- String videobridgeID = colibri.getID();
- String conferenceResultID = conferenceResult.getID();
-
- if (videobridgeID == null)
- colibri.setID(conferenceResultID);
- else if (!videobridgeID.equals(conferenceResultID))
- throw new IllegalStateException("conference.id");
-
- String videobridgeFrom = conferenceResult.getFrom();
-
- if ((videobridgeFrom != null)
- && (videobridgeFrom.length() != 0))
- {
- colibri.setFrom(videobridgeFrom);
- }
-
- for (ColibriConferenceIQ.Content contentResult
- : conferenceResult.getContents())
- {
- ColibriConferenceIQ.Content content
- = colibri.getOrCreateContent(
- contentResult.getName());
-
- for (ColibriConferenceIQ.Channel channelResult
- : contentResult.getChannels())
- {
- if (content.getChannel(channelResult.getID())
- == null)
- {
- content.addChannel(channelResult);
- }
- }
- }
- }
- else
- {
- /*
- * The call fails if the createColibriChannels method fails
- * which may happen if the conference packet times out or it
- * can't be built.
- */
- ProtocolProviderServiceJabberImpl
- .throwOperationFailedException(
- "Failed to allocate colibri channel.",
- OperationFailedException.GENERAL_ERROR,
- null,
- logger);
- }
- }
- }
-
- for (ContentPacketExtension cpe : cpes)
- {
- String contentName = cpe.getName();
- ContentPacketExtension ourContent
- = findContentByName(ourAnswer, contentName);
-
- //it might be that we decided not to reply to this content
- if (ourContent != null)
- {
- ContentPacketExtension theirContent
- = (theirOffer == null)
- ? null
- : findContentByName(theirOffer, contentName);
- RtpDescriptionPacketExtension rtpDesc
- = ourContent.getFirstChildOfType(
- RtpDescriptionPacketExtension.class);
- String media = rtpDesc.getMedia();
- PacketExtension pe
- = startCandidateHarvest(
- theirContent,
- ourContent,
- transportInfoSender,
- media);
-
- if (pe != null)
- ourContent.addChildExtension(pe);
- }
- }
- }
-
- /**
- * Starts transport candidate harvest. This method should complete rapidly
- * and, in case of lengthy procedures like STUN/TURN/UPnP candidate harvests
- * are necessary, they should be executed in a separate thread. Candidate
- * harvest would then need to be concluded in the
- * {@link #wrapupCandidateHarvest()} method which would be called once we
- * absolutely need the candidates.
- *
- * @param ourOffer the content descriptions that we should be adding our
- * transport lists to (although not necessarily in this very instance).
- * @param transportInfoSender the <tt>TransportInfoSender</tt> to be used by
- * this <tt>TransportManagerJabberImpl</tt> to send <tt>transport-info</tt>
- * <tt>JingleIQ</tt>s from the local peer to the remote peer if this
- * <tt>TransportManagerJabberImpl</tt> wishes to utilize
- * <tt>transport-info</tt>. Local candidate addresses sent by this
- * <tt>TransportManagerJabberImpl</tt> in <tt>transport-info</tt> are
- * expected to not be included in the result of
- * {@link #wrapupCandidateHarvest()}.
- * @throws OperationFailedException if we fail to allocate a port number.
- */
- public void startCandidateHarvest(
- List<ContentPacketExtension> ourOffer,
- TransportInfoSender transportInfoSender)
- throws OperationFailedException
- {
- startCandidateHarvest(
- /* theirOffer */ null,
- ourOffer,
- transportInfoSender);
- }
-
- /**
- * Notifies the transport manager that it should conclude candidate
- * harvesting as soon as possible and return the lists of candidates
- * gathered so far.
- *
- * @return the content list that we received earlier (possibly cloned into
- * a new instance) and that we have updated with transport lists.
- */
- public abstract List<ContentPacketExtension> wrapupCandidateHarvest();
-
- /**
- * Looks through the <tt>cpExtList</tt> and returns the {@link
- * ContentPacketExtension} with the specified name.
- *
- * @param cpExtList the list that we will be searching for a specific
- * content.
- * @param name the name of the content element we are looking for.
- * @return the {@link ContentPacketExtension} with the specified name or
- * <tt>null</tt> if no such content element exists.
- */
- public static ContentPacketExtension findContentByName(
- Iterable<ContentPacketExtension> cpExtList,
- String name)
- {
- for(ContentPacketExtension cpExt : cpExtList)
- {
- if(cpExt.getName().equals(name))
- return cpExt;
- }
- return null;
- }
-
- /**
- * Starts the connectivity establishment of this
- * <tt>TransportManagerJabberImpl</tt> i.e. checks the connectivity between
- * the local and the remote peers given the remote counterpart of the
- * negotiation between them.
- *
- * @param remote the collection of <tt>ContentPacketExtension</tt>s which
- * represents the remote counterpart of the negotiation between the local
- * and the remote peer
- * @return <tt>true</tt> if connectivity establishment has been started in
- * response to the call; otherwise, <tt>false</tt>.
- * <tt>TransportManagerJabberImpl</tt> implementations which do not perform
- * connectivity checks (e.g. raw UDP) should return <tt>true</tt>. The
- * default implementation does not perform connectivity checks and always
- * returns <tt>true</tt>.
- */
- public boolean startConnectivityEstablishment(
- Iterable<ContentPacketExtension> remote)
- {
- return true;
- }
-
- /**
- * Starts the connectivity establishment of this
- * <tt>TransportManagerJabberImpl</tt> i.e. checks the connectivity between
- * the local and the remote peers given the remote counterpart of the
- * negotiation between them.
- *
- * @param remote a <tt>Map</tt> of
- * media-<tt>IceUdpTransportPacketExtension</tt> pairs which represents the
- * remote counterpart of the negotiation between the local and the remote
- * peers
- * @return <tt>true</tt> if connectivity establishment has been started in
- * response to the call; otherwise, <tt>false</tt>.
- * <tt>TransportManagerJabberImpl</tt> implementations which do not perform
- * connectivity checks (e.g. raw UDP) should return <tt>true</tt>. The
- * default implementation does not perform connectivity checks and always
- * returns <tt>true</tt>.
- */
- protected boolean startConnectivityEstablishment(
- Map<String,IceUdpTransportPacketExtension> remote)
- {
- return true;
- }
-
- /**
- * Notifies this <tt>TransportManagerJabberImpl</tt> that it should conclude
- * any started connectivity establishment.
- *
- * @throws OperationFailedException if anything goes wrong with connectivity
- * establishment (i.e. ICE failed, ...)
- */
- public void wrapupConnectivityEstablishment()
- throws OperationFailedException
- {
- }
-
- /**
- * Removes a content with a specific name from the transport-related part of
- * the session represented by this <tt>TransportManagerJabberImpl</tt> which
- * may have been reported through previous calls to the
- * <tt>startCandidateHarvest</tt> and
- * <tt>startConnectivityEstablishment</tt> methods.
- * <p>
- * <b>Note</b>: Because <tt>TransportManager</tt> deals with
- * <tt>MediaType</tt>s, not content names and
- * <tt>TransportManagerJabberImpl</tt> does not implement translating from
- * content name to <tt>MediaType</tt>, implementers are expected to call
- * {@link TransportManager#closeStreamConnector(MediaType)}.
- * </p>
- *
- * @param name the name of the content to be removed from the
- * transport-related part of the session represented by this
- * <tt>TransportManagerJabberImpl</tt>
- */
- public abstract void removeContent(String name);
-
- /**
- * Removes a content with a specific name from a specific collection of
- * contents and closes any associated <tt>StreamConnector</tt>.
- *
- * @param contents the collection of contents to remove the content with the
- * specified name from
- * @param name the name of the content to remove
- * @return the removed <tt>ContentPacketExtension</tt> if any; otherwise,
- * <tt>null</tt>
- */
- protected ContentPacketExtension removeContent(
- Iterable<ContentPacketExtension> contents,
- String name)
- {
- for (Iterator<ContentPacketExtension> contentIter = contents.iterator();
- contentIter.hasNext();)
- {
- ContentPacketExtension content = contentIter.next();
-
- if (name.equals(content.getName()))
- {
- contentIter.remove();
-
- // closeStreamConnector
- MediaType mediaType = JingleUtils.getMediaType(content);
- if (mediaType != null)
- {
- closeStreamConnector(mediaType);
- }
-
- return content;
- }
- }
- return null;
- }
-
- /**
- * Clones a specific <tt>IceUdpTransportPacketExtension</tt> and its
- * candidates.
- *
- * @param src the <tt>IceUdpTransportPacketExtension</tt> to be cloned
- * @return a new <tt>IceUdpTransportPacketExtension</tt> instance which has
- * the same run-time type, attributes, namespace, text and candidates as the
- * specified <tt>src</tt>
- * @throws OperationFailedException if an error occurs during the cloing of
- * the specified <tt>src</tt> and its candidates
- */
- static IceUdpTransportPacketExtension cloneTransportAndCandidates(
- IceUdpTransportPacketExtension src)
- throws OperationFailedException
- {
- try
- {
- return IceUdpTransportPacketExtension
- .cloneTransportAndCandidates(src);
- }
- catch (Exception e)
- {
- ProtocolProviderServiceJabberImpl
- .throwOperationFailedException(
- "Failed to close transport and candidates.",
- OperationFailedException.GENERAL_ERROR,
- e,
- logger);
-
- }
- return null;
- }
-
- /**
- * Releases the resources acquired by this <tt>TransportManager</tt> and
- * prepares it for garbage collection.
- */
- public void close()
- {
- for (MediaType mediaType : MediaType.values())
- closeStreamConnector(mediaType);
- }
-
- /**
- * Closes a specific <tt>StreamConnector</tt> associated with a specific
- * <tt>MediaType</tt>. If this <tt>TransportManager</tt> has a reference to
- * the specified <tt>streamConnector</tt>, it remains.
- * Also expires the <tt>ColibriConferenceIQ.Channel</tt> associated with
- * the closed <tt>StreamConnector</tt>.
- *
- * @param mediaType the <tt>MediaType</tt> associated with the specified
- * <tt>streamConnector</tt>
- * @param streamConnector the <tt>StreamConnector</tt> to be closed
- */
- @Override
- protected void closeStreamConnector(
- MediaType mediaType,
- StreamConnector streamConnector)
- {
- try
- {
- boolean superCloseStreamConnector = true;
-
- if (streamConnector instanceof ColibriStreamConnector)
- {
- CallPeerJabberImpl peer = getCallPeer();
-
- if (peer != null)
- {
- CallJabberImpl call = peer.getCall();
-
- if (call != null)
- {
- superCloseStreamConnector = false;
- call.closeColibriStreamConnector(
- peer,
- mediaType,
- (ColibriStreamConnector) streamConnector);
- }
- }
- }
- if (superCloseStreamConnector)
- super.closeStreamConnector(mediaType, streamConnector);
- }
- finally
- {
- /*
- * Expire the ColibriConferenceIQ.Channel associated with the closed
- * StreamConnector.
- */
- if (colibri != null)
- {
- ColibriConferenceIQ.Content content
- = colibri.getContent(mediaType.toString());
-
- if (content != null)
- {
- List<ColibriConferenceIQ.Channel> channels
- = content.getChannels();
-
- if (channels.size() == 2)
- {
- ColibriConferenceIQ requestConferenceIQ
- = new ColibriConferenceIQ();
-
- requestConferenceIQ.setID(colibri.getID());
-
- ColibriConferenceIQ.Content requestContent
- = requestConferenceIQ.getOrCreateContent(
- content.getName());
-
- requestContent.addChannel(channels.get(1 /* remote */));
-
- /*
- * Regardless of whether the request to expire the
- * Channel associated with mediaType succeeds, consider
- * the Channel in question expired. Since
- * RawUdpTransportManager allocates a single channel per
- * MediaType, consider the whole Content expired.
- */
- colibri.removeContent(content);
-
- CallPeerJabberImpl peer = getCallPeer();
-
- if (peer != null)
- {
- CallJabberImpl call = peer.getCall();
-
- if (call != null)
- {
- call.expireColibriChannels(
- peer,
- requestConferenceIQ);
- }
- }
- }
- }
- }
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * Adds support for telephony conferences utilizing the Jitsi Videobridge
- * server-side technology.
- *
- * @see #doCreateStreamConnector(MediaType)
- */
- @Override
- protected StreamConnector createStreamConnector(final MediaType mediaType)
- throws OperationFailedException
- {
- ColibriConferenceIQ.Channel channel
- = getColibriChannel(mediaType, true /* local */);
-
- if (channel != null)
- {
- CallPeerJabberImpl peer = getCallPeer();
- CallJabberImpl call = peer.getCall();
- StreamConnector streamConnector
- = call.createColibriStreamConnector(
- peer,
- mediaType,
- channel,
- new StreamConnectorFactory()
- {
- public StreamConnector createStreamConnector()
- {
- try
- {
- return doCreateStreamConnector(mediaType);
- }
- catch (OperationFailedException ofe)
- {
- return null;
- }
- }
- });
-
- if (streamConnector != null)
- return streamConnector;
- }
-
- return doCreateStreamConnector(mediaType);
- }
-
- protected abstract PacketExtension createTransport(String media)
- throws OperationFailedException;
-
- protected PacketExtension createTransportForStartCandidateHarvest(
- String media)
- throws OperationFailedException
- {
- PacketExtension pe = null;
-
- if (getCallPeer().isJitsiVideobridge())
- {
- MediaType mediaType = MediaType.parseString(media);
- ColibriConferenceIQ.Channel channel
- = getColibriChannel(mediaType, false /* remote */);
-
- if (channel != null)
- pe = cloneTransportAndCandidates(channel.getTransport());
- }
- else
- pe = createTransport(media);
- return pe;
- }
-
- /**
- * Initializes a new <tt>PacketExtension</tt> instance appropriate to the
- * type of Jingle transport represented by this <tt>TransportManager</tt>.
- * The new instance is not initialized with any attributes or child
- * extensions.
- *
- * @return a new <tt>PacketExtension</tt> instance appropriate to the type
- * of Jingle transport represented by this <tt>TransportManager</tt>
- */
- protected abstract PacketExtension createTransportPacketExtension();
-
- /**
- * Creates a media <tt>StreamConnector</tt> for a stream of a specific
- * <tt>MediaType</tt>. The minimum and maximum of the media port boundaries
- * are taken into account.
- *
- * @param mediaType the <tt>MediaType</tt> of the stream for which a
- * <tt>StreamConnector</tt> is to be created
- * @return a <tt>StreamConnector</tt> for the stream of the specified
- * <tt>mediaType</tt>
- * @throws OperationFailedException if the binding of the sockets fails
- */
- protected StreamConnector doCreateStreamConnector(MediaType mediaType)
- throws OperationFailedException
- {
- return super.createStreamConnector(mediaType);
- }
-
- /**
- * Finds a <tt>TransportManagerJabberImpl</tt> participating in a telephony
- * conference utilizing the Jitsi Videobridge server-side technology that
- * this instance is participating in which is establishing the connectivity
- * with the Jitsi Videobridge server (as opposed to a <tt>CallPeer</tt>).
- *
- * @return a <tt>TransportManagerJabberImpl</tt> which is participating in
- * a telephony conference utilizing the Jitsi Videobridge server-side
- * technology that this instance is participating in which is establishing
- * the connectivity with the Jitsi Videobridge server (as opposed to a
- * <tt>CallPeer</tt>).
- */
- TransportManagerJabberImpl
- findTransportManagerEstablishingConnectivityWithJitsiVideobridge()
- {
- Call call = getCallPeer().getCall();
- TransportManagerJabberImpl transportManager = null;
-
- if (call != null)
- {
- CallConference conference = call.getConference();
-
- if ((conference != null) && conference.isJitsiVideobridge())
- {
- for (Call aCall : conference.getCalls())
- {
- Iterator<? extends CallPeer> callPeerIter
- = aCall.getCallPeers();
-
- while (callPeerIter.hasNext())
- {
- CallPeer aCallPeer = callPeerIter.next();
-
- if (aCallPeer instanceof CallPeerJabberImpl)
- {
- TransportManagerJabberImpl aTransportManager
- = ((CallPeerJabberImpl) aCallPeer)
- .getMediaHandler()
- .getTransportManager();
-
- if (aTransportManager
- .isEstablishingConnectivityWithJitsiVideobridge)
- {
- transportManager = aTransportManager;
- break;
- }
- }
- }
- }
- }
- }
- return transportManager;
- }
-
- /**
- * Gets the {@link ColibriConferenceIQ.Channel} which belongs to a content
- * associated with a specific <tt>MediaType</tt> and is to be either locally
- * or remotely used.
- * <p>
- * <b>Note</b>: Modifications to the <tt>ColibriConferenceIQ.Channel</tt>
- * instance returned by the method propagate to (the state of) this
- * instance.
- * </p>
- *
- * @param mediaType the <tt>MediaType</tt> associated with the content which
- * contains the <tt>ColibriConferenceIQ.Channel</tt> to get
- * @param local <tt>true</tt> if the <tt>ColibriConferenceIQ.Channel</tt>
- * which is to be used locally is to be returned or <tt>false</tt> for the
- * one which is to be used remotely
- * @return the <tt>ColibriConferenceIQ.Channel</tt> which belongs to a
- * content associated with the specified <tt>mediaType</tt> and which is to
- * be used in accord with the specified <tt>local</tt> indicator if such a
- * channel exists; otherwise, <tt>null</tt>
- */
- ColibriConferenceIQ.Channel getColibriChannel(
- MediaType mediaType,
- boolean local)
- {
- ColibriConferenceIQ.Channel channel = null;
-
- if (colibri != null)
- {
- ColibriConferenceIQ.Content content
- = colibri.getContent(mediaType.toString());
-
- if (content != null)
- {
- List<ColibriConferenceIQ.Channel> channels
- = content.getChannels();
-
- if (channels.size() == 2)
- channel = channels.get(local ? 0 : 1);
- }
- }
- return channel;
- }
-}
+package net.java.sip.communicator.impl.protocol.jabber;
+
+import java.net.*;
+import java.util.*;
+
+import net.java.sip.communicator.impl.protocol.jabber.extensions.colibri.*;
+import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
+import net.java.sip.communicator.impl.protocol.jabber.jinglesdp.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.media.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.neomedia.*;
+import org.jivesoftware.smack.packet.*;
+
+/**
+ * <tt>TransportManager</tt>s gather local candidates for incoming and outgoing
+ * calls. Their work starts by calling a start method which, using the remote
+ * peer's session description, would start the harvest. Calling a second wrapup
+ * method would deliver the candidate harvest, possibly after blocking if it has
+ * not yet completed.
+ *
+ * @author Emil Ivov
+ * @author Lyubomir Marinov
+ */
+public abstract class TransportManagerJabberImpl
+ extends TransportManager<CallPeerJabberImpl>
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>TransportManagerJabberImpl</tt> class
+ * and its instances to print debug messages.
+ */
+ private static final Logger logger
+ = Logger.getLogger(TransportManagerJabberImpl.class);
+
+ /**
+ * The ID that we will be assigning to our next candidate. We use
+ * <tt>int</tt>s for interoperability reasons (Emil: I believe that GTalk
+ * uses <tt>int</tt>s. If that turns out not to be the case we can stop
+ * using <tt>int</tt>s here if that's an issue).
+ */
+ private static int nextID = 1;
+
+ /**
+ * The information pertaining to the Jisti Videobridge conference which the
+ * local peer represented by this instance is a focus of. It gives a view of
+ * the whole Jitsi Videobridge conference managed by the associated
+ * <tt>CallJabberImpl</tt> which provides information specific to this
+ * <tt>TransportManager</tt> only.
+ */
+ private ColibriConferenceIQ colibri;
+
+ /**
+ * The generation of the candidates we are currently generating
+ */
+ private int currentGeneration = 0;
+
+ /**
+ * The indicator which determines whether this <tt>TransportManager</tt>
+ * instance is responsible to establish the connectivity with the associated
+ * Jitsi Videobridge (in case it is being employed at all).
+ */
+ boolean isEstablishingConnectivityWithJitsiVideobridge = false;
+
+ /**
+ * The indicator which determines whether this <tt>TransportManager</tt>
+ * instance is yet to start establishing the connectivity with the
+ * associated Jitsi Videobridge (in case it is being employed at all).
+ */
+ boolean startConnectivityEstablishmentWithJitsiVideobridge = false;
+
+ /**
+ * Creates a new instance of this transport manager, binding it to the
+ * specified peer.
+ *
+ * @param callPeer the {@link CallPeer} whose traffic we will be taking
+ * care of.
+ */
+ protected TransportManagerJabberImpl(CallPeerJabberImpl callPeer)
+ {
+ super(callPeer);
+ }
+
+ /**
+ * Returns the <tt>InetAddress</tt> that is most likely to be to be used
+ * as a next hop when contacting the specified <tt>destination</tt>. This is
+ * an utility method that is used whenever we have to choose one of our
+ * local addresses to put in the Via, Contact or (in the case of no
+ * registrar accounts) From headers.
+ *
+ * @param peer the CallPeer that we would contact.
+ *
+ * @return the <tt>InetAddress</tt> that is most likely to be to be used
+ * as a next hop when contacting the specified <tt>destination</tt>.
+ *
+ * @throws IllegalArgumentException if <tt>destination</tt> is not a valid
+ * host/IP/FQDN
+ */
+ @Override
+ protected InetAddress getIntendedDestination(CallPeerJabberImpl peer)
+ {
+ return peer.getProtocolProvider().getNextHop();
+ }
+
+ /**
+ * Returns the ID that we will be assigning to the next candidate we create.
+ *
+ * @return the next ID to use with a candidate.
+ */
+ protected String getNextID()
+ {
+ int nextID;
+
+ synchronized (TransportManagerJabberImpl.class)
+ {
+ nextID = TransportManagerJabberImpl.nextID++;
+ }
+ return Integer.toString(nextID);
+ }
+
+ /**
+ * Gets the <tt>MediaStreamTarget</tt> to be used as the <tt>target</tt> of
+ * the <tt>MediaStream</tt> with a specific <tt>MediaType</tt>.
+ *
+ * @param mediaType the <tt>MediaType</tt> of the <tt>MediaStream</tt> which
+ * is to have its <tt>target</tt> set to the returned
+ * <tt>MediaStreamTarget</tt>
+ * @return the <tt>MediaStreamTarget</tt> to be used as the <tt>target</tt>
+ * of the <tt>MediaStream</tt> with the specified <tt>MediaType</tt>
+ */
+ public abstract MediaStreamTarget getStreamTarget(MediaType mediaType);
+
+ /**
+ * Gets the XML namespace of the Jingle transport implemented by this
+ * <tt>TransportManagerJabberImpl</tt>.
+ *
+ * @return the XML namespace of the Jingle transport implemented by this
+ * <tt>TransportManagerJabberImpl</tt>
+ */
+ public abstract String getXmlNamespace();
+
+ /**
+ * Returns the generation that our current candidates belong to.
+ *
+ * @return the generation that we should assign to candidates that we are
+ * currently advertising.
+ */
+ protected int getCurrentGeneration()
+ {
+ return currentGeneration;
+ }
+
+ /**
+ * Increments the generation that we are assigning candidates.
+ */
+ protected void incrementGeneration()
+ {
+ currentGeneration++;
+ }
+
+ /**
+ * Sends transport-related information received from the remote peer to the
+ * associated Jiitsi Videobridge in order to update the (remote)
+ * <tt>ColibriConferenceIQ.Channel</tt> associated with this
+ * <tt>TransportManager</tt> instance.
+ *
+ * @param map a <tt>Map</tt> of media-IceUdpTransportPacketExtension pairs
+ * which represents the transport-related information which has been
+ * received from the remote peer and which is to be sent to the associated
+ * Jitsi Videobridge
+ */
+ protected void sendTransportInfoToJitsiVideobridge(
+ Map<String,IceUdpTransportPacketExtension> map)
+ {
+ CallPeerJabberImpl peer = getCallPeer();
+ boolean initiator = !peer.isInitiator();
+ ColibriConferenceIQ conferenceRequest = null;
+
+ for (Map.Entry<String,IceUdpTransportPacketExtension> e
+ : map.entrySet())
+ {
+ String media = e.getKey();
+ MediaType mediaType = MediaType.parseString(media);
+ ColibriConferenceIQ.Channel channel
+ = getColibriChannel(mediaType, false /* remote */);
+
+ if (channel != null)
+ {
+ IceUdpTransportPacketExtension transport;
+
+ try
+ {
+ transport = cloneTransportAndCandidates(e.getValue());
+ }
+ catch (OperationFailedException ofe)
+ {
+ transport = null;
+ }
+ if (transport == null)
+ continue;
+
+ ColibriConferenceIQ.Channel channelRequest
+ = new ColibriConferenceIQ.Channel();
+
+ channelRequest.setID(channel.getID());
+ channelRequest.setInitiator(initiator);
+ channelRequest.setTransport(transport);
+
+ if (conferenceRequest == null)
+ {
+ if (colibri == null)
+ break;
+ else
+ {
+ String id = colibri.getID();
+
+ if ((id == null) || (id.length() == 0))
+ break;
+ else
+ {
+ conferenceRequest = new ColibriConferenceIQ();
+ conferenceRequest.setID(id);
+ conferenceRequest.setTo(colibri.getFrom());
+ conferenceRequest.setType(IQ.Type.SET);
+ }
+ }
+ }
+ conferenceRequest.getOrCreateContent(media).addChannel(
+ channelRequest);
+ }
+ }
+ if (conferenceRequest != null)
+ {
+ peer.getProtocolProvider().getConnection().sendPacket(
+ conferenceRequest);
+ }
+ }
+
+ /**
+ * Starts transport candidate harvest for a specific
+ * <tt>ContentPacketExtension</tt> that we are going to offer or answer
+ * with.
+ *
+ * @param theirContent the <tt>ContentPacketExtension</tt> offered by the
+ * remote peer to which we are going to answer with <tt>ourContent</tt> or
+ * <tt>null</tt> if <tt>ourContent</tt> will be an offer to the remote peer
+ * @param ourContent the <tt>ContentPacketExtension</tt> for which transport
+ * candidate harvest is to be started
+ * @param transportInfoSender a <tt>TransportInfoSender</tt> if the
+ * harvested transport candidates are to be sent in a
+ * <tt>transport-info</tt> rather than in <tt>ourContent</tt>; otherwise,
+ * <tt>null</tt>
+ * @param media the media of the <tt>RtpDescriptionPacketExtension</tt>
+ * child of <tt>ourContent</tt>
+ * @return a <tt>PacketExtension</tt> to be added as a child to
+ * <tt>ourContent</tt>; otherwise, <tt>null</tt>
+ * @throws OperationFailedException if anything goes wrong while starting
+ * transport candidate harvest for the specified <tt>ourContent</tt>
+ */
+ protected abstract PacketExtension startCandidateHarvest(
+ ContentPacketExtension theirContent,
+ ContentPacketExtension ourContent,
+ TransportInfoSender transportInfoSender,
+ String media)
+ throws OperationFailedException;
+
+ /**
+ * Starts transport candidate harvest. This method should complete rapidly
+ * and, in case of lengthy procedures like STUN/TURN/UPnP candidate harvests
+ * are necessary, they should be executed in a separate thread. Candidate
+ * harvest would then need to be concluded in the
+ * {@link #wrapupCandidateHarvest()} method which would be called once we
+ * absolutely need the candidates.
+ *
+ * @param theirOffer a media description offer that we've received from the
+ * remote party and that we should use in case we need to know what
+ * transports our peer is using.
+ * @param ourAnswer the content descriptions that we should be adding our
+ * transport lists to (although not necessarily in this very instance).
+ * @param transportInfoSender the <tt>TransportInfoSender</tt> to be used by
+ * this <tt>TransportManagerJabberImpl</tt> to send <tt>transport-info</tt>
+ * <tt>JingleIQ</tt>s from the local peer to the remote peer if this
+ * <tt>TransportManagerJabberImpl</tt> wishes to utilize
+ * <tt>transport-info</tt>. Local candidate addresses sent by this
+ * <tt>TransportManagerJabberImpl</tt> in <tt>transport-info</tt> are
+ * expected to not be included in the result of
+ * {@link #wrapupCandidateHarvest()}.
+ *
+ * @throws OperationFailedException if we fail to allocate a port number.
+ */
+ public void startCandidateHarvest(
+ List<ContentPacketExtension> theirOffer,
+ List<ContentPacketExtension> ourAnswer,
+ TransportInfoSender transportInfoSender)
+ throws OperationFailedException
+ {
+ CallPeerJabberImpl peer = getCallPeer();
+ CallJabberImpl call = peer.getCall();
+ boolean isJitsiVideobridge = call.getConference().isJitsiVideobridge();
+ List<ContentPacketExtension> cpes
+ = (theirOffer == null) ? ourAnswer : theirOffer;
+
+ /*
+ * If Jitsi Videobridge is to be used, determine which channels are to
+ * be allocated and attempt to allocate them now.
+ */
+ if (isJitsiVideobridge)
+ {
+ Map<ContentPacketExtension,ContentPacketExtension> contentMap
+ = new LinkedHashMap
+ <ContentPacketExtension,ContentPacketExtension>();
+
+ for (ContentPacketExtension cpe : cpes)
+ {
+ MediaType mediaType = JingleUtils.getMediaType(cpe);
+
+ /*
+ * The existence of a content for the mediaType and regardless
+ * of the existence of channels in it signals that a channel
+ * allocation request has already been sent for that mediaType.
+ */
+ if ((colibri == null)
+ || (colibri.getContent(mediaType.toString()) == null))
+ {
+ ContentPacketExtension local, remote;
+
+ if (cpes == ourAnswer)
+ {
+ local = cpe;
+ remote
+ = (theirOffer == null)
+ ? null
+ : findContentByName(theirOffer, cpe.getName());
+ }
+ else
+ {
+ local = findContentByName(ourAnswer, cpe.getName());
+ remote = cpe;
+ }
+ contentMap.put(local, remote);
+ }
+ }
+ if (!contentMap.isEmpty())
+ {
+ /*
+ * We are about to request the channel allocations for the media
+ * types found in contentMap. Regardless of the response, we do
+ * not want to repeat these requests.
+ */
+ if (colibri == null)
+ colibri = new ColibriConferenceIQ();
+ for (Map.Entry<ContentPacketExtension,ContentPacketExtension> e
+ : contentMap.entrySet())
+ {
+ ContentPacketExtension cpe = e.getValue();
+
+ if (cpe == null)
+ cpe = e.getKey();
+
+ colibri.getOrCreateContent(
+ JingleUtils.getMediaType(cpe).toString());
+ }
+
+ ColibriConferenceIQ conferenceResult
+ = call.createColibriChannels(peer, contentMap);
+
+ if (conferenceResult != null)
+ {
+ String videobridgeID = colibri.getID();
+ String conferenceResultID = conferenceResult.getID();
+
+ if (videobridgeID == null)
+ colibri.setID(conferenceResultID);
+ else if (!videobridgeID.equals(conferenceResultID))
+ throw new IllegalStateException("conference.id");
+
+ String videobridgeFrom = conferenceResult.getFrom();
+
+ if ((videobridgeFrom != null)
+ && (videobridgeFrom.length() != 0))
+ {
+ colibri.setFrom(videobridgeFrom);
+ }
+
+ for (ColibriConferenceIQ.Content contentResult
+ : conferenceResult.getContents())
+ {
+ ColibriConferenceIQ.Content content
+ = colibri.getOrCreateContent(
+ contentResult.getName());
+
+ for (ColibriConferenceIQ.Channel channelResult
+ : contentResult.getChannels())
+ {
+ if (content.getChannel(channelResult.getID())
+ == null)
+ {
+ content.addChannel(channelResult);
+ }
+ }
+ }
+ }
+ else
+ {
+ /*
+ * The call fails if the createColibriChannels method fails
+ * which may happen if the conference packet times out or it
+ * can't be built.
+ */
+ ProtocolProviderServiceJabberImpl
+ .throwOperationFailedException(
+ "Failed to allocate colibri channel.",
+ OperationFailedException.GENERAL_ERROR,
+ null,
+ logger);
+ }
+ }
+ }
+
+ for (ContentPacketExtension cpe : cpes)
+ {
+ String contentName = cpe.getName();
+ ContentPacketExtension ourContent
+ = findContentByName(ourAnswer, contentName);
+
+ //it might be that we decided not to reply to this content
+ if (ourContent != null)
+ {
+ ContentPacketExtension theirContent
+ = (theirOffer == null)
+ ? null
+ : findContentByName(theirOffer, contentName);
+ RtpDescriptionPacketExtension rtpDesc
+ = ourContent.getFirstChildOfType(
+ RtpDescriptionPacketExtension.class);
+ String media = rtpDesc.getMedia();
+ PacketExtension pe
+ = startCandidateHarvest(
+ theirContent,
+ ourContent,
+ transportInfoSender,
+ media);
+
+ if (pe != null)
+ ourContent.addChildExtension(pe);
+ }
+ }
+ }
+
+ /**
+ * Starts transport candidate harvest. This method should complete rapidly
+ * and, in case of lengthy procedures like STUN/TURN/UPnP candidate harvests
+ * are necessary, they should be executed in a separate thread. Candidate
+ * harvest would then need to be concluded in the
+ * {@link #wrapupCandidateHarvest()} method which would be called once we
+ * absolutely need the candidates.
+ *
+ * @param ourOffer the content descriptions that we should be adding our
+ * transport lists to (although not necessarily in this very instance).
+ * @param transportInfoSender the <tt>TransportInfoSender</tt> to be used by
+ * this <tt>TransportManagerJabberImpl</tt> to send <tt>transport-info</tt>
+ * <tt>JingleIQ</tt>s from the local peer to the remote peer if this
+ * <tt>TransportManagerJabberImpl</tt> wishes to utilize
+ * <tt>transport-info</tt>. Local candidate addresses sent by this
+ * <tt>TransportManagerJabberImpl</tt> in <tt>transport-info</tt> are
+ * expected to not be included in the result of
+ * {@link #wrapupCandidateHarvest()}.
+ * @throws OperationFailedException if we fail to allocate a port number.
+ */
+ public void startCandidateHarvest(
+ List<ContentPacketExtension> ourOffer,
+ TransportInfoSender transportInfoSender)
+ throws OperationFailedException
+ {
+ startCandidateHarvest(
+ /* theirOffer */ null,
+ ourOffer,
+ transportInfoSender);
+ }
+
+ /**
+ * Notifies the transport manager that it should conclude candidate
+ * harvesting as soon as possible and return the lists of candidates
+ * gathered so far.
+ *
+ * @return the content list that we received earlier (possibly cloned into
+ * a new instance) and that we have updated with transport lists.
+ */
+ public abstract List<ContentPacketExtension> wrapupCandidateHarvest();
+
+ /**
+ * Looks through the <tt>cpExtList</tt> and returns the {@link
+ * ContentPacketExtension} with the specified name.
+ *
+ * @param cpExtList the list that we will be searching for a specific
+ * content.
+ * @param name the name of the content element we are looking for.
+ * @return the {@link ContentPacketExtension} with the specified name or
+ * <tt>null</tt> if no such content element exists.
+ */
+ public static ContentPacketExtension findContentByName(
+ Iterable<ContentPacketExtension> cpExtList,
+ String name)
+ {
+ for(ContentPacketExtension cpExt : cpExtList)
+ {
+ if(cpExt.getName().equals(name))
+ return cpExt;
+ }
+ return null;
+ }
+
+ /**
+ * Starts the connectivity establishment of this
+ * <tt>TransportManagerJabberImpl</tt> i.e. checks the connectivity between
+ * the local and the remote peers given the remote counterpart of the
+ * negotiation between them.
+ *
+ * @param remote the collection of <tt>ContentPacketExtension</tt>s which
+ * represents the remote counterpart of the negotiation between the local
+ * and the remote peer
+ * @return <tt>true</tt> if connectivity establishment has been started in
+ * response to the call; otherwise, <tt>false</tt>.
+ * <tt>TransportManagerJabberImpl</tt> implementations which do not perform
+ * connectivity checks (e.g. raw UDP) should return <tt>true</tt>. The
+ * default implementation does not perform connectivity checks and always
+ * returns <tt>true</tt>.
+ */
+ public boolean startConnectivityEstablishment(
+ Iterable<ContentPacketExtension> remote)
+ {
+ return true;
+ }
+
+ /**
+ * Starts the connectivity establishment of this
+ * <tt>TransportManagerJabberImpl</tt> i.e. checks the connectivity between
+ * the local and the remote peers given the remote counterpart of the
+ * negotiation between them.
+ *
+ * @param remote a <tt>Map</tt> of
+ * media-<tt>IceUdpTransportPacketExtension</tt> pairs which represents the
+ * remote counterpart of the negotiation between the local and the remote
+ * peers
+ * @return <tt>true</tt> if connectivity establishment has been started in
+ * response to the call; otherwise, <tt>false</tt>.
+ * <tt>TransportManagerJabberImpl</tt> implementations which do not perform
+ * connectivity checks (e.g. raw UDP) should return <tt>true</tt>. The
+ * default implementation does not perform connectivity checks and always
+ * returns <tt>true</tt>.
+ */
+ protected boolean startConnectivityEstablishment(
+ Map<String,IceUdpTransportPacketExtension> remote)
+ {
+ return true;
+ }
+
+ /**
+ * Notifies this <tt>TransportManagerJabberImpl</tt> that it should conclude
+ * any started connectivity establishment.
+ *
+ * @throws OperationFailedException if anything goes wrong with connectivity
+ * establishment (i.e. ICE failed, ...)
+ */
+ public void wrapupConnectivityEstablishment()
+ throws OperationFailedException
+ {
+ }
+
+ /**
+ * Removes a content with a specific name from the transport-related part of
+ * the session represented by this <tt>TransportManagerJabberImpl</tt> which
+ * may have been reported through previous calls to the
+ * <tt>startCandidateHarvest</tt> and
+ * <tt>startConnectivityEstablishment</tt> methods.
+ * <p>
+ * <b>Note</b>: Because <tt>TransportManager</tt> deals with
+ * <tt>MediaType</tt>s, not content names and
+ * <tt>TransportManagerJabberImpl</tt> does not implement translating from
+ * content name to <tt>MediaType</tt>, implementers are expected to call
+ * {@link TransportManager#closeStreamConnector(MediaType)}.
+ * </p>
+ *
+ * @param name the name of the content to be removed from the
+ * transport-related part of the session represented by this
+ * <tt>TransportManagerJabberImpl</tt>
+ */
+ public abstract void removeContent(String name);
+
+ /**
+ * Removes a content with a specific name from a specific collection of
+ * contents and closes any associated <tt>StreamConnector</tt>.
+ *
+ * @param contents the collection of contents to remove the content with the
+ * specified name from
+ * @param name the name of the content to remove
+ * @return the removed <tt>ContentPacketExtension</tt> if any; otherwise,
+ * <tt>null</tt>
+ */
+ protected ContentPacketExtension removeContent(
+ Iterable<ContentPacketExtension> contents,
+ String name)
+ {
+ for (Iterator<ContentPacketExtension> contentIter = contents.iterator();
+ contentIter.hasNext();)
+ {
+ ContentPacketExtension content = contentIter.next();
+
+ if (name.equals(content.getName()))
+ {
+ contentIter.remove();
+
+ // closeStreamConnector
+ MediaType mediaType = JingleUtils.getMediaType(content);
+ if (mediaType != null)
+ {
+ closeStreamConnector(mediaType);
+ }
+
+ return content;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Clones a specific <tt>IceUdpTransportPacketExtension</tt> and its
+ * candidates.
+ *
+ * @param src the <tt>IceUdpTransportPacketExtension</tt> to be cloned
+ * @return a new <tt>IceUdpTransportPacketExtension</tt> instance which has
+ * the same run-time type, attributes, namespace, text and candidates as the
+ * specified <tt>src</tt>
+ * @throws OperationFailedException if an error occurs during the cloing of
+ * the specified <tt>src</tt> and its candidates
+ */
+ static IceUdpTransportPacketExtension cloneTransportAndCandidates(
+ IceUdpTransportPacketExtension src)
+ throws OperationFailedException
+ {
+ try
+ {
+ return IceUdpTransportPacketExtension
+ .cloneTransportAndCandidates(src);
+ }
+ catch (Exception e)
+ {
+ ProtocolProviderServiceJabberImpl
+ .throwOperationFailedException(
+ "Failed to close transport and candidates.",
+ OperationFailedException.GENERAL_ERROR,
+ e,
+ logger);
+
+ }
+ return null;
+ }
+
+ /**
+ * Releases the resources acquired by this <tt>TransportManager</tt> and
+ * prepares it for garbage collection.
+ */
+ public void close()
+ {
+ for (MediaType mediaType : MediaType.values())
+ closeStreamConnector(mediaType);
+ }
+
+ /**
+ * Closes a specific <tt>StreamConnector</tt> associated with a specific
+ * <tt>MediaType</tt>. If this <tt>TransportManager</tt> has a reference to
+ * the specified <tt>streamConnector</tt>, it remains.
+ * Also expires the <tt>ColibriConferenceIQ.Channel</tt> associated with
+ * the closed <tt>StreamConnector</tt>.
+ *
+ * @param mediaType the <tt>MediaType</tt> associated with the specified
+ * <tt>streamConnector</tt>
+ * @param streamConnector the <tt>StreamConnector</tt> to be closed
+ */
+ @Override
+ protected void closeStreamConnector(
+ MediaType mediaType,
+ StreamConnector streamConnector)
+ {
+ try
+ {
+ boolean superCloseStreamConnector = true;
+
+ if (streamConnector instanceof ColibriStreamConnector)
+ {
+ CallPeerJabberImpl peer = getCallPeer();
+
+ if (peer != null)
+ {
+ CallJabberImpl call = peer.getCall();
+
+ if (call != null)
+ {
+ superCloseStreamConnector = false;
+ call.closeColibriStreamConnector(
+ peer,
+ mediaType,
+ (ColibriStreamConnector) streamConnector);
+ }
+ }
+ }
+ if (superCloseStreamConnector)
+ super.closeStreamConnector(mediaType, streamConnector);
+ }
+ finally
+ {
+ /*
+ * Expire the ColibriConferenceIQ.Channel associated with the closed
+ * StreamConnector.
+ */
+ if (colibri != null)
+ {
+ ColibriConferenceIQ.Content content
+ = colibri.getContent(mediaType.toString());
+
+ if (content != null)
+ {
+ List<ColibriConferenceIQ.Channel> channels
+ = content.getChannels();
+
+ if (channels.size() == 2)
+ {
+ ColibriConferenceIQ requestConferenceIQ
+ = new ColibriConferenceIQ();
+
+ requestConferenceIQ.setID(colibri.getID());
+
+ ColibriConferenceIQ.Content requestContent
+ = requestConferenceIQ.getOrCreateContent(
+ content.getName());
+
+ requestContent.addChannel(channels.get(1 /* remote */));
+
+ /*
+ * Regardless of whether the request to expire the
+ * Channel associated with mediaType succeeds, consider
+ * the Channel in question expired. Since
+ * RawUdpTransportManager allocates a single channel per
+ * MediaType, consider the whole Content expired.
+ */
+ colibri.removeContent(content);
+
+ CallPeerJabberImpl peer = getCallPeer();
+
+ if (peer != null)
+ {
+ CallJabberImpl call = peer.getCall();
+
+ if (call != null)
+ {
+ call.expireColibriChannels(
+ peer,
+ requestConferenceIQ);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Adds support for telephony conferences utilizing the Jitsi Videobridge
+ * server-side technology.
+ *
+ * @see #doCreateStreamConnector(MediaType)
+ */
+ @Override
+ protected StreamConnector createStreamConnector(final MediaType mediaType)
+ throws OperationFailedException
+ {
+ ColibriConferenceIQ.Channel channel
+ = getColibriChannel(mediaType, true /* local */);
+
+ if (channel != null)
+ {
+ CallPeerJabberImpl peer = getCallPeer();
+ CallJabberImpl call = peer.getCall();
+ StreamConnector streamConnector
+ = call.createColibriStreamConnector(
+ peer,
+ mediaType,
+ channel,
+ new StreamConnectorFactory()
+ {
+ public StreamConnector createStreamConnector()
+ {
+ try
+ {
+ return doCreateStreamConnector(mediaType);
+ }
+ catch (OperationFailedException ofe)
+ {
+ return null;
+ }
+ }
+ });
+
+ if (streamConnector != null)
+ return streamConnector;
+ }
+
+ return doCreateStreamConnector(mediaType);
+ }
+
+ protected abstract PacketExtension createTransport(String media)
+ throws OperationFailedException;
+
+ protected PacketExtension createTransportForStartCandidateHarvest(
+ String media)
+ throws OperationFailedException
+ {
+ PacketExtension pe = null;
+
+ if (getCallPeer().isJitsiVideobridge())
+ {
+ MediaType mediaType = MediaType.parseString(media);
+ ColibriConferenceIQ.Channel channel
+ = getColibriChannel(mediaType, false /* remote */);
+
+ if (channel != null)
+ pe = cloneTransportAndCandidates(channel.getTransport());
+ }
+ else
+ pe = createTransport(media);
+ return pe;
+ }
+
+ /**
+ * Initializes a new <tt>PacketExtension</tt> instance appropriate to the
+ * type of Jingle transport represented by this <tt>TransportManager</tt>.
+ * The new instance is not initialized with any attributes or child
+ * extensions.
+ *
+ * @return a new <tt>PacketExtension</tt> instance appropriate to the type
+ * of Jingle transport represented by this <tt>TransportManager</tt>
+ */
+ protected abstract PacketExtension createTransportPacketExtension();
+
+ /**
+ * Creates a media <tt>StreamConnector</tt> for a stream of a specific
+ * <tt>MediaType</tt>. The minimum and maximum of the media port boundaries
+ * are taken into account.
+ *
+ * @param mediaType the <tt>MediaType</tt> of the stream for which a
+ * <tt>StreamConnector</tt> is to be created
+ * @return a <tt>StreamConnector</tt> for the stream of the specified
+ * <tt>mediaType</tt>
+ * @throws OperationFailedException if the binding of the sockets fails
+ */
+ protected StreamConnector doCreateStreamConnector(MediaType mediaType)
+ throws OperationFailedException
+ {
+ return super.createStreamConnector(mediaType);
+ }
+
+ /**
+ * Finds a <tt>TransportManagerJabberImpl</tt> participating in a telephony
+ * conference utilizing the Jitsi Videobridge server-side technology that
+ * this instance is participating in which is establishing the connectivity
+ * with the Jitsi Videobridge server (as opposed to a <tt>CallPeer</tt>).
+ *
+ * @return a <tt>TransportManagerJabberImpl</tt> which is participating in
+ * a telephony conference utilizing the Jitsi Videobridge server-side
+ * technology that this instance is participating in which is establishing
+ * the connectivity with the Jitsi Videobridge server (as opposed to a
+ * <tt>CallPeer</tt>).
+ */
+ TransportManagerJabberImpl
+ findTransportManagerEstablishingConnectivityWithJitsiVideobridge()
+ {
+ Call call = getCallPeer().getCall();
+ TransportManagerJabberImpl transportManager = null;
+
+ if (call != null)
+ {
+ CallConference conference = call.getConference();
+
+ if ((conference != null) && conference.isJitsiVideobridge())
+ {
+ for (Call aCall : conference.getCalls())
+ {
+ Iterator<? extends CallPeer> callPeerIter
+ = aCall.getCallPeers();
+
+ while (callPeerIter.hasNext())
+ {
+ CallPeer aCallPeer = callPeerIter.next();
+
+ if (aCallPeer instanceof CallPeerJabberImpl)
+ {
+ TransportManagerJabberImpl aTransportManager
+ = ((CallPeerJabberImpl) aCallPeer)
+ .getMediaHandler()
+ .getTransportManager();
+
+ if (aTransportManager
+ .isEstablishingConnectivityWithJitsiVideobridge)
+ {
+ transportManager = aTransportManager;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return transportManager;
+ }
+
+ /**
+ * Gets the {@link ColibriConferenceIQ.Channel} which belongs to a content
+ * associated with a specific <tt>MediaType</tt> and is to be either locally
+ * or remotely used.
+ * <p>
+ * <b>Note</b>: Modifications to the <tt>ColibriConferenceIQ.Channel</tt>
+ * instance returned by the method propagate to (the state of) this
+ * instance.
+ * </p>
+ *
+ * @param mediaType the <tt>MediaType</tt> associated with the content which
+ * contains the <tt>ColibriConferenceIQ.Channel</tt> to get
+ * @param local <tt>true</tt> if the <tt>ColibriConferenceIQ.Channel</tt>
+ * which is to be used locally is to be returned or <tt>false</tt> for the
+ * one which is to be used remotely
+ * @return the <tt>ColibriConferenceIQ.Channel</tt> which belongs to a
+ * content associated with the specified <tt>mediaType</tt> and which is to
+ * be used in accord with the specified <tt>local</tt> indicator if such a
+ * channel exists; otherwise, <tt>null</tt>
+ */
+ ColibriConferenceIQ.Channel getColibriChannel(
+ MediaType mediaType,
+ boolean local)
+ {
+ ColibriConferenceIQ.Channel channel = null;
+
+ if (colibri != null)
+ {
+ ColibriConferenceIQ.Content content
+ = colibri.getContent(mediaType.toString());
+
+ if (content != null)
+ {
+ List<ColibriConferenceIQ.Channel> channels
+ = content.getChannels();
+
+ if (channels.size() == 2)
+ channel = channels.get(local ? 0 : 1);
+ }
+ }
+ return channel;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/DefaultPacketExtensionProvider.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/DefaultPacketExtensionProvider.java
index 1285581..778d086 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/DefaultPacketExtensionProvider.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/DefaultPacketExtensionProvider.java
@@ -19,6 +19,7 @@ package net.java.sip.communicator.impl.protocol.jabber.extensions;
import java.util.logging.*;
+import net.java.sip.communicator.service.protocol.jabber.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.provider.*;
import org.xmlpull.v1.*;
@@ -41,6 +42,13 @@ public class DefaultPacketExtensionProvider<C extends AbstractPacketExtension>
.getLogger(DefaultPacketExtensionProvider.class.getName());
/**
+ * The <tt>AbstractSmackInteroperabilityLayer</tt> instance implementing
+ * necessary methods
+ */
+ private AbstractSmackInteroperabilityLayer smackInteroperabilityLayer =
+ AbstractSmackInteroperabilityLayer.getInstance();
+
+ /**
* The {@link Class} that the packets we will be parsing here belong to.
*/
private final Class<C> packetClass;
@@ -100,8 +108,7 @@ public class DefaultPacketExtensionProvider<C extends AbstractPacketExtension>
if (eventType == XmlPullParser.START_TAG)
{
- PacketExtensionProvider provider
- = (PacketExtensionProvider)ProviderManager.getInstance()
+ PacketExtensionProvider provider = smackInteroperabilityLayer
.getExtensionProvider( elementName, namespace );
if(provider == null)
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/EntityCapsManager.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/EntityCapsManager.java
index ebdcbb0..97d9ff8 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/EntityCapsManager.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/EntityCapsManager.java
@@ -243,6 +243,7 @@ public class EntityCapsManager
if ((user != null) && (node != null) && (hash != null) && (ver != null))
{
Caps caps = userCaps.get(user);
+ String bareJid=StringUtils.parseBareAddress(user);
if ((caps == null)
|| !caps.node.equals(node)
@@ -270,7 +271,9 @@ public class EntityCapsManager
String nodeVer = caps.getNodeVer();
for (UserCapsNodeListener listener : listeners)
- listener.userCapsNodeAdded(user, nodeVer, online);
+ listener.userCapsNodeAdded(user,
+ getFullJidsByBareJid(bareJid),
+ nodeVer, online);
}
}
}
@@ -305,6 +308,8 @@ public class EntityCapsManager
{
Caps caps = null;
String lastRemovedJid = null;
+ String bareJid=StringUtils.parseBareAddress(
+ contact.getAddress());
Iterator<String> iter = userCaps.keySet().iterator();
while(iter.hasNext())
@@ -337,7 +342,9 @@ public class EntityCapsManager
for (UserCapsNodeListener listener : listeners)
listener.userCapsNodeRemoved(
- lastRemovedJid, nodeVer, false);
+ lastRemovedJid,
+ getFullJidsByBareJid(bareJid),
+ nodeVer, false);
}
}
}
@@ -350,6 +357,7 @@ public class EntityCapsManager
public void removeUserCapsNode(String user)
{
Caps caps = userCaps.remove(user);
+ String bareJid=StringUtils.parseBareAddress(user);
// Fire userCapsNodeRemoved.
if (caps != null)
@@ -367,7 +375,9 @@ public class EntityCapsManager
String nodeVer = caps.getNodeVer();
for (UserCapsNodeListener listener : listeners)
- listener.userCapsNodeRemoved(user, nodeVer, false);
+ listener.userCapsNodeRemoved(user,
+ getFullJidsByBareJid(bareJid),
+ nodeVer, false);
}
}
}
@@ -404,6 +414,24 @@ public class EntityCapsManager
{
return userCaps.get(user);
}
+
+ /**
+ * Gets the full Jids (with resources) as Strings.
+ *
+ * @param the bare Jid
+ * @return the full Jids as an ArrayList <tt>user</tt>
+ */
+ public ArrayList<String> getFullJidsByBareJid(String bareJid)
+ {
+ ArrayList<String> jids = new ArrayList<String>();
+ for(String jid: userCaps.keySet())
+ {
+ if(bareJid.equals(StringUtils.parseBareAddress(jid))){
+ jids.add(jid);
+ }
+ }
+ return jids;
+ }
/**
* Get the discover info given a user name. The discover info is returned if
@@ -605,14 +633,9 @@ public class EntityCapsManager
* @param connection the connection that we'd like this manager to register
* with.
*/
- public void addPacketListener(XMPPConnection connection)
+ public void addPacketListener(Connection connection)
{
- PacketFilter filter
- = new AndFilter(
- new PacketTypeFilter(Presence.class),
- new PacketExtensionFilter(
- CapsPacketExtension.ELEMENT_NAME,
- CapsPacketExtension.NAMESPACE));
+ PacketFilter filter = new PacketTypeFilter(Presence.class);
connection.addPacketListener(new CapsPacketListener(), filter);
}
@@ -913,48 +936,48 @@ public class EntityCapsManager
*/
public void processPacket(Packet packet)
{
+ // Check it the packet indicates that the user is online. We
+ // will use this information to decide if we're going to send
+ // the discover info request.
+ boolean online
+ = (packet instanceof Presence)
+ && ((Presence) packet).isAvailable();
+
CapsPacketExtension ext
= (CapsPacketExtension)
packet.getExtension(
CapsPacketExtension.ELEMENT_NAME,
CapsPacketExtension.NAMESPACE);
- /*
- * Before Version 1.4 of XEP-0115: Entity Capabilities, the 'ver'
- * attribute was generated differently and the 'hash' attribute was
- * absent. The 'ver' attribute in Version 1.3 represents the
- * specific version of the client and thus does not provide a way to
- * validate the DiscoverInfo sent by the client. If
- * EntityCapsManager receives no 'hash' attribute, it will assume
- * the legacy format and will not cache it because the DiscoverInfo
- * to be received from the client later on will not be trustworthy.
- */
- String hash = ext.getHash();
-
- /* Google Talk web does not set hash but we need it to be cached */
- if(hash == null)
- hash = "";
-
- if (hash != null)
+ if(ext != null && online)
{
- // Check it the packet indicates that the user is online. We
- // will use this information to decide if we're going to send
- // the discover info request.
- boolean online
- = (packet instanceof Presence)
- && ((Presence) packet).isAvailable();
-
- if(online)
- {
- addUserCapsNode(
- packet.getFrom(),
- ext.getNode(), hash, ext.getVersion(),
- ext.getExtensions(), online);
- }
- else
- {
- removeUserCapsNode(packet.getFrom());
- }
+ /*
+ * Before Version 1.4 of XEP-0115: Entity Capabilities,
+ * the 'ver' attribute was generated differently and the 'hash'
+ * attribute was absent. The 'ver' attribute in Version 1.3
+ * represents the specific version of the client and thus does
+ * not provide a way to validate the DiscoverInfo sent by
+ * the client. If EntityCapsManager receives no 'hash'
+ * attribute, it will assume the legacy format and will not
+ * cache it because the DiscoverInfo to be received from
+ * the client later on will not be trustworthy.
+ */
+ String hash = ext.getHash();
+
+ /* Google Talk web does not set hash, but we need it to
+ * be cached
+ */
+ if (hash == null)
+ hash = "";
+
+ addUserCapsNode(
+ packet.getFrom(),
+ ext.getNode(), hash, ext.getVersion(),
+ ext.getExtensions(), online);
+ }
+ else if (!online)
+ {
+ removeUserCapsNode(packet.getFrom());
}
}
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/UserCapsNodeListener.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/UserCapsNodeListener.java
index 5ee38b0..eda921f 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/UserCapsNodeListener.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/UserCapsNodeListener.java
@@ -17,6 +17,8 @@
*/
package net.java.sip.communicator.impl.protocol.jabber.extensions.caps;
+import java.util.ArrayList;
+
/**
* Represents a listener of events notifying about changes in the list of user
* caps nodes of <tt>EntityCapsManager</tt>.
@@ -30,18 +32,22 @@ public interface UserCapsNodeListener
* record for a specific user about the caps node the user has.
*
* @param user the user (full JID)
+ * @param fullJids a list of all resources of the user (full JIDs)
* @param node the entity caps node#ver
* @param online indicates if the user for which we're notified is online
*/
- public void userCapsNodeAdded(String user, String node, boolean online);
+ public void userCapsNodeAdded(String user, ArrayList<String> fullJids,
+ String node, boolean online);
/**
* Notifies this listener that an <tt>EntityCapsManager</tt> has removed a
* record for a specific user about the caps node the user has.
*
* @param user the user (full JID)
+ * @param fullJids a list of all resources of the user (full JIDs)
* @param node the entity caps node#ver
* @param online indicates if the user for which we're notified is online
*/
- public void userCapsNodeRemoved(String user, String node, boolean online);
+ public void userCapsNodeRemoved(String user, ArrayList<String> fullJids,
+ String node, boolean online);
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriBuilder.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriBuilder.java
index 547ebe8..48207c2 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriBuilder.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriBuilder.java
@@ -37,9 +37,9 @@ import java.util.*;
* Add one or multiple requests of the same type by calling
* {@link #addAllocateChannelsReq(boolean, String, boolean, java.util.List)}}
* or {@link #addExpireChannelsReq(ColibriConferenceIQ)}
- * or {@link #addTransportUpdateReq(boolean, java.util.Map, ColibriConferenceIQ)}
- * or {@link #addBundleTransportUpdateReq(
- * boolean, IceUdpTransportPacketExtension, ColibriConferenceIQ)}.
+ * or {@link #addRtpDescription(Map, ColibriConferenceIQ)}
+ * and {@link #addSSSRCGroupsInfo(Map, ColibriConferenceIQ)}
+ * and {@link #addSSSRCInfo(Map, ColibriConferenceIQ)}.
* </li>
* <li>
* Compile the request by calling {@link #getRequest(String)}. Then send it to
@@ -119,6 +119,20 @@ public class ColibriBuilder
private SimulcastMode simulcastMode;
/**
+ * Specifies the audio packet delay that will be set on all created audio
+ * channels. When set to <tt>null</tt> the builder will clear the attribute
+ * which stands for 'undefined'.
+ **/
+ private Integer audioPacketDelay;
+
+ /**
+ * Channel 'rtp-level-relay-type' option that will be used with all created
+ * audio channel. Possible values: mixer or translator (default).
+ *
+ */
+ private RTPLevelRelayType rtpLevelRelayType;
+
+ /**
* Creates new instance of {@link ColibriBuilder} for given
* <tt>conferenceState</tt>.
*
@@ -161,18 +175,26 @@ public class ColibriBuilder
* @param contents the list of {@link ContentPacketExtension} describing
* channels media.
*
- * @return this instance fo calls chaining purpose.
+ * @return <tt>true</tt> if the request yields any changes in Colibri
+ * channels state on the bridge or <tt>false</tt> otherwise.
+ * In general when <tt>false</tt> is returned for all
+ * combined requests it makes no sense to send it.
*/
- public ColibriBuilder addAllocateChannelsReq(
- boolean useBundle,
- String endpointName,
- boolean peerIsInitiator,
+ public boolean addAllocateChannelsReq(
+ boolean useBundle,
+ String endpointName,
+ boolean peerIsInitiator,
List<ContentPacketExtension> contents)
{
+ Objects.requireNonNull(endpointName, "endpointName");
+ Objects.requireNonNull(contents, "contents");
+
assertRequestType(RequestType.ALLOCATE_CHANNELS);
request.setType(IQ.Type.GET);
+ boolean hasAnyChanges = false;
+
for (ContentPacketExtension cpe : contents)
{
MediaType mediaType = JingleUtils.getMediaType(cpe);
@@ -193,7 +215,7 @@ public class ColibriBuilder
remoteChannelRequest.setChannelBundleId(endpointName);
}
- if (mediaType != MediaType.DATA)
+ if (remoteChannelRequest instanceof ColibriConferenceIQ.Channel)
{
RtpDescriptionPacketExtension rdpe
= cpe.getFirstChildOfType(
@@ -213,6 +235,13 @@ public class ColibriBuilder
remoteRtpChannelRequest.setAdaptiveLastN(adaptiveLastN);
remoteRtpChannelRequest.setAdaptiveSimulcast(adaptiveSimulcast);
remoteRtpChannelRequest.setSimulcastMode(simulcastMode);
+ if (MediaType.AUDIO.equals(mediaType))
+ {
+ // When audioPacketDelay is null it will clear the attribute
+ remoteRtpChannelRequest.setPacketDelay(audioPacketDelay);
+ // Set rtp packet relay type for this channel
+ remoteRtpChannelRequest.setRTPLevelRelayType(rtpLevelRelayType);
+ }
}
// Copy transport
@@ -221,13 +250,17 @@ public class ColibriBuilder
copyTransportOnChannel(cpe, remoteChannelRequest);
}
- if (mediaType != MediaType.DATA)
+ if (remoteChannelRequest instanceof ColibriConferenceIQ.Channel)
{
+ hasAnyChanges = true;
+
contentRequest.addChannel(
(ColibriConferenceIQ.Channel) remoteChannelRequest);
}
else
{
+ hasAnyChanges = true;
+
contentRequest.addSctpConnection(
(ColibriConferenceIQ.SctpConnection) remoteChannelRequest);
}
@@ -246,6 +279,8 @@ public class ColibriBuilder
IceUdpTransportPacketExtension.class);
if (transport != null)
{
+ hasAnyChanges = true;
+
bundle.setTransport(
IceUdpTransportPacketExtension
.cloneTransportAndCandidates(transport, true));
@@ -254,106 +289,38 @@ public class ColibriBuilder
request.addChannelBundle(bundle);
}
- return this;
- }
-
- /**
- * Adds next ICE transport update request to
- * {@link RequestType#TRANSPORT_UPDATE} query currently being built.
- *
- * @param initiator the value that will be set in 'initiator'
- * attribute({@link ColibriConferenceIQ.Channel#initiator}).
- * @param map the map of content name to transport extensions. Maps
- * transport to media types.
- * @param localChannelsInfo {@link ColibriConferenceIQ} holding info about
- * Colibri channels to be updated.
- *
- * @return this instance fo calls chaining purpose.
- */
- public ColibriBuilder addTransportUpdateReq(
- boolean initiator,
- Map<String, IceUdpTransportPacketExtension> map,
- ColibriConferenceIQ localChannelsInfo)
- {
- if (conferenceState == null
- || StringUtils.isNullOrEmpty(conferenceState.getID()))
- {
- // We are not initialized yet
- return null;
- }
-
- assertRequestType(RequestType.TRANSPORT_UPDATE);
-
- request.setType(IQ.Type.SET);
-
- for (Map.Entry<String,IceUdpTransportPacketExtension> e
- : map.entrySet())
- {
- String contentName = e.getKey();
- ColibriConferenceIQ.ChannelCommon channel
- = getColibriChannel(localChannelsInfo, contentName);
-
- if (channel != null)
- {
- IceUdpTransportPacketExtension transport
- = IceUdpTransportPacketExtension
- .cloneTransportAndCandidates(e.getValue(), true);
-
- ColibriConferenceIQ.ChannelCommon channelRequest
- = channel instanceof ColibriConferenceIQ.Channel
- ? new ColibriConferenceIQ.Channel()
- : new ColibriConferenceIQ.SctpConnection();
-
- channelRequest.setID(channel.getID());
- channelRequest.setEndpoint(channel.getEndpoint());
- channelRequest.setInitiator(initiator);
- channelRequest.setTransport(transport);
-
- if (channelRequest instanceof ColibriConferenceIQ.Channel)
- {
- request.getOrCreateContent(contentName)
- .addChannel(
- (ColibriConferenceIQ.Channel) channelRequest);
- }
- else
- {
- request.getOrCreateContent(contentName)
- .addSctpConnection(
- (ColibriConferenceIQ.SctpConnection) channelRequest);
- }
- }
- }
- return this;
+ return hasAnyChanges;
}
/**
- * Adds next request to {@link RequestType#BUNDLE_TRANSPORT_UPDATE} query.
- * @param initiator the value that will be set in 'initiator'
- * attribute({@link ColibriConferenceIQ.Channel#initiator}).
+ * Adds next request to {@link RequestType#CHANNEL_INFO_UPDATE} query.
* @param localChannelsInfo the {@link ColibriConferenceIQ} instance that
* describes the channel for which bundle transport will be updated.
* It should contain the description of only one "channel bundle".
* If it contains more than one then the first one will be used.
- * @return this instance for calls chaining purpose.
+ * @return <tt>true</tt> if the request yields any changes in Colibri
+ * channels state on the bridge or <tt>false</tt> otherwise.
+ * In general when <tt>false</tt> is returned for all
+ * combined requests it makes no sense to send it.
* @throws IllegalArgumentException if <tt>localChannelsInfo</tt> does not
* describe any channel bundles.
*/
- public ColibriBuilder addBundleTransportUpdateReq(
- boolean initiator,
- IceUdpTransportPacketExtension transport,
- ColibriConferenceIQ localChannelsInfo)
+ public boolean addBundleTransportUpdateReq(
+ IceUdpTransportPacketExtension transport,
+ ColibriConferenceIQ localChannelsInfo)
throws IllegalArgumentException
{
- // FIXME:'initiator' not used on bundle transport update ?
+ Objects.requireNonNull(transport, "transport");
+ Objects.requireNonNull(localChannelsInfo, "localChannelsInfo");
if (conferenceState == null
|| StringUtils.isNullOrEmpty(conferenceState.getID()))
{
// We are not initialized yet
- return null;
+ return false;
}
- assertRequestType(RequestType.BUNDLE_TRANSPORT_UPDATE);
+ assertRequestType(RequestType.CHANNEL_INFO_UPDATE);
request.setType(IQ.Type.SET);
@@ -371,7 +338,7 @@ public class ColibriBuilder
else
{
throw new IllegalArgumentException(
- "Expected ChannelBundle as not found");
+ "Expected ChannelBundle as not found");
}
ColibriConferenceIQ.ChannelBundle bundleUpdate
@@ -387,7 +354,7 @@ public class ColibriBuilder
request.addChannelBundle(bundleUpdate);
- return this;
+ return true;
}
/**
@@ -395,15 +362,20 @@ public class ColibriBuilder
* {@link RequestType#EXPIRE_CHANNELS} query currently being built.
* @param channelInfo the {@link ColibriConferenceIQ} instance that contains
* info about the channels to be expired.
- * @return this instance for the purpose of calls chaining.
+ * @return <tt>true</tt> if the request yields any changes in Colibri
+ * channels state on the bridge or <tt>false</tt> otherwise.
+ * In general when <tt>false</tt> is returned for all
+ * combined requests it makes no sense to send it.
*/
- public ColibriBuilder addExpireChannelsReq(ColibriConferenceIQ channelInfo)
+ public boolean addExpireChannelsReq(ColibriConferenceIQ channelInfo)
{
+ Objects.requireNonNull(channelInfo, "channelInfo");
+
// Formulate the ColibriConferenceIQ request which is to be sent.
if (conferenceState == null
|| StringUtils.isNullOrEmpty(conferenceState.getID()))
{
- return null;
+ return false;
}
assertRequestType(RequestType.EXPIRE_CHANNELS);
@@ -411,7 +383,7 @@ public class ColibriBuilder
request.setType(IQ.Type.SET);
for (ColibriConferenceIQ.Content expiredContent
- : channelInfo.getContents())
+ : channelInfo.getContents())
{
ColibriConferenceIQ.Content stateContent
= conferenceState.getContent(expiredContent.getName());
@@ -420,7 +392,7 @@ public class ColibriBuilder
{
ColibriConferenceIQ.Content requestContent
= request.getOrCreateContent(
- stateContent.getName());
+ stateContent.getName());
for (ColibriConferenceIQ.Channel expiredChannel
: expiredContent.getChannels())
@@ -490,7 +462,7 @@ public class ColibriBuilder
*/
/*if (stateContent.getChannelCount() == 1)
{
- stateChannel = stateContent.getChannel(0);
+ stateChannel = stateContent.getRtpChannel(0);
ColibriConferenceIQ.Channel channelRequest
= new ColibriConferenceIQ.Channel();
@@ -537,7 +509,294 @@ public class ColibriBuilder
}
}
- return this;
+ return hasAnyChannelsToExpire;
+ }
+
+ /**
+ * Adds next payload type information update request to
+ * {@link RequestType#CHANNEL_INFO_UPDATE} query currently being built.
+ *
+ * @param map the map of content name to RTP description packet extension.
+ * @param localChannelsInfo {@link ColibriConferenceIQ} holding info about
+ * Colibri channels to be updated.
+ *
+ * @return <tt>true</tt> if the request yields any changes in Colibri
+ * channels state on the bridge or <tt>false</tt> otherwise.
+ * In general when <tt>false</tt> is returned for all
+ * combined requests it makes no sense to send it.
+ */
+ public boolean addRtpDescription(
+ Map<String, RtpDescriptionPacketExtension> map,
+ ColibriConferenceIQ localChannelsInfo)
+ {
+ Objects.requireNonNull(map, "map");
+ Objects.requireNonNull(localChannelsInfo, "localChannelsInfo");
+
+ if (conferenceState == null
+ || StringUtils.isNullOrEmpty(conferenceState.getID()))
+ {
+ // We are not initialized yet
+ return false;
+ }
+
+ assertRequestType(RequestType.CHANNEL_INFO_UPDATE);
+
+ request.setType(IQ.Type.SET);
+
+ boolean anyUpdates = false;
+
+ for (Map.Entry<String, RtpDescriptionPacketExtension> e
+ : map.entrySet())
+ {
+ String contentName = e.getKey();
+ ColibriConferenceIQ.ChannelCommon channel
+ = getColibriChannel(localChannelsInfo, contentName);
+
+ if (channel != null
+ && channel instanceof ColibriConferenceIQ.Channel)
+ {
+ RtpDescriptionPacketExtension rtpPE = e.getValue();
+ if (rtpPE == null)
+ {
+ continue;
+ }
+
+ List<PayloadTypePacketExtension> pts = rtpPE.getPayloadTypes();
+ if (pts == null || pts.isEmpty())
+ {
+ continue;
+ }
+
+ anyUpdates = true;
+
+ ColibriConferenceIQ.Channel channelRequest
+ = (ColibriConferenceIQ.Channel) getRequestChannel(
+ request.getOrCreateContent(contentName),
+ channel);
+ if (channelRequest == null)
+ {
+ channelRequest = new ColibriConferenceIQ.Channel();
+ channelRequest.setID(channel.getID());
+ }
+
+ for (PayloadTypePacketExtension ptPE : pts)
+ {
+ channelRequest.addPayloadType(ptPE);
+ }
+ }
+ }
+
+ return anyUpdates;
+ }
+
+ /**
+ * Adds next SSRC information update request to
+ * {@link RequestType#CHANNEL_INFO_UPDATE} query currently being built.
+ *
+ * @param ssrcMap the map of content name to the list of
+ * <tt>SourcePacketExtension</tt>.
+ * @param localChannelsInfo {@link ColibriConferenceIQ} holding info about
+ * Colibri channels to be updated.
+ *
+ * @return <tt>true</tt> if the request yields any changes in Colibri
+ * channels state on the bridge or <tt>false</tt> otherwise.
+ * In general when <tt>false</tt> is returned for all
+ * combined requests it makes no sense to send it.
+ */
+ public boolean addSSSRCInfo(
+ Map<String, List<SourcePacketExtension>> ssrcMap,
+ ColibriConferenceIQ localChannelsInfo)
+ {
+ Objects.requireNonNull(ssrcMap, "ssrcMap");
+ Objects.requireNonNull(localChannelsInfo, "localChannelsInfo");
+
+ if (conferenceState == null
+ || StringUtils.isNullOrEmpty(conferenceState.getID()))
+ {
+ // We are not initialized yet
+ return false;
+ }
+
+ assertRequestType(RequestType.CHANNEL_INFO_UPDATE);
+
+ request.setType(IQ.Type.SET);
+
+ boolean anyUpdates = false;
+
+ // Go over SSRCs
+ for (String contentName : ssrcMap.keySet())
+ {
+ // Get channel from local channel info
+ ColibriConferenceIQ.ChannelCommon rtpChanel
+ = getRtpChannel(localChannelsInfo, contentName);
+ if (rtpChanel == null)
+ {
+ // There's no channel for this content name in localChannelsInfo
+ continue;
+ }
+
+ anyUpdates = true;
+
+ // Ok we have channel for this content, let's add SSRCs
+ ColibriConferenceIQ.Channel reqChannel
+ = (ColibriConferenceIQ.Channel) getRequestChannel(
+ request.getOrCreateContent(contentName), rtpChanel);
+
+ for (SourcePacketExtension ssrc : ssrcMap.get(contentName))
+ {
+ reqChannel.addSource(ssrc.copy());
+ }
+
+ if (reqChannel.getSources() == null
+ || reqChannel.getSources().isEmpty())
+ {
+ // Put an empty source to remove all sources
+ SourcePacketExtension emptySource = new SourcePacketExtension();
+ emptySource.setSSRC(-1L);
+ reqChannel.addSource(emptySource);
+ }
+ }
+
+ return anyUpdates;
+ }
+
+ /**
+ * Adds next SSRC group information update request to
+ * {@link RequestType#CHANNEL_INFO_UPDATE} query currently being built.
+ *
+ * @param ssrcGroupMap the map of content name to the list of
+ * <tt>SourceGroupPacketExtension</tt>.
+ * @param localChannelsInfo {@link ColibriConferenceIQ} holding info about
+ * Colibri channels to be updated.
+ *
+ * @return <tt>true</tt> if the request yields any changes in Colibri
+ * channels state on the bridge or <tt>false</tt> otherwise.
+ * In general when <tt>false</tt> is returned for all
+ * combined requests it makes no sense to send it.
+ */
+ public boolean addSSSRCGroupsInfo(
+ Map<String, List<SourceGroupPacketExtension>> ssrcGroupMap,
+ ColibriConferenceIQ localChannelsInfo)
+ {
+ Objects.requireNonNull(ssrcGroupMap, "ssrcGroupMap");
+ Objects.requireNonNull(localChannelsInfo, "localChannelsInfo");
+
+ if (conferenceState == null
+ || StringUtils.isNullOrEmpty(conferenceState.getID()))
+ {
+ // We are not initialized yet
+ return false;
+ }
+
+ assertRequestType(RequestType.CHANNEL_INFO_UPDATE);
+
+ request.setType(IQ.Type.SET);
+
+ boolean anyUpdates = false;
+
+ // Go over SSRC groups
+ for (String contentName : ssrcGroupMap.keySet())
+ {
+ // Get channel from local channel info
+ ColibriConferenceIQ.Channel rtpChannel
+ = getRtpChannel(localChannelsInfo, contentName);
+ if (rtpChannel == null)
+ {
+ // There's no channel for this content name in localChannelsInfo
+ continue;
+ }
+
+ List<SourceGroupPacketExtension> groups
+ = ssrcGroupMap.get(contentName);
+
+ // Ok we have channel for this content, let's add SSRCs
+ ColibriConferenceIQ.Channel reqChannel
+ = (ColibriConferenceIQ.Channel) getRequestChannel(
+ request.getOrCreateContent(contentName), rtpChannel);
+
+ if (groups.isEmpty() && "video".equalsIgnoreCase(contentName))
+ {
+ anyUpdates = true;
+
+ // Put empty source group to turn off simulcast layers
+ reqChannel.addSourceGroup(
+ SourceGroupPacketExtension.createSimulcastGroup());
+ }
+
+ for (SourceGroupPacketExtension group : groups)
+ {
+ anyUpdates = true;
+
+ reqChannel.addSourceGroup(group);
+ }
+ }
+
+ return anyUpdates;
+ }
+
+ /**
+ * Adds next ICE transport update request to
+ * {@link RequestType#CHANNEL_INFO_UPDATE} query currently being built.
+ *
+ * @param map the map of content name to transport extensions. Maps
+ * transport to media types.
+ * @param localChannelsInfo {@link ColibriConferenceIQ} holding info about
+ * Colibri channels to be updated.
+ *
+ * @return <tt>true</tt> if the request yields any changes in Colibri
+ * channels state on the bridge or <tt>false</tt> otherwise.
+ * In general when <tt>false</tt> is returned for all
+ * combined requests it makes no sense to send it.
+ */
+ public boolean addTransportUpdateReq(
+ Map<String, IceUdpTransportPacketExtension> map,
+ ColibriConferenceIQ localChannelsInfo)
+ {
+ Objects.requireNonNull(map, "map");
+ Objects.requireNonNull(localChannelsInfo, "localChannelsInfo");
+
+ if (conferenceState == null
+ || StringUtils.isNullOrEmpty(conferenceState.getID()))
+ {
+ // We are not initialized yet
+ return false;
+ }
+
+ boolean hasAnyChanges = false;
+
+ assertRequestType(RequestType.CHANNEL_INFO_UPDATE);
+
+ request.setType(IQ.Type.SET);
+
+ for (Map.Entry<String,IceUdpTransportPacketExtension> e
+ : map.entrySet())
+ {
+ String contentName = e.getKey();
+ ColibriConferenceIQ.ChannelCommon channel
+ = getColibriChannel(localChannelsInfo, contentName);
+
+ if (channel != null)
+ {
+ IceUdpTransportPacketExtension transport
+ = IceUdpTransportPacketExtension
+ .cloneTransportAndCandidates(e.getValue(), true);
+
+ ColibriConferenceIQ.ChannelCommon channelRequest
+ = channel instanceof ColibriConferenceIQ.Channel
+ ? new ColibriConferenceIQ.Channel()
+ : new ColibriConferenceIQ.SctpConnection();
+
+ channelRequest.setID(channel.getID());
+ channelRequest.setEndpoint(channel.getEndpoint());
+ channelRequest.setTransport(transport);
+
+ request.getOrCreateContent(contentName)
+ .addChannelCommon(channelRequest);
+
+ hasAnyChanges = true;
+ }
+ }
+ return hasAnyChanges;
}
/**
@@ -583,10 +842,12 @@ public class ColibriBuilder
request.setTo(videobridge);
- if (requestType == RequestType.EXPIRE_CHANNELS
- && !hasAnyChannelsToExpire)
+ if (requestType == RequestType.EXPIRE_CHANNELS)
{
- return null;
+ if (!hasAnyChannelsToExpire)
+ return null;
+
+ hasAnyChannelsToExpire = false;
}
return request;
@@ -720,6 +981,28 @@ public class ColibriBuilder
}
/**
+ * Returns an <tt>Integer</tt> which stands for the audio packet delay
+ * that will be set on all created audio channels or <tt>null</tt> if
+ * the builder should leave not include the XML attribute at all.
+ */
+ public Integer getAudioPacketDelay()
+ {
+ return audioPacketDelay;
+ }
+
+ /**
+ * Configures audio channels packet delay.
+ * @param audioPacketDelay an <tt>Integer</tt> value which stands for
+ * the audio packet delay that will be set on all created audio channels or
+ * <tt>null</tt> if the builder should not set that channel property to any
+ * value.
+ */
+ public void setAudioPacketDelay(Integer audioPacketDelay)
+ {
+ this.audioPacketDelay = audioPacketDelay;
+ }
+
+ /**
* Sets channel 'simulcast-mode' option that will be added to the
* request when channels are created.
* @param simulcastMode a <tt>SimulcastMode</tt> value to specify
@@ -732,69 +1015,64 @@ public class ColibriBuilder
}
/**
- * Adds next payload type information update request to
- * {@link RequestType#RTP_DESCRIPTION_UPDATE} query currently being built.
+ * Creates a new instance of <tt>localChannelInfo</tt> and initializes only
+ * the fields required to identify particular Colibri channel on the bridge.
+ * This instance is meant to be used in Colibri
+ * {@link RequestType#CHANNEL_INFO_UPDATE} requests. This instance is also
+ * added to given <tt>requestContent</tt> which used to construct current
+ * request.
*
- * @param map the map of content name to RTP description packet extension.
- * @param localChannelsInfo {@link ColibriConferenceIQ} holding info about
- * Colibri channels to be updated.
+ * @param requestContent <tt>Content</tt> of Colibri update request to which
+ * new instance wil be automatically added after has been created.
+ * @param localChannelInfo the original channel for which "update request"
+ * equivalent is to be created with this call.
*
- * @return this instance for calls chaining purpose.
+ * @return new instance of <tt>localChannelInfo</tt> and initialized with
+ * only those fields required to identify particular Colibri channel on
+ * the bridge.
*/
- public ColibriBuilder addRtpDescription(
- Map<String, RtpDescriptionPacketExtension> map,
- ColibriConferenceIQ localChannelsInfo) {
-
- if (conferenceState == null
- || StringUtils.isNullOrEmpty(conferenceState.getID()))
- {
- // We are not initialized yet
- return null;
- }
-
- assertRequestType(RequestType.RTP_DESCRIPTION_UPDATE);
-
- request.setType(IQ.Type.SET);
-
- for (Map.Entry<String, RtpDescriptionPacketExtension> e
- : map.entrySet())
+ private ColibriConferenceIQ.ChannelCommon getRequestChannel(
+ ColibriConferenceIQ.Content requestContent,
+ ColibriConferenceIQ.ChannelCommon localChannelInfo)
+ {
+ ColibriConferenceIQ.ChannelCommon reqChannel
+ = requestContent.getChannel(localChannelInfo.getID());
+ if (reqChannel == null)
{
- String contentName = e.getKey();
- ColibriConferenceIQ.ChannelCommon channel
- = getColibriChannel(localChannelsInfo, contentName);
-
- if (channel != null
- && channel instanceof ColibriConferenceIQ.Channel)
+ if (localChannelInfo instanceof ColibriConferenceIQ.Channel)
{
- RtpDescriptionPacketExtension rtpPE = e.getValue();
- if (rtpPE == null)
- {
- continue;
- }
-
- List<PayloadTypePacketExtension> pts = rtpPE.getPayloadTypes();
- if (pts == null || pts.isEmpty())
- {
- continue;
- }
-
- ColibriConferenceIQ.Channel channelRequest
- = new ColibriConferenceIQ.Channel();
+ reqChannel = new ColibriConferenceIQ.Channel();
+ }
+ else if (
+ localChannelInfo instanceof ColibriConferenceIQ.SctpConnection)
+ {
+ reqChannel = new ColibriConferenceIQ.SctpConnection();
+ }
+ else
+ {
+ throw new RuntimeException(
+ "Unsupported ChannelCommon class: "
+ + localChannelInfo.getClass());
+ }
- channelRequest.setID(channel.getID());
+ reqChannel.setID(localChannelInfo.getID());
- for (PayloadTypePacketExtension ptPE : rtpPE.getPayloadTypes())
- {
- channelRequest.addPayloadType(ptPE);
- }
+ requestContent.addChannelCommon(reqChannel);
+ }
+ return reqChannel;
+ }
- request.getOrCreateContent(contentName)
- .addChannel(channelRequest);
- }
+ private ColibriConferenceIQ.Channel getRtpChannel(
+ ColibriConferenceIQ localChannelsInfo,
+ String contentName)
+ {
+ ColibriConferenceIQ.Content content
+ = localChannelsInfo.getContent(contentName);
- }
+ if (content == null)
+ return null;
- return this;
+ return content.getChannelCount() > 0 ? content.getChannel(0) : null;
}
/**
@@ -808,19 +1086,10 @@ public class ColibriBuilder
ALLOCATE_CHANNELS,
/**
- * Updates transport information for channels that use RTP bundle.
- */
- BUNDLE_TRANSPORT_UPDATE,
-
- /**
- * Updates channel transport information(ICE transport candidates).
+ * An update request which is meant to modify some values of existing
+ * Colibri channels on the bridge.
*/
- TRANSPORT_UPDATE,
-
- /**
- * Updates the RTP description of a channel (payload types).
- */
- RTP_DESCRIPTION_UPDATE,
+ CHANNEL_INFO_UPDATE,
/**
* Expires specified Colibri channels.
@@ -833,4 +1102,28 @@ public class ColibriBuilder
*/
UNDEFINED;
}
+
+ /**
+ * Configures RTP-level relay (RFC 3550, section 2.3).
+ * @param rtpLevelRelayType an <tt>RTPLevelRelayType</tt> value which
+ * stands for the rtp level relay type that will be set on all created
+ * audio channels.
+ */
+ public void setRTPLevelRelayType(RTPLevelRelayType rtpLevelRelayType)
+ {
+ this.rtpLevelRelayType = rtpLevelRelayType;
+ }
+
+ /**
+ * Configures RTP-level relay (RFC 3550, section 2.3).
+ * @param rtpLevelRelayType a <tt>String</tt> value which
+ * stands for the rtp level relay type that will be set on all created
+ * audio channels.
+ */
+ public void setRTPLevelRelayType(String rtpLevelRelayType)
+ {
+ setRTPLevelRelayType
+ (RTPLevelRelayType.parseRTPLevelRelayType(rtpLevelRelayType));
+ }
+
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriConferenceIQ.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriConferenceIQ.java
index 52368bf..d5cf175 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriConferenceIQ.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriConferenceIQ.java
@@ -161,7 +161,7 @@ public class ColibriConferenceIQ
throw new NullPointerException("channelBundle");
return
- channelBundles.contains(channelBundles)
+ channelBundles.contains(channelBundle)
? false
: channelBundles.add(channelBundle);
}
@@ -543,6 +543,14 @@ public class ColibriConferenceIQ
= "receive-simulcast-layer";
/**
+ * The XML name of the <tt>packet-delay</tt> attribute of
+ * a <tt>channel</tt> of a <tt>content</tt> of a <tt>conference</tt> IQ
+ * which represents the value of the {@link #packetDelay} property of
+ * <tt>ColibriConferenceIQ.Channel</tt>.
+ */
+ public static final String PACKET_DELAY_ATTR_NAME = "packet-delay";
+
+ /**
* The XML name of the <tt>rtcpport</tt> attribute of a <tt>channel</tt>
* of a <tt>content</tt> of a <tt>conference</tt> IQ which represents
* the value of the <tt>rtcpPort</tt> property of
@@ -613,6 +621,11 @@ public class ColibriConferenceIQ
private SimulcastMode simulcastMode;
/**
+ * The amount of delay added to the RTP stream in a number of packets.
+ */
+ private Integer packetDelay;
+
+ /**
* The <tt>payload-type</tt> elements defined by XEP-0167: Jingle RTP
* Sessions associated with this <tt>channel</tt>.
*/
@@ -893,6 +906,18 @@ public class ColibriConferenceIQ
}
/**
+ * Returns an <tt>Integer</tt> which stands for the amount of delay
+ * added to the RTP stream in a number of packets.
+ *
+ * @return <tt>Integer</tt> with the value or <tt>null</tt> if
+ * unspecified.
+ */
+ public Integer getPacketDelay()
+ {
+ return packetDelay;
+ }
+
+ /**
* Gets a list of <tt>payload-type</tt> elements defined by XEP-0167:
* Jingle RTP Sessions added to this <tt>channel</tt>.
*
@@ -1077,8 +1102,16 @@ public class ColibriConferenceIQ
if (adaptiveSimulcast != null)
{
- xml.append(' ').append(adaptiveSimulcast).append("='")
- .append(adaptiveSimulcast).append('\'');
+ xml.append(' ').append(ADAPTIVE_SIMULCAST_ATTR_NAME)
+ .append("='").append(adaptiveSimulcast).append('\'');
+ }
+
+ // packet-delay
+ Integer packetDelay = getPacketDelay();
+ if (packetDelay != null)
+ {
+ xml.append(' ').append(PACKET_DELAY_ATTR_NAME).append("='")
+ .append(packetDelay).append('\'');
}
// simulcastMode
@@ -1314,6 +1347,17 @@ public class ColibriConferenceIQ
}
/**
+ * Configures channel's packet delay which tells by how many packets
+ * the RTP streams will be delayed.
+ * @param packetDelay an <tt>Integer</tt> value which stands for
+ * the packet delay that will be set or <tt>null</tt> to leave undefined
+ */
+ public void setPacketDelay(Integer packetDelay)
+ {
+ this.packetDelay = packetDelay;
+ }
+
+ /**
* Sets the value of the 'simulcast-mode' flag.
* @param simulcastMode the value to set.
*/
@@ -1925,6 +1969,25 @@ public class ColibriConferenceIQ
}
/**
+ * Adds <tt>ChannelCommon</tt> to this <tt>Content</tt>.
+ * @param channelCommon {@link ChannelCommon} instance to be added to
+ * this content.
+ * @return <tt>true</tt> if given <tt>channelCommon</tt> has been
+ * actually added to this <tt>Content</tt> instance.
+ */
+ public boolean addChannelCommon(ChannelCommon channelCommon)
+ {
+ if (channelCommon instanceof Channel)
+ {
+ return addChannel((Channel) channelCommon);
+ }
+ else
+ {
+ return addSctpConnection((SctpConnection) channelCommon);
+ }
+ }
+
+ /**
* Adds a specific <tt>SctpConnection</tt> to the list of
* <tt>SctpConnection</tt>s included into this <tt>Content</tt>.
*
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriIQProvider.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriIQProvider.java
index 39e299f..ce676ef 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriIQProvider.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriIQProvider.java
@@ -20,6 +20,7 @@ package net.java.sip.communicator.impl.protocol.jabber.extensions.colibri;
import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
+import net.java.sip.communicator.service.protocol.jabber.*;
import org.jitsi.service.neomedia.*;
import org.jitsi.util.*;
import org.jivesoftware.smack.packet.*;
@@ -36,89 +37,101 @@ import org.xmlpull.v1.*;
public class ColibriIQProvider
implements IQProvider
{
+
+ /**
+ * Smack interoperation layer
+ */
+ private AbstractSmackInteroperabilityLayer smackInteroperabilityLayer =
+ AbstractSmackInteroperabilityLayer.getInstance();
+
/** Initializes a new <tt>ColibriIQProvider</tt> instance. */
public ColibriIQProvider()
{
- ProviderManager providerManager = ProviderManager.getInstance();
-
- providerManager.addExtensionProvider(
+ smackInteroperabilityLayer.addExtensionProvider(
PayloadTypePacketExtension.ELEMENT_NAME,
ColibriConferenceIQ.NAMESPACE,
new DefaultPacketExtensionProvider<PayloadTypePacketExtension>(
PayloadTypePacketExtension.class));
- providerManager.addExtensionProvider(
+ smackInteroperabilityLayer.addExtensionProvider(
RtcpFbPacketExtension.ELEMENT_NAME,
RtcpFbPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<RtcpFbPacketExtension>(
RtcpFbPacketExtension.class));
- providerManager.addExtensionProvider(
+ smackInteroperabilityLayer.addExtensionProvider(
RTPHdrExtPacketExtension.ELEMENT_NAME,
ColibriConferenceIQ.NAMESPACE,
new DefaultPacketExtensionProvider<RTPHdrExtPacketExtension>(
RTPHdrExtPacketExtension.class));
- providerManager.addExtensionProvider(
+ smackInteroperabilityLayer.addExtensionProvider(
SourcePacketExtension.ELEMENT_NAME,
SourcePacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<SourcePacketExtension>(
SourcePacketExtension.class));
- providerManager.addExtensionProvider(
+ smackInteroperabilityLayer.addExtensionProvider(
SourceGroupPacketExtension.ELEMENT_NAME,
SourceGroupPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<SourceGroupPacketExtension>(
SourceGroupPacketExtension.class));
PacketExtensionProvider parameterProvider
- = new DefaultPacketExtensionProvider<ParameterPacketExtension>(
- ParameterPacketExtension.class);
+ = new DefaultPacketExtensionProvider<ParameterPacketExtension>(
+ ParameterPacketExtension.class);
- providerManager.addExtensionProvider(
+ smackInteroperabilityLayer.addExtensionProvider(
ParameterPacketExtension.ELEMENT_NAME,
ColibriConferenceIQ.NAMESPACE,
parameterProvider);
- providerManager.addExtensionProvider(
+ smackInteroperabilityLayer.addExtensionProvider(
ParameterPacketExtension.ELEMENT_NAME,
SourcePacketExtension.NAMESPACE,
parameterProvider);
// Shutdown IQ
- providerManager.addIQProvider(
- GracefulShutdownIQ.ELEMENT_NAME,
- GracefulShutdownIQ.NAMESPACE,
+ smackInteroperabilityLayer.addIQProvider(
+ ShutdownIQ.GRACEFUL_ELEMENT_NAME,
+ ShutdownIQ.NAMESPACE,
+ this);
+ smackInteroperabilityLayer.addIQProvider(
+ ShutdownIQ.FORCE_ELEMENT_NAME,
+ ShutdownIQ.NAMESPACE,
this);
// Shutdown extension
PacketExtensionProvider shutdownProvider
- = new DefaultPacketExtensionProvider
- <ColibriConferenceIQ.GracefulShutdown>(
- ColibriConferenceIQ.GracefulShutdown.class);
+ = new DefaultPacketExtensionProvider
+ <ColibriConferenceIQ.GracefulShutdown>(
+ ColibriConferenceIQ.GracefulShutdown.class);
- providerManager.addExtensionProvider(
- ColibriConferenceIQ.GracefulShutdown.ELEMENT_NAME,
- ColibriConferenceIQ.GracefulShutdown.NAMESPACE,
- shutdownProvider);
+ smackInteroperabilityLayer.addExtensionProvider(
+ ColibriConferenceIQ.GracefulShutdown.ELEMENT_NAME,
+ ColibriConferenceIQ.GracefulShutdown.NAMESPACE,
+ shutdownProvider);
// ColibriStatsIQ
- providerManager.addIQProvider(
- ColibriStatsIQ.ELEMENT_NAME,
- ColibriStatsIQ.NAMESPACE,
- this);
+ smackInteroperabilityLayer.addIQProvider(
+ ColibriStatsIQ.ELEMENT_NAME,
+ ColibriStatsIQ.NAMESPACE,
+ this);
// ColibriStatsExtension
PacketExtensionProvider statsProvider
- = new DefaultPacketExtensionProvider<ColibriStatsExtension>(
- ColibriStatsExtension.class);
+ = new DefaultPacketExtensionProvider<ColibriStatsExtension>(
+ ColibriStatsExtension.class);
- providerManager.addExtensionProvider(
- ColibriStatsExtension.ELEMENT_NAME,
- ColibriStatsExtension.NAMESPACE,
- statsProvider);
+ smackInteroperabilityLayer.addExtensionProvider(
+ ColibriStatsExtension.ELEMENT_NAME,
+ ColibriStatsExtension.NAMESPACE,
+ statsProvider);
// ColibriStatsExtension.Stat
PacketExtensionProvider statProvider
- = new DefaultPacketExtensionProvider<ColibriStatsExtension.Stat>(
- ColibriStatsExtension.Stat.class);
-
- providerManager.addExtensionProvider(
- ColibriStatsExtension.Stat.ELEMENT_NAME,
- ColibriStatsExtension.NAMESPACE,
- statProvider);
+ = new DefaultPacketExtensionProvider
+ <ColibriStatsExtension.Stat>(
+ ColibriStatsExtension.Stat.class);
+
+ smackInteroperabilityLayer.addExtensionProvider(
+ ColibriStatsExtension.Stat.ELEMENT_NAME,
+ ColibriStatsExtension.NAMESPACE,
+ statProvider);
+
+
}
private void addChildExtension(
@@ -199,8 +212,7 @@ public class ColibriIQProvider
throws Exception
{
PacketExtensionProvider extensionProvider
- = (PacketExtensionProvider)
- ProviderManager.getInstance().getExtensionProvider(
+ = smackInteroperabilityLayer.getExtensionProvider(
name,
namespace);
PacketExtension extension;
@@ -416,6 +428,15 @@ public class ColibriIQProvider
if ((expire != null) && (expire.length() != 0))
channel.setExpire(Integer.parseInt(expire));
+ String packetDelay
+ = parser.getAttributeValue(
+ "",
+ ColibriConferenceIQ.Channel
+ .PACKET_DELAY_ATTR_NAME);
+ if (!StringUtils.isNullOrEmpty(packetDelay))
+ channel.setPacketDelay(
+ Integer.parseInt(packetDelay));
+
// host
String host
= parser.getAttributeValue(
@@ -464,6 +485,18 @@ public class ColibriIQProvider
channel.setAdaptiveLastN(
Boolean.parseBoolean(adaptiveLastN));
+ String adaptiveSimulcast
+ = parser.getAttributeValue(
+ "",
+ ColibriConferenceIQ.Channel
+ .ADAPTIVE_SIMULCAST_ATTR_NAME);
+
+ if (!StringUtils.isNullOrEmpty(adaptiveSimulcast))
+ {
+ channel.setAdaptiveSimulcast(
+ Boolean.parseBoolean(adaptiveSimulcast));
+ }
+
// simulcastMode
String simulcastMode
= parser.getAttributeValue(
@@ -802,12 +835,12 @@ public class ColibriIQProvider
iq = conference;
}
- else if (GracefulShutdownIQ.ELEMENT_NAME.equals(parser.getName())
- && GracefulShutdownIQ.NAMESPACE.equals(namespace))
+ else if (ShutdownIQ.NAMESPACE.equals(namespace) &&
+ ShutdownIQ.isValidElementName(parser.getName()))
{
String rootElement = parser.getName();
- iq = new GracefulShutdownIQ();
+ iq = ShutdownIQ.createShutdownIQ(rootElement);
boolean done = false;
@@ -825,12 +858,6 @@ public class ColibriIQProvider
}
break;
}
-
- case XmlPullParser.TEXT:
- {
- // Parse some text here
- break;
- }
}
}
}
@@ -891,12 +918,6 @@ public class ColibriIQProvider
}
break;
}
-
- case XmlPullParser.TEXT:
- {
- // Parse some text here
- break;
- }
}
}
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriStreamConnector.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriStreamConnector.java
index d5a6ce1..ef80392 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriStreamConnector.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ColibriStreamConnector.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,74 +15,74 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.protocol.jabber.extensions.colibri;
-
-import org.jitsi.service.neomedia.*;
-
-/**
- * Implements a <tt>StreamConnector</tt> which allows sharing a specific
- * <tt>StreamConnector</tt> instance among multiple <tt>TransportManager</tt>s
- * for the purposes of the Jitsi Videobridge.
- *
- * @author Lyubomir Marinov
- */
-public class ColibriStreamConnector
- extends StreamConnectorDelegate<StreamConnector>
-{
- /**
- * Initializes a new <tt>ColibriStreamConnector</tt> instance which is to
- * share a specific <tt>StreamConnector</tt> instance among multiple
- * <tt>TransportManager</tt>s for the purposes of the Jitsi Videobridge.
- *
- * @param streamConnector the <tt>StreamConnector</tt> instance to be shared
- * by the new instance among multiple <tt>TransportManager</tt>s for the
- * purposes of the Jitsi Videobridge
- */
- public ColibriStreamConnector(StreamConnector streamConnector)
- {
- super(streamConnector);
- }
-
- /**
- * {@inheritDoc}
- *
- * Overrides {@link StreamConnectorDelegate#close()} in order to prevent the
- * closing of the <tt>StreamConnector</tt> wrapped by this instance because
- * the latter is shared and it is not clear whether no
- * <tt>TransportManager</tt> is using it.
- */
- @Override
- public void close()
- {
- /*
- * Do not close the shared StreamConnector because it is not clear
- * whether no TransportManager is using it.
- */
- }
-
- /**
- * {@inheritDoc}
- *
- * Invokes {@link #close()} on this instance when it is clear that no
- * <tt>TransportManager</tt> is using it in order to release the resources
- * allocated by this instance throughout its life time (that need explicit
- * disposal).
- */
- @Override
- protected void finalize()
- throws Throwable
- {
- try
- {
- /*
- * Close the shared StreamConnector because it is clear that no
- * TrasportManager is using it.
- */
- super.close();
- }
- finally
- {
- super.finalize();
- }
- }
-}
+package net.java.sip.communicator.impl.protocol.jabber.extensions.colibri;
+
+import org.jitsi.service.neomedia.*;
+
+/**
+ * Implements a <tt>StreamConnector</tt> which allows sharing a specific
+ * <tt>StreamConnector</tt> instance among multiple <tt>TransportManager</tt>s
+ * for the purposes of the Jitsi Videobridge.
+ *
+ * @author Lyubomir Marinov
+ */
+public class ColibriStreamConnector
+ extends StreamConnectorDelegate<StreamConnector>
+{
+ /**
+ * Initializes a new <tt>ColibriStreamConnector</tt> instance which is to
+ * share a specific <tt>StreamConnector</tt> instance among multiple
+ * <tt>TransportManager</tt>s for the purposes of the Jitsi Videobridge.
+ *
+ * @param streamConnector the <tt>StreamConnector</tt> instance to be shared
+ * by the new instance among multiple <tt>TransportManager</tt>s for the
+ * purposes of the Jitsi Videobridge
+ */
+ public ColibriStreamConnector(StreamConnector streamConnector)
+ {
+ super(streamConnector);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Overrides {@link StreamConnectorDelegate#close()} in order to prevent the
+ * closing of the <tt>StreamConnector</tt> wrapped by this instance because
+ * the latter is shared and it is not clear whether no
+ * <tt>TransportManager</tt> is using it.
+ */
+ @Override
+ public void close()
+ {
+ /*
+ * Do not close the shared StreamConnector because it is not clear
+ * whether no TransportManager is using it.
+ */
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Invokes {@link #close()} on this instance when it is clear that no
+ * <tt>TransportManager</tt> is using it in order to release the resources
+ * allocated by this instance throughout its life time (that need explicit
+ * disposal).
+ */
+ @Override
+ protected void finalize()
+ throws Throwable
+ {
+ try
+ {
+ /*
+ * Close the shared StreamConnector because it is clear that no
+ * TrasportManager is using it.
+ */
+ super.close();
+ }
+ finally
+ {
+ super.finalize();
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ShutdownIQ.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ShutdownIQ.java
new file mode 100644
index 0000000..4df251b
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/ShutdownIQ.java
@@ -0,0 +1,134 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.protocol.jabber.extensions.colibri;
+
+import org.jivesoftware.smack.packet.*;
+
+/**
+ * The IQ used to trigger the graceful shutdown mode of the videobridge or force
+ * shutdown the one which receives the stanza(given that source JID is
+ * authorized to do so).
+ *
+ * @author Pawel Domas
+ */
+public class ShutdownIQ
+ extends IQ
+{
+ /**
+ * XML namespace name for shutdown IQs.
+ */
+ final static public String NAMESPACE = ColibriConferenceIQ.NAMESPACE;
+
+ /**
+ * Force shutdown IQ element name.
+ */
+ final static public String FORCE_ELEMENT_NAME = "force-shutdown";
+
+ /**
+ * Graceful shutdown IQ element name.
+ */
+ final static public String GRACEFUL_ELEMENT_NAME = "graceful-shutdown";
+
+ /**
+ * The element name of this IQ. Either {@link #FORCE_ELEMENT_NAME} or
+ * {@link #GRACEFUL_ELEMENT_NAME}.
+ */
+ private final String elementName;
+
+ /**
+ * Checks if given element is a valid one for <tt>ShutdownIQ</tt>.
+ *
+ * @param elementName the name if XML element name inside of the IQ.
+ *
+ * @return <tt>true</tt> if given <tt>elementName</tt> is correct for
+ * <tt>ShutdownIQ</tt>.
+ */
+ public static boolean isValidElementName(String elementName)
+ {
+ return GRACEFUL_ELEMENT_NAME.equals(elementName)
+ || FORCE_ELEMENT_NAME.equals(elementName);
+ }
+
+ /**
+ * Creates shutdown IQ for given element name.
+ *
+ * @param elementName can be {@link #FORCE_ELEMENT_NAME} or
+ * {@link #GRACEFUL_ELEMENT_NAME}
+ *
+ * @return new <tt>ShutdownIQ</tt> instance for given element name.
+ *
+ * @throws IllegalArgumentException if given element name is neither
+ * {@link #FORCE_ELEMENT_NAME} nor {@link #GRACEFUL_ELEMENT_NAME}.
+ */
+ public static ShutdownIQ createShutdownIQ(String elementName)
+ {
+ if (!isValidElementName(elementName))
+ {
+ throw new IllegalArgumentException(
+ "Invalid element name: " + elementName);
+ }
+
+ if (GRACEFUL_ELEMENT_NAME.equals(elementName))
+ {
+ return createGracefulShutdownIQ();
+ }
+ else
+ {
+ return createForceShutdownIQ();
+ }
+ }
+
+ /**
+ * Creates and returns new instance of graceful shutdown IQ.
+ */
+ public static ShutdownIQ createGracefulShutdownIQ()
+ {
+ return new ShutdownIQ(GRACEFUL_ELEMENT_NAME);
+ }
+
+ /**
+ * Creates and returns new instance of force shutdown IQ.
+ */
+ public static ShutdownIQ createForceShutdownIQ()
+ {
+ return new ShutdownIQ(FORCE_ELEMENT_NAME);
+ }
+
+ private ShutdownIQ(String elementName)
+ {
+ this.elementName = elementName;
+ }
+
+ /**
+ * Returns <tt>true</tt> if this IQ instance is a "graceful shutdown" one.
+ * Otherwise it is a force shutdown IQ.
+ */
+ public boolean isGracefulShutdown()
+ {
+ return elementName.equals(GRACEFUL_ELEMENT_NAME);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getChildElementXML()
+ {
+ return "<" + elementName + " xmlns='" + NAMESPACE + "' />";
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/GracefulShutdownIQ.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/health/HealthCheckIQ.java
index 9808b11..661bb1b 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/colibri/GracefulShutdownIQ.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/health/HealthCheckIQ.java
@@ -15,23 +15,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.protocol.jabber.extensions.colibri;
+package net.java.sip.communicator.impl.protocol.jabber.extensions.health;
import org.jivesoftware.smack.packet.*;
/**
- * The IQ used to trigger the graceful shutdown mode of the videobridge which
- * receives the stanza(given that source JID is authorized to start it).
+ * The health check IQ used to trigger health checks on the Jitsi Videobridge.
*
* @author Pawel Domas
*/
-public class GracefulShutdownIQ
+public class HealthCheckIQ
extends IQ
{
- public static final String NAMESPACE = ColibriConferenceIQ.NAMESPACE;
+ /**
+ * Health check IQ element name.
+ */
+ final static public String ELEMENT_NAME = "healthcheck";
- public static final String ELEMENT_NAME = "graceful-shutdown";
+ /**
+ * XML namespace name for health check IQs.
+ */
+ final static public String NAMESPACE
+ = "http://jitsi.org/protocol/healthcheck";
+ /**
+ * {@inheritDoc}
+ */
@Override
public String getChildElementXML()
{
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/health/HealthCheckIQProvider.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/health/HealthCheckIQProvider.java
new file mode 100644
index 0000000..9c2903d
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/health/HealthCheckIQProvider.java
@@ -0,0 +1,94 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.protocol.jabber.extensions.health;
+
+import net.java.sip.communicator.service.protocol.jabber.*;
+
+import org.jivesoftware.smack.packet.*;
+import org.jivesoftware.smack.provider.*;
+
+import org.xmlpull.v1.*;
+
+/**
+ * The <tt>IQProvider</tt> for {@link HealthCheckIQ}.
+ *
+ * @author Pawel Domas
+ */
+public class HealthCheckIQProvider
+ implements IQProvider
+{
+ /**
+ * Registers <tt>HealthCheckIQProvider</tt> as an <tt>IQProvider</tt>
+ * in {@link AbstractSmackInteroperabilityLayer}.
+ */
+ public static void registerIQProvider()
+ {
+ AbstractSmackInteroperabilityLayer smackInteropLayer =
+ AbstractSmackInteroperabilityLayer.getInstance();
+
+ // ColibriStatsIQ
+ smackInteropLayer.addIQProvider(
+ HealthCheckIQ.ELEMENT_NAME,
+ HealthCheckIQ.NAMESPACE,
+ new HealthCheckIQProvider());
+ }
+
+ /**
+ * Parses <tt>HealthCheckIQ</tt>.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public IQ parseIQ(XmlPullParser parser)
+ throws Exception
+ {
+ String namespace = parser.getNamespace();
+ IQ iq;
+
+ if (HealthCheckIQ.ELEMENT_NAME.equals(parser.getName())
+ && HealthCheckIQ.NAMESPACE.equals(namespace))
+ {
+ String rootElement = parser.getName();
+
+ iq = new HealthCheckIQ();
+
+ boolean done = false;
+
+ while (!done)
+ {
+ switch (parser.next())
+ {
+ case XmlPullParser.END_TAG:
+ {
+ String name = parser.getName();
+
+ if (rootElement.equals(name))
+ {
+ done = true;
+ }
+ break;
+ }
+ }
+ }
+ }
+ else
+ iq = null;
+
+ return iq;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/JibriIq.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/JibriIq.java
new file mode 100644
index 0000000..8b964af
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/JibriIq.java
@@ -0,0 +1,413 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.protocol.jabber.extensions.jibri;
+
+import org.jitsi.util.*;
+
+import org.jivesoftware.smack.packet.*;
+
+import java.util.*;
+
+/**
+ * The IQ used to control conference recording with Jibri component.
+ *
+ * Start the recording:
+ *
+ * 1. Send Jibri IQ with {@link Action#START} to Jibri.
+ * 2. Jibri replies with RESULT and status {@link Status#PENDING}.
+ * 3. Jibri sends SET IQ with status {@link Status#ON} once recording actually
+ * starts.
+ *
+ * Stop the recording:
+ *
+ * 1. Send Jibri IQ with {@link Action#STOP} to Jibri.
+ * 2. Jibri replies with {@link Status#OFF} immediately if the recording has
+ * been stopped already or sends separate Jibri SET IQ later on if it takes
+ * more time.
+ *
+ * @author lishunyang
+ * @author Pawel Domas
+ */
+public class JibriIq
+ extends IQ
+{
+ /**
+ * Attribute name of "action".
+ */
+ public static final String ACTION_ATTR_NAME = "action";
+
+ /**
+ * XML element name of the Jibri IQ.
+ */
+ public static final String ELEMENT_NAME = "jibri";
+
+ /**
+ * XML namespace of the Jibri IQ.
+ */
+ public static final String NAMESPACE = "http://jitsi.org/protocol/jibri";
+
+ /**
+ * The name of XML attribute which stores the recording status.
+ */
+ static final String STATUS_ATTR_NAME = "status";
+
+ /**
+ * The name of XML attribute which stores the stream id.
+ */
+ static final String STREAM_ID_ATTR_NAME = "streamid";
+
+ /**
+ * The name of XML attribute which stores the name of the conference room to
+ * be recorded.
+ */
+ static final String ROOM_ATTR_NAME = "room";
+
+ /**
+ * Holds the action.
+ */
+ private Action action = Action.UNDEFINED;
+
+ /**
+ * XMPPError stores error details for {@link Status#FAILED}.
+ */
+ private XMPPError error;
+
+ /**
+ * Holds recording status.
+ */
+ private Status status = Status.UNDEFINED;
+
+ /**
+ * The ID of the stream which will be used to record the conference. The
+ * value depends on recording service provider.
+ */
+ private String streamId = null;
+
+ /**
+ * The name of the conference room to be recorded.
+ */
+ private String room = null;
+
+ /**
+ * Returns the value of {@link #STREAM_ID_ATTR_NAME} attribute.
+ * @return a <tt>String</tt> which contains the value of "stream id"
+ * attribute or <tt>null</tt> if empty.
+ */
+ public String getStreamId()
+ {
+ return streamId;
+ }
+
+ /**
+ * Sets the value for {@link #STREAM_ID_ATTR_NAME} attribute.
+ * @param streamId a <tt>String</tt> for the stream id attribute or
+ * <tt>null</tt> to remove it from XML element.
+ */
+ public void setStreamId(String streamId)
+ {
+ this.streamId = streamId;
+ }
+
+ /**
+ * Returns the value of {@link #ROOM_ATTR_NAME} attribute.
+ * @return a <tt>String</tt> which contains the value of the room attribute
+ * or <tt>null</tt> if empty.
+ * @see #room
+ */
+ public String getRoom()
+ {
+ return room;
+ }
+
+ /**
+ * Sets the value for {@link #ROOM_ATTR_NAME} attribute.
+ * @param room a <tt>String</tt> for the room attribute or <tt>null</tt> to
+ * remove it from XML element.
+ * @see #room
+ */
+ public void setRoom(String room)
+ {
+ this.room = room;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getChildElementXML()
+ {
+ StringBuilder xml = new StringBuilder();
+
+ xml.append('<').append(ELEMENT_NAME);
+ xml.append(" xmlns='").append(NAMESPACE).append("' ");
+
+ if (action != Action.UNDEFINED)
+ {
+ printStringAttribute(xml, ACTION_ATTR_NAME, action.toString());
+ }
+
+ if (status != Status.UNDEFINED)
+ {
+ printStringAttribute(xml, STATUS_ATTR_NAME, status.toString());
+ }
+
+ if (room != null)
+ {
+ printStringAttribute(xml, ROOM_ATTR_NAME, room);
+ }
+
+ if (streamId != null)
+ {
+ printStringAttribute(xml, STREAM_ID_ATTR_NAME, streamId);
+ }
+
+ Collection<PacketExtension> extensions = getExtensions();
+ if (extensions.size() > 0)
+ {
+ xml.append(">");
+ for (PacketExtension extension : extensions)
+ {
+ xml.append(extension.toXML());
+ }
+ xml.append("</").append(ELEMENT_NAME).append(">");
+ }
+ else
+ {
+ xml.append("/>");
+ }
+
+ return xml.toString();
+ }
+
+ private void printStringAttribute(
+ StringBuilder xml, String attrName, String attr)
+ {
+ if (!StringUtils.isNullOrEmpty(attr))
+ {
+ attr = org.jivesoftware.smack.util.StringUtils.escapeForXML(attr);
+ xml.append(attrName).append("='")
+ .append(attr).append("' ");
+ }
+ }
+
+ /**
+ * Sets the value of 'action' attribute.
+ *
+ * @param action the value to be set as 'action' attribute of this IQ.
+ */
+ public void setAction(Action action)
+ {
+ this.action = action;
+ }
+
+ /**
+ * Returns the value of 'action' attribute.
+ */
+ public Action getAction()
+ {
+ return action;
+ }
+
+ /**
+ * Sets the value of 'status' attribute.
+ */
+ public void setStatus(Status status)
+ {
+ this.status = status;
+ }
+
+ /**
+ * Returns the value of 'status' attribute.
+ */
+ public Status getStatus()
+ {
+ return status;
+ }
+
+ /**
+ * Sets the <tt>XMPPError</tt> which will provide details about Jibri
+ * failure. It is expected to be set when this IQ's status value is
+ * {@link Status#FAILED}.
+ *
+ * @param error <tt>XMPPError</tt> to be set on this <tt>JibriIq</tt>
+ * instance.
+ */
+ public void setXMPPError(XMPPError error)
+ {
+ this.error = error;
+ }
+
+ /**
+ * Returns {@link XMPPError} with Jibri error details when the status is
+ * {@link Status#FAILED}.
+ */
+ public XMPPError getError()
+ {
+ return error;
+ }
+
+ /**
+ * Enumerative value of attribute "action" in recording extension.
+ *
+ * @author lishunyang
+ * @author Pawel Domas
+ *
+ */
+ public enum Action
+ {
+ /**
+ * Start the recording.
+ */
+ START("start"),
+ /**
+ * Stop the recording.
+ */
+ STOP("stop"),
+ /**
+ * Unknown/uninitialized
+ */
+ UNDEFINED("undefined");
+
+ private String name;
+
+ Action(String name)
+ {
+ this.name = name;
+ }
+
+ @Override
+ public String toString()
+ {
+ return name;
+ }
+
+ /**
+ * Parses <tt>Action</tt> from given string.
+ *
+ * @param action the string representation of <tt>Action</tt>.
+ *
+ * @return <tt>Action</tt> value for given string or
+ * {@link #UNDEFINED} if given string does not
+ * reflect any of valid values.
+ */
+ public static Action parse(String action)
+ {
+ if (StringUtils.isNullOrEmpty(action))
+ return UNDEFINED;
+
+ try
+ {
+ return Action.valueOf(action.toUpperCase());
+ }
+ catch(IllegalArgumentException e)
+ {
+ return UNDEFINED;
+ }
+ }
+ }
+
+ /**
+ * The enumeration of recording status values.
+ */
+ public enum Status
+ {
+ /**
+ * Recording is in progress.
+ */
+ ON("on"),
+
+ /**
+ * Recording stopped.
+ */
+ OFF("off"),
+
+ /**
+ * Starting the recording process.
+ */
+ PENDING("pending"),
+
+ /**
+ * The recorder has failed and the service is retrying on another
+ * instance.
+ */
+ RETRYING("retrying"),
+
+ /**
+ * An error occurred any point during startup, recording or shutdown.
+ */
+ FAILED("failed"),
+
+ /**
+ * There are Jibri instances connected to the system, but all of them
+ * are currently busy.
+ */
+ BUSY("busy"),
+
+ /**
+ * Unknown/uninitialized.
+ */
+ UNDEFINED("undefined");
+
+ /**
+ * Status name holder.
+ */
+ private String name;
+
+ /**
+ * Creates new {@link Status} instance.
+ * @param name a string corresponding to one of {@link Status} values.
+ */
+ Status(String name)
+ {
+ this.name = name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString()
+ {
+ return name;
+ }
+
+ /**
+ * Parses <tt>Status</tt> from given string.
+ *
+ * @param status the string representation of <tt>Status</tt>.
+ *
+ * @return <tt>Status</tt> value for given string or
+ * {@link #UNDEFINED} if given string does not
+ * reflect any of valid values.
+ */
+ public static Status parse(String status)
+ {
+ if (StringUtils.isNullOrEmpty(status))
+ return UNDEFINED;
+
+ try
+ {
+ return Status.valueOf(status.toUpperCase());
+ }
+ catch(IllegalArgumentException e)
+ {
+ return UNDEFINED;
+ }
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/JibriIqProvider.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/JibriIqProvider.java
new file mode 100644
index 0000000..155853c
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/JibriIqProvider.java
@@ -0,0 +1,112 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.protocol.jabber.extensions.jibri;
+
+import org.jitsi.util.*;
+
+import org.jivesoftware.smack.packet.*;
+import org.jivesoftware.smack.provider.*;
+import org.jivesoftware.smack.util.PacketParserUtils;
+
+import org.xmlpull.v1.*;
+
+/**
+ * Parses {@link JibriIq}.
+ */
+public class JibriIqProvider
+ implements IQProvider
+{
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IQ parseIQ(XmlPullParser parser)
+ throws Exception
+ {
+ String namespace = parser.getNamespace();
+
+ // Check the namespace
+ if (!JibriIq.NAMESPACE.equals(namespace))
+ {
+ return null;
+ }
+
+ String rootElement = parser.getName();
+
+ JibriIq iq;
+
+ if (JibriIq.ELEMENT_NAME.equals(rootElement))
+ {
+ iq = new JibriIq();
+
+ String action
+ = parser.getAttributeValue("", JibriIq.ACTION_ATTR_NAME);
+ iq.setAction(JibriIq.Action.parse(action));
+
+ String status
+ = parser.getAttributeValue("", JibriIq.STATUS_ATTR_NAME);
+ iq.setStatus(JibriIq.Status.parse(status));
+
+ String room
+ = parser.getAttributeValue("", JibriIq.ROOM_ATTR_NAME);
+ if (!StringUtils.isNullOrEmpty(room))
+ iq.setRoom(room);
+
+ String streamId
+ = parser.getAttributeValue("", JibriIq.STREAM_ID_ATTR_NAME);
+ if (!StringUtils.isNullOrEmpty(streamId))
+ iq.setStreamId(streamId);
+ }
+ else
+ {
+ return null;
+ }
+
+ boolean done = false;
+
+ while (!done)
+ {
+ switch (parser.next())
+ {
+ case XmlPullParser.START_TAG:
+ {
+ String name = parser.getName();
+
+ if ("error".equals(name))
+ {
+ XMPPError error = PacketParserUtils.parseError(parser);
+ iq.setXMPPError(error);
+ }
+ break;
+ }
+ case XmlPullParser.END_TAG:
+ {
+ String name = parser.getName();
+
+ if (rootElement.equals(name))
+ {
+ done = true;
+ }
+ break;
+ }
+ }
+ }
+
+ return iq;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/JibriStatusPacketExt.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/JibriStatusPacketExt.java
new file mode 100644
index 0000000..e046b68
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/JibriStatusPacketExt.java
@@ -0,0 +1,121 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.protocol.jabber.extensions.jibri;
+
+import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
+
+import org.jitsi.util.*;
+
+import org.jivesoftware.smack.provider.*;
+
+/**
+ * Status extension included in MUC presence by Jibri to indicate it's status.
+ * One of:
+ * <li>idle</li> - the instance is idle and can be used for recording
+ * <li>busy</li> - the instance is currently recording or doing something very
+ * important and should not be disturbed
+ *
+ *
+ */
+public class JibriStatusPacketExt
+ extends AbstractPacketExtension
+{
+ /**
+ * The namespace of this packet extension.
+ */
+ public static final String NAMESPACE = JibriIq.NAMESPACE;
+
+ /**
+ * XML element name of this packet extension.
+ */
+ public static final String ELEMENT_NAME = "jibri-status";
+
+ private static final String STATUS_ATTRIBUTE = "status";
+
+ /**
+ * Creates new instance of <tt>VideoMutedExtension</tt>.
+ */
+ public JibriStatusPacketExt()
+ {
+ super(NAMESPACE, ELEMENT_NAME);
+ }
+
+ static public void registerExtensionProvider()
+ {
+ ProviderManager.getInstance().addExtensionProvider(
+ ELEMENT_NAME,
+ NAMESPACE,
+ new DefaultPacketExtensionProvider<JibriStatusPacketExt>(
+ JibriStatusPacketExt.class)
+ );
+ }
+
+ public Status getStatus()
+ {
+ return Status.parse(getAttributeAsString(STATUS_ATTRIBUTE));
+ }
+
+ public void setStatus(Status status)
+ {
+ setAttribute(STATUS_ATTRIBUTE, String.valueOf(status));
+ }
+
+ public enum Status
+ {
+ IDLE("idle"),
+ BUSY("busy"),
+ UNDEFINED("undefined");
+
+ private String name;
+
+ Status(String name)
+ {
+ this.name = name;
+ }
+
+ @Override
+ public String toString()
+ {
+ return name;
+ }
+
+ /**
+ * Parses <tt>Status</tt> from given string.
+ *
+ * @param status the string representation of <tt>Status</tt>.
+ *
+ * @return <tt>Status</tt> value for given string or
+ * {@link #UNDEFINED} if given string does not
+ * reflect any of valid values.
+ */
+ public static Status parse(String status)
+ {
+ if (StringUtils.isNullOrEmpty(status))
+ return UNDEFINED;
+
+ try
+ {
+ return Status.valueOf(status.toUpperCase());
+ }
+ catch(IllegalArgumentException e)
+ {
+ return UNDEFINED;
+ }
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/RecordingStatus.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/RecordingStatus.java
new file mode 100644
index 0000000..13177cf
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/RecordingStatus.java
@@ -0,0 +1,126 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.protocol.jabber.extensions.jibri;
+
+import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
+
+import org.jivesoftware.smack.packet.*;
+
+import java.util.*;
+
+/**
+ * The packet extension added to Jicofo MUC presence to broadcast current
+ * recording status to all conference participants.
+ *
+ * Status meaning:
+ * <tt>{@link JibriIq.Status#UNDEFINED}</tt> - recording not available
+ * <tt>{@link JibriIq.Status#OFF}</tt> - recording stopped(available to start)
+ * <tt>{@link JibriIq.Status#PENDING}</tt> - starting recording
+ * <tt>{@link JibriIq.Status#ON}</tt> - recording in progress
+ */
+public class RecordingStatus
+ extends AbstractPacketExtension
+{
+ /**
+ * The namespace of this packet extension.
+ */
+ public static final String NAMESPACE = JibriIq.NAMESPACE;
+
+ /**
+ * XML element name of this packet extension.
+ */
+ public static final String ELEMENT_NAME = "jibri-recording-status";
+
+ /**
+ * The name of XML attribute which holds the recording status.
+ */
+ private static final String STATUS_ATTRIBUTE = "status";
+
+ public RecordingStatus()
+ {
+ super(NAMESPACE, ELEMENT_NAME);
+ }
+
+ /**
+ * Returns the value of current recording status stored in it's attribute.
+ * @return one of {@link JibriIq.Status}
+ */
+ public JibriIq.Status getStatus()
+ {
+ String statusAttr = getAttributeAsString(STATUS_ATTRIBUTE);
+
+ return JibriIq.Status.parse(statusAttr);
+ }
+
+ /**
+ * Sets new value for the recording status.
+ * @param status one of {@link JibriIq.Status}
+ */
+ public void setStatus(JibriIq.Status status)
+ {
+ setAttribute(STATUS_ATTRIBUTE, String.valueOf(status));
+ }
+
+ /**
+ * Returns <tt>XMPPError</tt> associated with current
+ * {@link RecordingStatus}.
+ */
+ public XMPPError getError()
+ {
+ XMPPErrorPE errorPe = getErrorPE();
+ return errorPe != null ? errorPe.getError() : null;
+ }
+
+ /**
+ * Gets <tt>{@link XMPPErrorPE}</tt> from the list of child packet
+ * extensions.
+ * @return {@link XMPPErrorPE} or <tt>null</tt> if not found.
+ */
+ private XMPPErrorPE getErrorPE()
+ {
+ List<? extends PacketExtension> errorPe
+ = getChildExtensionsOfType(XMPPErrorPE.class);
+
+ return (XMPPErrorPE) (!errorPe.isEmpty() ? errorPe.get(0) : null);
+ }
+
+ /**
+ * Sets <tt>XMPPError</tt> on this <tt>RecordingStatus</tt>.
+ * @param error <tt>XMPPError</tt> to add error details to this
+ * <tt>RecordingStatus</tt> instance or <tt>null</tt> to have it removed.
+ */
+ public void setError(XMPPError error)
+ {
+ if (error != null)
+ {
+ // Wrap and add XMPPError as packet extension
+ XMPPErrorPE errorPe = getErrorPE();
+ if (errorPe == null)
+ {
+ errorPe = new XMPPErrorPE(error);
+ addChildExtension(errorPe);
+ }
+ errorPe.setError(error);
+ }
+ else
+ {
+ // Remove error PE
+ getChildExtensions().remove(getErrorPE());
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/XMPPErrorPE.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/XMPPErrorPE.java
new file mode 100644
index 0000000..a72f310
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jibri/XMPPErrorPE.java
@@ -0,0 +1,93 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.protocol.jabber.extensions.jibri;
+
+import org.jivesoftware.smack.packet.*;
+
+import java.util.*;
+
+/**
+ * Wraps Smack's <tt>XMPPError</tt> into <tt>PacketExtension</tt>, so that it
+ * can be easily inserted into {@link RecordingStatus}.
+ */
+public class XMPPErrorPE
+ implements PacketExtension
+{
+ /**
+ * <tt>XMPPError</tt> wrapped into this <tt>XMPPErrorPE</tt>.
+ */
+ private XMPPError error;
+
+ /**
+ * Creates new instance of <tt>XMPPErrorPE</tt>.
+ * @param xmppError the instance of <tt>XMPPError</tt> that will be wrapped
+ * by the newly created <tt>XMPPErrorPE</tt>.
+ */
+ public XMPPErrorPE(XMPPError xmppError)
+ {
+ setError(xmppError);
+ }
+
+ /**
+ * Returns the underlying instance of <tt>XMPPError</tt>.
+ */
+ public XMPPError getError()
+ {
+ return error;
+ }
+
+ /**
+ * Sets new instance of <tt>XMPPError</tt> to be wrapped by this
+ * <tt>XMPPErrorPE</tt>.
+ * @param error <tt>XMPPError</tt> that will be wrapped by this
+ * <TT>XMPPErrorPE</TT>.
+ */
+ public void setError(XMPPError error)
+ {
+ Objects.requireNonNull(error, "error");
+
+ this.error = error;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getElementName()
+ {
+ return "error";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getNamespace()
+ {
+ return "";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toXML()
+ {
+ return error.toXML();
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/CandidatePacketExtension.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/CandidatePacketExtension.java
index 0c5b190..46b1e77 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/CandidatePacketExtension.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/CandidatePacketExtension.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,441 +15,441 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.protocol.jabber.extensions.jingle;
-
-import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
-import org.ice4j.ice.*;
-
-/**
- * @author Emil Ivov
- */
-public class CandidatePacketExtension extends AbstractPacketExtension
- implements Comparable<CandidatePacketExtension>
-{
- /**
- * The name of the "candidate" element.
- */
- public static final String ELEMENT_NAME = "candidate";
-
- /**
- * The name of the "component" element.
- */
- public static final String COMPONENT_ATTR_NAME = "component";
-
- /**
- * The "component" ID for RTP components.
- */
- public static final int RTP_COMPONENT_ID = 1;
-
- /**
- * The "component" ID for RTCP components.
- */
- public static final int RTCP_COMPONENT_ID = 2;
-
- /**
- * The name of the "foundation" element.
- */
- public static final String FOUNDATION_ATTR_NAME = "foundation";
-
- /**
- * The name of the "generation" element.
- */
- public static final String GENERATION_ATTR_NAME = "generation";
-
- /**
- * The name of the "id" element.
- */
- public static final String ID_ATTR_NAME = "id";
-
- /**
- * The name of the "ip" element.
- */
- public static final String IP_ATTR_NAME = "ip";
-
- /**
- * The name of the "network" element.
- */
- public static final String NETWORK_ATTR_NAME = "network";
-
- /**
- * The name of the "port" element.
- */
- public static final String PORT_ATTR_NAME = "port";
-
- /**
- * The name of the "priority" element.
- */
- public static final String PRIORITY_ATTR_NAME = "priority";
-
- /**
- * The name of the "protocol" element.
- */
- public static final String PROTOCOL_ATTR_NAME = "protocol";
-
- /**
- * The name of the "rel-addr" element.
- */
- public static final String REL_ADDR_ATTR_NAME = "rel-addr";
-
- /**
- * The name of the "rel-port" element.
- */
- public static final String REL_PORT_ATTR_NAME = "rel-port";
-
- /**
- * The name of the "type" element.
- */
- public static final String TYPE_ATTR_NAME = "type";
-
- /**
- * The name of the "tcptype" element.
- */
- public static final String TCPTYPE_ATTR_NAME = "tcptype";
-
- /**
- * Creates a new {@link CandidatePacketExtension}
- */
- public CandidatePacketExtension()
- {
- super(null, ELEMENT_NAME);
- }
-
- /**
- * Creates a new {@link CandidatePacketExtension} with the specified
- * <tt>elementName</tt> so that this class would be usable as a
- * <tt>RemoteCandidatePacketExtension</tt> parent.
- *
- * @param elementName the element name that this instance should be using.
- */
- protected CandidatePacketExtension(String elementName)
- {
- super(null, elementName);
- }
-
- /**
- * Sets a component ID as defined in ICE-CORE.
- *
- * @param component a component ID as defined in ICE-CORE.
- */
- public void setComponent(int component)
- {
- super.setAttribute(COMPONENT_ATTR_NAME, component);
- }
-
- /**
- * Returns a component ID as defined in ICE-CORE.
- *
- * @return a component ID as defined in ICE-CORE.
- */
- public int getComponent()
- {
- return super.getAttributeAsInt(COMPONENT_ATTR_NAME);
- }
-
- /**
- * Sets the candidate foundation as defined in ICE-CORE.
- *
- * @param foundation the candidate foundation as defined in ICE-CORE.
- */
- public void setFoundation(String foundation)
- {
- super.setAttribute(FOUNDATION_ATTR_NAME, foundation);
- }
-
- /**
- * Returns the candidate foundation as defined in ICE-CORE.
- *
- * @return the candidate foundation as defined in ICE-CORE.
- */
- public String getFoundation()
- {
- return super.getAttributeAsString(FOUNDATION_ATTR_NAME);
- }
-
- /**
- * Sets this candidate's generation index. A generation is an index,
- * starting at 0, that enables the parties to keep track of updates to the
- * candidate throughout the life of the session. For details, see the ICE
- * Restarts section of XEP-0176.
- *
- * @param generation this candidate's generation index.
- */
- public void setGeneration(int generation)
- {
- super.setAttribute(GENERATION_ATTR_NAME, generation);
- }
-
- /**
- * Returns this candidate's generation. A generation is an index, starting at
- * 0, that enables the parties to keep track of updates to the candidate
- * throughout the life of the session. For details, see the ICE Restarts
- * section of XEP-0176.
- *
- * @return this candidate's generation index.
- */
- public int getGeneration()
- {
- return super.getAttributeAsInt(GENERATION_ATTR_NAME);
- }
-
- /**
- * Sets this candidates's unique identifier <tt>String</tt>.
- *
- * @param id this candidates's unique identifier <tt>String</tt>
- */
- public void setID(String id)
- {
- super.setAttribute(ID_ATTR_NAME, id);
- }
-
- /**
- * Returns this candidates's unique identifier <tt>String</tt>.
- *
- * @return this candidates's unique identifier <tt>String</tt>
- */
- public String getID()
- {
- return super.getAttributeAsString(ID_ATTR_NAME);
- }
-
- /**
- * Sets this candidate's Internet Protocol (IP) address; this can be either
- * an IPv4 address or an IPv6 address.
- *
- * @param ip this candidate's IPv4 or IPv6 address.
- */
- public void setIP(String ip)
- {
- super.setAttribute(IP_ATTR_NAME, ip);
- }
-
- /**
- * Returns this candidate's Internet Protocol (IP) address; this can be
- * either an IPv4 address or an IPv6 address.
- *
- * @return this candidate's IPv4 or IPv6 address.
- */
- public String getIP()
- {
- return super.getAttributeAsString(IP_ATTR_NAME);
- }
-
- /**
- * The network index indicating the interface that the candidate belongs to.
- * The network ID is used for diagnostic purposes only in cases where the
- * calling hardware has more than one Network Interface Card.
- *
- * @param network the network index indicating the interface that the
- * candidate belongs to.
- */
- public void setNetwork(int network)
- {
- super.setAttribute(NETWORK_ATTR_NAME, network);
- }
-
- /**
- * Returns the network index indicating the interface that the candidate
- * belongs to. The network ID is used for diagnostic purposes only in cases
- * where the calling hardware has more than one Network Interface Card.
- *
- * @return the network index indicating the interface that the candidate
- * belongs to.
- */
- public int getNetwork()
- {
- return super.getAttributeAsInt(NETWORK_ATTR_NAME);
- }
-
- /**
- * Sets this candidate's port number.
- *
- * @param port this candidate's port number.
- */
- public void setPort(int port)
- {
- super.setAttribute(PORT_ATTR_NAME, port);
- }
-
- /**
- * Returns this candidate's port number.
- *
- * @return this candidate's port number.
- */
- public int getPort()
- {
- return super.getAttributeAsInt(PORT_ATTR_NAME);
- }
-
- /**
- * This candidate's priority as defined in ICE's RFC 5245
- *
- * @param priority this candidate's priority
- */
- public void setPriority(long priority)
- {
- super.setAttribute(PRIORITY_ATTR_NAME, priority);
- }
-
- /**
- * This candidate's priority as defined in ICE's RFC 5245
- *
- * @return this candidate's priority
- */
- public int getPriority()
- {
- return super.getAttributeAsInt(PRIORITY_ATTR_NAME);
- }
-
- /**
- * Sets this candidate's transport protocol.
- *
- * @param protocol this candidate's transport protocol.
- */
- public void setProtocol(String protocol)
- {
- super.setAttribute(PROTOCOL_ATTR_NAME, protocol);
- }
-
- /**
- * Sets this candidate's transport protocol.
- *
- * @return this candidate's transport protocol.
- */
- public String getProtocol()
- {
- return super.getAttributeAsString(PROTOCOL_ATTR_NAME);
- }
-
- /**
- * Sets this candidate's related address as described by ICE's RFC 5245.
- *
- * @param relAddr this candidate's related address as described by ICE's
- * RFC 5245.
- */
- public void setRelAddr(String relAddr)
- {
- super.setAttribute(REL_ADDR_ATTR_NAME, relAddr);
- }
-
- /**
- * Returns this candidate's related address as described by ICE's RFC 5245.
- *
- * @return this candidate's related address as described by ICE's RFC 5245.
- */
- public String getRelAddr()
- {
- return super.getAttributeAsString(REL_ADDR_ATTR_NAME);
- }
-
- /**
- * Sets this candidate's related port as described by ICE's RFC 5245.
- *
- * @param relPort this candidate's related port as described by ICE's
- * RFC 5245.
- */
- public void setRelPort(int relPort)
- {
- super.setAttribute(REL_PORT_ATTR_NAME, relPort);
- }
-
- /**
- * Returns this candidate's related port as described by ICE's RFC 5245.
- *
- * @return this candidate's related port as described by ICE's RFC 5245.
- */
- public int getRelPort()
- {
- return super.getAttributeAsInt(REL_PORT_ATTR_NAME);
- }
-
- /**
- * Sets a Candidate Type as defined in ICE-CORE. The allowable values are
- * "host" for host candidates, "prflx" for peer reflexive candidates,
- * "relay" for relayed candidates, and "srflx" for server reflexive
- * candidates. All allowable values are enumerated in the {@link
- * CandidateType} enum.
- *
- * @param type this candidates' type as per ICE's RFC 5245.
- */
- public void setType(CandidateType type)
- {
- super.setAttribute(TYPE_ATTR_NAME, type);
- }
-
- /**
- * Returns a Candidate Type as defined in ICE-CORE. The allowable values are
- * "host" for host candidates, "prflx" for peer reflexive candidates,
- * "relay" for relayed candidates, and "srflx" for server reflexive
- * candidates. All allowable values are enumerated in the {@link
- * CandidateType} enum.
- *
- * @return this candidates' type as per ICE's RFC 5245.
- */
- public CandidateType getType()
- {
- return CandidateType.valueOf(getAttributeAsString(TYPE_ATTR_NAME));
- }
-
- /**
- * Compares this instance with another CandidatePacketExtension by
- * preference of type: host < local < prflx < srflx < stun < relay.
- *
- * @return 0 if the type are equal. -1 if this instance type is preferred.
- * Otherwise 1.
- */
- public int compareTo(CandidatePacketExtension candidatePacketExtension)
- {
- // If the types are different.
- if(this.getType() != candidatePacketExtension.getType())
- {
- CandidateType[] types = {
- CandidateType.host,
- CandidateType.local,
- CandidateType.prflx,
- CandidateType.srflx,
- CandidateType.stun,
- CandidateType.relay
- };
- for(int i = 0; i < types.length; ++i)
- {
- // this object is preferred.
- if(types[i] == this.getType())
- {
- return -1;
- }
- // the candidatePacketExtension is preferred.
- else if(types[i] == candidatePacketExtension.getType())
- {
- return 1;
- }
- }
- }
- // If the types are equal.
- return 0;
- }
-
- /**
- * Gets the TCP type for this <tt>CandidatePacketExtension</tt>.
- */
- public CandidateTcpType getTcpType()
- {
- String tcpTypeString = getAttributeAsString(TCPTYPE_ATTR_NAME);
- try
- {
- return CandidateTcpType.parse(tcpTypeString);
- }
- catch (IllegalArgumentException iae)
- {
- return null;
- }
- }
-
- /**
- * Sets the TCP type for this <tt>CandidatePacketExtension</tt>.
- * @param tcpType
- */
- public void setTcpType(CandidateTcpType tcpType)
- {
- setAttribute(TCPTYPE_ATTR_NAME, tcpType.toString());
- }
-}
+package net.java.sip.communicator.impl.protocol.jabber.extensions.jingle;
+
+import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
+import org.ice4j.ice.*;
+
+/**
+ * @author Emil Ivov
+ */
+public class CandidatePacketExtension extends AbstractPacketExtension
+ implements Comparable<CandidatePacketExtension>
+{
+ /**
+ * The name of the "candidate" element.
+ */
+ public static final String ELEMENT_NAME = "candidate";
+
+ /**
+ * The name of the "component" element.
+ */
+ public static final String COMPONENT_ATTR_NAME = "component";
+
+ /**
+ * The "component" ID for RTP components.
+ */
+ public static final int RTP_COMPONENT_ID = 1;
+
+ /**
+ * The "component" ID for RTCP components.
+ */
+ public static final int RTCP_COMPONENT_ID = 2;
+
+ /**
+ * The name of the "foundation" element.
+ */
+ public static final String FOUNDATION_ATTR_NAME = "foundation";
+
+ /**
+ * The name of the "generation" element.
+ */
+ public static final String GENERATION_ATTR_NAME = "generation";
+
+ /**
+ * The name of the "id" element.
+ */
+ public static final String ID_ATTR_NAME = "id";
+
+ /**
+ * The name of the "ip" element.
+ */
+ public static final String IP_ATTR_NAME = "ip";
+
+ /**
+ * The name of the "network" element.
+ */
+ public static final String NETWORK_ATTR_NAME = "network";
+
+ /**
+ * The name of the "port" element.
+ */
+ public static final String PORT_ATTR_NAME = "port";
+
+ /**
+ * The name of the "priority" element.
+ */
+ public static final String PRIORITY_ATTR_NAME = "priority";
+
+ /**
+ * The name of the "protocol" element.
+ */
+ public static final String PROTOCOL_ATTR_NAME = "protocol";
+
+ /**
+ * The name of the "rel-addr" element.
+ */
+ public static final String REL_ADDR_ATTR_NAME = "rel-addr";
+
+ /**
+ * The name of the "rel-port" element.
+ */
+ public static final String REL_PORT_ATTR_NAME = "rel-port";
+
+ /**
+ * The name of the "type" element.
+ */
+ public static final String TYPE_ATTR_NAME = "type";
+
+ /**
+ * The name of the "tcptype" element.
+ */
+ public static final String TCPTYPE_ATTR_NAME = "tcptype";
+
+ /**
+ * Creates a new {@link CandidatePacketExtension}
+ */
+ public CandidatePacketExtension()
+ {
+ super(null, ELEMENT_NAME);
+ }
+
+ /**
+ * Creates a new {@link CandidatePacketExtension} with the specified
+ * <tt>elementName</tt> so that this class would be usable as a
+ * <tt>RemoteCandidatePacketExtension</tt> parent.
+ *
+ * @param elementName the element name that this instance should be using.
+ */
+ protected CandidatePacketExtension(String elementName)
+ {
+ super(null, elementName);
+ }
+
+ /**
+ * Sets a component ID as defined in ICE-CORE.
+ *
+ * @param component a component ID as defined in ICE-CORE.
+ */
+ public void setComponent(int component)
+ {
+ super.setAttribute(COMPONENT_ATTR_NAME, component);
+ }
+
+ /**
+ * Returns a component ID as defined in ICE-CORE.
+ *
+ * @return a component ID as defined in ICE-CORE.
+ */
+ public int getComponent()
+ {
+ return super.getAttributeAsInt(COMPONENT_ATTR_NAME);
+ }
+
+ /**
+ * Sets the candidate foundation as defined in ICE-CORE.
+ *
+ * @param foundation the candidate foundation as defined in ICE-CORE.
+ */
+ public void setFoundation(String foundation)
+ {
+ super.setAttribute(FOUNDATION_ATTR_NAME, foundation);
+ }
+
+ /**
+ * Returns the candidate foundation as defined in ICE-CORE.
+ *
+ * @return the candidate foundation as defined in ICE-CORE.
+ */
+ public String getFoundation()
+ {
+ return super.getAttributeAsString(FOUNDATION_ATTR_NAME);
+ }
+
+ /**
+ * Sets this candidate's generation index. A generation is an index,
+ * starting at 0, that enables the parties to keep track of updates to the
+ * candidate throughout the life of the session. For details, see the ICE
+ * Restarts section of XEP-0176.
+ *
+ * @param generation this candidate's generation index.
+ */
+ public void setGeneration(int generation)
+ {
+ super.setAttribute(GENERATION_ATTR_NAME, generation);
+ }
+
+ /**
+ * Returns this candidate's generation. A generation is an index, starting at
+ * 0, that enables the parties to keep track of updates to the candidate
+ * throughout the life of the session. For details, see the ICE Restarts
+ * section of XEP-0176.
+ *
+ * @return this candidate's generation index.
+ */
+ public int getGeneration()
+ {
+ return super.getAttributeAsInt(GENERATION_ATTR_NAME);
+ }
+
+ /**
+ * Sets this candidates's unique identifier <tt>String</tt>.
+ *
+ * @param id this candidates's unique identifier <tt>String</tt>
+ */
+ public void setID(String id)
+ {
+ super.setAttribute(ID_ATTR_NAME, id);
+ }
+
+ /**
+ * Returns this candidates's unique identifier <tt>String</tt>.
+ *
+ * @return this candidates's unique identifier <tt>String</tt>
+ */
+ public String getID()
+ {
+ return super.getAttributeAsString(ID_ATTR_NAME);
+ }
+
+ /**
+ * Sets this candidate's Internet Protocol (IP) address; this can be either
+ * an IPv4 address or an IPv6 address.
+ *
+ * @param ip this candidate's IPv4 or IPv6 address.
+ */
+ public void setIP(String ip)
+ {
+ super.setAttribute(IP_ATTR_NAME, ip);
+ }
+
+ /**
+ * Returns this candidate's Internet Protocol (IP) address; this can be
+ * either an IPv4 address or an IPv6 address.
+ *
+ * @return this candidate's IPv4 or IPv6 address.
+ */
+ public String getIP()
+ {
+ return super.getAttributeAsString(IP_ATTR_NAME);
+ }
+
+ /**
+ * The network index indicating the interface that the candidate belongs to.
+ * The network ID is used for diagnostic purposes only in cases where the
+ * calling hardware has more than one Network Interface Card.
+ *
+ * @param network the network index indicating the interface that the
+ * candidate belongs to.
+ */
+ public void setNetwork(int network)
+ {
+ super.setAttribute(NETWORK_ATTR_NAME, network);
+ }
+
+ /**
+ * Returns the network index indicating the interface that the candidate
+ * belongs to. The network ID is used for diagnostic purposes only in cases
+ * where the calling hardware has more than one Network Interface Card.
+ *
+ * @return the network index indicating the interface that the candidate
+ * belongs to.
+ */
+ public int getNetwork()
+ {
+ return super.getAttributeAsInt(NETWORK_ATTR_NAME);
+ }
+
+ /**
+ * Sets this candidate's port number.
+ *
+ * @param port this candidate's port number.
+ */
+ public void setPort(int port)
+ {
+ super.setAttribute(PORT_ATTR_NAME, port);
+ }
+
+ /**
+ * Returns this candidate's port number.
+ *
+ * @return this candidate's port number.
+ */
+ public int getPort()
+ {
+ return super.getAttributeAsInt(PORT_ATTR_NAME);
+ }
+
+ /**
+ * This candidate's priority as defined in ICE's RFC 5245
+ *
+ * @param priority this candidate's priority
+ */
+ public void setPriority(long priority)
+ {
+ super.setAttribute(PRIORITY_ATTR_NAME, priority);
+ }
+
+ /**
+ * This candidate's priority as defined in ICE's RFC 5245
+ *
+ * @return this candidate's priority
+ */
+ public int getPriority()
+ {
+ return super.getAttributeAsInt(PRIORITY_ATTR_NAME);
+ }
+
+ /**
+ * Sets this candidate's transport protocol.
+ *
+ * @param protocol this candidate's transport protocol.
+ */
+ public void setProtocol(String protocol)
+ {
+ super.setAttribute(PROTOCOL_ATTR_NAME, protocol);
+ }
+
+ /**
+ * Sets this candidate's transport protocol.
+ *
+ * @return this candidate's transport protocol.
+ */
+ public String getProtocol()
+ {
+ return super.getAttributeAsString(PROTOCOL_ATTR_NAME);
+ }
+
+ /**
+ * Sets this candidate's related address as described by ICE's RFC 5245.
+ *
+ * @param relAddr this candidate's related address as described by ICE's
+ * RFC 5245.
+ */
+ public void setRelAddr(String relAddr)
+ {
+ super.setAttribute(REL_ADDR_ATTR_NAME, relAddr);
+ }
+
+ /**
+ * Returns this candidate's related address as described by ICE's RFC 5245.
+ *
+ * @return this candidate's related address as described by ICE's RFC 5245.
+ */
+ public String getRelAddr()
+ {
+ return super.getAttributeAsString(REL_ADDR_ATTR_NAME);
+ }
+
+ /**
+ * Sets this candidate's related port as described by ICE's RFC 5245.
+ *
+ * @param relPort this candidate's related port as described by ICE's
+ * RFC 5245.
+ */
+ public void setRelPort(int relPort)
+ {
+ super.setAttribute(REL_PORT_ATTR_NAME, relPort);
+ }
+
+ /**
+ * Returns this candidate's related port as described by ICE's RFC 5245.
+ *
+ * @return this candidate's related port as described by ICE's RFC 5245.
+ */
+ public int getRelPort()
+ {
+ return super.getAttributeAsInt(REL_PORT_ATTR_NAME);
+ }
+
+ /**
+ * Sets a Candidate Type as defined in ICE-CORE. The allowable values are
+ * "host" for host candidates, "prflx" for peer reflexive candidates,
+ * "relay" for relayed candidates, and "srflx" for server reflexive
+ * candidates. All allowable values are enumerated in the {@link
+ * CandidateType} enum.
+ *
+ * @param type this candidates' type as per ICE's RFC 5245.
+ */
+ public void setType(CandidateType type)
+ {
+ super.setAttribute(TYPE_ATTR_NAME, type);
+ }
+
+ /**
+ * Returns a Candidate Type as defined in ICE-CORE. The allowable values are
+ * "host" for host candidates, "prflx" for peer reflexive candidates,
+ * "relay" for relayed candidates, and "srflx" for server reflexive
+ * candidates. All allowable values are enumerated in the {@link
+ * CandidateType} enum.
+ *
+ * @return this candidates' type as per ICE's RFC 5245.
+ */
+ public CandidateType getType()
+ {
+ return CandidateType.valueOf(getAttributeAsString(TYPE_ATTR_NAME));
+ }
+
+ /**
+ * Compares this instance with another CandidatePacketExtension by
+ * preference of type: host < local < prflx < srflx < stun < relay.
+ *
+ * @return 0 if the type are equal. -1 if this instance type is preferred.
+ * Otherwise 1.
+ */
+ public int compareTo(CandidatePacketExtension candidatePacketExtension)
+ {
+ // If the types are different.
+ if(this.getType() != candidatePacketExtension.getType())
+ {
+ CandidateType[] types = {
+ CandidateType.host,
+ CandidateType.local,
+ CandidateType.prflx,
+ CandidateType.srflx,
+ CandidateType.stun,
+ CandidateType.relay
+ };
+ for(int i = 0; i < types.length; ++i)
+ {
+ // this object is preferred.
+ if(types[i] == this.getType())
+ {
+ return -1;
+ }
+ // the candidatePacketExtension is preferred.
+ else if(types[i] == candidatePacketExtension.getType())
+ {
+ return 1;
+ }
+ }
+ }
+ // If the types are equal.
+ return 0;
+ }
+
+ /**
+ * Gets the TCP type for this <tt>CandidatePacketExtension</tt>.
+ */
+ public CandidateTcpType getTcpType()
+ {
+ String tcpTypeString = getAttributeAsString(TCPTYPE_ATTR_NAME);
+ try
+ {
+ return CandidateTcpType.parse(tcpTypeString);
+ }
+ catch (IllegalArgumentException iae)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Sets the TCP type for this <tt>CandidatePacketExtension</tt>.
+ * @param tcpType
+ */
+ public void setTcpType(CandidateTcpType tcpType)
+ {
+ setAttribute(TCPTYPE_ATTR_NAME, tcpType.toString());
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/CryptoPacketExtension.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/CryptoPacketExtension.java
index 69b2e47..3ccbd72 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/CryptoPacketExtension.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/CryptoPacketExtension.java
@@ -17,6 +17,8 @@
*/
package net.java.sip.communicator.impl.protocol.jabber.extensions.jingle;
+import java.util.Objects;
+
import ch.imvs.sdes4j.srtp.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
@@ -332,4 +334,14 @@ public class CryptoPacketExtension
}
return false;
}
+
+ @Override
+ public int hashCode()
+ {
+ return Objects.hash(
+ getCryptoSuite(),
+ getKeyParams(),
+ getSessionParams(),
+ getTag());
+ }
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/IceUdpTransportPacketExtension.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/IceUdpTransportPacketExtension.java
index 1112c8c..173701f 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/IceUdpTransportPacketExtension.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/IceUdpTransportPacketExtension.java
@@ -191,6 +191,27 @@ public class IceUdpTransportPacketExtension
}
/**
+ * Removes given <tt>PacketExtension</tt> from the list of child packet
+ * extensions. <tt>CandidatePacketExtension</tt> are not taken into account
+ * in this method and {@link #removeCandidate(CandidatePacketExtension)}
+ * should be used instead.
+ *
+ * @param childExtension <tt>PacketExtension</tt> instance to be removed
+ * from child packet extensions list.
+ *
+ * @return <tt>true</tt> if given <tt>childExtension</tt> has been in the
+ * list and was removed or <tt>false</tt> otherwise.
+ */
+ public boolean removeChildExtension(PacketExtension childExtension)
+ {
+ List<? extends PacketExtension> childExtensions
+ = super.getChildExtensions();
+
+ return childExtensions != null
+ && childExtensions.remove(childExtension);
+ }
+
+ /**
* Returns the list of {@link CandidatePacketExtension}s currently
* registered with this transport.
*
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/JingleIQ.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/JingleIQ.java
index 9183fa0..65b0849 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/JingleIQ.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/JingleIQ.java
@@ -21,6 +21,7 @@ import java.math.*;
import java.security.*;
import java.util.*;
+import net.java.sip.communicator.service.protocol.jabber.*;
import org.jivesoftware.smack.packet.*;
/**
@@ -62,7 +63,8 @@ public class JingleIQ extends IQ
* The name of the argument that contains the session id.
*/
public static final String SID_ATTR_NAME = "sid";
-
+
+
/**
* The <tt>JingleAction</tt> that describes the purpose of this
* <tt>jingle</tt> element.
@@ -104,8 +106,8 @@ public class JingleIQ extends IQ
* The list of "content" elements included in this IQ.
*/
private final List<ContentPacketExtension> contentList
- = new ArrayList<ContentPacketExtension>();
-
+ = new ArrayList<ContentPacketExtension>();
+
/**
* Returns the XML string of this Jingle IQ's "section" sub-element.
*
@@ -124,17 +126,18 @@ public class JingleIQ extends IQ
if( initiator != null)
bldr.append(" " + INITIATOR_ATTR_NAME
- + "='" + getInitiator() + "'");
+ + "='" + getInitiator() + "'");
if( responder != null)
bldr.append(" " + RESPONDER_ATTR_NAME
- + "='" + getResponder() + "'");
+ + "='" + getResponder() + "'");
bldr.append(" " + SID_ATTR_NAME
- + "='" + getSID() + "'");
-
- String extensionsXML = getExtensionsXML();
+ + "='" + getSID() + "'");
+ CharSequence extensionsXMLSeq = getExtensionsXML();
+ String extensionsXML = extensionsXMLSeq.toString();
+
if ((contentList.size() == 0)
&& (reason == null)
&& (sessionInfo == null)
@@ -348,7 +351,7 @@ public class JingleIQ extends IQ
* otherwise.
*/
public boolean containsContentChildOfType(
- Class<? extends PacketExtension> contentType)
+ Class<? extends PacketExtension> contentType)
{
if(getContentForType(contentType) != null)
return true;
@@ -369,14 +372,14 @@ public class JingleIQ extends IQ
* found.
*/
public ContentPacketExtension getContentForType(
- Class<? extends PacketExtension> contentType)
+ Class<? extends PacketExtension> contentType)
{
synchronized(contentList)
{
for(ContentPacketExtension content : contentList)
{
PacketExtension child
- = content.getFirstChildOfType(contentType);
+ = content.getFirstChildOfType(contentType);
if(child != null)
return content;
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/JingleIQProvider.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/JingleIQProvider.java
index 11f909a..49934e5 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/JingleIQProvider.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/JingleIQProvider.java
@@ -20,6 +20,7 @@ package net.java.sip.communicator.impl.protocol.jabber.extensions.jingle;
import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.jitsimeet.*;
+import net.java.sip.communicator.service.protocol.jabber.*;
import org.jivesoftware.smack.provider.*;
import org.xmlpull.v1.*;
@@ -37,174 +38,187 @@ public class JingleIQProvider implements IQProvider
*/
public JingleIQProvider()
{
- ProviderManager providerManager = ProviderManager.getInstance();
+
+ AbstractSmackInteroperabilityLayer smackInteroperabilityLayer =
+ AbstractSmackInteroperabilityLayer.getInstance();
//<description/> provider
- providerManager.addExtensionProvider(
- RtpDescriptionPacketExtension.ELEMENT_NAME,
- RtpDescriptionPacketExtension.NAMESPACE,
- new DefaultPacketExtensionProvider
- <RtpDescriptionPacketExtension>(
- RtpDescriptionPacketExtension.class));
+ smackInteroperabilityLayer.addExtensionProvider(
+ RtpDescriptionPacketExtension.ELEMENT_NAME,
+ RtpDescriptionPacketExtension.NAMESPACE,
+ new DefaultPacketExtensionProvider
+ <RtpDescriptionPacketExtension>(
+ RtpDescriptionPacketExtension.class));
//<payload-type/> provider
- providerManager.addExtensionProvider(
- PayloadTypePacketExtension.ELEMENT_NAME,
- RtpDescriptionPacketExtension.NAMESPACE,
- new DefaultPacketExtensionProvider
- <PayloadTypePacketExtension>(
- PayloadTypePacketExtension.class));
+ smackInteroperabilityLayer.addExtensionProvider(
+ PayloadTypePacketExtension.ELEMENT_NAME,
+ RtpDescriptionPacketExtension.NAMESPACE,
+ new DefaultPacketExtensionProvider
+ <PayloadTypePacketExtension>(
+ PayloadTypePacketExtension.class));
//<parameter/> provider
- providerManager.addExtensionProvider(
- ParameterPacketExtension.ELEMENT_NAME,
- RtpDescriptionPacketExtension.NAMESPACE,
- new DefaultPacketExtensionProvider
- <ParameterPacketExtension>(ParameterPacketExtension.class));
+ smackInteroperabilityLayer.addExtensionProvider(
+ ParameterPacketExtension.ELEMENT_NAME,
+ RtpDescriptionPacketExtension.NAMESPACE,
+ new DefaultPacketExtensionProvider
+ <ParameterPacketExtension>
+ (ParameterPacketExtension.class));
//<rtp-hdrext/> provider
- providerManager.addExtensionProvider(
- RTPHdrExtPacketExtension.ELEMENT_NAME,
- RTPHdrExtPacketExtension.NAMESPACE,
- new DefaultPacketExtensionProvider
- <RTPHdrExtPacketExtension>(RTPHdrExtPacketExtension.class));
+ smackInteroperabilityLayer.addExtensionProvider(
+ RTPHdrExtPacketExtension.ELEMENT_NAME,
+ RTPHdrExtPacketExtension.NAMESPACE,
+ new DefaultPacketExtensionProvider
+ <RTPHdrExtPacketExtension>
+ (RTPHdrExtPacketExtension.class));
// <sctpmap/> provider
- providerManager.addExtensionProvider(
- SctpMapExtension.ELEMENT_NAME,
- SctpMapExtension.NAMESPACE,
- new SctpMapExtensionProvider());
+ smackInteroperabilityLayer.addExtensionProvider(
+ SctpMapExtension.ELEMENT_NAME,
+ SctpMapExtension.NAMESPACE,
+ new SctpMapExtensionProvider());
//<encryption/> provider
- providerManager.addExtensionProvider(
- EncryptionPacketExtension.ELEMENT_NAME,
- RtpDescriptionPacketExtension.NAMESPACE,
- new DefaultPacketExtensionProvider
- <EncryptionPacketExtension>(EncryptionPacketExtension.class));
+ smackInteroperabilityLayer.addExtensionProvider(
+ EncryptionPacketExtension.ELEMENT_NAME,
+ RtpDescriptionPacketExtension.NAMESPACE,
+ new DefaultPacketExtensionProvider
+ <EncryptionPacketExtension>
+ (EncryptionPacketExtension.class));
//<zrtp-hash/> provider
- providerManager.addExtensionProvider(
- ZrtpHashPacketExtension.ELEMENT_NAME,
- ZrtpHashPacketExtension.NAMESPACE,
- new DefaultPacketExtensionProvider
- <ZrtpHashPacketExtension>(ZrtpHashPacketExtension.class));
+ smackInteroperabilityLayer.addExtensionProvider(
+ ZrtpHashPacketExtension.ELEMENT_NAME,
+ ZrtpHashPacketExtension.NAMESPACE,
+ new DefaultPacketExtensionProvider
+ <ZrtpHashPacketExtension>
+ (ZrtpHashPacketExtension.class));
//<crypto/> provider
- providerManager.addExtensionProvider(
- CryptoPacketExtension.ELEMENT_NAME,
- RtpDescriptionPacketExtension.NAMESPACE,
- new DefaultPacketExtensionProvider
- <CryptoPacketExtension>(CryptoPacketExtension.class));
+ smackInteroperabilityLayer.addExtensionProvider(
+ CryptoPacketExtension.ELEMENT_NAME,
+ RtpDescriptionPacketExtension.NAMESPACE,
+ new DefaultPacketExtensionProvider
+ <CryptoPacketExtension>
+ (CryptoPacketExtension.class));
// <bundle/> provider
- providerManager.addExtensionProvider(
- BundlePacketExtension.ELEMENT_NAME,
- BundlePacketExtension.NAMESPACE,
- new DefaultPacketExtensionProvider
- <BundlePacketExtension>(BundlePacketExtension.class));
+ smackInteroperabilityLayer.addExtensionProvider(
+ BundlePacketExtension.ELEMENT_NAME,
+ BundlePacketExtension.NAMESPACE,
+ new DefaultPacketExtensionProvider
+ <BundlePacketExtension>
+ (BundlePacketExtension.class));
// <group/> provider
- providerManager.addExtensionProvider(
- GroupPacketExtension.ELEMENT_NAME,
- GroupPacketExtension.NAMESPACE,
- new DefaultPacketExtensionProvider
- <GroupPacketExtension>(GroupPacketExtension.class));
+ smackInteroperabilityLayer.addExtensionProvider(
+ GroupPacketExtension.ELEMENT_NAME,
+ GroupPacketExtension.NAMESPACE,
+ new DefaultPacketExtensionProvider
+ <GroupPacketExtension>(GroupPacketExtension.class));
//ice-udp transport
- providerManager.addExtensionProvider(
- IceUdpTransportPacketExtension.ELEMENT_NAME,
- IceUdpTransportPacketExtension.NAMESPACE,
- new DefaultPacketExtensionProvider<IceUdpTransportPacketExtension>(
- IceUdpTransportPacketExtension.class));
+ smackInteroperabilityLayer.addExtensionProvider(
+ IceUdpTransportPacketExtension.ELEMENT_NAME,
+ IceUdpTransportPacketExtension.NAMESPACE,
+ new DefaultPacketExtensionProvider
+ <IceUdpTransportPacketExtension>(
+ IceUdpTransportPacketExtension.class));
//<raw-udp/> provider
- providerManager.addExtensionProvider(
- RawUdpTransportPacketExtension.ELEMENT_NAME,
- RawUdpTransportPacketExtension.NAMESPACE,
- new DefaultPacketExtensionProvider<RawUdpTransportPacketExtension>(
- RawUdpTransportPacketExtension.class));
+ smackInteroperabilityLayer.addExtensionProvider(
+ RawUdpTransportPacketExtension.ELEMENT_NAME,
+ RawUdpTransportPacketExtension.NAMESPACE,
+ new DefaultPacketExtensionProvider
+ <RawUdpTransportPacketExtension>(
+ RawUdpTransportPacketExtension.class));
//ice-udp <candidate/> provider
- providerManager.addExtensionProvider(
- CandidatePacketExtension.ELEMENT_NAME,
- IceUdpTransportPacketExtension.NAMESPACE,
- new DefaultPacketExtensionProvider<CandidatePacketExtension>(
- CandidatePacketExtension.class));
+ smackInteroperabilityLayer.addExtensionProvider(
+ CandidatePacketExtension.ELEMENT_NAME,
+ IceUdpTransportPacketExtension.NAMESPACE,
+ new DefaultPacketExtensionProvider
+ <CandidatePacketExtension>(
+ CandidatePacketExtension.class));
//raw-udp <candidate/> provider
- providerManager.addExtensionProvider(
- CandidatePacketExtension.ELEMENT_NAME,
- RawUdpTransportPacketExtension.NAMESPACE,
- new DefaultPacketExtensionProvider<CandidatePacketExtension>(
- CandidatePacketExtension.class));
+ smackInteroperabilityLayer.addExtensionProvider(
+ CandidatePacketExtension.ELEMENT_NAME,
+ RawUdpTransportPacketExtension.NAMESPACE,
+ new DefaultPacketExtensionProvider
+ <CandidatePacketExtension>(
+ CandidatePacketExtension.class));
//ice-udp <remote-candidate/> provider
- providerManager.addExtensionProvider(
- RemoteCandidatePacketExtension.ELEMENT_NAME,
- IceUdpTransportPacketExtension.NAMESPACE,
- new DefaultPacketExtensionProvider<RemoteCandidatePacketExtension>(
- RemoteCandidatePacketExtension.class));
+ smackInteroperabilityLayer.addExtensionProvider(
+ RemoteCandidatePacketExtension.ELEMENT_NAME,
+ IceUdpTransportPacketExtension.NAMESPACE,
+ new DefaultPacketExtensionProvider
+ <RemoteCandidatePacketExtension>(
+ RemoteCandidatePacketExtension.class));
//inputevt <inputevt/> provider
- providerManager.addExtensionProvider(
+ smackInteroperabilityLayer.addExtensionProvider(
InputEvtPacketExtension.ELEMENT_NAME,
InputEvtPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<InputEvtPacketExtension>(
InputEvtPacketExtension.class));
//coin <conference-info/> provider
- providerManager.addExtensionProvider(
+ smackInteroperabilityLayer.addExtensionProvider(
CoinPacketExtension.ELEMENT_NAME,
CoinPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<CoinPacketExtension>(
CoinPacketExtension.class));
// DTLS-SRTP
- providerManager.addExtensionProvider(
+ smackInteroperabilityLayer.addExtensionProvider(
DtlsFingerprintPacketExtension.ELEMENT_NAME,
DtlsFingerprintPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider
- <DtlsFingerprintPacketExtension>(
+ <DtlsFingerprintPacketExtension>(
DtlsFingerprintPacketExtension.class));
/*
* XEP-0251: Jingle Session Transfer <transfer/> and <transferred>
* providers
*/
- providerManager.addExtensionProvider(
+ smackInteroperabilityLayer.addExtensionProvider(
TransferPacketExtension.ELEMENT_NAME,
TransferPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<TransferPacketExtension>(
TransferPacketExtension.class));
- providerManager.addExtensionProvider(
+ smackInteroperabilityLayer.addExtensionProvider(
TransferredPacketExtension.ELEMENT_NAME,
TransferredPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<TransferredPacketExtension>(
TransferredPacketExtension.class));
//conference description <callid/> provider
- providerManager.addExtensionProvider(
+ smackInteroperabilityLayer.addExtensionProvider(
ConferenceDescriptionPacketExtension.CALLID_ELEM_NAME,
ConferenceDescriptionPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<CallIdPacketExtension>(
CallIdPacketExtension.class));
//rtcp-fb
- providerManager.addExtensionProvider(
- RtcpFbPacketExtension.ELEMENT_NAME,
- RtcpFbPacketExtension.NAMESPACE,
- new DefaultPacketExtensionProvider<RtcpFbPacketExtension>(
- RtcpFbPacketExtension.class));
+ smackInteroperabilityLayer.addExtensionProvider(
+ RtcpFbPacketExtension.ELEMENT_NAME,
+ RtcpFbPacketExtension.NAMESPACE,
+ new DefaultPacketExtensionProvider<RtcpFbPacketExtension>(
+ RtcpFbPacketExtension.class));
//rtcp-mux
- providerManager.addExtensionProvider(
+ smackInteroperabilityLayer.addExtensionProvider(
RtcpmuxPacketExtension.ELEMENT_NAME,
IceUdpTransportPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<RtcpmuxPacketExtension>(
RtcpmuxPacketExtension.class));
//ssrcInfo
- providerManager.addExtensionProvider(
+ smackInteroperabilityLayer.addExtensionProvider(
SSRCInfoPacketExtension.ELEMENT_NAME,
SSRCInfoPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<SSRCInfoPacketExtension>(
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jitsimeet/ComponentVersionsExtension.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jitsimeet/ComponentVersionsExtension.java
new file mode 100644
index 0000000..bcc3397
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jitsimeet/ComponentVersionsExtension.java
@@ -0,0 +1,135 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.protocol.jabber.extensions.jitsimeet;
+
+import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
+
+/**
+ * The packet extension is used by Jicofo to broadcast versions of all video
+ * conferencing system components. This packets extension is added to jicofo's
+ * MUC presence. It will contain {@link Component} children which carry each
+ * component's name and version.
+ *
+ * @author Pawel Domas
+ */
+public class ComponentVersionsExtension
+ extends AbstractPacketExtension
+{
+ /**
+ * The XML element name of {@link ComponentVersionsExtension}.
+ */
+ public static final String ELEMENT_NAME = "versions";
+
+ /**
+ * The name of XML sub-elements which carry the info about particular
+ * component's version.
+ */
+ public static final String COMPONENT_ELEMENT_NAME = "component";
+
+ /**
+ * Constant for {@link Component} name used to signal the version of
+ * conference focus.
+ */
+ public static final String COMPONENT_FOCUS = "focus";
+
+ /**
+ * Constant for {@link Component} name used to signal the version of
+ * XMPP server.
+ */
+ public static final String COMPONENT_XMPP_SERVER = "xmpp";
+
+ /**
+ * Constant for {@link Component} name used to signal the version of
+ * the videobridge.
+ */
+ public static final String COMPONENT_VIDEOBRIDGE = "videobridge";
+
+ /**
+ * The XML element namespace of {@link ComponentVersionsExtension}.
+ */
+ public static final String NAMESPACE = "http://jitsi.org/jitmeet";
+
+ /**
+ * Creates an {@link AbstractPacketExtension} instance for the specified
+ * <tt>namespace</tt> and <tt>elementName</tt>.
+ */
+ public ComponentVersionsExtension()
+ {
+ super(NAMESPACE, ELEMENT_NAME);
+ }
+
+ /**
+ * Adds component's version to this extension.
+ *
+ * @param componentName the name of the component for which
+ * child {@link Component} extension will be added.
+ * @param versionStr human readable string that describes component's
+ * version.
+ */
+ public void addComponentVersion(String componentName, String versionStr)
+ {
+ Component v = new Component();
+
+ v.setName(componentName);
+ v.setText(versionStr);
+
+ addChildExtension(v);
+ }
+
+ /**
+ * Component child element of {@link ComponentVersionsExtension}. The name
+ * of the component is carried in name attribute and the version string is
+ * the text value.
+ */
+ public class Component
+ extends AbstractPacketExtension
+ {
+ /**
+ * The name of that attribute that carries component's name.
+ */
+ private final String NAME_ATTR_NAME = "name";
+
+ /**
+ * Creates new instance of {@link Component} packet extension.
+ */
+ public Component()
+ {
+ super(NAMESPACE, COMPONENT_ELEMENT_NAME);
+ }
+
+ /**
+ * Returns the value of the name attribute.
+ * @return <tt>String</tt> which describes the name of video
+ * conferencing system component.
+ */
+ public String getName()
+ {
+ return getAttributeAsString(NAME_ATTR_NAME);
+ }
+
+ /**
+ * Sets new value for the component's name attribute.
+ * @param name a <tt>String</tt> which describes the name of video
+ * conferencing system component.
+ */
+ public void setName(String name)
+ {
+ setAttribute(NAME_ATTR_NAME, name);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jitsimeet/SSRCInfoPacketExtension.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jitsimeet/SSRCInfoPacketExtension.java
index 239c708..7384c9e 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jitsimeet/SSRCInfoPacketExtension.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jitsimeet/SSRCInfoPacketExtension.java
@@ -1,8 +1,19 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package net.java.sip.communicator.impl.protocol.jabber.extensions.jitsimeet;
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jitsimeet/VideoMutedExtension.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jitsimeet/VideoMutedExtension.java
new file mode 100644
index 0000000..cf76d89
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jitsimeet/VideoMutedExtension.java
@@ -0,0 +1,70 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.protocol.jabber.extensions.jitsimeet;
+
+import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
+
+/**
+ * Video muted extension that is included in users presence in Jitsi-meet
+ * conferences. It does carry the info about user's video muted status.
+ *
+ * @author Pawel Domas
+ */
+public class VideoMutedExtension
+ extends AbstractPacketExtension
+{
+ /**
+ * The namespace of this packet extension.
+ */
+ public static final String NAMESPACE = "http://jitsi.org/jitmeet/video";
+
+ /**
+ * XML element name of this packet extension.
+ */
+ public static final String ELEMENT_NAME = "videomuted";
+
+ /**
+ * Creates new instance of <tt>VideoMutedExtension</tt>.
+ */
+ public VideoMutedExtension()
+ {
+ super(NAMESPACE, ELEMENT_NAME);
+ }
+
+ /**
+ * Check whether or not user's video is in muted status.
+ * @return <tt>true</tt> if muted, <tt>false</tt> if unmuted or
+ * <tt>null</tt> if no valid info found in the extension body.
+ */
+ public Boolean isVideoMuted()
+ {
+ return Boolean.valueOf(getText());
+ }
+
+ /**
+ * Sets user's video muted status.
+ *
+ * @param videoMuted <tt>true</tt> or <tt>false</tt> which indicates video
+ * muted status of the user.
+ */
+ public void setVideoMuted(Boolean videoMuted)
+ {
+ setText(
+ String.valueOf(videoMuted));
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/jinglesdp/JingleUtils.java b/src/net/java/sip/communicator/impl/protocol/jabber/jinglesdp/JingleUtils.java
index 93cdead..8094f68 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/jinglesdp/JingleUtils.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/jinglesdp/JingleUtils.java
@@ -179,12 +179,17 @@ public class JingleUtils
else
paramsMap.put(paramName, param.getValue());
}
-
- // video-related attributes in payload-type element
+
for(String attr : payloadType.getAttributeNames())
{
+ //video-related attributes in payload-type element
if(attr.equals("width") || attr.equals("height"))
paramsMap.put(attr, payloadType.getAttributeAsString(attr));
+
+ //update ptime with the actual value from the payload
+ if (attr.equals(PayloadTypePacketExtension.PTIME_ATTR_NAME))
+ advancedMap.put(PayloadTypePacketExtension.PTIME_ATTR_NAME,
+ Integer.toString(payloadType.getPtime()));
}
//now create the format.
diff --git a/src/net/java/sip/communicator/impl/protocol/mock/MockContactGroup.java b/src/net/java/sip/communicator/impl/protocol/mock/MockContactGroup.java
index fa4fff1..e6cdd36 100644
--- a/src/net/java/sip/communicator/impl/protocol/mock/MockContactGroup.java
+++ b/src/net/java/sip/communicator/impl/protocol/mock/MockContactGroup.java
@@ -506,6 +506,31 @@ public class MockContactGroup
return true;
}
+ @Override
+ public int hashCode()
+ {
+ List<Object> objects = new ArrayList<Object>();
+ objects.add(getGroupName());
+ objects.add(getUID());
+ objects.add(countContacts());
+ objects.add(countSubgroups());
+
+ //traverse child contacts
+ for (Contact c : contacts)
+ {
+ objects.add(c.getAddress());
+ }
+
+
+ //traverse subgroups
+ for (ContactGroup g : subGroups)
+ {
+ objects.add(g.getGroupName());
+ }
+
+ return Objects.hash(objects.toArray());
+ }
+
public void setPersistent(boolean isPersistent)
{
this.isPersistent = isPersistent;
diff --git a/src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java b/src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java
index bcff799..a7b6e5e 100644
--- a/src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java
+++ b/src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java
@@ -294,6 +294,15 @@ public class MockProvider
}
/**
+ * Always true.
+ */
+ @Override
+ public boolean validateContactAddress(String contactId, List<String> result)
+ {
+ return true;
+ }
+
+ /**
* Mock implementation of the corresponding ProtocolProviderService method.
* We have no icon corresponding to this protocol provider.
*/
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/AddressResolverImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/AddressResolverImpl.java
index eba0da6..4fd1b6f 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/AddressResolverImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/AddressResolverImpl.java
@@ -70,18 +70,8 @@ public class AddressResolverImpl
// if it is a textual IP address, do no try to resolve it
if(NetworkUtils.isValidIPAddress(hostAddress))
{
- byte[] addr = null;
-
- addr = NetworkUtils.strToIPv4(hostAddress);
-
- // not an IPv4, try IPv6
- if (addr == null)
- {
- addr = NetworkUtils.strToIPv6(hostAddress);
- }
-
InetSocketAddress hostSocketAddress = new InetSocketAddress(
- InetAddress.getByAddress(hostAddress, addr),
+ NetworkUtils.getInetAddress(hostAddress),
inputAddress.getPort());
return new HopImpl(hostSocketAddress.getHostName(),
inputAddress.getPort(),
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandlerSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandlerSipImpl.java
index c4193a5..b626dbb 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandlerSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandlerSipImpl.java
@@ -87,7 +87,7 @@ public class CallPeerMediaHandlerSipImpl
* Whether other party is able to change video quality settings.
* Normally its whether we have detected existence of imageattr in sdp.
*/
- boolean supportQualityControls;
+ private boolean supportQualityControls;
/**
* The current quality controls for this peer media handler if any.
@@ -98,7 +98,7 @@ public class CallPeerMediaHandlerSipImpl
* The lock we use to make sure that we won't be processing a second
* offer/answer exchange while a .
*/
- private Object offerAnswerLock = new Object();
+ private final Object offerAnswerLock = new Object();
/**
* Creates a new handler that will be managing media streams for
@@ -164,7 +164,7 @@ public class CallPeerMediaHandlerSipImpl
throws OperationFailedException
{
//Audio Media Description
- Vector<MediaDescription> mediaDescs = createMediaDescriptions();
+ List<MediaDescription> mediaDescs = createMediaDescriptions();
//wrap everything up in a session description
String userName
@@ -197,7 +197,7 @@ public class CallPeerMediaHandlerSipImpl
* for reasons like - problems with device interaction, allocating ports,
* etc.
*/
- private Vector<MediaDescription> createMediaDescriptions()
+ private List<MediaDescription> createMediaDescriptions()
throws OperationFailedException
{
//Audio Media Description
@@ -215,12 +215,16 @@ public class CallPeerMediaHandlerSipImpl
receiveQualityPreset = qualityControls.getRemoteSendMaxPreset();
}
- for (MediaType mediaType : MediaType.values())
+ for (MediaType mediaType : new MediaType[] { MediaType.AUDIO , MediaType.VIDEO})
{
MediaDevice dev = getDefaultDevice(mediaType);
if (!isDeviceActive(dev, sendQualityPreset, receiveQualityPreset))
+ {
+ logger.warn("No active device for " + mediaType.toString()
+ + " was found!");
continue;
+ }
MediaDirection direction
= dev.getDirection().and(getDirectionUserPreference(mediaType));
@@ -339,7 +343,7 @@ public class CallPeerMediaHandlerSipImpl
* it is known that the other endpoint supports this
* profile" and "[o]ther profiles MAY also be used."
*/
- updateMediaDescriptionForZrtp(mediaType, md, null);
+ updateMediaDescriptionForZrtp(mediaType, md);
if (SrtpControl.RTP_SAVP.equals(proto)
|| SrtpControl.RTP_SAVPF.equals(proto))
{
@@ -400,7 +404,7 @@ public class CallPeerMediaHandlerSipImpl
{
//create the media descriptions reflecting our current state.
- Vector<MediaDescription> newMediaDescs = createMediaDescriptions();
+ List<MediaDescription> newMediaDescs = createMediaDescriptions();
SessionDescription newOffer = SdpUtils.createSessionUpdateDescription(
sdescToUpdate, getTransportManager().getLastUsedLocalHost(),
@@ -510,7 +514,7 @@ public class CallPeerMediaHandlerSipImpl
throws OperationFailedException,
IllegalArgumentException
{
- Vector<MediaDescription> answerDescriptions
+ List<MediaDescription> answerDescriptions
= createMediaDescriptionsForAnswer(newOffer);
// wrap everything up in a session description
SessionDescription newAnswer
@@ -555,10 +559,11 @@ public class CallPeerMediaHandlerSipImpl
boolean rejectedAvpOfferDueToSavpMandatory = false;
AccountID accountID = getPeer().getProtocolProvider().getAccountID();
- int savpOption
- = accountID.getAccountPropertyBoolean(
- ProtocolProviderFactory.DEFAULT_ENCRYPTION,
- true)
+ boolean useDefaultEncryption =
+ accountID.getAccountPropertyBoolean(
+ ProtocolProviderFactory.DEFAULT_ENCRYPTION , true);
+
+ int savpOption = useDefaultEncryption
? accountID.getAccountPropertyInt(
ProtocolProviderFactory.SAVP_OPTION,
ProtocolProviderFactory.SAVP_OFF)
@@ -638,7 +643,7 @@ public class CallPeerMediaHandlerSipImpl
{
mutuallySupportedFormats = null;
}
- else if(mediaType.equals(MediaType.VIDEO)
+ else if(MediaType.VIDEO.equals(mediaType)
&& (qualityControls != null))
{
/*
@@ -705,18 +710,18 @@ public class CallPeerMediaHandlerSipImpl
= getTransportManager().getStreamConnector(mediaType);
// check for options from remote party and set them locally
- if(mediaType.equals(MediaType.VIDEO))
+ if(MediaType.VIDEO.equals(mediaType))
{
// update stream
MediaStream stream = getStream(MediaType.VIDEO);
- if(stream != null && dev != null)
+ if(stream != null)
{
List<MediaFormat> fmts = intersectFormats(
getLocallySupportedFormats(dev),
remoteFormats);
- if(fmts.size() > 0)
+ if(!fmts.isEmpty())
{
MediaFormat fmt = fmts.get(0);
@@ -809,7 +814,7 @@ public class CallPeerMediaHandlerSipImpl
{
if(remoteDescriptions.size() > 1)
{
- if(mediaType.equals(MediaType.AUDIO))
+ if(MediaType.AUDIO.equals(mediaType))
{
masterStream = true;
masterStreamSet = true;
@@ -1192,8 +1197,7 @@ public class CallPeerMediaHandlerSipImpl
*/
private boolean updateMediaDescriptionForZrtp(
MediaType mediaType,
- MediaDescription localMd,
- MediaDescription remoteMd)
+ MediaDescription localMd)
{
MediaAwareCallPeer<?, ?, ?> peer = getPeer();
AccountID accountID = peer.getProtocolProvider().getAccountID();
@@ -1499,7 +1503,7 @@ public class CallPeerMediaHandlerSipImpl
// check for options from remote party and set
// is quality controls supported
- if(mediaType.equals(MediaType.VIDEO))
+ if(MediaType.VIDEO.equals(mediaType))
{
supportQualityControls
= SdpUtils.containsAttribute(mediaDescription, "imageattr");
@@ -1544,7 +1548,7 @@ public class CallPeerMediaHandlerSipImpl
{
if(remoteDescriptions.size() > 1)
{
- if(mediaType.equals(MediaType.AUDIO))
+ if(MediaType.AUDIO.equals(mediaType))
{
masterStream = true;
masterStreamSet = true;
@@ -1882,7 +1886,7 @@ public class CallPeerMediaHandlerSipImpl
// ZRTP
else if(srtpControlType == SrtpControlType.ZRTP)
{
- if(updateMediaDescriptionForZrtp(mediaType, localMd, remoteMd))
+ if(updateMediaDescriptionForZrtp(mediaType, localMd))
{
// Stop once an encryption advertisement has been chosen.
return;
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/CallSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/CallSipImpl.java
index fa0e08e..62711c7 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/CallSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/CallSipImpl.java
@@ -61,15 +61,27 @@ public class CallSipImpl
* Name of extra INVITE header which specifies name of MUC room that is
* hosting the Jitsi Meet conference.
*/
- public static final String JITSI_MEET_ROOM_HEADER
- = "Jitsi-Conference-Room";
+ public String JITSI_MEET_ROOM_HEADER = "Jitsi-Conference-Room";
+
+ /**
+ * Property name of extra INVITE header which specifies name of MUC room
+ * that is hosting the Jitsi Meet conference.
+ */
+ private static final String JITSI_MEET_ROOM_HEADER_PROPERTY
+ = "JITSI_MEET_ROOM_HEADER_NAME";
+
+ /**
+ * Property name of extra INVITE header which specifies password required
+ * to enter MUC room that is hosting the Jitsi Meet conference.
+ */
+ public String JITSI_MEET_ROOM_PASS_HEADER = "Jitsi-Conference-Room-Pass";
/**
* Name of extra INVITE header which specifies password required to enter
* MUC room that is hosting the Jitsi Meet conference.
*/
- public static final String JITSI_MEET_ROOM_PASS_HEADER
- = "Jitsi-Conference-Room-Pass";
+ private static final String JITSI_MEET_ROOM_PASS_HEADER_PROPERTY
+ = "JITSI_MEET_ROOM_PASS_HEADER_NAME";
/**
* Custom header included in initial desktop sharing call creation.
@@ -78,16 +90,27 @@ public class CallSipImpl
public static final String DS_SHARING_HEADER = "X-Desktop-Share";
/**
- * When starting call we may have quality preferences we must use
- * for the call.
+ * Custom header name prefix that can be added to the call instance.
+ * Several headers can be specified in the form of:
+ * EXTRA_HEADER_NAME.1=...
+ * EXTRA_HEADER_NAME.2=...
+ * Index starting from 1.
*/
- private QualityPreset initialQualityPreferences;
+ public static final String EXTRA_HEADER_NAME = "EXTRA_HEADER_NAME";
/**
- * A reference to the <tt>SipMessageFactory</tt> instance that we should
- * use when creating requests.
+ * Custom header value prefix that can be added to the call instance.
+ * Several headers can be specified in the form of:
+ * EXTRA_HEADER_VALUE.1=...
+ * EXTRA_HEADER_VALUE.2=...
+ * Index starting from 1.
*/
- private final SipMessageFactory messageFactory;
+ public static final String EXTRA_HEADER_VALUE = "EXTRA_HEADER_VALUE";
+
+ /**
+ * Maximum number of retransmissions that will be sent.
+ */
+ private static final int MAX_RETRANSMISSIONS = 3;
/**
* The name of the property under which the user may specify the number of
@@ -95,19 +118,27 @@ public class CallSipImpl
* 180.
*/
private static final String RETRANSMITS_RINGING_INTERVAL
- = "net.java.sip.communicator.impl.protocol.sip"
- + ".RETRANSMITS_RINGING_INTERVAL";
+ = "net.java.sip.communicator.impl.protocol.sip"
+ + ".RETRANSMITS_RINGING_INTERVAL";
/**
- * The default amount of time (in milliseconds) for the initial interval for
- * retransmissions of response 180.
- */
+ * The default amount of time (in milliseconds) for the initial interval for
+ * retransmissions of response 180.
+ */
private static final int DEFAULT_RETRANSMITS_RINGING_INTERVAL = 500;
/**
- * Maximum number of retransmissions that will be sent.
+ * When starting call we may have quality preferences we must use
+ * for the call.
*/
- private static final int MAX_RETRANSMISSIONS = 3;
+ private QualityPreset initialQualityPreferences;
+
+ /**
+ * A reference to the <tt>SipMessageFactory</tt> instance that we should
+ * use when creating requests.
+ */
+ private final SipMessageFactory messageFactory;
+
/**
* The amount of time (in milliseconds) for the initial interval for
@@ -140,6 +171,13 @@ public class CallSipImpl
}
this.retransmitsRingingInterval = retransmitsRingingInterval;
+ AccountID account = parentOpSet.getProtocolProvider().getAccountID();
+ // Specify custom header names
+ JITSI_MEET_ROOM_HEADER = account.getAccountPropertyString(
+ JITSI_MEET_ROOM_HEADER_PROPERTY, JITSI_MEET_ROOM_HEADER);
+ JITSI_MEET_ROOM_PASS_HEADER = account.getAccountPropertyString(
+ JITSI_MEET_ROOM_PASS_HEADER_PROPERTY, JITSI_MEET_ROOM_PASS_HEADER);
+
//let's add ourselves to the calls repo. we are doing it ourselves just
//to make sure that no one ever forgets.
parentOpSet.getActiveCallsRepository().addCall(this);
@@ -387,24 +425,21 @@ public class CallSipImpl
logger.trace("Looking for peer with dialog: " + dialog
+ "among " + getCallPeerCount() + " calls");
}
- while (callPeers.hasNext())
+ for (CallPeerSipImpl callPeer : getCallPeerList())
{
- CallPeerSipImpl cp = callPeers.next();
-
- if (cp.getDialog() == dialog)
+ if (callPeer.getDialog() == dialog)
{
if (logger.isTraceEnabled())
- logger.trace("Returning cp=" + cp);
- return cp;
+ logger.trace("Returning cp=" + callPeer);
+ return callPeer;
}
else
{
if (logger.isTraceEnabled())
- logger.trace("Ignoring cp=" + cp + " because cp.dialog="
- + cp.getDialog() + " while dialog=" + dialog);
+ logger.trace("Ignoring cp=" + callPeer + " because cp.dialog="
+ + callPeer.getDialog() + " while dialog=" + dialog);
}
}
-
return null;
}
@@ -449,7 +484,7 @@ public class CallSipImpl
// Transport preference
String forceTransport = null;
javax.sip.address.URI calleeURI = calleeAddress.getURI();
- if(calleeURI.getScheme().toLowerCase().equals("sips"))
+ if("sips".equals(calleeURI.getScheme().toLowerCase()))
{
// MUST use TLS
forceTransport = "TLS";
@@ -553,7 +588,7 @@ public class CallSipImpl
String alternativeIMPPAddress = null;
if (infoHeader != null
&& infoHeader.getParameter("purpose") != null
- && infoHeader.getParameter("purpose").equals("impp"))
+ && "impp".equals(infoHeader.getParameter("purpose")))
{
alternativeIMPPAddress = infoHeader.getInfo().toString();
}
@@ -585,7 +620,7 @@ public class CallSipImpl
{
if (logger.isTraceEnabled())
logger.trace("will send ringing response: ");
- if(peer.getState().equals(CallPeerState.INCOMING_CALL))
+ if( CallPeerState.INCOMING_CALL.equals(peer.getState()) )
{
response = messageFactory.createResponse(Response.RINGING, invite);
@@ -680,10 +715,10 @@ public class CallSipImpl
*/
public void reInvite() throws OperationFailedException
{
- Iterator<CallPeerSipImpl> peers = getCallPeers();
-
- while (peers.hasNext())
- peers.next().sendReInvite();
+ for(CallPeerSipImpl peer : getCallPeerList())
+ {
+ peer.sendReInvite();
+ }
}
/**
@@ -706,6 +741,22 @@ public class CallSipImpl
protected void processExtraHeaders(javax.sip.message.Message message)
throws ParseException
{
+ // If there are custom headers added to the call instance, add those
+ // headers
+ int extraHeaderIx = 1;
+
+ Object name = getData(EXTRA_HEADER_NAME + "." + extraHeaderIx);
+ while(name != null)
+ {
+ Object value = getData(EXTRA_HEADER_VALUE + "." + extraHeaderIx);
+
+ Header header = getProtocolProvider().getHeaderFactory()
+ .createHeader((String) name, (String) value);
+ message.setHeader(header);
+
+ extraHeaderIx++;
+ name = getData(EXTRA_HEADER_NAME + "." + extraHeaderIx);
+ }
}
/**
@@ -758,8 +809,8 @@ public class CallSipImpl
{
try
{
- if(!peer.getState().equals(
- CallPeerState.INCOMING_CALL))
+ if( !CallPeerState.INCOMING_CALL.equals(
+ peer.getState()) )
{
timer.cancel();
}
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/ContactGroupSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/ContactGroupSipImpl.java
index f5782f1..3c2aeb5 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/ContactGroupSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/ContactGroupSipImpl.java
@@ -641,5 +641,31 @@ public class ContactGroupSipImpl
return true;
}
+
+ @Override
+ public int hashCode()
+ {
+ List<Object> objects = new ArrayList<Object>();
+ objects.add(getGroupName());
+ objects.add(getUID());
+ objects.add(countContacts());
+ objects.add(countSubgroups());
+ objects.add(getProtocolProvider());
+
+ //traverse child contacts
+ for (Contact c : contacts)
+ {
+ objects.add(c.getAddress());
+ }
+
+
+ //traverse subgroups
+ for (ContactGroup g : subGroups)
+ {
+ objects.add(g.getGroupName());
+ }
+
+ return Objects.hash(objects.toArray());
+ }
}
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/ContactSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/ContactSipImpl.java
index 0d0b5e8..d4662dd 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/ContactSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/ContactSipImpl.java
@@ -172,7 +172,7 @@ public class ContactSipImpl
public String getAddress()
{
SipURI sipURI = (SipURI) sipAddress.getURI();
- return sipURI.getUser() + "@" + sipURI.getHost();
+ return sipURI.toString().substring(sipURI.getScheme().length() + 1);
}
/**
@@ -535,9 +535,7 @@ public class ContactSipImpl
if(obj instanceof String)
{
String sobj = (String)obj;
-
- if(sobj.startsWith("sip:"))
- sobj = sobj.substring(4);
+ sobj = stripScheme(stripAddress(sobj));
if(getAddress().equalsIgnoreCase(sobj))
return true;
@@ -556,6 +554,43 @@ public class ContactSipImpl
}
/**
+ * Get rid of any parameters, ports etc. within a sip contact
+ * @param address the address to strip
+ * @return [sip[s]:]user@host without any params or port numbers.
+ */
+ static String stripAddress(String address)
+ {
+ if (address != null && address.length() > 0)
+ {
+ int idx = address.indexOf(':', 5);
+ if (idx > -1)
+ address = address.substring(0, idx);
+ idx = address.indexOf(';');
+ if (idx > -1)
+ address = address.substring(0, idx);
+ }
+ return address;
+ }
+
+ /**
+ * @param from address to strip
+ * @return the address, stripped from either "sip:" or "sips:"
+ */
+ public static String stripScheme(String from)
+ {
+ if (from.startsWith("sip:"))
+ {
+ return from.substring(4);
+ }
+ else if (from.startsWith("sips:"))
+ {
+ return from.substring(5);
+ }
+
+ return from;
+ }
+
+ /**
* Returns the presence operation set that this contact belongs
* to.
*
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetBasicTelephonySipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetBasicTelephonySipImpl.java
index 5ee32c9..fc99643 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetBasicTelephonySipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetBasicTelephonySipImpl.java
@@ -434,7 +434,10 @@ public class OperationSetBasicTelephonySipImpl
CSeqHeader cseq = ((CSeqHeader) response.getHeader(CSeqHeader.NAME));
if (cseq == null)
+ {
logger.error("An incoming response did not contain a CSeq header");
+ return false;
+ }
String method = cseq.getMethod();
@@ -1163,11 +1166,7 @@ public class OperationSetBasicTelephonySipImpl
protocolProvider.getAccountID().getService()
, 399, reasonText);
}
- catch(InvalidArgumentException e)
- {
- logger.error("Cannot create warning header", e);
- }
- catch(ParseException e)
+ catch(InvalidArgumentException | ParseException e)
{
logger.error("Cannot create warning header", e);
}
@@ -1458,11 +1457,7 @@ public class OperationSetBasicTelephonySipImpl
{
serverTransaction.sendResponse(accepted);
}
- catch (InvalidArgumentException ex)
- {
- failure = ex;
- }
- catch (SipException ex)
+ catch (InvalidArgumentException | SipException ex)
{
failure = ex;
}
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetJitsiMeetToolsSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetJitsiMeetToolsSipImpl.java
index 77a7fae..4997fc1 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetJitsiMeetToolsSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetJitsiMeetToolsSipImpl.java
@@ -142,6 +142,16 @@ public class OperationSetJitsiMeetToolsSipImpl
* {@inheritDoc}
*/
@Override
+ public void removePresenceExtension(ChatRoom chatRoom,
+ PacketExtension extension)
+ {
+ throw new RuntimeException("Not implemented for SIP");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public void setPresenceStatus(ChatRoom chatRoom, String statusMessage)
{
throw new RuntimeException("Not implemented for SIP");
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetMessageWaitingSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetMessageWaitingSipImpl.java
index 28fce28..7972ee8 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetMessageWaitingSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetMessageWaitingSipImpl.java
@@ -209,6 +209,10 @@ public class OperationSetMessageWaitingSipImpl
try
{
subscribeAddress = getSubscribeAddress();
+ if (subscribeAddress == null)
+ {
+ return;
+ }
}
catch (ParseException e)
{
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetPresenceSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetPresenceSipImpl.java
index 2fce57e..ef0ec4c 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetPresenceSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetPresenceSipImpl.java
@@ -2240,6 +2240,40 @@ public class OperationSetPresenceSipImpl
updateContactIcon((ContactSipImpl) contact, personStatusIcon);
}
+ // search for a <note> that can define a more precise
+ // status this is not recommended by RFC3863 but some im
+ // clients use this.
+ NodeList presNoteList = getPidfChilds(presence, NOTE_ELEMENT);
+ if (presNoteList.getLength() >= 1)
+ {
+ Node noteNode = presNoteList.item(presNoteList.getLength() - 1);
+ if (noteNode.getNodeType() == Node.ELEMENT_NODE)
+ {
+ String state = getTextContent((Element)noteNode);
+ if (state != null)
+ {
+ switch (state.toLowerCase())
+ {
+ case "ready":
+ case "available":
+ personStatus = sipStatusEnum
+ .getStatus(SipStatusEnum.ONLINE);
+ break;
+ case "ringing":
+ case "on the phone":
+ case "on hold":
+ personStatus = sipStatusEnum
+ .getStatus(SipStatusEnum.ON_THE_PHONE);
+ break;
+ case "unavailable":
+ personStatus = sipStatusEnum
+ .getStatus(SipStatusEnum.OFFLINE);
+ break;
+ }
+ }
+ }
+ }
+
// Vector containing the list of status to set for each contact in
// the presence document ordered by priority (highest first).
// <SipContact, Float (priority), SipStatusEnum>
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetTelephonyBLFSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetTelephonyBLFSipImpl.java
index 644c85a..a9aefbe 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetTelephonyBLFSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetTelephonyBLFSipImpl.java
@@ -72,6 +72,10 @@ public class OperationSetTelephonyBLFSipImpl
* Account property suffix to set/provision monitored line group.
*/
public static final String BLF_LINE_GROUP_ACC_PROP_PREFIX = "Group";
+ /**
+ * Account property suffix to set/provision monitored line pickup template.
+ */
+ public static final String BLF_LINE_PICKUP_ACC_PROP_PREFIX = "Pickup";
/**
* The name of the event package supported by
@@ -195,7 +199,7 @@ public class OperationSetTelephonyBLFSipImpl
String[] lineValues = lines.get(ix);
if(lineValues == null)
{
- lineValues = new String[3];
+ lineValues = new String[4];
lines.put(ix, lineValues);
}
@@ -211,13 +215,17 @@ public class OperationSetTelephonyBLFSipImpl
{
lineValues[2] = entryValue;
}
+ else if(pName.contains(BLF_LINE_PICKUP_ACC_PROP_PREFIX))
+ {
+ lineValues[3] = entryValue;
+ }
}
for(Map.Entry<String, String[]> en : lines.entrySet())
{
String[] vals = en.getValue();
- this.lines.add(new Line(vals[0], vals[1], vals[2], this.provider));
+ this.lines.add(new Line(vals[0], vals[1], vals[2], vals[3], this.provider));
}
}
@@ -263,16 +271,25 @@ public class OperationSetTelephonyBLFSipImpl
if(details == null)
return;
- if(StringUtils.isNullOrEmpty(details.callID)
- || StringUtils.isNullOrEmpty(details.localTag)
- || StringUtils.isNullOrEmpty(details.remoteTag))
- return;
-
// replaces
Address targetAddress = null;
try
{
- targetAddress = provider.parseAddressString(line.getAddress());
+ String address = line.getAddress();
+ if(asteriskMode(details))
+ {
+ // broken mode for Asterisk, doesn't provide us with
+ // the proper call-id, etc. attributes.
+ // send an unspecified pickup-call if a template is set
+ if (StringUtils.isNullOrEmpty(line.getPickupTemplate(), true))
+ {
+ return;
+ }
+
+ address = line.getPickupTemplate().replace("\\1", address);
+ }
+
+ targetAddress = provider.parseAddressString(address);
}
catch (ParseException ex)
{
@@ -281,6 +298,16 @@ public class OperationSetTelephonyBLFSipImpl
OperationFailedException.ILLEGAL_ARGUMENT, ex, logger);
}
+ OperationSetBasicTelephonySipImpl telOpSet
+ = (OperationSetBasicTelephonySipImpl)provider
+ .getOperationSet(OperationSetBasicTelephony.class);
+
+ if (asteriskMode(details))
+ {
+ telOpSet.createOutgoingCall(targetAddress, null, null);
+ return;
+ }
+
Replaces replacesHeader = null;
SipURI sipURI = (SipURI) targetAddress.getURI();
@@ -315,12 +342,14 @@ public class OperationSetTelephonyBLFSipImpl
OperationFailedException.INTERNAL_ERROR, ex, logger);
}
- OperationSetBasicTelephonySipImpl telOpSet
- = (OperationSetBasicTelephonySipImpl)provider
- .getOperationSet(OperationSetBasicTelephony.class);
-
- CallSipImpl call
- = telOpSet.createOutgoingCall(targetAddress, null, null);
+ telOpSet.createOutgoingCall(targetAddress, null, null);
+ }
+
+ private boolean asteriskMode(LineDetails details)
+ {
+ return StringUtils.isNullOrEmpty(details.callID)
+ || StringUtils.isNullOrEmpty(details.localTag)
+ || StringUtils.isNullOrEmpty(details.remoteTag);
}
/**
@@ -549,6 +578,8 @@ public class OperationSetTelephonyBLFSipImpl
Node dialogNode = dialogList.item(i);
Element dialogElem = (Element)dialogNode;
+ details.id = dialogElem.getAttribute("id");
+ details.direction = dialogElem.getAttribute("direction");
details.callID = dialogElem.getAttribute("call-id");
details.localTag = dialogElem.getAttribute("local-tag");
details.remoteTag = dialogElem.getAttribute("remote-tag");
@@ -698,12 +729,25 @@ public class OperationSetTelephonyBLFSipImpl
*/
private class LineDetails
{
+
/**
* The current status of the line, the last event fired for it.
*/
int lastStatusEvent = BLFStatusEvent.STATUS_OFFLINE;
/**
+ * id of the dialog. Mandatory.
+ */
+ String id = null;
+
+ /**
+ * either initiator or recipient, and indicates whether the observed
+ * user was the initiator of the dialog, or the recipient of the INVITE
+ * that created it.
+ */
+ String direction;
+
+ /**
* call-id of the dialog if any, used for remote pickup.
*/
String callID = null;
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java
index 0fbcf23..927c0a3 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java
@@ -246,6 +246,76 @@ public class ProtocolProviderServiceSipImpl
}
/**
+ * Validates the contact identifier and returns an error message if
+ * applicable and a suggested correction
+ *
+ * @param contactId the contact identifier to validate
+ * @param result Must be supplied as an empty a list. Implementors add
+ * items:
+ * <ol>
+ * <li>is the error message if applicable
+ * <li>a suggested correction. Index 1 is optional and can only
+ * be present if there was a validation failure.
+ * </ol>
+ * @return true if the contact id is valid, false otherwise
+ */
+ @Override
+ public boolean validateContactAddress(String contactId, List<String> result)
+ {
+ if (result == null)
+ {
+ throw new IllegalArgumentException("result must be an empty list");
+ }
+
+ result.clear();
+ try
+ {
+ Address address = parseAddressString(contactId);
+ if (address.toString().equals(contactId))
+ {
+ return true;
+ }
+ else if (((SipUri) address.getURI()).getUser().equals(contactId))
+ {
+ return true;
+ }
+ else if (address.toString().equals(address.getURI().getScheme() + ":" + contactId))
+ {
+ return true;
+ }
+ else
+ {
+ result.add(SipActivator.getResources().getI18NString(
+ "impl.protocol.sip.INVALID_ADDRESS", new String[]
+ { contactId }));
+ result.add(((SipUri) address.getURI()).getUser());
+ }
+ }
+ catch (Exception ex)
+ {
+ logger.error("Validating SIP address failed for " + contactId, ex);
+ result.add(SipActivator.getResources()
+ .getI18NString("impl.protocol.sip.INVALID_ADDRESS", new String[]
+ { contactId }));
+
+ String user = contactId;
+ String remainder = "";
+ int at = contactId.indexOf('@');
+ if (at > -1)
+ {
+ user = contactId.substring(0, at);
+ remainder = contactId.substring(at);
+ }
+
+ // replace invalid characters in user part with hex encoding
+ String banned = "([^a-z0-9-_.!~*'()&=+$,;?/])+";
+ result.add(user.replaceAll(banned, "") + remainder);
+ }
+
+ return false;
+ }
+
+ /**
* Indicates whether or not this provider must registered
* when placing outgoing calls.
*
@@ -610,50 +680,50 @@ public class ProtocolProviderServiceSipImpl
addSupportedOperationSet(
OperationSetPresence.class,
opSetPersPresence);
+ }
- // Only init messaging and typing if enabled.
- boolean isMessagingDisabled
- = SipActivator.getConfigurationService()
- .getBoolean(IS_MESSAGING_DISABLED, false);
+ // Only init messaging and typing if enabled.
+ boolean isMessagingDisabled
+ = SipActivator.getConfigurationService()
+ .getBoolean(IS_MESSAGING_DISABLED, false);
- if (!isMessagingDisabled)
- {
- // init instant messaging
- this.opSetBasicIM =
- new OperationSetBasicInstantMessagingSipImpl(this);
+ if (!isMessagingDisabled)
+ {
+ // init instant messaging
+ this.opSetBasicIM =
+ new OperationSetBasicInstantMessagingSipImpl(this);
- addSupportedOperationSet(
- OperationSetBasicInstantMessaging.class,
- opSetBasicIM);
+ addSupportedOperationSet(
+ OperationSetBasicInstantMessaging.class,
+ opSetBasicIM);
- // init typing notifications
- this.opSetTypingNotif
- = new OperationSetTypingNotificationsSipImpl(
- this, opSetBasicIM);
- addSupportedOperationSet(
- OperationSetTypingNotifications.class,
- opSetTypingNotif);
+ // init typing notifications
+ this.opSetTypingNotif
+ = new OperationSetTypingNotificationsSipImpl(
+ this, opSetBasicIM);
+ addSupportedOperationSet(
+ OperationSetTypingNotifications.class,
+ opSetTypingNotif);
- addSupportedOperationSet(
- OperationSetInstantMessageTransform.class,
- new OperationSetInstantMessageTransformImpl());
- }
+ addSupportedOperationSet(
+ OperationSetInstantMessageTransform.class,
+ new OperationSetInstantMessageTransformImpl());
+ }
- this.opSetSSAccountInfo =
- new OperationSetServerStoredAccountInfoSipImpl(this);
+ this.opSetSSAccountInfo =
+ new OperationSetServerStoredAccountInfoSipImpl(this);
- // Set the display name.
- opSetSSAccountInfo.setOurDisplayName(ourDisplayName);
+ // Set the display name.
+ opSetSSAccountInfo.setOurDisplayName(ourDisplayName);
- // init avatar
- addSupportedOperationSet(
- OperationSetServerStoredAccountInfo.class,
- opSetSSAccountInfo);
+ // init avatar
+ addSupportedOperationSet(
+ OperationSetServerStoredAccountInfo.class,
+ opSetSSAccountInfo);
- addSupportedOperationSet(
- OperationSetAvatar.class,
- new OperationSetAvatarSipImpl(this, opSetSSAccountInfo));
- }
+ addSupportedOperationSet(
+ OperationSetAvatar.class,
+ new OperationSetAvatarSipImpl(this, opSetSSAccountInfo));
// MWI is enabled by default
if(accountID.getAccountPropertyBoolean(
@@ -1519,16 +1589,16 @@ public class ProtocolProviderServiceSipImpl
Set<ProtocolProviderServiceSipImpl> instances
= new HashSet<ProtocolProviderServiceSipImpl>();
BundleContext context = SipActivator.getBundleContext();
- ServiceReference[] references = context.getServiceReferences(
- ProtocolProviderService.class.getName(),
- null
- );
- for(ServiceReference reference : references)
+ Collection<ServiceReference<ProtocolProviderService>> references =
+ context.getServiceReferences(ProtocolProviderService.class,
+ null);
+ for(ServiceReference<ProtocolProviderService> ref : references)
{
- Object service = context.getService(reference);
+ ProtocolProviderService service = context.getService(ref);
if(service instanceof ProtocolProviderServiceSipImpl)
instances.add((ProtocolProviderServiceSipImpl) service);
}
+
return instances;
}
catch(InvalidSyntaxException ex)
@@ -2390,21 +2460,38 @@ public class ProtocolProviderServiceSipImpl
//we don't know how to handle the "tel:" and "callto:" schemes ... or
// rather we handle them same as sip so replace:
if(uriStr.toLowerCase().startsWith("tel:"))
- uriStr = "sip:" + uriStr.substring("tel:".length());
+ uriStr = uriStr.substring("tel:".length());
else if(uriStr.toLowerCase().startsWith("callto:"))
- uriStr = "sip:" + uriStr.substring("callto:".length());
+ uriStr = uriStr.substring("callto:".length());
+ else if(uriStr.toLowerCase().startsWith("sips:"))
+ uriStr = uriStr.substring("sips:".length());
+ else if(uriStr.toLowerCase().startsWith("sip:"))
+ uriStr = uriStr.substring("sip:".length());
+
+ String user = uriStr;
+ String remainder = "";
+ int at = uriStr.indexOf('@');
+ if (at > -1)
+ {
+ user = uriStr.substring(0, at);
+ remainder = uriStr.substring(at);
+ }
+
+ //replace invalid characters in user part with hex encoding
+ String banned = "([^a-z0-9-_.!~*'()&=+$,;?/])+";
+ user = user.replaceAll(banned, "") + remainder;
//Handle default domain name (i.e. transform 1234 -> 1234@sip.com)
//assuming that if no domain name is specified then it should be the
//same as ours.
- if (uriStr.indexOf('@') == -1)
+ if (at == -1)
{
//if we have a registrar, then we could append its domain name as
//default
SipRegistrarConnection src = sipRegistrarConnection;
if(src != null && !src.isRegistrarless() )
{
- uriStr = uriStr + "@"
+ uriStr = user + "@"
+ ((SipURI)src.getAddressOfRecord().getURI()).getHost();
}
@@ -2684,6 +2771,11 @@ public class ProtocolProviderServiceSipImpl
*/
protected void notifyConnectionFailed()
{
+ if (sipRegistrarConnection.isRegistrarless())
+ {
+ return;
+ }
+
if(getRegistrationState().equals(RegistrationState.REGISTERED)
&& sipRegistrarConnection != null)
sipRegistrarConnection.setRegistrationState(
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/ProxyRouter.java b/src/net/java/sip/communicator/impl/protocol/sip/ProxyRouter.java
index 5d60612..b6bf997 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/ProxyRouter.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/ProxyRouter.java
@@ -19,6 +19,7 @@ package net.java.sip.communicator.impl.protocol.sip;
import gov.nist.javax.sip.stack.*;
+import java.net.*;
import java.util.*;
import javax.sip.*;
@@ -26,6 +27,7 @@ import javax.sip.address.*;
import javax.sip.header.*;
import javax.sip.message.*;
+import net.java.sip.communicator.impl.protocol.sip.net.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.*;
@@ -137,7 +139,9 @@ public class ProxyRouter
ProtocolProviderServiceSipImpl sipProvider
= ((ProtocolProviderServiceSipImpl) service);
- String proxy = sipProvider.getConnection().getOutboundProxyString();
+ final ProxyConnection connection = sipProvider.getConnection();
+ final String proxy = connection.getOutboundProxyString();
+ logger.trace("Router for proxy: " + proxy);
boolean forceLooseRouting
= sipProvider.getAccountID()
@@ -146,13 +150,30 @@ public class ProxyRouter
// P2P case
if (proxy == null || forceLooseRouting )
+ {
+ logger.info("Returning default SIP router, P2P/loose routing");
return this.getDefaultRouter();
+ }
// outbound proxy case
Router router = routerCache.get(proxy);
if (router == null)
{
- router = new DefaultRouter(stack, proxy);
+ router = new DefaultRouter(stack, proxy)
+ {
+ @Override
+ public Hop getNextHop(Request request) throws SipException
+ {
+ logger.info("Outbound proxy mode, using proxy " +
+ proxy + " as hop instead of an address resolved" +
+ " by the SIP router");
+ InetSocketAddress sa = connection.getAddress();
+ return new HopImpl(
+ sa.getAddress().getHostAddress(),
+ sa.getPort(),
+ connection.getTransport());
+ }
+ };
routerCache.put(proxy, router);
}
return router;
@@ -164,6 +185,7 @@ public class ProxyRouter
logger.error("unable to identify the service which created this "
+ "out-of-dialog request");
+ logger.info("Returning default router");
return this.getDefaultRouter();
}
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/SipRegistrarConnection.java b/src/net/java/sip/communicator/impl/protocol/sip/SipRegistrarConnection.java
index 99cb0f8..2a3ed00 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/SipRegistrarConnection.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/SipRegistrarConnection.java
@@ -1288,8 +1288,11 @@ public class SipRegistrarConnection
if(registrarPort != ListeningPoint.PORT_5060)
registrarURI.setPort(registrarPort);
- if(!registrationTransport.equals(ListeningPoint.UDP))
+ if(!registrationTransport.equals(ListeningPoint.UDP)
+ && !registrationTransport.equals(ListeningPoint.TLS))
+ {
registrarURI.setTransportParam(registrationTransport);
+ }
}
return registrarURI;
}
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/SipStackSharing.java b/src/net/java/sip/communicator/impl/protocol/sip/SipStackSharing.java
index 2e714b5..c92782e 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/SipStackSharing.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/SipStackSharing.java
@@ -1172,6 +1172,9 @@ public class SipStackSharing
String transport)
throws IOException
{
+ logger.info("Gettting source address for " +
+ localAddress + " -> " + dst + ":" + dstPort +
+ "(" + transport + ")");
if(ListeningPoint.TLS.equalsIgnoreCase(transport))
return (java.net.InetSocketAddress)(((SipStackImpl)this.stack)
.getLocalAddressForTlsDst(dst, dstPort, localAddress));
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/UriHandlerSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/UriHandlerSipImpl.java
index 885455a..ecec5c5 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/UriHandlerSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/UriHandlerSipImpl.java
@@ -351,7 +351,11 @@ public class UriHandlerSipImpl
// Even if not registered after the timeout, try the call
// anyway and the error popup will appear to ask the
// user if they want to register
- handleUri(uri, provider);
+ if(provider.getRegistrationState()
+ != RegistrationState.REGISTERED)
+ {
+ handleUri(uri, provider);
+ }
}
}, initialRegistrationTimeout);
}
@@ -401,9 +405,34 @@ public class UriHandlerSipImpl
OperationSetBasicTelephony<?> telephonyOpSet
= provider.getOperationSet(OperationSetBasicTelephony.class);
+ OperationSetVideoTelephony videoTelephonyOpSet
+ = provider.getOperationSet(OperationSetVideoTelephony.class);
+
+ boolean videoCall = false;
+ if(videoTelephonyOpSet != null
+ && uri.contains("?"))
+ {
+ String params = uri.substring(uri.indexOf('?') + 1);
+ uri = uri.substring(0, uri.indexOf('?'));
+
+ StringTokenizer paramTokens = new StringTokenizer(params, "&");
+ while(paramTokens.hasMoreTokens())
+ {
+ String tok = paramTokens.nextToken();
+ String[] keyValue = tok.split("\\=");
+ if (keyValue.length == 2
+ && keyValue[0].equalsIgnoreCase("video")
+ && keyValue[1].equalsIgnoreCase("true"))
+ videoCall = true;
+ }
+ }
+
try
{
- telephonyOpSet.createCall(uri);
+ if(videoCall)
+ videoTelephonyOpSet.createVideoCall(uri);
+ else
+ telephonyOpSet.createCall(uri);
}
catch (OperationFailedException exc)
{
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/net/ManualProxyConnection.java b/src/net/java/sip/communicator/impl/protocol/sip/net/ManualProxyConnection.java
index 5439d99..ca7faa9 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/net/ManualProxyConnection.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/net/ManualProxyConnection.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,115 +15,115 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.protocol.sip.net;
-
-import static javax.sip.ListeningPoint.PORT_5060;
-import static net.java.sip.communicator.service.protocol.ProtocolProviderFactory.PREFERRED_TRANSPORT;
-import static net.java.sip.communicator.service.protocol.ProtocolProviderFactory.PROXY_ADDRESS;
-import static net.java.sip.communicator.service.protocol.ProtocolProviderFactory.PROXY_PORT;
-
-import java.net.*;
-import java.text.*;
-
-import net.java.sip.communicator.impl.protocol.sip.*;
-import net.java.sip.communicator.service.dns.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Implementation of the manually configured SIP proxy connection. IP Address
- * lookups are performed using the account's proxy address.
- *
- * @author Ingo Bauersachs
- */
-public class ManualProxyConnection
- extends ProxyConnection
-{
- private final static Logger logger
- = Logger.getLogger(ManualProxyConnection.class);
-
- private String address;
- private int port;
-
- private InetSocketAddress[] lookups;
- private int lookupIndex;
-
- /**
- * Creates a new instance of this class. Uses the server from the account.
- *
- * @param account the account of this SIP protocol instance
- */
- public ManualProxyConnection(SipAccountIDImpl account)
- {
- super(account);
- reset();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see net.java.sip.communicator.impl.protocol.sip.net.ProxyConnection#
- * getNextAddress()
- */
- @Override
- public boolean getNextAddressFromDns()
- throws DnssecException
- {
- if(lookups == null)
- {
- try
- {
- lookupIndex = 0;
- lookups = NetworkUtils.getAandAAAARecords(address, port);
-
- //no result found, reset state and indicate "out of addresses"
- if(lookups.length == 0)
- {
- lookups = null;
- return false;
- }
- }
- catch (ParseException e)
- {
- logger.error("Invalid address <" + address + ">", e);
- return false;
- }
- }
-
- //check if the available addresses are exhausted
- if(lookupIndex >= lookups.length)
- {
- if(logger.isDebugEnabled())
- logger.debug("No more addresses for " + account);
- lookups = null;
- return false;
- }
-
- //assign the next address and return lookup success
- if(logger.isDebugEnabled())
- logger.debug("Returning <" + socketAddress
- + "> as next address for " + account);
- socketAddress = lookups[lookupIndex];
- lookupIndex++;
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * net.java.sip.communicator.impl.protocol.sip.net.ProxyConnection#reset()
- */
- @Override
- public void reset()
- {
- super.reset();
- address = account.getAccountPropertyString(PROXY_ADDRESS);
- port = account.getAccountPropertyInt(PROXY_PORT, PORT_5060);
- transport = account.getAccountPropertyString(PREFERRED_TRANSPORT);
-
- //check property sanity
- if(!ProtocolProviderServiceSipImpl.isValidTransport(transport))
- throw new IllegalArgumentException(
- transport + " is not a valid SIP transport");
- }
-}
+package net.java.sip.communicator.impl.protocol.sip.net;
+
+import static javax.sip.ListeningPoint.PORT_5060;
+import static net.java.sip.communicator.service.protocol.ProtocolProviderFactory.PREFERRED_TRANSPORT;
+import static net.java.sip.communicator.service.protocol.ProtocolProviderFactory.PROXY_ADDRESS;
+import static net.java.sip.communicator.service.protocol.ProtocolProviderFactory.PROXY_PORT;
+
+import java.net.*;
+import java.text.*;
+
+import net.java.sip.communicator.impl.protocol.sip.*;
+import net.java.sip.communicator.service.dns.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Implementation of the manually configured SIP proxy connection. IP Address
+ * lookups are performed using the account's proxy address.
+ *
+ * @author Ingo Bauersachs
+ */
+public class ManualProxyConnection
+ extends ProxyConnection
+{
+ private final static Logger logger
+ = Logger.getLogger(ManualProxyConnection.class);
+
+ private String address;
+ private int port;
+
+ private InetSocketAddress[] lookups;
+ private int lookupIndex;
+
+ /**
+ * Creates a new instance of this class. Uses the server from the account.
+ *
+ * @param account the account of this SIP protocol instance
+ */
+ public ManualProxyConnection(SipAccountIDImpl account)
+ {
+ super(account);
+ reset();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.java.sip.communicator.impl.protocol.sip.net.ProxyConnection#
+ * getNextAddress()
+ */
+ @Override
+ public boolean getNextAddressFromDns()
+ throws DnssecException
+ {
+ if(lookups == null)
+ {
+ try
+ {
+ lookupIndex = 0;
+ lookups = NetworkUtils.getAandAAAARecords(address, port);
+
+ //no result found, reset state and indicate "out of addresses"
+ if(lookups.length == 0)
+ {
+ lookups = null;
+ return false;
+ }
+ }
+ catch (ParseException e)
+ {
+ logger.error("Invalid address <" + address + ">", e);
+ return false;
+ }
+ }
+
+ //check if the available addresses are exhausted
+ if(lookupIndex >= lookups.length)
+ {
+ if(logger.isDebugEnabled())
+ logger.debug("No more addresses for " + account);
+ lookups = null;
+ return false;
+ }
+
+ //assign the next address and return lookup success
+ if(logger.isDebugEnabled())
+ logger.debug("Returning <" + socketAddress
+ + "> as next address for " + account);
+ socketAddress = lookups[lookupIndex];
+ lookupIndex++;
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * net.java.sip.communicator.impl.protocol.sip.net.ProxyConnection#reset()
+ */
+ @Override
+ public void reset()
+ {
+ super.reset();
+ address = account.getAccountPropertyString(PROXY_ADDRESS);
+ port = account.getAccountPropertyInt(PROXY_PORT, PORT_5060);
+ transport = account.getAccountPropertyString(PREFERRED_TRANSPORT);
+
+ //check property sanity
+ if(!ProtocolProviderServiceSipImpl.isValidTransport(transport))
+ throw new IllegalArgumentException(
+ transport + " is not a valid SIP transport");
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/net/ProxyConnection.java b/src/net/java/sip/communicator/impl/protocol/sip/net/ProxyConnection.java
index 99fcfb2..f7079f4 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/net/ProxyConnection.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/net/ProxyConnection.java
@@ -1,180 +1,180 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.sip.net;
-
-import static net.java.sip.communicator.service.protocol.ProtocolProviderFactory.PROXY_AUTO_CONFIG;
-
-import java.net.*;
-import java.util.*;
-
-import net.java.sip.communicator.impl.protocol.sip.*;
-import net.java.sip.communicator.service.dns.*;
-
-/**
- * Abstract class for the determining the address for the SIP proxy.
- *
- * @author Ingo Bauersachs
- */
-public abstract class ProxyConnection
-{
- private List<String> returnedAddresses = new LinkedList<String>();
-
- protected String transport;
- protected InetSocketAddress socketAddress;
- protected final SipAccountIDImpl account;
-
- /**
- * Creates a new instance of this class.
- * @param account the account of this SIP protocol instance
- */
- protected ProxyConnection(SipAccountIDImpl account)
- {
- this.account = account;
- }
-
- /**
- * Gets the address to use for the next connection attempt.
- * @return the address of the last lookup.
- */
- public final InetSocketAddress getAddress()
- {
- return socketAddress;
- }
-
- /**
- * Gets the transport to use for the next connection attempt.
- * @return the transport of the last lookup.
- */
- public final String getTransport()
- {
- return transport;
- }
-
- /**
- * In case we are using an outbound proxy this method returns
- * a suitable string for use with Router.
- * The method returns <tt>null</tt> otherwise.
- *
- * @return the string of our outbound proxy if we are using one and
- * <tt>null</tt> otherwise.
- */
- public final String getOutboundProxyString()
- {
- if(socketAddress == null)
- return null;
-
- InetAddress proxyAddress = socketAddress.getAddress();
- StringBuilder proxyStringBuffer
- = new StringBuilder(proxyAddress.getHostAddress());
-
- if(proxyAddress instanceof Inet6Address)
- {
- proxyStringBuffer.insert(0, '[');
- proxyStringBuffer.append(']');
- }
-
- proxyStringBuffer.append(':');
- proxyStringBuffer.append(socketAddress.getPort());
- proxyStringBuffer.append('/');
- proxyStringBuffer.append(transport);
-
- return proxyStringBuffer.toString();
- }
-
- /**
- * Compares an InetAddress against the active outbound proxy. The comparison
- * is by reference, not equals.
- *
- * @param addressToTest The addres to test.
- * @return True when the InetAddress is the same as the outbound proxy.
- */
- public final boolean isSameInetAddress(InetAddress addressToTest)
- {
- // if the proxy is not yet initialized then this is not the provider
- // that caused this comparison
- if(socketAddress == null)
- return false;
- return addressToTest == socketAddress.getAddress();
- }
-
- /**
- * Retrieves the next address to use from DNS. Duplicate results are
- * suppressed.
- *
- * @return True if a new address is available through {@link #getAddress()},
- * false if the last address was reached. A new lookup from scratch
- * can be started by calling {@link #reset()}.
- * @throws DnssecException if there is a problem related to DNSSEC
- */
- public final boolean getNextAddress() throws DnssecException
- {
- boolean result;
- String key = null;
- do
- {
- result = getNextAddressFromDns();
- if(result && socketAddress != null)
- {
- key = getOutboundProxyString();
- if(!returnedAddresses.contains(key))
- {
- returnedAddresses.add(key);
- break;
- }
- }
- }
- while(result && returnedAddresses.contains(key));
- return result;
- }
-
- /**
- * Implementations must use this method to get the next address, but do not
- * have to care about duplicate addresses.
- *
- * @return True when a further address was available.
- * @throws DnssecException when a DNSSEC validation failure occured.
- */
- protected abstract boolean getNextAddressFromDns()
- throws DnssecException;
-
- /**
- * Resets the lookup to it's initial state. Overriders methods have to call
- * this method through a super-call.
- */
- public void reset()
- {
- returnedAddresses.clear();
- }
-
- /**
- * Factory method to create a proxy connection based on the account settings
- * of the protocol provider.
- *
- * @param pps the protocol provider that needs a SIP server connection.
- * @return An instance of a derived class.
- */
- public static ProxyConnection create(ProtocolProviderServiceSipImpl pps)
- {
- if (pps.getAccountID().getAccountPropertyBoolean(PROXY_AUTO_CONFIG,
- true))
- return new AutoProxyConnection((SipAccountIDImpl) pps.getAccountID(),
- pps.getDefaultTransport());
- else
- return new ManualProxyConnection((SipAccountIDImpl) pps.getAccountID());
- }
-}
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.impl.protocol.sip.net;
+
+import static net.java.sip.communicator.service.protocol.ProtocolProviderFactory.PROXY_AUTO_CONFIG;
+
+import java.net.*;
+import java.util.*;
+
+import net.java.sip.communicator.impl.protocol.sip.*;
+import net.java.sip.communicator.service.dns.*;
+
+/**
+ * Abstract class for the determining the address for the SIP proxy.
+ *
+ * @author Ingo Bauersachs
+ */
+public abstract class ProxyConnection
+{
+ private List<String> returnedAddresses = new LinkedList<String>();
+
+ protected String transport;
+ protected InetSocketAddress socketAddress;
+ protected final SipAccountIDImpl account;
+
+ /**
+ * Creates a new instance of this class.
+ * @param account the account of this SIP protocol instance
+ */
+ protected ProxyConnection(SipAccountIDImpl account)
+ {
+ this.account = account;
+ }
+
+ /**
+ * Gets the address to use for the next connection attempt.
+ * @return the address of the last lookup.
+ */
+ public final InetSocketAddress getAddress()
+ {
+ return socketAddress;
+ }
+
+ /**
+ * Gets the transport to use for the next connection attempt.
+ * @return the transport of the last lookup.
+ */
+ public final String getTransport()
+ {
+ return transport;
+ }
+
+ /**
+ * In case we are using an outbound proxy this method returns
+ * a suitable string for use with Router.
+ * The method returns <tt>null</tt> otherwise.
+ *
+ * @return the string of our outbound proxy if we are using one and
+ * <tt>null</tt> otherwise.
+ */
+ public final String getOutboundProxyString()
+ {
+ if(socketAddress == null)
+ return null;
+
+ InetAddress proxyAddress = socketAddress.getAddress();
+ StringBuilder proxyStringBuffer
+ = new StringBuilder(proxyAddress.getHostAddress());
+
+ if(proxyAddress instanceof Inet6Address)
+ {
+ proxyStringBuffer.insert(0, '[');
+ proxyStringBuffer.append(']');
+ }
+
+ proxyStringBuffer.append(':');
+ proxyStringBuffer.append(socketAddress.getPort());
+ proxyStringBuffer.append('/');
+ proxyStringBuffer.append(transport);
+
+ return proxyStringBuffer.toString();
+ }
+
+ /**
+ * Compares an InetAddress against the active outbound proxy. The comparison
+ * is by reference, not equals.
+ *
+ * @param addressToTest The addres to test.
+ * @return True when the InetAddress is the same as the outbound proxy.
+ */
+ public final boolean isSameInetAddress(InetAddress addressToTest)
+ {
+ // if the proxy is not yet initialized then this is not the provider
+ // that caused this comparison
+ if(socketAddress == null)
+ return false;
+ return addressToTest == socketAddress.getAddress();
+ }
+
+ /**
+ * Retrieves the next address to use from DNS. Duplicate results are
+ * suppressed.
+ *
+ * @return True if a new address is available through {@link #getAddress()},
+ * false if the last address was reached. A new lookup from scratch
+ * can be started by calling {@link #reset()}.
+ * @throws DnssecException if there is a problem related to DNSSEC
+ */
+ public final boolean getNextAddress() throws DnssecException
+ {
+ boolean result;
+ String key = null;
+ do
+ {
+ result = getNextAddressFromDns();
+ if(result && socketAddress != null)
+ {
+ key = getOutboundProxyString();
+ if(!returnedAddresses.contains(key))
+ {
+ returnedAddresses.add(key);
+ break;
+ }
+ }
+ }
+ while(result && returnedAddresses.contains(key));
+ return result;
+ }
+
+ /**
+ * Implementations must use this method to get the next address, but do not
+ * have to care about duplicate addresses.
+ *
+ * @return True when a further address was available.
+ * @throws DnssecException when a DNSSEC validation failure occured.
+ */
+ protected abstract boolean getNextAddressFromDns()
+ throws DnssecException;
+
+ /**
+ * Resets the lookup to it's initial state. Overriders methods have to call
+ * this method through a super-call.
+ */
+ public void reset()
+ {
+ returnedAddresses.clear();
+ }
+
+ /**
+ * Factory method to create a proxy connection based on the account settings
+ * of the protocol provider.
+ *
+ * @param pps the protocol provider that needs a SIP server connection.
+ * @return An instance of a derived class.
+ */
+ public static ProxyConnection create(ProtocolProviderServiceSipImpl pps)
+ {
+ if (pps.getAccountID().getAccountPropertyBoolean(PROXY_AUTO_CONFIG,
+ true))
+ return new AutoProxyConnection((SipAccountIDImpl) pps.getAccountID(),
+ pps.getDefaultTransport());
+ else
+ return new ManualProxyConnection((SipAccountIDImpl) pps.getAccountID());
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/net/RFC5922Matcher.java b/src/net/java/sip/communicator/impl/protocol/sip/net/RFC5922Matcher.java
index 0027ec5..262b717 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/net/RFC5922Matcher.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/net/RFC5922Matcher.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,211 +15,211 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.protocol.sip.net;
-
-import java.security.cert.*;
-import java.text.*;
-import java.util.*;
-import java.util.regex.*;
-
-import javax.sip.address.*;
-
-import net.java.sip.communicator.impl.protocol.sip.*;
-import net.java.sip.communicator.service.certificate.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Matcher that extracts certificate identities according to <a
- * href="http://tools.ietf.org/html/rfc5922#section-7.1">RFC5922, Section
- * 7.1</a> and compares them with the rules from Section 7.2 and 7.3.
- * @see #PNAME_STRICT_RFC5922 for wildcard handling; the default is false
- *
- * @author Ingo Bauersachs
- */
-public class RFC5922Matcher
- implements CertificateMatcher
-{
- /**
- * When set to true, enables strict validation of the hostname according to
- * <a href="http://tools.ietf.org/html/rfc5922#section-7.2">RFC5922 Section
- * 7.2</a>
- */
- public final static String PNAME_STRICT_RFC5922 =
- "net.java.sip.communicator.sip.tls.STRICT_RFC5922";
-
- private ProtocolProviderServiceSipImpl provider;
-
- /**
- * Creates a new instance of this class.
- * @param provider The SIP Provider to which this matcher belongs.
- */
- public RFC5922Matcher(ProtocolProviderServiceSipImpl provider)
- {
- this.provider = provider;
- }
-
- /** Our class logger. */
- private static final Logger logger = Logger
- .getLogger(CertificateMatcher.class);
-
- /*
- * (non-Javadoc)
- *
- * @see
- * net.java.sip.communicator.service.certificate.CertificateMatcher#verify
- * (java.lang.Iterable, java.security.cert.X509Certificate)
- */
- public void verify(Iterable<String> identitiesToTest, X509Certificate cert)
- throws CertificateException
- {
- boolean strict = SipActivator.getConfigurationService()
- .getBoolean(PNAME_STRICT_RFC5922, false);
-
- // if any of the identities is contained in the certificate we're good
- boolean oneMatched = false;
- Iterable<String> certIdentities = extractCertIdentities(cert);
- for (String identity : identitiesToTest)
- {
- // check if the intended hostname is contained in one of the
- // hostnames of the certificate according to
- // http://tools.ietf.org/html/rfc5922#section-7.2
- for(String dnsName : certIdentities)
- {
- try
- {
- if(NetworkUtils.compareDnsNames(dnsName, identity) == 0)
- {
- // one of the hostnames matched, we're good to go
- return;
- }
-
- if(!strict
- // is a wildcard name
- && dnsName.startsWith("*.")
- // contains at least two dots (*.example.com)
- && identity.indexOf(".") < identity.lastIndexOf(".")
- // compare *.example.com stripped to example.com with
- // - foo.example.com stripped to example.com
- // - foo.bar.example.com to bar.example.com
- && NetworkUtils.compareDnsNames(
- dnsName.substring(2),
- identity.substring(identity.indexOf(".")+1)) == 0)
- {
- // the wildcard matched, we're good to go
- return;
- }
- }
- catch (ParseException e)
- {} // we don't care - this hostname did not match
- }
- }
- if (!oneMatched)
- throw new CertificateException("None of <" + identitiesToTest
- + "> matched by the rules of RFC5922 to the cert with CN="
- + cert.getSubjectDN());
- }
-
- private Iterable<String> extractCertIdentities(X509Certificate cert)
- {
- List<String> certIdentities = new ArrayList<String>();
- Collection<List<?>> subjAltNames = null;
- try
- {
- subjAltNames = cert.getSubjectAlternativeNames();
- }
- catch (CertificateParsingException ex)
- {
- logger.error("Error parsing TLS certificate", ex);
- }
- // subjAltName types are defined in rfc2459
- final Integer dnsNameType = 2;
- final Integer uriNameType = 6;
- if (subjAltNames != null)
- {
- if (logger.isDebugEnabled())
- logger.debug("found subjAltNames: " + subjAltNames);
-
- // First look for a URI in the subjectAltName field
- for (List<?> altName : subjAltNames)
- {
- // 0th position is the alt name type
- // 1st position is the alt name data
- if (altName.get(0).equals(uriNameType))
- {
- SipURI altNameUri;
- try
- {
- altNameUri =
- provider.getAddressFactory().createSipURI(
- (String) altName.get(1));
- // only sip URIs are allowed
- if (!"sip".equals(altNameUri.getScheme()))
- continue;
- // user certificates are not allowed
- if (altNameUri.getUser() != null)
- continue;
- String altHostName = altNameUri.getHost();
- if (logger.isDebugEnabled())
- {
- logger.debug("found uri " + altName.get(1)
- + ", hostName " + altHostName);
- }
- certIdentities.add(altHostName);
- }
- catch (ParseException e)
- {
- logger.error("certificate contains invalid uri: "
- + altName.get(1));
- }
- }
-
- }
- // DNS An implementation MUST accept a domain name system
- // identifier as a SIP domain identity if and only if no other
- // identity is found that matches the "sip" URI type described
- // above.
- if (certIdentities.isEmpty())
- {
- for (List<?> altName : subjAltNames)
- {
- if (altName.get(0).equals(dnsNameType))
- {
- if (logger.isDebugEnabled())
- logger.debug("found dns " + altName.get(1));
- certIdentities.add(altName.get(1).toString());
- }
- }
- }
- }
- else
- {
- // If and only if the subjectAltName does not appear in the
- // certificate, the implementation MAY examine the CN field of the
- // certificate. If a valid DNS name is found there, the
- // implementation MAY accept this value as a SIP domain identity.
- String dname = cert.getSubjectDN().getName();
- String cname = "";
- try
- {
- Pattern EXTRACT_CN =
- Pattern.compile(".*CN\\s*=\\s*([\\w*\\.]+).*");
- Matcher matcher = EXTRACT_CN.matcher(dname);
- if (matcher.matches())
- {
- cname = matcher.group(1);
- if (logger.isDebugEnabled())
- {
- logger.debug("found CN: " + cname + " from DN: "
- + dname);
- }
- certIdentities.add(cname);
- }
- }
- catch (Exception ex)
- {
- logger.error("exception while extracting CN", ex);
- }
- }
- return certIdentities;
- }
-}
+package net.java.sip.communicator.impl.protocol.sip.net;
+
+import java.security.cert.*;
+import java.text.*;
+import java.util.*;
+import java.util.regex.*;
+
+import javax.sip.address.*;
+
+import net.java.sip.communicator.impl.protocol.sip.*;
+import net.java.sip.communicator.service.certificate.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Matcher that extracts certificate identities according to <a
+ * href="http://tools.ietf.org/html/rfc5922#section-7.1">RFC5922, Section
+ * 7.1</a> and compares them with the rules from Section 7.2 and 7.3.
+ * @see #PNAME_STRICT_RFC5922 for wildcard handling; the default is false
+ *
+ * @author Ingo Bauersachs
+ */
+public class RFC5922Matcher
+ implements CertificateMatcher
+{
+ /**
+ * When set to true, enables strict validation of the hostname according to
+ * <a href="http://tools.ietf.org/html/rfc5922#section-7.2">RFC5922 Section
+ * 7.2</a>
+ */
+ public final static String PNAME_STRICT_RFC5922 =
+ "net.java.sip.communicator.sip.tls.STRICT_RFC5922";
+
+ private ProtocolProviderServiceSipImpl provider;
+
+ /**
+ * Creates a new instance of this class.
+ * @param provider The SIP Provider to which this matcher belongs.
+ */
+ public RFC5922Matcher(ProtocolProviderServiceSipImpl provider)
+ {
+ this.provider = provider;
+ }
+
+ /** Our class logger. */
+ private static final Logger logger = Logger
+ .getLogger(CertificateMatcher.class);
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * net.java.sip.communicator.service.certificate.CertificateMatcher#verify
+ * (java.lang.Iterable, java.security.cert.X509Certificate)
+ */
+ public void verify(Iterable<String> identitiesToTest, X509Certificate cert)
+ throws CertificateException
+ {
+ boolean strict = SipActivator.getConfigurationService()
+ .getBoolean(PNAME_STRICT_RFC5922, false);
+
+ // if any of the identities is contained in the certificate we're good
+ boolean oneMatched = false;
+ Iterable<String> certIdentities = extractCertIdentities(cert);
+ for (String identity : identitiesToTest)
+ {
+ // check if the intended hostname is contained in one of the
+ // hostnames of the certificate according to
+ // http://tools.ietf.org/html/rfc5922#section-7.2
+ for(String dnsName : certIdentities)
+ {
+ try
+ {
+ if(NetworkUtils.compareDnsNames(dnsName, identity) == 0)
+ {
+ // one of the hostnames matched, we're good to go
+ return;
+ }
+
+ if(!strict
+ // is a wildcard name
+ && dnsName.startsWith("*.")
+ // contains at least two dots (*.example.com)
+ && identity.indexOf(".") < identity.lastIndexOf(".")
+ // compare *.example.com stripped to example.com with
+ // - foo.example.com stripped to example.com
+ // - foo.bar.example.com to bar.example.com
+ && NetworkUtils.compareDnsNames(
+ dnsName.substring(2),
+ identity.substring(identity.indexOf(".")+1)) == 0)
+ {
+ // the wildcard matched, we're good to go
+ return;
+ }
+ }
+ catch (ParseException e)
+ {} // we don't care - this hostname did not match
+ }
+ }
+ if (!oneMatched)
+ throw new CertificateException("None of <" + identitiesToTest
+ + "> matched by the rules of RFC5922 to the cert with CN="
+ + cert.getSubjectDN());
+ }
+
+ private Iterable<String> extractCertIdentities(X509Certificate cert)
+ {
+ List<String> certIdentities = new ArrayList<String>();
+ Collection<List<?>> subjAltNames = null;
+ try
+ {
+ subjAltNames = cert.getSubjectAlternativeNames();
+ }
+ catch (CertificateParsingException ex)
+ {
+ logger.error("Error parsing TLS certificate", ex);
+ }
+ // subjAltName types are defined in rfc2459
+ final Integer dnsNameType = 2;
+ final Integer uriNameType = 6;
+ if (subjAltNames != null)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("found subjAltNames: " + subjAltNames);
+
+ // First look for a URI in the subjectAltName field
+ for (List<?> altName : subjAltNames)
+ {
+ // 0th position is the alt name type
+ // 1st position is the alt name data
+ if (altName.get(0).equals(uriNameType))
+ {
+ SipURI altNameUri;
+ try
+ {
+ altNameUri =
+ provider.getAddressFactory().createSipURI(
+ (String) altName.get(1));
+ // only sip URIs are allowed
+ if (!"sip".equals(altNameUri.getScheme()))
+ continue;
+ // user certificates are not allowed
+ if (altNameUri.getUser() != null)
+ continue;
+ String altHostName = altNameUri.getHost();
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("found uri " + altName.get(1)
+ + ", hostName " + altHostName);
+ }
+ certIdentities.add(altHostName);
+ }
+ catch (ParseException e)
+ {
+ logger.error("certificate contains invalid uri: "
+ + altName.get(1));
+ }
+ }
+
+ }
+ // DNS An implementation MUST accept a domain name system
+ // identifier as a SIP domain identity if and only if no other
+ // identity is found that matches the "sip" URI type described
+ // above.
+ if (certIdentities.isEmpty())
+ {
+ for (List<?> altName : subjAltNames)
+ {
+ if (altName.get(0).equals(dnsNameType))
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("found dns " + altName.get(1));
+ certIdentities.add(altName.get(1).toString());
+ }
+ }
+ }
+ }
+ else
+ {
+ // If and only if the subjectAltName does not appear in the
+ // certificate, the implementation MAY examine the CN field of the
+ // certificate. If a valid DNS name is found there, the
+ // implementation MAY accept this value as a SIP domain identity.
+ String dname = cert.getSubjectDN().getName();
+ String cname = "";
+ try
+ {
+ Pattern EXTRACT_CN =
+ Pattern.compile(".*CN\\s*=\\s*([\\w*\\.]+).*");
+ Matcher matcher = EXTRACT_CN.matcher(dname);
+ if (matcher.matches())
+ {
+ cname = matcher.group(1);
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("found CN: " + cname + " from DN: "
+ + dname);
+ }
+ certIdentities.add(cname);
+ }
+ }
+ catch (Exception ex)
+ {
+ logger.error("exception while extracting CN", ex);
+ }
+ }
+ return certIdentities;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/net/SslNetworkLayer.java b/src/net/java/sip/communicator/impl/protocol/sip/net/SslNetworkLayer.java
index f1c5856..9d088a2 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/net/SslNetworkLayer.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/net/SslNetworkLayer.java
@@ -18,6 +18,7 @@
package net.java.sip.communicator.impl.protocol.sip.net;
import gov.nist.core.net.*;
+import gov.nist.javax.sip.*;
import java.io.*;
import java.net.*;
@@ -421,4 +422,9 @@ public class SslNetworkLayer
return 0;
}
+
+ @Override
+ public void setSipStack(SipStackImpl sipStack)
+ {
+ }
}
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/sdp/SdpUtils.java b/src/net/java/sip/communicator/impl/protocol/sip/sdp/SdpUtils.java
index c51a96c..e30b12d 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/sdp/SdpUtils.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/sdp/SdpUtils.java
@@ -36,6 +36,7 @@ import org.jitsi.service.neomedia.*;
import org.jitsi.service.neomedia.MediaType;
import org.jitsi.service.neomedia.format.*;
import org.jitsi.util.*;
+import org.opentelecoms.javax.sdp.*;
/**
* The class contains a number of utility methods that are meant to facilitate
@@ -64,7 +65,7 @@ public class SdpUtils
/**
* A reference to the currently valid SDP factory instance.
*/
- private static final SdpFactory sdpFactory = SdpFactory.getInstance();
+ private static final SdpFactory sdpFactory = new NistSdpFactory();
/**
* The name of the SDP attribute that defines zrtp hello hash.
@@ -455,8 +456,21 @@ public class SdpUtils
while (iter.hasNext())
{
Map.Entry<String, String> ntry = iter.next();
- Attribute adv = sdpFactory.createAttribute(ntry.getKey(),
- payloadType + " " + ntry.getValue());
+ Attribute adv;
+ switch (ntry.getKey())
+ {
+ // RFC7587, Sect. 7 says there's no payload number for ptime
+ case "ptime":
+ case "maxptime":
+ adv = sdpFactory.createAttribute(ntry.getKey(),
+ ntry.getValue());
+ break;
+ default:
+ adv = sdpFactory.createAttribute(ntry.getKey(),
+ payloadType + " " + ntry.getValue());
+ break;
+ }
+
mediaAttributes.add(adv);
}
@@ -567,7 +581,7 @@ public class SdpUtils
public static SessionDescription createSessionDescription(
InetAddress localAddress,
String userName,
- Vector<MediaDescription> mediaDescriptions)
+ List<MediaDescription> mediaDescriptions)
throws OperationFailedException
{
SessionDescription sessDescr = null;
@@ -613,8 +627,9 @@ public class SdpUtils
sessDescr.setConnection(c);
if ( mediaDescriptions != null)
- sessDescr.setMediaDescriptions(mediaDescriptions);
-
+ {
+ sessDescr.setMediaDescriptions( new Vector<>(mediaDescriptions));
+ }
return sessDescr;
}
catch (SdpException exc)
@@ -655,7 +670,7 @@ public class SdpUtils
public static SessionDescription createSessionUpdateDescription(
SessionDescription descToUpdate,
InetAddress newConnectionAddress,
- Vector<MediaDescription> newMediaDescriptions)
+ List<MediaDescription> newMediaDescriptions)
throws OperationFailedException
{
SessionDescription update = createSessionDescription(
@@ -1711,7 +1726,7 @@ public class SdpUtils
* <tt>descs</tt> <tt>Vector</tt>.
*/
private static MediaDescription removeMediaDesc(
- Vector<MediaDescription> descs,
+ List<MediaDescription> descs,
MediaType type)
{
for (Iterator<MediaDescription> i = descs.iterator(); i.hasNext();)
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf
index c15c025..2015a17 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf
+++ b/src/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf
@@ -5,9 +5,22 @@ Bundle-Vendor: jitsi.org
Bundle-Version: 0.0.1
Bundle-SymbolicName: net.java.sip.communicator.protocol.sip
Import-Package: ch.imvs.sdes4j.srtp,
+ gov.nist.core,
+ gov.nist.core.net,
+ gov.nist.javax.sip,
+ gov.nist.javax.sip.address,
+ gov.nist.javax.sip.header,
+ gov.nist.javax.sip.header.extensions,
+ gov.nist.javax.sip.message,
+ gov.nist.javax.sip.stack,
javax.net,
javax.net.ssl,
javax.security.auth.x500,
+ javax.sdp,
+ javax.sip,
+ javax.sip.address,
+ javax.sip.header,
+ javax.sip.message,
javax.xml.datatype,
javax.xml.namespace,
javax.xml.parsers,
@@ -76,6 +89,7 @@ Import-Package: ch.imvs.sdes4j.srtp,
org.jitsi.util.xml,
org.json.simple,
org.osgi.framework,
+ org.opentelecoms.javax.sdp,
org.w3c.dom,
org.xml.sax
Export-Package: net.java.sip.communicator.impl.protocol.sip,
@@ -88,6 +102,4 @@ Export-Package: net.java.sip.communicator.impl.protocol.sip,
net.java.sip.communicator.impl.protocol.sip.xcap.model.resourcelists,
net.java.sip.communicator.impl.protocol.sip.xcap.model.xcapcaps,
net.java.sip.communicator.impl.protocol.sip.xcap.model.xcaperror,
- net.java.sip.communicator.impl.protocol.sip.xcap.utils,
- javax.sdp,
- gov.nist.javax.sdp.fields
+ net.java.sip.communicator.impl.protocol.sip.xcap.utils
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/ContactGroupSSHImpl.java b/src/net/java/sip/communicator/impl/protocol/ssh/ContactGroupSSHImpl.java
deleted file mode 100644
index 7de2e16..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/ContactGroupSSHImpl.java
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * A simple, straightforward implementation of a ssh ContactGroup. Since
- * the SSH protocol is not a real one, we simply store all group details
- * in class fields. You should know that when implementing a real protocol,
- * the contact group implementation would rather encapsulate group objects from
- * the protocol stack and group property values should be returned by
- * consulting the encapsulated object.
- *
- * @author Shobhit Jindal
- */
-public class ContactGroupSSHImpl
- implements ContactGroup
-{
-
- /**
- * The name of this SSH contact group.
- */
- private String groupName = null;
-
- /**
- * The list of this group's members.
- */
- private Vector<Contact> contacts = new Vector<Contact>();
-
- /**
- * The list of sub groups belonging to this group.
- */
- private Vector<ContactGroup> subGroups = new Vector<ContactGroup>();
-
- /**
- * The group that this group belongs to (or null if this is the root group).
- */
- private ContactGroupSSHImpl parentGroup = null;
-
- /**
- * Determines whether this group is really in the contact list or whether
- * it is here only temporarily and will be gone next time we restart.
- */
- private boolean isPersistent = true;
-
- /**
- * The protocol provider that created us.
- */
- private ProtocolProviderServiceSSHImpl parentProvider = null;
-
- /**
- * Determines whether this group has been resolved on the server.
- * Unresolved groups are groups that were available on previous runs and
- * that the meta contact list has stored. During all next runs, when
- * bootstrapping, the meta contact list would create these groups as
- * unresolved. Once a protocol provider implementation confirms that the
- * groups are still on the server, it would issue an event indicating that
- * the groups are now resolved.
- */
- private boolean isResolved = true;
-
- /**
- * An id uniquely identifying the group. For many protocols this could be
- * the group name itself.
- */
- private String uid = null;
- private static final String UID_SUFFIX = ".uid";
-
- /**
- * Creates a ContactGroupSSHImpl with the specified name.
- *
- * @param groupName the name of the group.
- * @param parentProvider the protocol provider that created this group.
- */
- public ContactGroupSSHImpl(
- String groupName,
- ProtocolProviderServiceSSHImpl parentProvider)
- {
- this.groupName = groupName;
- this.uid = groupName + UID_SUFFIX;
- this.parentProvider = parentProvider;
- }
-
- /**
- * Determines whether the group may contain subgroups or not.
- *
- * @return always true in this implementation.
- */
- public boolean canContainSubgroups()
- {
- return true;
- }
-
- /**
- * Returns the protocol provider that this group belongs to.
- * @return a regerence to the ProtocolProviderService instance that this
- * ContactGroup belongs to.
- */
- public ProtocolProviderService getProtocolProvider()
- {
- return parentProvider;
- }
-
- /**
- * Returns an Iterator over all contacts, member of this
- * <tt>ContactGroup</tt>.
- *
- * @return a java.util.Iterator over all contacts inside this
- * <tt>ContactGroup</tt>
- */
- public Iterator<Contact> contacts()
- {
- return contacts.iterator();
- }
-
- /**
- * Adds the specified contact to this group.
- * @param contactToAdd the ContactSSHImpl to add to this group.
- */
- public void addContact(ContactSSH contactToAdd)
- {
- this.contacts.add(contactToAdd);
- contactToAdd.setParentGroup(this);
- }
-
- /**
- * Returns the number of <tt>Contact</tt> members of this
- * <tt>ContactGroup</tt>
- *
- * @return an int indicating the number of <tt>Contact</tt>s, members of
- * this <tt>ContactGroup</tt>.
- */
- public int countContacts()
- {
- return contacts.size();
- }
-
- /**
- * Returns the number of subgroups contained by this
- * <tt>ContactGroup</tt>.
- *
- * @return the number of subGroups currently added to this group.
- */
- public int countSubgroups()
- {
- return subGroups.size();
- }
-
- /**
- * Adds the specified contact group to the contained by this group.
- * @param subgroup the ContactGroupSSHImpl to add as a subgroup to this
- * group.
- */
- public void addSubgroup(ContactGroupSSHImpl subgroup)
- {
- this.subGroups.add(subgroup);
- subgroup.setParentGroup(this);
- }
-
- /**
- * Sets the group that is the new parent of this group
- * @param parent ContactGroupSSHImpl
- */
- void setParentGroup(ContactGroupSSHImpl parent)
- {
- this.parentGroup = parent;
- }
-
- /**
- * Returns the contact group that currently contains this group or null if
- * this is the root contact group.
- * @return the contact group that currently contains this group or null if
- * this is the root contact group.
- */
- public ContactGroup getParentContactGroup()
- {
- return this.parentGroup;
- }
-
- /**
- * Removes the specified contact group from the this group's subgroups.
- * @param subgroup the ContactGroupSSHImpl subgroup to remove.
- */
- public void removeSubGroup(ContactGroupSSHImpl subgroup)
- {
- this.subGroups.remove(subgroup);
- subgroup.setParentGroup(null);
- }
-
- /**
- * Returns the group that is parent of the specified sshGroup or null
- * if no parent was found.
- * @param sshGroup the group whose parent we're looking for.
- * @return the ContactGroupSSHImpl instance that sshGroup
- * belongs to or null if no parent was found.
- */
- public ContactGroupSSHImpl findGroupParent(
- ContactGroupSSHImpl sshGroup)
- {
- if ( subGroups.contains(sshGroup) )
- return this;
-
- Iterator<ContactGroup> subGroupsIter = subgroups();
- while (subGroupsIter.hasNext())
- {
- ContactGroupSSHImpl subgroup
- = (ContactGroupSSHImpl) subGroupsIter.next();
-
- ContactGroupSSHImpl parent
- = subgroup.findGroupParent(sshGroup);
-
- if(parent != null)
- return parent;
- }
- return null;
- }
-
- /**
- * Returns the group that is parent of the specified sshContact or
- * null if no parent was found.
- *
- * @param sshContact the contact whose parent we're looking for.
- * @return the ContactGroupSSHImpl instance that sshContact
- * belongs to or <tt>null</tt> if no parent was found.
- */
- public ContactGroupSSHImpl findContactParent(
- ContactSSHImpl sshContact)
- {
- if ( contacts.contains(sshContact) )
- return this;
-
- Iterator<ContactGroup> subGroupsIter = subgroups();
- while (subGroupsIter.hasNext())
- {
- ContactGroupSSHImpl subgroup
- = (ContactGroupSSHImpl) subGroupsIter.next();
-
- ContactGroupSSHImpl parent
- = subgroup.findContactParent(sshContact);
-
- if(parent != null)
- return parent;
- }
- return null;
- }
-
-
-
- /**
- * Returns the <tt>Contact</tt> with the specified address or identifier.
- *
- * @param id the addres or identifier of the <tt>Contact</tt> we are
- * looking for.
- * @return the <tt>Contact</tt> with the specified id or address.
- */
- public Contact getContact(String id)
- {
- Iterator<Contact> contactsIter = contacts();
- while (contactsIter.hasNext())
- {
- ContactSSHImpl contact = (ContactSSHImpl) contactsIter.next();
- if (contact.getAddress().equals(id))
- return contact;
-
- }
- return null;
- }
-
- /**
- * Returns the subgroup with the specified index.
- *
- * @param index the index of the <tt>ContactGroup</tt> to retrieve.
- * @return the <tt>ContactGroup</tt> with the specified index.
- */
- public ContactGroup getGroup(int index)
- {
- return subGroups.get(index);
- }
-
- /**
- * Returns the subgroup with the specified name.
- *
- * @param groupName the name of the <tt>ContactGroup</tt> to retrieve.
- * @return the <tt>ContactGroup</tt> with the specified index.
- */
- public ContactGroup getGroup(String groupName)
- {
- Iterator<ContactGroup> groupsIter = subgroups();
- while (groupsIter.hasNext())
- {
- ContactGroupSSHImpl contactGroup
- = (ContactGroupSSHImpl) groupsIter.next();
- if (contactGroup.getGroupName().equals(groupName))
- return contactGroup;
-
- }
- return null;
-
- }
-
- /**
- * Returns the name of this group.
- *
- * @return a String containing the name of this group.
- */
- public String getGroupName()
- {
- return this.groupName;
- }
-
- /**
- * Sets this group a new name.
- * @param newGrpName a String containing the new name of this group.
- */
- public void setGroupName(String newGrpName)
- {
- this.groupName = newGrpName;
- }
-
- /**
- * Returns an iterator over the sub groups that this
- * <tt>ContactGroup</tt> contains.
- *
- * @return a java.util.Iterator over the <tt>ContactGroup</tt> children
- * of this group (i.e. subgroups).
- */
- public Iterator<ContactGroup> subgroups()
- {
- return subGroups.iterator();
- }
-
- /**
- * Removes the specified contact from this group.
- * @param contact the ContactSSHImpl to remove from this group
- */
- public void removeContact(ContactSSHImpl contact)
- {
- this.contacts.remove(contact);
- }
-
- /**
- * Returns the contact with the specified id or null if no such contact
- * exists.
- * @param id the id of the contact we're looking for.
- * @return ContactSSHImpl
- */
- public ContactSSHImpl findContactByID(String id)
- {
- //first go through the contacts that are direct children.
- Iterator<Contact> contactsIter = contacts();
-
- while(contactsIter.hasNext())
- {
- ContactSSHImpl mContact = (ContactSSHImpl)contactsIter.next();
-
- if( mContact.getAddress().equals(id) )
- return mContact;
- }
-
- //if we didn't find it here, let's try in the subougroups
- Iterator<ContactGroup> groupsIter = subgroups();
-
- while( groupsIter.hasNext() )
- {
- ContactGroupSSHImpl mGroup = (ContactGroupSSHImpl)groupsIter.next();
-
- ContactSSHImpl mContact = mGroup.findContactByID(id);
-
- if (mContact != null)
- return mContact;
- }
-
- return null;
- }
-
- /**
- * Returns a String representation of this group and the contacts it
- * contains (may turn out to be a relatively long string).
- * @return a String representing this group and its child contacts.
- */
- @Override
- public String toString()
- {
- StringBuffer buff = new StringBuffer(getGroupName());
- buff.append(".subGroups=" + countSubgroups() + ":\n");
-
- Iterator<ContactGroup> subGroups = subgroups();
- while (subGroups.hasNext())
- {
- ContactGroup group = subGroups.next();
- buff.append(group.toString());
- if (subGroups.hasNext())
- buff.append("\n");
- }
-
- buff.append("\nChildContacts="+countContacts()+":[");
-
- Iterator<Contact> contacts = contacts();
- while (contacts.hasNext())
- {
- Contact contact = contacts.next();
- buff.append(contact.toString());
- if(contacts.hasNext())
- buff.append(", ");
- }
- return buff.append("]").toString();
- }
-
- /**
- * Specifies whether or not this contact group is being stored by the
- * server.
- * Non persistent contact groups are common in the case of simple,
- * non-persistent presence operation sets. They could however also be seen
- * in persistent presence operation sets when for example we have received
- * an event from someone not on our contact list and the contact that we
- * associated with that user is placed in a non persistent group. Non
- * persistent contact groups are volatile even when coming from a
- * persistent presence op. set. They would only exist until the
- * application is closed and will not be there next time it is loaded.
- *
- * @param isPersistent true if the contact group is to be persistent and
- * false otherwise.
- */
- public void setPersistent(boolean isPersistent)
- {
- this.isPersistent = isPersistent;
- }
-
- /**
- * Determines whether or not this contact group is being stored by the
- * server. Non persistent contact groups exist for the sole purpose of
- * containing non persistent contacts.
- * @return true if the contact group is persistent and false otherwise.
- */
- public boolean isPersistent()
- {
- return isPersistent;
- }
-
- /**
- * Returns null as no persistent data is required and the contact address is
- * sufficient for restoring the contact.
- * <p>
- * @return null as no such data is needed.
- */
- public String getPersistentData()
- {
- return null;
- }
-
- /**
- * Determines whether or not this contact has been resolved against the
- * server. Unresolved contacts are used when initially loading a contact
- * list that has been stored in a local file until the presence operation
- * set has managed to retrieve all the contact list from the server and has
- * properly mapped contacts to their on-line buddies.
- * @return true if the contact has been resolved (mapped against a buddy)
- * and false otherwise.
- */
- public boolean isResolved()
- {
- return isResolved;
- }
-
- /**
- * Makes the group resolved or unresolved.
- *
- * @param resolved true to make the group resolved; false to
- * make it unresolved
- */
- public void setResolved(boolean resolved)
- {
- this.isResolved = resolved;
- }
-
- /**
- * Returns a <tt>String</tt> that uniquely represnets the group inside
- * the current protocol. The string MUST be persistent (it must not change
- * across connections or runs of the application). In many cases (Jabber,
- * ICQ) the string may match the name of the group as these protocols
- * only allow a single level of contact groups and there is no danger of
- * having the same name twice in the same contact list. Other protocols
- * (no examples come to mind but that doesn't bother me ;) ) may be
- * supporting mutilple levels of grooups so it might be possible for group
- * A and group B to both contain groups named C. In such cases the
- * implementation must find a way to return a unique identifier in this
- * method and this UID should never change for a given group.
- *
- * @return a String representing this group in a unique and persistent
- * way.
- */
- public String getUID()
- {
- return uid;
- }
-
- /**
- * Ugly but tricky conversion method.
- * @param uid the uid we'd like to get a name from
- * @return the name of the group with the specified <tt>uid</tt>.
- */
- static String createNameFromUID(String uid)
- {
- return uid.substring(0, uid.length() - (UID_SUFFIX.length()));
- }
-
- /**
- * Indicates whether some other object is "equal to" this one which in terms
- * of contact groups translates to having the equal names and matching
- * subgroups and child contacts. The resolved status of contactgroups and
- * contacts is deliberately ignored so that groups and/or contacts would
- * be assumed equal even if it differs.
- * <p>
- * @param obj the reference object with which to compare.
- * @return <code>true</code> if this contact group has the equal child
- * contacts and subgroups to those of the <code>obj</code> argument.
- */
- @Override
- public boolean equals(Object obj)
- {
- if(obj == null
- || !(obj instanceof ContactGroupSSHImpl))
- return false;
-
- ContactGroupSSHImpl sshGroup
- = (ContactGroupSSHImpl)obj;
-
- if( ! sshGroup.getGroupName().equals(getGroupName())
- || ! sshGroup.getUID().equals(getUID())
- || sshGroup.countContacts() != countContacts()
- || sshGroup.countSubgroups() != countSubgroups())
- return false;
-
- //traverse child contacts
- Iterator<Contact> theirContacts = sshGroup.contacts();
-
- while(theirContacts.hasNext())
- {
- Contact theirContact = theirContacts.next();
- Contact ourContact = getContact(theirContact.getAddress());
-
- if(ourContact == null
- || !ourContact.equals(theirContact))
- return false;
- }
-
- //traverse subgroups
- Iterator<ContactGroup> theirSubgroups = sshGroup.subgroups();
-
- while(theirSubgroups.hasNext())
- {
- ContactGroup theirSubgroup = theirSubgroups.next();
- ContactGroup ourSubgroup = getGroup(theirSubgroup.getGroupName());
-
- if(ourSubgroup == null
- || !ourSubgroup.equals(theirSubgroup))
- return false;
- }
-
- return true;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/ContactSSH.java b/src/net/java/sip/communicator/impl/protocol/ssh/ContactSSH.java
deleted file mode 100644
index a13414b..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/ContactSSH.java
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.io.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-import com.jcraft.jsch.*;
-
-/**
- * This interface represents a Contact of SSH Type
- * As a SSH Session is specific to a contact, additional information needed
- * to maintain its state with the remote server is present here
- *
- * @author Shobhit Jindal
- */
-interface ContactSSH
- extends Contact
-{
- /**
- * An event type indicating that the message being received is a standard
- * conversation message sent by another contact.
- */
- public static final int CONVERSATION_MESSAGE_RECEIVED = 1;
-
- /**
- * An event type indicting that the message being received is a system
- * message being sent by the server or a system administrator.
- */
- public static final int SYSTEM_MESSAGE_RECEIVED = 2;
-
- //Following eight function declations to be moved to Contact
-
- /**
- * This method is only called when the contact is added to a new
- * <tt>ContactGroupSSHImpl</tt> by the
- * <tt>ContactGroupSSHImpl</tt> itself.
- *
- * @param newParentGroup the <tt>ContactGroupSSHImpl</tt> that is now
- * parent of this <tt>ContactSSHImpl</tt>
- */
- void setParentGroup (ContactGroupSSHImpl newParentGroup);
-
- /**
- * Sets <tt>sshPresenceStatus</tt> as the PresenceStatus that this
- * contact is currently in.
- * @param sshPresenceStatus the <tt>SSHPresenceStatus</tt>
- * currently valid for this contact.
- */
- public void setPresenceStatus (PresenceStatus sshPresenceStatus);
-
- /**
- * Returns the persistent presence operation set that this contact belongs
- * to.
- *
- * @return the <tt>OperationSetPersistentPresenceSSHImpl</tt> that
- * this contact belongs to.
- */
- public OperationSetPersistentPresence
- getParentPresenceOperationSet ();
-
- /**
- * Returns the BasicInstant Messaging operation set that this contact
- * belongs to.
- *
- * @return the <tt>OperationSetBasicInstantMessagingSSHImpl</tt> that
- * this contact belongs to.
- */
- public OperationSetBasicInstantMessaging
- getParentBasicInstantMessagingOperationSet ();
-
- /**
- * Returns the File Transfer operation set that this contact belongs
- * to.
- *
- * @return the <tt>OperationSetFileTransferSSHImpl</tt> that
- * this contact belongs to.
- */
- public OperationSetFileTransfer
- getFileTransferOperationSet ();
-
- /**
- * Return the type of message received from remote server
- *
- * @return messageType
- */
- public int getMessageType ();
-
- /**
- * Sets the type of message received from remote server
- *
- * @param messageType
- */
- public void setMessageType (int messageType);
-
- /**
- * Stores persistent data of the contact.
- *
- * @param persistentData of the contact
- */
- public void setPersistentData (String persistentData);
-
- /**
- * Makes the contact resolved or unresolved.
- *
- * @param resolved true to make the contact resolved; false to
- * make it unresolved
- */
- public void setResolved (boolean resolved);
-
- /**
- * Specifies whether or not this contact is being stored by the server.
- * Non persistent contacts are common in the case of simple, non-persistent
- * presence operation sets. They could however also be seen in persistent
- * presence operation sets when for example we have received an event
- * from someone not on our contact list. Non persistent contacts are
- * volatile even when coming from a persistent presence op. set. They would
- * only exist until the application is closed and will not be there next
- * time it is loaded.
- *
- * @param isPersistent true if the contact is persistent and false
- * otherwise.
- */
- public void setPersistent (boolean isPersistent);
-
- /**
- * Returns true if a command has been sent whos reply was not received yet
- * false otherwise
- *
- * @return commandSent
- */
- public boolean isCommandSent ();
-
- /**
- * Set the state of commandSent variable which determines whether a reply
- * to a command sent is awaited
- *
- * @param commandSent
- */
- public void setCommandSent (boolean commandSent);
-
- /**
- * Initializes the reader and writers associated with shell of this contact
- *
- * @param shellInputStream The InputStream of stack
- * @param shellOutputStream The OutputStream of stack
- */
- void initializeShellIO (InputStream shellInputStream,
- OutputStream shellOutputStream);
-
- /**
- * Closes the readers and writer associated with shell of this contact
- */
- void closeShellIO ();
-
- /**
- * Determines whether a connection to a remote server is already underway
- *
- * @return connectionInProgress
- */
- public boolean isConnectionInProgress ();
-
- /**
- * Sets the status of connection attempt to remote server
- *
- * @param connectionInProgress
- */
- public void setConnectionInProgress (boolean connectionInProgress);
-
-// /**
-// * Sets the PS1 prompt of the current shell of Contact
-// * This method is synchronized
-// *
-// * @param sshPrompt to be associated
-// */
-// public void setShellPrompt(String sshPrompt);
-//
-// /**
-// * Returns the PS1 prompt of the current shell of Contact
-// *
-// * @return sshPrompt
-// */
-// public String getShellPrompt();
-
-
- /**
- * Saves the details of contact in persistentData
- */
- public void savePersistentDetails ();
-
- /*
- * Returns the SSHContactInfo associated with this contact
- *
- * @return sshConfigurationForm
- */
- public SSHContactInfo getSSHConfigurationForm ();
-
- /**
- * Returns the JSch Stack identified associated with this contact
- *
- * @return jsch
- */
- JSch getJSch ();
-
- /**
- * Starts the timer and its task to periodically update the status of
- * remote machine
- */
- void startTimerTask ();
-
- /**
- * Stops the timer and its task to stop updating the status of
- * remote machine
- */
- void stopTimerTask ();
-
- /**
- * Sets the JSch Stack identified associated with this contact
- *
- * @param jsch to be associated
- */
- void setJSch (JSch jsch);
-
- /**
- * Returns the Username associated with this contact
- *
- * @return userName
- */
- String getUserName ();
-
- /**
- * Returns the Hostname associated with this contact
- *
- * @return hostName
- */
- String getHostName ();
-
- /**
- * Returns the Password associated with this contact
- *
- * @return password
- */
- String getPassword ();
-
- /**
- * Sets the Password associated with this contact
- *
- * @param password
- */
- void setPassword (String password);
-
- /**
- * Returns the SSH Session associated with this contact
- *
- * @return sshSession
- */
- Session getSSHSession ();
-
- /**
- * Sets the SSH Session associated with this contact
- *
- * @param sshSession the newly created SSH Session to be associated
- */
- void setSSHSession (Session sshSession);
-
- /**
- * Returns the SSH Shell Channel associated with this contact
- *
- * @return shellChannel
- */
- Channel getShellChannel ();
-
- /**
- * Sets the SSH Shell channel associated with this contact
- *
- * @param shellChannel to be associated with SSH Session of this contact
- */
- void setShellChannel (Channel shellChannel);
-
- /**
- * Sends a message a line to remote machine via the Shell Writer
- *
- * @param message to be sent
- * @throws IOException if message failed to be sent
- */
- public void sendLine (String message)
- throws IOException;
-
-// /**
-// * Reads a line from the remote machine via the Shell Reader
-// *
-// * @return message read
-// */
-// public String getLine()
-// throws IOException;
-
- /**
- * Returns the Input Stream associated with SSH Channel of this contact
- *
- * @return shellInputStream associated with SSH Channel of this contact
- */
- public InputStream getShellInputStream ();
-
-// /**
-// * Sets the Input Stream associated with SSH Channel of this contact
-// *
-// * @param shellInputStream to be associated with SSH Channel of this
-// * contact
-// */
-// public void setShellInputStream(InputStream shellInputStream);
-
- /**
- * Returns the Output Stream associated with SSH Channel of this contact
- *
- * @return shellOutputStream associated with SSH Channel of this contact
- */
- public OutputStream getShellOutputStream ();
-
-// /**
-// * Sets the Output Stream associated with SSH Channel of this contact
-// *
-// * @param shellOutputStream to be associated with SSH Channel of this
-// * contact
-// */
-// public void setShellOutputStream(OutputStream shellOutputStream);
-//
- /**
- * Returns the BufferedReader associated with SSH Channel of this contact
- *
- * @return shellReader associated with SSH Channel of this contact
- */
- public InputStreamReader getShellReader ();
-//
-// /**
-// * Sets the BufferedReader associated with SSH Channel of this contact
-// *
-// * @param shellReader to be associated with SSH Channel of this contact
-// */
-// public void setShellReader(BufferedReader shellReader);
-
- /**
- * Returns the PrintWriter associated with SSH Channel of this contact
- *
- * @return shellWriter associated with SSH Channel of this contact
- */
- public PrintWriter getShellWriter ();
-
-// /**
-// * Sets the PrintWriter associated with SSH Channel of this contact
-// *
-// * @param shellWriter to be associated with SSH Channel of this contact
-// */
-// public void setShellWriter(PrintWriter shellWriter);
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/ContactSSHImpl.java b/src/net/java/sip/communicator/impl/protocol/ssh/ContactSSHImpl.java
deleted file mode 100644
index 15da209..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/ContactSSHImpl.java
+++ /dev/null
@@ -1,918 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.io.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.Base64; // disambiguation
-import net.java.sip.communicator.util.Logger;
-
-import com.jcraft.jsch.*;
-// disambiguation
-
-/**
- * A Contact of SSH Type
- *
- * @author Shobhit Jindal
- */
-public class ContactSSHImpl
- extends AbstractContact
- implements ContactSSH
-{
- private static final Logger logger
- = Logger.getLogger(ContactSSHImpl.class);
-
- /**
- * This acts as a separator between details stored in persistent data
- */
- private final String separator =
- Resources.getString("impl.protocol.ssh.DETAILS_SEPARATOR");
-
- /**
- * The identifier for SSH Stack
- * Java Secure Channel JSch
- */
- private JSch jsch;
-
- /**
- * Interface for user to provide details about machine
- */
- private SSHContactInfo sshConfigurationForm;
-
- /**
- * A Timer Daemon to update the status of this contact
- */
- private Timer timer = new Timer(true);
-
- /**
- * A Daemon to retrieve and fire messages received from remote machine
- */
- private SSHReaderDaemon contactSSHReaderDaemon;
-
- /**
- * The id of the contact.
- */
- private String contactID = null;
-
- /**
- * The persistentData of the contact.
- */
- private String persistentData = null;
-
-// /**
-// * This stores the prompt string of shell
-// */
-// private String sshPrompt;
-
- /**
- * The provider that created us.
- */
- private ProtocolProviderServiceSSHImpl parentProvider = null;
-
- /**
- * The identifier of the type of message received from server
- */
- private int messageType;
-
-
-
- /**
- * The identifier for SSH Session with the remote server
- */
- private Session sshSession = null;
-
- /**
- * The identifier for a sshShellChannel with the remote server is of type
- * shell - for an interactive SSH Session with the remote machine
- *
- * Other types
- * sftp - to tranfer files from/to the remote machine
- * exec - X forwarding
- * direct-tcpip - stream forwarding
- */
- private Channel sshShellChannel = null;
-
- /**
- * The identifier for the Shell Input Stream associated with SSH Sesion
- */
- private InputStream shellInputStream = null;
-
- /**
- * The identifier for the Shell Output Stream associated with SSH Sesion
- */
- private OutputStream shellOutputStream = null;
-
- /**
- * Higher wrapper for shellInputStream
- */
- private InputStreamReader shellReader = null;
-
- /**
- * Higher wrapper for shellOutputStream
- */
- private PrintWriter shellWriter = null;
-
- /**
- * The group that belong to.
- */
- private ContactGroupSSHImpl parentGroup = null;
-
- /**
- * The presence status of the contact.
- */
- private PresenceStatus presenceStatus = SSHStatusEnum.NOT_AVAILABLE;
-
- /**
- * Determines whether this contact is persistent, i.e. member of the contact
- * list or whether it is here only temporarily.
- */
- private boolean isPersistent = false;
-
- /**
- * Determines whether the contact has been resolved (i.e. we have a
- * confirmation that it is still on the server contact list).
- */
- private boolean isResolved = true;
-
- /**
- * Determines whether an connection attempt to remote server is already
- * underway
- */
- private boolean isConnectionInProgress = false;
-
- /**
- * Determines whether the message received from remote machine is as a
- * result of command sent to it
- */
- private boolean commandSent = false;
-
- /**
- * A lock to synchronize the access of commandSent boolean object
- * with the reader thread.
- */
- private final Object lock = new Object();
-
- /**
- * Creates an instance of a meta contact with the specified string used
- * as a name and identifier.
- *
- * @param id the identifier of this contact (also used as a name).
- * @param parentProvider the provider that created us.
- */
- public ContactSSHImpl(
- String id,
- ProtocolProviderServiceSSHImpl parentProvider)
- {
- this.contactID = id;
- this.parentProvider = parentProvider;
-
- this.sshConfigurationForm =
- new SSHContactInfo(this);
-
- this.savePersistentDetails();
- }
-
- /**
- * Initializes the reader and writers associated with shell of this contact
- *
- * @param shellInputStream The InputStream of stack
- * @param shellOutputStream The OutputStream of stack
- */
- public void initializeShellIO(
- InputStream shellInputStream,
- OutputStream shellOutputStream)
- {
- this.shellInputStream = shellInputStream;
- this.shellOutputStream = shellOutputStream;
- shellReader = new InputStreamReader(shellInputStream);
- shellWriter = new PrintWriter(shellOutputStream);
-
- contactSSHReaderDaemon = new SSHReaderDaemon(this);
- contactSSHReaderDaemon.setDaemon(true);
- contactSSHReaderDaemon.isActive(true);
- contactSSHReaderDaemon.start();
- }
-
- /**
- * Closes the readers and writer associated with shell of this contact
- */
- public void closeShellIO()
- {
- try
- {
- shellReader.close();
- shellInputStream.close();
- }
- catch(IOException ex)
- {}
-
- try
- {
- shellWriter.close();
- shellOutputStream.close();
- }
- catch(IOException ex)
- {}
-
- shellInputStream = null;
-
- shellReader = null;
-
- shellOutputStream = null;
-
- shellWriter = null;
-
- try
- {
- sshShellChannel.disconnect();
- }
- catch(Exception e)
- {}
-
- // Removing the reference to current channel
- // a new shell channel will be created for the next message
- sshShellChannel = null;
-
- // remove the reference of session if it were also disconnected
- // like in the case of exit command
- if(!sshSession.isConnected())
- {
- sshSession = null;
- jsch = null;
- }
-
- ((OperationSetPersistentPresenceSSHImpl)
- getParentPresenceOperationSet()).
- changeContactPresenceStatus(this, SSHStatusEnum.ONLINE);
- }
-
- /**
- * Sends a message a line to remote machine via the Shell Writer
- *
- * @param message to be sent
- */
- public void sendLine(String message)
- throws IOException
- {
-// logger.debug("SSH TO: " + this.contactID + ": " + message);
- shellWriter.println(message);
- shellWriter.flush();
- }
-
- /**
- * Reads a line from the remote machine via the Shell Reader
- *
- * @return message read
- */
-// public String getLine()
-// throws IOException
-// {
-// String line = shellReader.readLine();
-//// logger.debug("SSH FROM: " + this.contactID + ": " + line);
-//
-// // null is never returned normally, the reading attempt returs a
-// // string
-// // or blocks until one line is available
-// if(line == null)
-// {
-// sshShellChannel.disconnect();
-// sshShellChannel = null;
-// sshSession = null;
-// throw(new IOException("Unexpected Reply from remote Server"));
-// }
-// return line;
-// }
-
- /**
- * Starts the timer and its task to periodically update the status of
- * remote machine
- */
- public void startTimerTask()
- {
- timer.scheduleAtFixedRate(new ContactTimerSSHImpl(this),
- 2000, sshConfigurationForm.getUpdateInterval()*1000);
- }
-
- /**
- * Stops the timer and its task to stop updating the status of
- * remote machine
- */
- public void stopTimerTask()
- {
- timer.cancel();
- }
-
-
- /**
- * Saves the details of contact in persistentData seperated by
- * separator
- * Passowrd is saved unsecurely using Base64 encoding
- */
- public void savePersistentDetails()
- {
- persistentData =
- this.sshConfigurationForm.getHostName() +
- separator +
- this.sshConfigurationForm.getUserName() +
- separator +
- new String(Base64.encode(this.sshConfigurationForm.getPassword()
- .getBytes())) +
- separator + sshConfigurationForm.getPort() +
- separator +
- sshConfigurationForm.getTerminalType() +
- separator +
- sshConfigurationForm.getUpdateInterval();
- }
-
- /**
- * Stores persistent data in fields of the contact seperated by
- * separator.
- *
- * @param persistentData of the contact
- */
- public void setPersistentData(String persistentData)
- {
- try
- {
- this.persistentData = persistentData;
- int firstCommaIndex = this.persistentData.indexOf(separator);
- int secondCommaIndex = this.persistentData.indexOf(separator,
- firstCommaIndex +1);
- int thirdCommaIndex = this.persistentData.indexOf(separator,
- secondCommaIndex +1);
- int fourthCommaIndex = this.persistentData.indexOf(separator,
- thirdCommaIndex +1);
- int fifthCommaIndex = this.persistentData.indexOf(separator,
- fourthCommaIndex +1);
-
- if (logger.isDebugEnabled())
- logger.debug("Commas: " + firstCommaIndex + " " + secondCommaIndex + " "
- + thirdCommaIndex + " " +fourthCommaIndex + " "
- +fifthCommaIndex);
-
- this.sshConfigurationForm.setHostNameField(
- this.persistentData.substring(0,firstCommaIndex));
-
- this.sshConfigurationForm.setUserNameField(
- this.persistentData.substring(firstCommaIndex+1,
- secondCommaIndex));
-
- if( (thirdCommaIndex - secondCommaIndex) > 1)
- {
- if(this.persistentData.substring(secondCommaIndex+1).length()>0)
- this.sshConfigurationForm.setPasswordField(
- new String(Base64.decode(this.persistentData
- .substring(secondCommaIndex+1, thirdCommaIndex))));
- }
-
-
- this.sshConfigurationForm.setPort(
- this.persistentData.substring(thirdCommaIndex + 1,
- fourthCommaIndex));
-
- this.sshConfigurationForm.setTerminalType(
- this.persistentData.substring(fourthCommaIndex + 1,
- fifthCommaIndex));
-
- this.sshConfigurationForm.setUpdateInterval(
- Integer.parseInt(this.persistentData.substring(fifthCommaIndex+1)));
- }
- catch(Exception ex)
- {
- logger.error("Error setting persistent data!", ex);
- }
- }
-
- /**
- * Determines whether a connection to a remote server is already underway
- *
- * @return isConnectionInProgress
- */
- public boolean isConnectionInProgress()
- {
- return this.isConnectionInProgress;
- }
-
- /**
- * Sets the status of connection attempt to remote server
- * This method is synchronized
- *
- * @param isConnectionInProgress
- */
- public synchronized void setConnectionInProgress(
- boolean isConnectionInProgress)
- {
- this.isConnectionInProgress = isConnectionInProgress;
- }
-
- /**
- * Returns the SSHContactInfo associated with this contact
- *
- * @return sshConfigurationForm
- */
- public SSHContactInfo getSSHConfigurationForm()
- {
- return this.sshConfigurationForm;
- }
-
- /**
- * Returns the JSch Stack identified associated with this contact
- *
- * @return jsch
- */
- public JSch getJSch()
- {
- return this.jsch;
- }
-
- /**
- * Sets the JSch Stack identified associated with this contact
- *
- * @param jsch to be associated
- */
- public void setJSch(JSch jsch)
- {
- this.jsch = jsch;
- }
-
- /**
- * This method is only called when the contact is added to a new
- * <tt>ContactGroupSSHImpl</tt> by the
- * <tt>ContactGroupSSHImpl</tt> itself.
- *
- * @param newParentGroup the <tt>ContactGroupSSHImpl</tt> that is now
- * parent of this <tt>ContactSSHImpl</tt>
- */
- public void setParentGroup(ContactGroupSSHImpl newParentGroup)
- {
- this.parentGroup = newParentGroup;
- }
-
- /**
- * Returns the Hostname associated with this contact
- *
- * @return hostName
- */
- public String getHostName()
- {
- return sshConfigurationForm.getHostName();
- }
-
- /**
- * Returns a String that can be used for identifying the contact.
- *
- * @return a String id representing and uniquely identifying the contact.
- */
- public String getAddress()
- {
- return contactID;
- }
-
- /**
- * Returns a String that could be used by any user interacting modules
- * for referring to this contact.
- *
- * @return a String that can be used for referring to this contact when
- * interacting with the user.
- */
- public String getDisplayName()
- {
- return contactID;
- }
-
- /**
- * Returns a byte array containing an image (most often a photo or an
- * avatar) that the contact uses as a representation.
- *
- * @return byte[] an image representing the contact.
- */
- public byte[] getImage()
- {
- return null;
- }
-
- /**
- * Returns true if a command has been sent whos reply was not received yet
- * false otherwise
- *
- * @return commandSent
- */
- public boolean isCommandSent()
- {
- return this.commandSent;
- }
-
- /**
- * Set the state of commandSent variable which determines whether a reply
- * to a command sent is awaited
- */
- public void setCommandSent(boolean commandSent)
- {
- synchronized(lock)
- {
- this.commandSent = commandSent;
- }
- }
-
- /**
- * Return the type of message received from remote server
- *
- * @return messageType
- */
- public int getMessageType()
- {
- return this.messageType;
- }
-
- /**
- * Sets the type of message received from remote server
- *
- * @param messageType
- */
- public void setMessageType(int messageType)
- {
- this.messageType = messageType;
- }
-
- /**
- * Returns the status of the contact.
- *
- * @return presenceStatus
- */
- public PresenceStatus getPresenceStatus()
- {
- return this.presenceStatus;
- }
-
- /**
- * Sets <tt>sshPresenceStatus</tt> as the PresenceStatus that this
- * contact is currently in.
- * @param sshPresenceStatus the <tt>SSHPresenceStatus</tt>
- * currently valid for this contact.
- */
- public void setPresenceStatus(PresenceStatus sshPresenceStatus)
- {
- this.presenceStatus = sshPresenceStatus;
- }
-
- /**
- * Returns a reference to the protocol provider that created the contact.
- *
- * @return a refererence to an instance of the ProtocolProviderService
- */
- public ProtocolProviderService getProtocolProvider()
- {
- return parentProvider;
- }
-
- /**
- * Determines whether or not this contact represents our own identity.
- *
- * @return true
- */
- public boolean isLocal()
- {
- return true;
- }
-
- /**
- * Returns the group that contains this contact.
- * @return a reference to the <tt>ContactGroupSSHImpl</tt> that
- * contains this contact.
- */
- public ContactGroup getParentContactGroup()
- {
- return this.parentGroup;
- }
-
- /**
- * Returns a string representation of this contact, containing most of its
- * representative details.
- *
- * @return a string representation of this contact.
- */
- @Override
- public String toString()
- {
- StringBuffer buff
- = new StringBuffer("ContactSSHImpl[ DisplayName=")
- .append(getDisplayName()).append("]");
-
- return buff.toString();
- }
-
- /**
- * Determines whether or not this contact is being stored by the server.
- * Non persistent contacts are common in the case of simple, non-persistent
- * presence operation sets. They could however also be seen in persistent
- * presence operation sets when for example we have received an event
- * from someone not on our contact list. Non persistent contacts are
- * volatile even when coming from a persistent presence op. set. They would
- * only exist until the application is closed and will not be there next
- * time it is loaded.
- *
- * @return true if the contact is persistent and false otherwise.
- */
- public boolean isPersistent()
- {
- return isPersistent;
- }
-
- /**
- * Specifies whether or not this contact is being stored by the server.
- * Non persistent contacts are common in the case of simple, non-persistent
- * presence operation sets. They could however also be seen in persistent
- * presence operation sets when for example we have received an event
- * from someone not on our contact list. Non persistent contacts are
- * volatile even when coming from a persistent presence op. set. They would
- * only exist until the application is closed and will not be there next
- * time it is loaded.
- *
- * @param isPersistent true if the contact is persistent and false
- * otherwise.
- */
- public void setPersistent(boolean isPersistent)
- {
- this.isPersistent = isPersistent;
- }
-
-
- /**
- * Returns persistent data of the contact.
- *
- * @return persistentData of the contact
- */
- public String getPersistentData()
- {
- return persistentData;
- }
-
- /**
- * Determines whether or not this contact has been resolved against the
- * server. Unresolved contacts are used when initially loading a contact
- * list that has been stored in a local file until the presence operation
- * set has managed to retrieve all the contact list from the server and has
- * properly mapped contacts to their on-line buddies.
- *
- * @return true if the contact has been resolved (mapped against a buddy)
- * and false otherwise.
- */
- public boolean isResolved()
- {
- return isResolved;
- }
-
- /**
- * Makes the contact resolved or unresolved.
- *
- * @param resolved true to make the contact resolved; false to
- * make it unresolved
- */
- public void setResolved(boolean resolved)
- {
- this.isResolved = resolved;
- }
-
- /**
- * Returns the persistent presence operation set that this contact belongs
- * to.
- *
- * @return the <tt>OperationSetPersistentPresenceSSHImpl</tt> that
- * this contact belongs to.
- */
- public OperationSetPersistentPresence
- getParentPresenceOperationSet()
- {
- return
- parentProvider
- .getOperationSet(OperationSetPersistentPresence.class);
- }
-
- /**
- * Returns the BasicInstant Messaging operation set that this contact
- * belongs to.
- *
- * @return the <tt>OperationSetBasicInstantMessagingSSHImpl</tt> that
- * this contact belongs to.
- */
- public OperationSetBasicInstantMessaging
- getParentBasicInstantMessagingOperationSet()
- {
- return
- parentProvider
- .getOperationSet(OperationSetBasicInstantMessaging.class);
- }
-
- /**
- * Returns the File Transfer operation set that this contact belongs
- * to.
- *
- * @return the <tt>OperationSetFileTransferSSHImpl</tt> that
- * this contact belongs to.
- */
- public OperationSetFileTransfer
- getFileTransferOperationSet()
- {
- return parentProvider.getOperationSet(OperationSetFileTransfer.class);
- }
-
-
- /**
- * Returns the SSH Session associated with this contact
- *
- * @return sshSession
- */
- public Session getSSHSession()
- {
- return this.sshSession;
- }
-
- /**
- * Sets the SSH Session associated with this contact
- *
- * @param sshSession the newly created SSH Session to be associated
- */
- public void setSSHSession(Session sshSession)
- {
- this.sshSession = sshSession;
- }
-
- /**
- * Returns the SSH Shell Channel associated with this contact
- *
- * @return sshShellChannel
- */
- public Channel getShellChannel()
- {
- return this.sshShellChannel;
- }
-
- /**
- * Sets the SSH Shell channel associated with this contact
- *
- * @param sshShellChannel to be associated with SSH Session of this contact
- */
- public void setShellChannel(Channel sshShellChannel)
- {
- this.sshShellChannel = sshShellChannel;
- }
-
- /**
- * Returns the Input Stream associated with SSH Channel of this contact
- *
- * @return shellInputStream associated with SSH Channel of this contact
- */
- public InputStream getShellInputStream()
- {
- return this.shellInputStream;
- }
-
-// /**
-// * Sets the Input Stream associated with SSH Channel of this contact
-// *
-// * @param shellInputStream to be associated with SSH Channel of
-// * this contact
-// */
-// public void setShellInputStream(InputStream shellInputStream)
-// {
-// this.shellInputStream = shellInputStream;
-// }
-
- /**
- * Returns the Output Stream associated with SSH Channel of this contact
- *
- * @return shellOutputStream associated with SSH Channel of this contact
- */
- public OutputStream getShellOutputStream()
- {
- return this.shellOutputStream;
- }
-
-// /**
-// * Sets the Output Stream associated with SSH Channel of this contact
-// *
-// * @param shellOutputStream to be associated with SSH Channel of this contact
-// */
-// public void setShellOutputStream(OutputStream shellOutputStream)
-// {
-// this.shellOutputStream = shellOutputStream;
-// }
-
- /**
- * Returns the BufferedReader associated with SSH Channel of this contact
- *
- * @return shellReader associated with SSH Channel of this contact
- */
- public InputStreamReader getShellReader()
- {
- return this.shellReader;
- }
-
-// /**
-// * Sets the BufferedReader associated with SSH Channel of this contact
-// *
-// * @param shellReader to be associated with SSH Channel of this contact
-// */
-// public void setShellReader(BufferedReader shellReader)
-// {
-// this.shellReader = shellReader;
-// }
-
- /**
- * Returns the PrintWriter associated with SSH Channel of this contact
- *
- * @return shellWriter associated with SSH Channel of this contact
- */
- public PrintWriter getShellWriter()
- {
- return this.shellWriter;
- }
-
-// /**
-// * Sets the PrintWriter associated with SSH Channel of this contact
-// *
-// * @param shellWriter to be associated with SSH Channel of this contact
-// */
-// public void setShellWriter(PrintWriter shellWriter)
-// {
-// this.shellWriter = shellWriter;
-// }
-
- /**
- * Returns the userName associated with SSH Channel of this contact
- *
- * @return userName associated with SSH Channel of this contact
- */
- public String getUserName()
- {
- return sshConfigurationForm.getUserName();
- }
-
- /**
- * Returns the password associated with SSH Channel of this contact
- *
- * @return password associated with SSH Channel of this contact
- */
- public String getPassword()
- {
- return sshConfigurationForm.getPassword();
- }
-
- /**
- * Sets the Password associated with this contact
- *
- * @param password
- */
- public void setPassword(String password)
- {
- this.sshConfigurationForm.setPasswordField(password);
- savePersistentDetails();
- }
-
-// /**
-// * Sets the PS1 prompt of the current shell of Contact
-// *
-// * @param sshPrompt to be associated
-// */
-// public void setShellPrompt(String sshPrompt)
-// {
-// this.sshPrompt = sshPrompt;
-// }
-//
-// /**
-// * Returns the PS1 prompt of the current shell of Contact
-// *
-// * @return sshPrompt
-// */
-// public String getShellPrompt()
-// {
-// return this.sshPrompt;
-// }
-
- /**
- * Return the current status message of this contact.
- *
- * @return the current status message
- */
- public String getStatusMessage()
- {
- return presenceStatus.getStatusName();
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/ContactTimerSSHImpl.java b/src/net/java/sip/communicator/impl/protocol/ssh/ContactTimerSSHImpl.java
deleted file mode 100644
index 4e3664d..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/ContactTimerSSHImpl.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-import net.java.sip.communicator.util.*;
-
-/**
- * Timer Task to update the reachability status of SSH Contact in contact list.
- * (Reachability of remote machine from user's machine)
- * The timer is started at either of the two places
- * - A new contact - OperationSetPersistentPresenceSSHImpl
- * .createUnresolvedContact
- * - Existing Contact - OperationSetPersistentPresenceSSHImpl.subscribe
- *
- * @author Shobhit Jindal
- */
-public class ContactTimerSSHImpl
- extends TimerTask
-{
- private static final Logger logger
- = Logger.getLogger(OperationSetFileTransferSSHImpl.class);
-
- /**
- * The contact ID of the remote machine
- */
- private ContactSSH sshContact;
-
- /**
- * PersistentPresence Identifer assoiciated with SSH Contact
- */
- private OperationSetPersistentPresenceSSHImpl persistentPresence;
-
- /**
- * The method which is called at regular intervals to update the status
- * of remote machines
- *
- * Presently only ONLINE and OFFILINE status are checked
- */
- @Override
- public void run()
- {
- try
- {
- InetAddress remoteMachine = InetAddress.getByName(
- sshContact.getSSHConfigurationForm().getHostName());
-
- //check if machine is reachable
- if(remoteMachine.isReachable(
- sshContact.getSSHConfigurationForm().getUpdateInterval()))
- {
- if (sshContact.getPresenceStatus().equals(SSHStatusEnum.OFFLINE)
- || sshContact.getPresenceStatus().equals(SSHStatusEnum
- .NOT_AVAILABLE))
- {
- // change status to online
- persistentPresence.changeContactPresenceStatus(
- sshContact, SSHStatusEnum.ONLINE);
-
- if (logger.isDebugEnabled())
- logger.debug("SSH Host " + sshContact
- .getSSHConfigurationForm().getHostName() + ": Online");
- }
-
- }
- else throw new IOException();
-
- }
- catch (IOException ex)
- {
- if (sshContact.getPresenceStatus().equals(SSHStatusEnum.ONLINE)
- || sshContact.getPresenceStatus().equals(
- SSHStatusEnum.NOT_AVAILABLE))
- {
- persistentPresence.changeContactPresenceStatus(
- sshContact, SSHStatusEnum.OFFLINE);
-
- if (logger.isDebugEnabled())
- logger.debug("SSH Host " + sshContact.getSSHConfigurationForm()
- .getHostName() + ": Offline");
- }
- }
- }
- /**
- * Creates a new instance of ContactTimerSSHImpl
- *
- * @param sshContact the <tt>Contact</tt>
- */
- public ContactTimerSSHImpl(ContactSSH sshContact)
- {
- super();
- this.sshContact = sshContact;
- this.persistentPresence = (OperationSetPersistentPresenceSSHImpl)
- sshContact.getParentPresenceOperationSet();
- }
-
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/FileTransferSSHImpl.java b/src/net/java/sip/communicator/impl/protocol/ssh/FileTransferSSHImpl.java
deleted file mode 100644
index 1e95032..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/FileTransferSSHImpl.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.io.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * SSH implementation of the <tt>AbstractFileTransfer</tt>.
- *
- * @author Yana Stamcheva
- */
-public class FileTransferSSHImpl
- extends AbstractFileTransfer
-{
- private final SSHFileTransferDaemon fileTransfer;
-
- private final Date initialDate;
-
- /**
- * Creates an SSH implementation of the file transfer interface.
- *
- * @param fileTransfer the SSH file transfer
- * @param date the initial date of the transfer
- */
- public FileTransferSSHImpl( SSHFileTransferDaemon fileTransfer,
- Date date)
- {
- this.fileTransfer = fileTransfer;
- this.initialDate = date;
- }
-
- /**
- * Cancels this file transfer. When this method is called transfer should
- * be interrupted.
- */
- @Override
- public void cancel()
- {
- // TODO: Implement cancel() for SSH file transfer.
- }
-
- /**
- * Returns the number of bytes already transfered through this file transfer.
- *
- * @return the number of bytes already transfered through this file transfer
- */
- @Override
- public long getTransferedBytes()
- {
- // TODO: Implement getTransferedBytes() for SSH file transfer.
- return 0;
- }
-
- public int getDirection()
- {
- return IN;
- }
-
- public File getLocalFile()
- {
- return null;
- }
-
- public Contact getContact()
- {
- return null;
- }
-
- public String getID()
- {
- return null;
- }
-
- public Date getInitialDate()
- {
- return initialDate;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/MessageSSHImpl.java b/src/net/java/sip/communicator/impl/protocol/ssh/MessageSSHImpl.java
deleted file mode 100644
index a8324f7..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/MessageSSHImpl.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * Very simple message implementation for the SSH protocol.
- *
- * @author Shobhit Jindal
- * @author Lubomir Marinov
- */
-public class MessageSSHImpl
- extends AbstractMessage
-{
-
- /**
- * The content type of the message.
- */
- public static String contentType = "text/plain";
-
- /**
- * Creates a message instance according to the specified parameters.
- *
- * @param content the message body
- * @param contentType message content type or null for text/plain
- * @param contentEncoding message encoding or null for UTF8
- * @param subject the subject of the message or null for no subject.
- */
- public MessageSSHImpl(String content, String contentType,
- String contentEncoding, String subject)
- {
- super(content, null, contentEncoding, subject);
-
- MessageSSHImpl.contentType = contentType;
- }
-
- /**
- * Returns the type of the content of this message.
- *
- * @return the type of the content of this message.
- */
- @Override
- public String getContentType()
- {
- return contentType;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/OperationSetBasicInstantMessagingSSHImpl.java b/src/net/java/sip/communicator/impl/protocol/ssh/OperationSetBasicInstantMessagingSSHImpl.java
deleted file mode 100644
index 9073ad5..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/OperationSetBasicInstantMessagingSSHImpl.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.io.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-
-/**
- * Instant messaging functionality for the SSH protocol.
- *
- * @author Shobhit Jindal
- */
-public class OperationSetBasicInstantMessagingSSHImpl
- extends AbstractOperationSetBasicInstantMessaging
-{
-
- /**
- * The currently valid persistent presence operation set..
- */
- private OperationSetPersistentPresenceSSHImpl opSetPersPresence = null;
-
- /**
- * The currently valid file transfer operation set
- */
- private OperationSetFileTransferSSHImpl fileTransfer;
-
- /**
- * The protocol provider that created us.
- */
- private ProtocolProviderServiceSSHImpl parentProvider = null;
-
- /**
- * Creates an instance of this operation set keeping a reference to the
- * parent protocol provider and presence operation set.
- *
- * @param provider The provider instance that creates us.
- */
- public OperationSetBasicInstantMessagingSSHImpl(
- ProtocolProviderServiceSSHImpl provider)
- {
- this.parentProvider = provider;
-
- this.opSetPersPresence
- = (OperationSetPersistentPresenceSSHImpl)
- provider
- .getOperationSet(OperationSetPersistentPresence.class);
- }
-
- @Override
- public Message createMessage(String content, String contentType,
- String encoding, String subject)
- {
- return new MessageSSHImpl(content, contentType, encoding, subject);
- }
-
- /**
- * Sends the <tt>message</tt> to the destination indicated by the
- * <tt>to</tt> contact. An attempt is made to re-establish the shell
- * connection if the current one is invalid.
- * The reply from server is sent by a seperate reader thread
- *
- * @param to the <tt>Contact</tt> to send <tt>message</tt> to
- * @param message the <tt>Message</tt> to send.
- * @throws IllegalStateException if the underlying ICQ stack is not
- * registered and initialized.
- * @throws IllegalArgumentException if <tt>to</tt> is not an instance
- * belonging to the underlying implementation.
- */
- public void sendInstantMessage(
- Contact to,
- Message message)
- throws IllegalStateException,
- IllegalArgumentException
- {
- if( !(to instanceof ContactSSHImpl) )
- throw new IllegalArgumentException(
- "The specified contact is not a SSH contact."
- + to);
-
- ContactSSH sshContact = (ContactSSH)to;
-
- // making sure no messages are sent and no new threads are triggered,
- // until a thread trying to connect to remote server returns
- if(sshContact.isConnectionInProgress())
- {
- deliverMessage(
- createMessage("A connection attempt is in progress"),
- (ContactSSHImpl)to);
- return;
- }
-
- if( !parentProvider.isShellConnected(sshContact) )
- {
-
- try
- {
- /**
- * creating a new SSH session / shell channel
- * - first message
- * - session is timed out
- * - network problems
- */
- parentProvider.connectShell(sshContact, message);
-
- //the first message is ignored
- return;
- }
- catch (Exception ex)
- {
- throw new IllegalStateException(ex.getMessage());
- }
- }
-
- if(wrappedMessage(message.getContent(), sshContact))
- {
- fireMessageDelivered(message, to);
- return;
- }
-
- try
- {
- sshContact.sendLine(message.getContent());
- sshContact.setCommandSent(true);
- }
- catch (IOException ex)
- {
- // Closing IO Streams
- sshContact.closeShellIO();
-
- throw new IllegalStateException(ex.getMessage());
- }
-
- fireMessageDelivered(message, to);
- }
-
- /**
- * Check the message for wrapped Commands
- * All commands begin with /
- *
- * @param message from user
- * @param sshContact of the remote machine
- *
- * @return true if the message had commands, false otherwise
- */
- private boolean wrappedMessage(
- String message,
- ContactSSH sshContact)
- {
- if(message.startsWith("/upload"))
- {
- int firstSpace = message.indexOf(' ');
-
- try
- {
- sshContact.getFileTransferOperationSet().sendFile(
- sshContact,
- null,
- message.substring(message.indexOf(' ', firstSpace+1) + 1),
- message.substring(
- firstSpace+1,
- message.indexOf(' ', firstSpace+1)));
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
-
- return true;
- }
- else if(message.startsWith("/download"))
- {
- int firstSpace = message.indexOf(' ');
-
- try
- {
- sshContact.getFileTransferOperationSet().sendFile(
- null,
- sshContact,
- message.substring(firstSpace+1, message.indexOf(' ',
- firstSpace+1)),
- message.substring(message.indexOf(' ', firstSpace+1) + 1));
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
- return true;
- }
- return false;
- }
-
- /**
- * In case the <tt>to</tt> Contact corresponds to another ssh
- * protocol provider registered with SIP Communicator, we deliver
- * the message to them, in case the <tt>to</tt> Contact represents us, we
- * fire a <tt>MessageReceivedEvent</tt>, and if <tt>to</tt> is simply
- * a contact in our contact list, then we simply echo the message.
- *
- * @param message the <tt>Message</tt> the message to deliver.
- * @param to the <tt>Contact</tt> that we should deliver the message to.
- */
- void deliverMessage(
- Message message,
- ContactSSH to)
- {
- String userID = to.getAddress();
-
- //if the user id is owr own id, then this message is being routed to us
- //from another instance of the ssh provider.
- if (userID.equals(this.parentProvider.getAccountID().getUserID()))
- {
- //check who is the provider sending the message
- String sourceUserID
- = to.getProtocolProvider().getAccountID().getUserID();
-
- //check whether they are in our contact list
- Contact from = opSetPersPresence.findContactByID(sourceUserID);
-
- //and if not - add them there as volatile.
- if(from == null)
- {
- from = opSetPersPresence.createVolatileContact(sourceUserID);
- }
-
- //and now fire the message received event.
- fireMessageReceived(message, from);
- }
- else
- {
- //if userID is not our own, try an check whether another provider
- //has that id and if yes - deliver the message to them.
- ProtocolProviderServiceSSHImpl sshProvider
- = this.opSetPersPresence.findProviderForSSHUserID(userID);
- if(sshProvider != null)
- {
- OperationSetBasicInstantMessagingSSHImpl opSetIM
- = (OperationSetBasicInstantMessagingSSHImpl)
- sshProvider
- .getOperationSet(
- OperationSetBasicInstantMessaging.class);
- opSetIM.deliverMessage(message, to);
- }
- else
- {
- //if we got here then "to" is simply someone in our contact
- //list so let's just echo the message.
- fireMessageReceived(message, to);
- }
- }
- }
-
- /**
- * Notifies all registered message listeners that a message has been
- * received.
- *
- * @param message the <tt>Message</tt> that has been received.
- * @param from the <tt>Contact</tt> that <tt>message</tt> was received from.
- */
- @Override
- protected void fireMessageReceived(Message message, Contact from)
- {
- fireMessageEvent(
- new MessageReceivedEvent(
- message,
- from,
- new Date(),
- ((ContactSSH) from).getMessageType()));
- }
-
- /**
- * Determines whether the SSH protocol provider supports
- * sending and receiving offline messages.
- *
- * @return <tt>false</tt>
- */
- public boolean isOfflineMessagingSupported()
- {
- return false;
- }
-
- /**
- * Determines wheter the protocol supports the supplied content type
- *
- * @param contentType the type we want to check
- * @return <tt>true</tt> if the protocol supports it and
- * <tt>false</tt> otherwise.
- */
- public boolean isContentTypeSupported(String contentType)
- {
- return MessageSSHImpl.contentType.equals(contentType);
- }
-
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/OperationSetFileTransferSSHImpl.java b/src/net/java/sip/communicator/impl/protocol/ssh/OperationSetFileTransferSSHImpl.java
deleted file mode 100644
index 61d8160..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/OperationSetFileTransferSSHImpl.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.io.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * This class provides operations to upload/download files to remote machines
- *
- * @author Shobhit Jindal
- */
-public class OperationSetFileTransferSSHImpl
- implements OperationSetFileTransfer
-{
- private static final Logger logger
- = Logger.getLogger(OperationSetFileTransferSSHImpl.class);
-
- /**
- * Currently registered message listeners.
- */
- private Vector<FileTransferListener> fileTransferListeners
- = new Vector<FileTransferListener>();
-
- /**
- * The protocol provider that created us.
- */
- private ProtocolProviderServiceSSHImpl parentProvider = null;
-
-
- /**
- * Creates a new instance of OperationSetFileTransferSSHImpl
- *
- * @param parentProvider the parent protocol provider service
- */
- public OperationSetFileTransferSSHImpl(
- ProtocolProviderServiceSSHImpl parentProvider)
- {
- this.parentProvider = parentProvider;
- }
-
- /**
- * Registers a FileTransferListener with this operation set so that it gets
- * notifications of start, complete, failure of file transfers
- *
- * @param listener the <tt>FileListener</tt> to register.
- */
- public void addFileTransferListener(
- FileTransferListener listener)
- {
- synchronized (fileTransferListeners)
- {
- if(!fileTransferListeners.contains(listener))
- fileTransferListeners.add(listener);
- }
- }
-
- public void removeFileTransferListener(
- FileTransferListener listener)
- {
- synchronized (fileTransferListeners)
- {
- fileTransferListeners.remove(listener);
- }
- }
-
- /**
- * Sends a file transfer request to the given <tt>toContact</tt>.
- * @param toContact the contact that should receive the file
- * @param file the file to send
- */
- public FileTransfer sendFile( Contact toContact,
- File file)
- {
- return this.sendFile( toContact,
- null,
- file.getAbsolutePath(),
- file.getAbsolutePath());
- }
-
- /**
- * The file transfer method to/from the remote machine
- * either toContact is null(we are downloading file from remote machine
- * or fromContact is null(we are uploading file to remote machine
- *
- * @param toContact - the file recipient
- * @param fromContact - the file sender
- * @param remotePath - the identifier for the remote file
- * @param localPath - the identifier for the local file
- */
- public FileTransfer sendFile(
- Contact toContact,
- Contact fromContact,
- String remotePath,
- String localPath)
- {
- if(toContact == null)
- {
- SSHFileTransferDaemon fileTransferDaemon
- = new SSHFileTransferDaemon(
- (ContactSSH)fromContact,
- parentProvider);
-
- if(localPath.endsWith(System.getProperty("file.separator")))
- localPath += remotePath.substring(remotePath.lastIndexOf(
- System.getProperty("file.separator")) + 1);
-
- fileTransferDaemon.downloadFile(
- remotePath,
- localPath);
-
- return new FileTransferSSHImpl(fileTransferDaemon, new Date());
- }
- else if(fromContact == null)
- {
- SSHFileTransferDaemon fileTransferDaemon
- = new SSHFileTransferDaemon(
- (ContactSSH) toContact,
- parentProvider);
-
- fileTransferDaemon.uploadFile(
- remotePath,
- localPath);
-
- return new FileTransferSSHImpl(fileTransferDaemon, new Date());
- }
-
- // code should not reach here
- // assert false;
- logger.error("we should not be here !");
- return null;
- }
-
- /**
- * Returns the maximum file length supported by the protocol in bytes.
- * @return the file length that is supported.
- */
- public long getMaximumFileLength()
- {
- return 2048*1024*1024;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/OperationSetPersistentPresenceSSHImpl.java b/src/net/java/sip/communicator/impl/protocol/ssh/OperationSetPersistentPresenceSSHImpl.java
deleted file mode 100644
index d4c63bd..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/OperationSetPersistentPresenceSSHImpl.java
+++ /dev/null
@@ -1,980 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * A SSH implementation of a persistent presence operation set. In order
- * to simulate server persistence, this operation set would simply accept all
- * unresolved contacts and resolve them immediately. A real world protocol
- * implementation would save it on a server using methods provided by the
- * protocol stack.
- *
- * @author Shobhit Jindal
- */
-public class OperationSetPersistentPresenceSSHImpl
- extends AbstractOperationSetPersistentPresence<ProtocolProviderServiceSSHImpl>
-{
- private static final Logger logger =
- Logger.getLogger(OperationSetPersistentPresenceSSHImpl.class);
-
- /**
- * The root of the ssh contact list.
- */
- private ContactGroupSSHImpl contactListRoot = null;
-
- /**
- * The currently active status message.
- */
- private String statusMessage = "Online";
-
- /**
- * Our default presence status.
- */
- private PresenceStatus presenceStatus = SSHStatusEnum.ONLINE;
-
- /**
- * Creates an instance of this operation set keeping a reference to the
- * specified parent <tt>provider</tt>.
- * @param provider the ProtocolProviderServiceSSHImpl instance that
- * created us.
- */
- public OperationSetPersistentPresenceSSHImpl(
- ProtocolProviderServiceSSHImpl provider)
- {
- super(provider);
-
- contactListRoot = new ContactGroupSSHImpl("RootGroup", provider);
-
- //add our unregistration listener
- parentProvider.addRegistrationStateChangeListener(
- new UnregistrationListener());
- }
-
- /**
- * This function changes the status of contact as well as that of the
- * provider
- *
- * @param sshContact the contact of the remote machine
- * @param newStatus new status of the contact
- */
- public void changeContactPresenceStatus(
- ContactSSH sshContact,
- PresenceStatus newStatus)
- {
- PresenceStatus oldStatus = sshContact.getPresenceStatus();
- sshContact.setPresenceStatus(newStatus);
- fireContactPresenceStatusChangeEvent(
- sshContact
- , sshContact.getParentContactGroup()
- , oldStatus);
- fireProviderStatusChangeEvent(oldStatus);
- }
-
- /**
- * Creates a group with the specified name and parent in the server
- * stored contact list.
- *
- * @param parent the group where the new group should be created
- * @param groupName the name of the new group to create.
- */
- public void createServerStoredContactGroup(
- ContactGroup parent,
- String groupName)
- {
- ContactGroupSSHImpl newGroup
- = new ContactGroupSSHImpl(groupName, parentProvider);
-
- ((ContactGroupSSHImpl)parent).addSubgroup(newGroup);
-
- this.fireServerStoredGroupEvent(
- newGroup, ServerStoredGroupEvent.GROUP_CREATED_EVENT);
- }
-
- /**
- * A SSH Provider method to use for fast filling of a contact list.
- *
- * @param contactGroup the group to add
- */
- public void addSSHGroup(ContactGroupSSHImpl contactGroup)
- {
- contactListRoot.addSubgroup(contactGroup);
- }
-
- /**
- * A SSH Provider method to use for fast filling of a contact list.
- * This method would add both the group and fire an event.
- *
- * @param parent the group where <tt>contactGroup</tt> should be added.
- * @param contactGroup the group to add
- */
- public void addSSHGroupAndFireEvent(
- ContactGroupSSHImpl parent,
- ContactGroupSSHImpl contactGroup)
- {
- parent.addSubgroup(contactGroup);
-
- this.fireServerStoredGroupEvent(
- contactGroup, ServerStoredGroupEvent.GROUP_CREATED_EVENT);
- }
-
-
- /**
- * Returns a reference to the contact with the specified ID in case we
- * have a subscription for it and null otherwise/
- *
- * @param contactID a String identifier of the contact which we're
- * seeking a reference of.
- * @return a reference to the Contact with the specified
- * <tt>contactID</tt> or null if we don't have a subscription for the
- * that identifier.
- */
- public Contact findContactByID(String contactID)
- {
- return contactListRoot.findContactByID(contactID);
- }
-
- /**
- * Sets the specified status message.
- * @param statusMessage a String containing the new status message.
- */
- public void setStatusMessage(String statusMessage)
- {
- this.statusMessage = statusMessage;
- }
-
- /**
- * Returns the status message that was last set through
- * setCurrentStatusMessage.
- *
- * @return the last status message that we have requested and the aim
- * server has confirmed.
- */
- public String getCurrentStatusMessage()
- {
- return statusMessage;
- }
-
- /**
- * Returns the protocol specific contact instance representing the local
- * user.
- *
- * @return the Contact (address, phone number, or uin) that the Provider
- * implementation is communicating on behalf of.
- */
- public Contact getLocalContact()
- {
- return null;
- }
-
- /**
- * Returns a PresenceStatus instance representing the state this provider
- * is currently in.
- *
- * @return the PresenceStatus last published by this provider.
- */
- public PresenceStatus getPresenceStatus()
- {
- return presenceStatus;
- }
-
- /**
- * Returns the root group of the server stored contact list.
- *
- * @return the root ContactGroup for the ContactList stored by this
- * service.
- */
- public ContactGroup getServerStoredContactListRoot()
- {
- return contactListRoot;
- }
-
- /**
- * Returns the set of PresenceStatus objects that a user of this service
- * may request the provider to enter.
- *
- * @return Iterator a PresenceStatus array containing "enterable" status
- * instances.
- */
- public Iterator<PresenceStatus> getSupportedStatusSet()
- {
- return SSHStatusEnum.supportedStatusSet();
- }
-
- /**
- * Removes the specified contact from its current parent and places it
- * under <tt>newParent</tt>.
- *
- * @param contactToMove the <tt>Contact</tt> to move
- * @param newParent the <tt>ContactGroup</tt> where <tt>Contact</tt>
- * would be placed.
- */
- public void moveContactToGroup(
- Contact contactToMove,
- ContactGroup newParent)
- {
- ContactSSHImpl sshContact
- = (ContactSSHImpl)contactToMove;
-
- ContactGroupSSHImpl parentSSHGroup
- = findContactParent(sshContact);
-
- parentSSHGroup.removeContact(sshContact);
-
- //if this is a volatile contact then we haven't really subscribed to
- //them so we'd need to do so here
- if(!sshContact.isPersistent())
- {
- //first tell everyone that the volatile contact was removed
- fireSubscriptionEvent(sshContact
- , parentSSHGroup
- , SubscriptionEvent.SUBSCRIPTION_REMOVED);
-
- try
- {
- //now subscribe
- this.subscribe(newParent, contactToMove.getAddress());
-
- //now tell everyone that we've added the contact
- fireSubscriptionEvent(sshContact
- , newParent
- , SubscriptionEvent.SUBSCRIPTION_CREATED);
- }
- catch (Exception ex)
- {
- logger.error("Failed to move contact "
- + sshContact.getAddress()
- , ex);
- }
- }
- else
- {
- ( (ContactGroupSSHImpl) newParent)
- .addContact(sshContact);
-
- fireSubscriptionMovedEvent(contactToMove
- , parentSSHGroup
- , newParent);
- }
- }
-
- /**
- * Requests the provider to enter into a status corresponding to the
- * specified paramters.
- *
- * @param status the PresenceStatus as returned by
- * getRequestableStatusSet
- * @param statusMessage the message that should be set as the reason to
- * enter that status
- * @throws IllegalArgumentException if the status requested is not a
- * valid PresenceStatus supported by this provider.
- * @throws IllegalStateException if the provider is not currently
- * registered.
- */
- public void publishPresenceStatus(
- PresenceStatus status,
- String statusMessage)
- throws IllegalArgumentException,
- IllegalStateException
- {
- PresenceStatus oldPresenceStatus = this.presenceStatus;
- this.presenceStatus = status;
- this.statusMessage = statusMessage;
-
- this.fireProviderStatusChangeEvent(oldPresenceStatus);
-
-
-// //since we are not a real protocol, we set the contact presence status
-// //ourselves and make them have the same status as ours.
-// changePresenceStatusForAllContacts( getServerStoredContactListRoot()
-// , getPresenceStatus());
-//
-// //now check whether we are in someone else's contact list and modify
-// //our status there
-// List contacts = findContactsPointingToUs();
-//
-// Iterator contactsIter = contacts.iterator();
-// while (contactsIter.hasNext())
-// {
-// ContactSSHImpl contact
-// = (ContactSSHImpl) contactsIter.next();
-//
-// PresenceStatus oldStatus = contact.getPresenceStatus();
-// contact.setPresenceStatus(status);
-// contact.getParentPresenceOperationSet()
-// .fireContactPresenceStatusChangeEvent(
-// contact
-// , contact.getParentContactGroup()
-// , oldStatus);
-//
-// }
- }
-
-
-
- /**
- * Get the PresenceStatus for a particular contact.
- *
- * @param contactIdentifier the identifier of the contact whose status
- * we're interested in.
- * @return PresenceStatus the <tt>PresenceStatus</tt> of the specified
- * <tt>contact</tt>
- * @throws IllegalArgumentException if <tt>contact</tt> is not a contact
- * known to the underlying protocol provider
- * @throws IllegalStateException if the underlying protocol provider is
- * not registered/signed on a public service.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * retrieving the status fails due to errors experienced during
- * network communication
- */
- public PresenceStatus queryContactStatus(String contactIdentifier)
- throws IllegalArgumentException,
- IllegalStateException,
- OperationFailedException
- {
- return findContactByID(contactIdentifier).getPresenceStatus();
- }
-
- /**
- * Sets the presence status of <tt>contact</tt> to <tt>newStatus</tt>.
- *
- * @param contact the <tt>ContactSSHImpl</tt> whose status we'd like
- * to set.
- * @param newStatus the new status we'd like to set to <tt>contact</tt>.
- */
- private void changePresenceStatusForContact(
- ContactSSH contact,
- PresenceStatus newStatus)
- {
- PresenceStatus oldStatus = contact.getPresenceStatus();
- contact.setPresenceStatus(newStatus);
-
- fireContactPresenceStatusChangeEvent(
- contact, findContactParent(contact), oldStatus);
- }
-
- /**
- * Sets the presence status of all <tt>contact</tt>s in our contact list
- * (except those that correspond to another provider registered with SC)
- * to <tt>newStatus</tt>.
- *
- * @param newStatus the new status we'd like to set to <tt>contact</tt>.
- * @param parent the group in which we'd have to update the status of all
- * direct and indirect child contacts.
- */
- private void changePresenceStatusForAllContacts(
- ContactGroup parent,
- PresenceStatus newStatus)
- {
- //first set the status for contacts in this group
- Iterator<Contact> childContacts = parent.contacts();
-
- while(childContacts.hasNext())
- {
- ContactSSHImpl contact
- = (ContactSSHImpl)childContacts.next();
-
- if(findProviderForSSHUserID(contact.getAddress()) != null)
- {
- //this is a contact corresponding to another SIP Communicator
- //provider so we won't change it's status here.
- continue;
- }
- PresenceStatus oldStatus = contact.getPresenceStatus();
- contact.setPresenceStatus(newStatus);
-
- fireContactPresenceStatusChangeEvent(
- contact, parent, oldStatus);
- }
-
- //now call this method recursively for all subgroups
- Iterator<ContactGroup> subgroups = parent.subgroups();
-
- while(subgroups.hasNext())
- {
- ContactGroup subgroup = subgroups.next();
- changePresenceStatusForAllContacts(subgroup, newStatus);
- }
- }
-
- /**
- * Returns the group that is parent of the specified sshGroup or null
- * if no parent was found.
- * @param sshGroup the group whose parent we're looking for.
- * @return the ContactGroupSSHImpl instance that sshGroup
- * belongs to or null if no parent was found.
- */
- public ContactGroupSSHImpl findGroupParent(
- ContactGroupSSHImpl sshGroup)
- {
- return contactListRoot.findGroupParent(sshGroup);
- }
-
- /**
- * Returns the group that is parent of the specified sshContact or
- * null if no parent was found.
- * @param sshContact the contact whose parent we're looking for.
- * @return the ContactGroupSSHImpl instance that sshContact
- * belongs to or null if no parent was found.
- */
- public ContactGroupSSHImpl findContactParent(
- ContactSSH sshContact)
- {
- return (ContactGroupSSHImpl)sshContact
- .getParentContactGroup();
- }
-
-
- /**
- * Removes the specified group from the server stored contact list.
- *
- * @param group the group to remove.
- *
- * @throws IllegalArgumentException if <tt>group</tt> was not found in this
- * protocol's contact list.
- */
- public void removeServerStoredContactGroup(ContactGroup group)
- throws IllegalArgumentException
- {
- ContactGroupSSHImpl sshGroup
- = (ContactGroupSSHImpl)group;
-
- ContactGroupSSHImpl parent = findGroupParent(sshGroup);
-
- if(parent == null)
- {
- throw new IllegalArgumentException(
- "group " + group
- + " does not seem to belong to this protocol's contact "
- + "list.");
- }
-
- parent.removeSubGroup(sshGroup);
-
- this.fireServerStoredGroupEvent(
- sshGroup, ServerStoredGroupEvent.GROUP_REMOVED_EVENT);
- }
-
- /**
- * Renames the specified group from the server stored contact list.
- *
- * @param group the group to rename.
- * @param newName the new name of the group.
- */
- public void renameServerStoredContactGroup(
- ContactGroup group,
- String newName)
- {
- ((ContactGroupSSHImpl)group).setGroupName(newName);
-
- this.fireServerStoredGroupEvent(
- group, ServerStoredGroupEvent
- .GROUP_RENAMED_EVENT);
- }
-
-
- /**
- * Persistently adds a subscription for the presence status of the
- * contact corresponding to the specified contactIdentifier and indicates
- * that it should be added to the specified group of the server stored
- * contact list.
- *
- * @param parent the parent group of the server stored contact list
- * where the contact should be added. <p>
- * @param contactIdentifier the contact whose status updates we are
- * subscribing for.
- * @throws IllegalArgumentException if <tt>contact</tt> or
- * <tt>parent</tt> are not a contact known to the underlying protocol
- * provider.
- * @throws IllegalStateException if the underlying protocol provider is
- * not registered/signed on a public service.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * subscribing fails due to errors experienced during network
- * communication
- */
- public void subscribe(
- ContactGroup parent,
- String contactIdentifier)
- throws IllegalArgumentException,
- IllegalStateException,
- OperationFailedException
- {
- ContactSSH sshContact = new ContactSSHImpl(contactIdentifier,
- parentProvider);
-
-/* ProtocolProviderServiceSSHImpl.getUIService().getConfigurationWindow()
- .setVisible(true);
-*/
- sshContact.setParentGroup((ContactGroupSSHImpl)parent);
- sshContact.getSSHConfigurationForm().setVisible(true);
-
-
-
-/* Gets the domain name or IP address of the sshContact machine via the
- * UI Service Interface
- sshContact.setPersistentData(ProtocolProviderServiceSSHImpl
- .getUIService().getPopupDialog()
- .showInputPopupDialog("Enter Domain Name or IP Address of "
- + sshContact.getDisplayName()));
-
- // contact is added to list later after the user has provided
- // details in SSHConfigurationForm
-
- // addContactToList method is called
-*/
- }
-
- /**
- * Add a contact to the specified group
- *
- * @param parent the group
- * @param sshContact the contact
- */
- public void addContactToList(
- ContactGroup parent,
- ContactSSH sshContact)
- {
- // Adds the sshContact to the sshContact list
-
- ((ContactGroupSSHImpl)parent).addContact(sshContact);
-
- fireSubscriptionEvent(sshContact,
- parent,
- SubscriptionEvent.SUBSCRIPTION_CREATED);
-
- //notify presence listeners for the status change.
- fireContactPresenceStatusChangeEvent(sshContact
- , parent
- , SSHStatusEnum.NOT_AVAILABLE);
-
- sshContact.startTimerTask();
- }
-
- /**
- * Adds a subscription for the presence status of the contact
- * corresponding to the specified contactIdentifier.
- *
- * @param contactIdentifier the identifier of the contact whose status
- * updates we are subscribing for. <p>
- * @throws IllegalArgumentException if <tt>contact</tt> is not a contact
- * known to the underlying protocol provider
- * @throws IllegalStateException if the underlying protocol provider is
- * not registered/signed on a public service.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * subscribing fails due to errors experienced during network
- * communication
- */
- public void subscribe(String contactIdentifier) throws
- IllegalArgumentException,
- IllegalStateException,
- OperationFailedException
- {
- subscribe(contactListRoot, contactIdentifier);
-
- }
-
- /**
- * Removes a subscription for the presence status of the specified
- * contact.
- *
- * @param contact the contact whose status updates we are unsubscribing
- * from.
- * @throws IllegalArgumentException if <tt>contact</tt> is not a contact
- * known to the underlying protocol provider
- * @throws IllegalStateException if the underlying protocol provider is
- * not registered/signed on a public service.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * unsubscribing fails due to errors experienced during network
- * communication
- */
- public void unsubscribe(Contact contact) throws
- IllegalArgumentException,
- IllegalStateException,
- OperationFailedException
- {
- ContactGroupSSHImpl parentGroup
- = (ContactGroupSSHImpl)((ContactSSHImpl)contact)
- .getParentContactGroup();
-
- parentGroup.removeContact((ContactSSHImpl)contact);
-
- fireSubscriptionEvent(contact,
- ((ContactSSHImpl)contact).getParentContactGroup()
- , SubscriptionEvent.SUBSCRIPTION_REMOVED);
- }
-
- /**
- * Creates and returns a unresolved contact from the specified
- * <tt>address</tt> and <tt>persistentData</tt>. The method will not try
- * to establish a network connection and resolve the newly created Contact
- * against the server. The protocol provider may will later try and resolve
- * the contact. When this happens the corresponding event would notify
- * interested subscription listeners.
- *
- * @param address an identifier of the contact that we'll be creating.
- * @param persistentData a String returned Contact's getPersistentData()
- * method during a previous run and that has been persistently stored
- * locally.
- * @return the unresolved <tt>Contact</tt> created from the specified
- * <tt>address</tt> and <tt>persistentData</tt>
- */
- public Contact createUnresolvedContact(
- String address,
- String persistentData)
- {
- return createUnresolvedContact(address
- , persistentData
- , getServerStoredContactListRoot());
- }
-
- /**
- * Creates and returns a unresolved contact from the specified
- * <tt>address</tt> and <tt>persistentData</tt>. The method will not try
- * to establish a network connection and resolve the newly created Contact
- * against the server. The protocol provider may will later try and resolve
- * the contact. When this happens the corresponding event would notify
- * interested subscription listeners.
- *
- * @param address an identifier of the contact that we'll be creating.
- * @param persistentData a String returned Contact's getPersistentData()
- * method during a previous run and that has been persistently stored
- * locally.
- * @param parent the group where the unresolved contact is
- * supposed to belong to.
- *
- * @return the unresolved <tt>Contact</tt> created from the specified
- * <tt>address</tt> and <tt>persistentData</tt>
- */
- public Contact createUnresolvedContact(
- String address,
- String persistentData,
- ContactGroup parent)
- {
- ContactSSH contact = new ContactSSHImpl(
- address,
- parentProvider);
-
- contact.setPersistentData(persistentData);
- contact.startTimerTask();
-
- // SSH Contacts are resolved by default
- contact.setResolved(true);
-
- ( (ContactGroupSSHImpl) parent).addContact(contact);
-
- fireSubscriptionEvent(contact,
- parent,
- SubscriptionEvent.SUBSCRIPTION_CREATED);
-
- //since we don't have any server, we'll simply resolve the contact
- //ourselves as if we've just received an event from the server telling
- //us that it has been resolved.
- fireSubscriptionEvent(
- contact, parent, SubscriptionEvent.SUBSCRIPTION_RESOLVED);
-
- return contact;
- }
-
- /**
- * Looks for a ssh protocol provider registered for a user id matching
- * <tt>sshUserID</tt>.
- *
- * @param sshUserID the ID of the SSH user whose corresponding
- * protocol provider we'd like to find.
- * @return ProtocolProviderServiceSSHImpl a ssh protocol
- * provider registered for a user with id <tt>sshUserID</tt> or null
- * if there is no such protocol provider.
- */
- public ProtocolProviderServiceSSHImpl
- findProviderForSSHUserID(String sshUserID)
- {
- BundleContext bc = SSHActivator.getBundleContext();
-
- String osgiQuery = "(&"
- + "(" + ProtocolProviderFactory.PROTOCOL
- + "=" + ProtocolNames.SSH + ")"
- + "(" + ProtocolProviderFactory.USER_ID
- + "=" + sshUserID + ")"
- + ")";
-
- ServiceReference[] refs = null;
- try
- {
- refs = bc.getServiceReferences(
- ProtocolProviderService.class.getName()
- ,osgiQuery);
- }
- catch (InvalidSyntaxException ex)
- {
- logger.error("Failed to execute the following osgi query: "
- + osgiQuery
- , ex);
- }
-
- if(refs != null && refs.length > 0)
- {
- return (ProtocolProviderServiceSSHImpl)bc.getService(refs[0]);
- }
-
- return null;
- }
-
- /**
- * Looks for ssh protocol providers that have added us to their
- * contact list and returns list of all contacts representing us in these
- * providers.
- *
- * @return a list of all contacts in other providers' contact lists that
- * point to us.
- */
- public List<Contact> findContactsPointingToUs()
- {
- List<Contact> contacts = new LinkedList<Contact>();
- BundleContext bc = SSHActivator.getBundleContext();
-
- String osgiQuery =
- "(" + ProtocolProviderFactory.PROTOCOL
- + "=SSH)";
-
- ServiceReference[] refs = null;
- try
- {
- refs = bc.getServiceReferences(
- ProtocolProviderService.class.getName()
- ,osgiQuery);
- }
- catch (InvalidSyntaxException ex)
- {
- logger.error("Failed to execute the following osgi query: "
- + osgiQuery
- , ex);
- }
-
- for (int i =0; refs != null && i < refs.length; i++)
- {
- ProtocolProviderServiceSSHImpl gibProvider
- = (ProtocolProviderServiceSSHImpl)bc.getService(refs[i]);
-
- OperationSetPersistentPresenceSSHImpl opSetPersPresence
- = (OperationSetPersistentPresenceSSHImpl)gibProvider
- .getOperationSet(OperationSetPersistentPresence.class);
-
- Contact contact = opSetPersPresence.findContactByID(
- parentProvider.getAccountID().getUserID());
-
- if (contact != null)
- contacts.add(contact);
- }
-
- return contacts;
- }
-
-
- /**
- * Creates and returns a unresolved contact group from the specified
- * <tt>address</tt> and <tt>persistentData</tt>. The method will not try
- * to establish a network connection and resolve the newly created
- * <tt>ContactGroup</tt> against the server or the contact itself. The
- * protocol provider will later resolve the contact group. When this happens
- * the corresponding event would notify interested subscription listeners.
- *
- * @param groupUID an identifier, returned by ContactGroup's getGroupUID,
- * that the protocol provider may use in order to create the group.
- * @param persistentData a String returned ContactGroups's
- * getPersistentData() method during a previous run and that has been
- * persistently stored locally.
- * @param parentGroup the group under which the new group is to be created
- * or null if this is group directly underneath the root.
- * @return the unresolved <tt>ContactGroup</tt> created from the specified
- * <tt>uid</tt> and <tt>persistentData</tt>
- */
- public ContactGroup createUnresolvedContactGroup(
- String groupUID,
- String persistentData,
- ContactGroup parentGroup)
- {
- ContactGroupSSHImpl newGroup
- = new ContactGroupSSHImpl(
- ContactGroupSSHImpl.createNameFromUID(groupUID)
- , parentProvider);
- newGroup.setResolved(false);
-
- //if parent is null then we're adding under root.
- if(parentGroup == null)
- parentGroup = getServerStoredContactListRoot();
-
- ((ContactGroupSSHImpl)parentGroup).addSubgroup(newGroup);
-
- this.fireServerStoredGroupEvent(
- newGroup, ServerStoredGroupEvent.GROUP_CREATED_EVENT);
-
- return newGroup;
- }
-
- private class UnregistrationListener
- implements RegistrationStateChangeListener
- {
- /**
- * The method is called by a ProtocolProvider implementation whenver
- * a change in the registration state of the corresponding provider had
- * occurred. The method is particularly interested in events stating
- * that the ssh provider has unregistered so that it would fire
- * status change events for all contacts in our buddy list.
- *
- * @param evt ProviderStatusChangeEvent the event describing the status
- * change.
- */
- public void registrationStateChanged(RegistrationStateChangeEvent evt)
- {
- if (! evt.getNewState().equals(RegistrationState.UNREGISTERED)
- && !evt.getNewState().equals(RegistrationState
- .AUTHENTICATION_FAILED)
- && !evt.getNewState().equals(RegistrationState.CONNECTION_FAILED))
- {
- return;
- }
-
- //send event notifications saying that all our buddies are
- //offline. The icq protocol does not implement top level buddies
- //nor subgroups for top level groups so a simple nested loop
- //would be enough.
- Iterator<ContactGroup> groupsIter
- = getServerStoredContactListRoot().subgroups();
- while (groupsIter.hasNext())
- {
- ContactGroup group = groupsIter.next();
- Iterator<Contact> contactsIter = group.contacts();
-
- while (contactsIter.hasNext())
- {
- ContactSSHImpl contact
- = (ContactSSHImpl) contactsIter.next();
-
- PresenceStatus oldContactStatus
- = contact.getPresenceStatus();
-
- if (!oldContactStatus.isOnline())
- continue;
-
- contact.setPresenceStatus(SSHStatusEnum.OFFLINE);
-
- fireContactPresenceStatusChangeEvent(
- contact
- , contact.getParentContactGroup()
- , oldContactStatus);
- }
- }
- }
- }
-
- /**
- * Returns the volatile group or null if this group has not yet been
- * created.
- *
- * @return a volatile group existing in our contact list or <tt>null</tt>
- * if such a group has not yet been created.
- */
- private ContactGroupSSHImpl getNonPersistentGroup()
- {
- for (int i = 0
- ; i < getServerStoredContactListRoot().countSubgroups()
- ; i++)
- {
- ContactGroupSSHImpl gr =
- (ContactGroupSSHImpl)getServerStoredContactListRoot()
- .getGroup(i);
-
- if(!gr.isPersistent())
- return gr;
- }
-
- return null;
- }
-
-
- /**
- * Creates a non persistent contact for the specified address. This would
- * also create (if necessary) a group for volatile contacts that would not
- * be added to the server stored contact list. This method would have no
- * effect on the server stored contact list.
- *
- * @param contactAddress the address of the volatile contact we'd like to
- * create.
- * @return the newly created volatile contact.
- */
- public ContactSSHImpl createVolatileContact(String contactAddress)
- {
- //First create the new volatile contact;
- ContactSSHImpl newVolatileContact = new ContactSSHImpl(
- contactAddress,
- this.parentProvider);
-
- newVolatileContact.setPersistent(false);
-
-
- //Check whether a volatile group already exists and if not create
- //one
- ContactGroupSSHImpl theVolatileGroup = getNonPersistentGroup();
-
-
- //if the parent volatile group is null then we create it
- if (theVolatileGroup == null)
- {
- theVolatileGroup = new ContactGroupSSHImpl(
- SSHActivator.getResources().getI18NString(
- "service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME")
- , parentProvider);
- theVolatileGroup.setResolved(false);
- theVolatileGroup.setPersistent(false);
- theVolatileGroup.addContact(newVolatileContact);
-
- this.contactListRoot.addSubgroup(theVolatileGroup);
-
- fireServerStoredGroupEvent(theVolatileGroup
- , ServerStoredGroupEvent.GROUP_CREATED_EVENT);
- }
-
- //now add the volatile contact instide it
- theVolatileGroup.addContact(newVolatileContact);
- fireSubscriptionEvent(newVolatileContact
- , theVolatileGroup
- , SubscriptionEvent.SUBSCRIPTION_CREATED);
-
- return newVolatileContact;
- }
-
- /**
- * DUMMY METHOD
- * Handler for incoming authorization requests.
- *
- * @param handler an instance of an AuthorizationHandler for
- * authorization requests coming from other users requesting
- * permission add us to their contact list.
- */
- public void setAuthorizationHandler(AuthorizationHandler handler)
- {
- }
-
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/ProtocolIconSSHImpl.java b/src/net/java/sip/communicator/impl/protocol/ssh/ProtocolIconSSHImpl.java
deleted file mode 100644
index 592b2b1..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/ProtocolIconSSHImpl.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.io.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Represents the SSH protocol icon. Implements the <tt>ProtocolIcon</tt>
- * interface in order to provide a SSH logo image in two different sizes.
- *
- * @author Shobhit Jindal
- */
-public class ProtocolIconSSHImpl
- implements ProtocolIcon
-{
- private static Logger logger
- = Logger.getLogger(ProtocolIconSSHImpl.class);
-
- /**
- * A hash table containing the protocol icon in different sizes.
- */
- private static Hashtable<String, byte[]> iconsTable
- = new Hashtable<String, byte[]>();
- static {
- iconsTable.put(ProtocolIcon.ICON_SIZE_16x16,
- getImageInBytes("service.protocol.ssh.SSH_16x16"));
-
- iconsTable.put(ProtocolIcon.ICON_SIZE_32x32,
- getImageInBytes("service.protocol.ssh.SSH_32x32"));
-
- iconsTable.put(ProtocolIcon.ICON_SIZE_48x48,
- getImageInBytes("service.protocol.ssh.SSH_48x48"));
-
- iconsTable.put(ProtocolIcon.ICON_SIZE_64x64,
- getImageInBytes("service.protocol.ssh.SSH_64x64"));
- }
-
- /**
- * A hash table containing the protocol icon in different sizes.
- */
- private static Hashtable<String, String> iconPathsTable
- = new Hashtable<String, String>();
- static {
- iconPathsTable.put(ProtocolIcon.ICON_SIZE_16x16,
- SSHActivator.getResources().getImagePath(
- "service.protocol.ssh.SSH_16x16"));
-
- iconPathsTable.put(ProtocolIcon.ICON_SIZE_32x32,
- SSHActivator.getResources().getImagePath(
- "service.protocol.ssh.SSH_32x32"));
-
- iconPathsTable.put(ProtocolIcon.ICON_SIZE_48x48,
- SSHActivator.getResources().getImagePath(
- "service.protocol.ssh.SSH_48x48"));
-
- iconPathsTable.put(ProtocolIcon.ICON_SIZE_64x64,
- SSHActivator.getResources().getImagePath(
- "service.protocol.ssh.SSH_64x64"));
- }
-
- /**
- * Implements the <tt>ProtocolIcon.getSupportedSizes()</tt> method. Returns
- * an iterator to a set containing the supported icon sizes.
- * @return an iterator to a set containing the supported icon sizes
- */
- public Iterator<String> getSupportedSizes()
- {
- return iconsTable.keySet().iterator();
- }
-
- /**
- * Returns TRUE if a icon with the given size is supported, FALSE-otherwise.
- *
- * @return TRUE if a icon with the given size is supported, FALSE otherwise
- */
- public boolean isSizeSupported(String iconSize)
- {
- return iconsTable.containsKey(iconSize);
- }
-
- /**
- * Returns the icon image in the given size.
- * @param iconSize the icon size; one of ICON_SIZE_XXX constants
- * @return the icon
- */
- public byte[] getIcon(String iconSize)
- {
- return iconsTable.get(iconSize);
- }
-
- /**
- * Returns a path to the icon with the given size.
- * @param iconSize the size of the icon we're looking for
- * @return the path to the icon with the given size
- */
- public String getIconPath(String iconSize)
- {
- return iconPathsTable.get(iconSize);
- }
-
- /**
- * Returns the icon image used to represent the protocol connecting state.
- * @return the icon image used to represent the protocol connecting state
- */
- public byte[] getConnectingIcon()
- {
- return getImageInBytes("protocolIconSsh");
- }
-
- /**
- * Returns the byte representation of the image corresponding to the given
- * identifier.
- *
- * @param imageID the identifier of the image
- * @return the byte representation of the image corresponding to the given
- * identifier.
- */
- public static byte[] getImageInBytes(String imageID)
- {
- InputStream in = SSHActivator.getResources().
- getImageInputStream(imageID);
-
- if (in == null)
- return null;
- byte[] image = null;
- try
- {
- image = new byte[in.available()];
-
- in.read(image);
- }
- catch (IOException e)
- {
- logger.error("Failed to load image:" + imageID, e);
- }
-
- return image;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/ProtocolProviderFactorySSH.java b/src/net/java/sip/communicator/impl/protocol/ssh/ProtocolProviderFactorySSH.java
deleted file mode 100644
index 8c38f60..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/ProtocolProviderFactorySSH.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import net.java.sip.communicator.service.protocol.*;
-
-import org.osgi.framework.*;
-
-/**
- *
- * @author Shobhit Jindal
- */
-public abstract class ProtocolProviderFactorySSH
- extends ProtocolProviderFactory
-{
- /**
- * The name of a property representing the IDENTITY_FILE of the protocol for
- * a ProtocolProviderFactory.
- */
- public static final String IDENTITY_FILE = "IDENTITY_FILE";
-
- /**
- * The name of a property representing the KNOWN_HOSTS_FILE of the protocol
- * for a ProtocolProviderFactory.
- */
- public static final String KNOWN_HOSTS_FILE = "KNOWN_HOSTS_FILE";
-
- protected ProtocolProviderFactorySSH(BundleContext bundleContext,
- String protocolName)
- {
- super(bundleContext, protocolName);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/ProtocolProviderFactorySSHImpl.java b/src/net/java/sip/communicator/impl/protocol/ssh/ProtocolProviderFactorySSHImpl.java
deleted file mode 100644
index 68e33bc..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/ProtocolProviderFactorySSHImpl.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-import org.osgi.framework.*;
-
-/**
- * The SSH protocol provider factory creates instances of the SSH
- * protocol provider service. One Service instance corresponds to one account.
- *
- * @author Shobhit Jindal
- */
-public class ProtocolProviderFactorySSHImpl
- extends ProtocolProviderFactorySSH
-{
-
- /**
- * Creates an instance of the ProtocolProviderFactorySSHImpl.
- */
- public ProtocolProviderFactorySSHImpl()
- {
- super(SSHActivator.getBundleContext(), ProtocolNames.SSH);
- }
-
- /**
- * Initializaed and creates an account corresponding to the specified
- * accountProperties and registers the resulting ProtocolProvider in the
- * <tt>context</tt> BundleContext parameter.
- *
- * @param userIDStr tha/a user identifier uniquely representing the newly
- * created account within the protocol namespace.
- * @param accountProperties a set of protocol (or implementation)
- * specific properties defining the new account.
- * @return the AccountID of the newly created account.
- */
- @Override
- public AccountID installAccount(
- String userIDStr,
- Map<String, String> accountProperties)
- {
- BundleContext context = SSHActivator.getBundleContext();
- if (context == null)
- throw new NullPointerException("The specified BundleContext was " +
- "null");
-
- if (userIDStr == null)
- throw new NullPointerException("The specified AccountID was null");
-
- if (accountProperties == null)
- throw new NullPointerException("The specified property map was" +
- " null");
-
- accountProperties.put(USER_ID, userIDStr);
-
- AccountID accountID = new SSHAccountID(userIDStr, accountProperties);
-
- //make sure we haven't seen this account id before.
- if (registeredAccounts.containsKey(accountID))
- throw new IllegalStateException(
- "An account for id " + userIDStr + " was already" +
- " installed!");
-
- //first store the account and only then load it as the load generates
- //an osgi event, the osgi event triggers (through the UI) a call to the
- //ProtocolProviderService.register() method and it needs to acces
- //the configuration service and check for a stored password.
- this.storeAccount(accountID, false);
-
- accountID = loadAccount(accountProperties);
-
-/* ServiceReference ppServiceRef = context
- .getServiceReference(ProtocolProviderService.class.getName());
-
- ProtocolProviderService ppService = (ProtocolProviderService)
- context.getService(ppServiceRef);
-
- OperationSetPersistentPresence operationSetPersistentPresence =
- (OperationSetPersistentPresence) ppService.getOperationSet(
- OperationSetPersistentPresence.class);
-
- try
- {
- // The below should never fail for SSH accounts
- operationSetPersistentPresence.subscribe(userIDStr);
-
- }
- catch(OperationFailedException ex)
- {
- ex.printStackTrace();
- }
-*/
- return accountID;
- }
-
- @Override
- protected AccountID createAccountID(String userID, Map<String, String> accountProperties)
- {
- return new SSHAccountID(userID, accountProperties);
- }
-
- @Override
- protected ProtocolProviderService createService(String userID,
- AccountID accountID)
- {
- ProtocolProviderServiceSSHImpl service =
- new ProtocolProviderServiceSSHImpl();
-
- service.initialize(userID, accountID);
- return service;
- }
-
-// /**
-// * Saves the password for the specified account after scrambling it a bit
-// * so that it is not visible from first sight (Method remains highly
-// * insecure).
-// *
-// * @param accountID the AccountID for the account whose password we're
-// * storing.
-// * @param passwd the password itself.
-// *
-// * @throws java.lang.IllegalArgumentException if no account corresponding
-// * to <tt>accountID</tt> has been previously stored.
-// */
-// public void storePassword(AccountID accountID, String passwd)
-// throws IllegalArgumentException
-// {
-// super.storePassword(SSHActivator.getBundleContext(),
-// accountID,
-// String.valueOf(Base64.encode(passwd.getBytes())));
-// }
-//
-// /**
-// * Returns the password last saved for the specified account.
-// *
-// * @param accountID the AccountID for the account whose password we're
-// * looking for..
-// *
-// * @return a String containing the password for the specified accountID.
-// *
-// * @throws java.lang.IllegalArgumentException if no account corresponding
-// * to <tt>accountID</tt> has been previously stored.
-// */
-// public String loadPassword(AccountID accountID)
-// throws IllegalArgumentException
-// {
-// String password = super.loadPassword(SSHActivator.getBundleContext()
-// , accountID );
-// return(String.valueOf(Base64.decode(password)));
-// }
-
- @Override
- public void modifyAccount( ProtocolProviderService protocolProvider,
- Map<String, String> accountProperties)
- throws NullPointerException
- {
- // TODO Auto-generated method stub
-
- }
-
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/ProtocolProviderServiceSSHImpl.java b/src/net/java/sip/communicator/impl/protocol/ssh/ProtocolProviderServiceSSHImpl.java
deleted file mode 100644
index a4b16e6..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/ProtocolProviderServiceSSHImpl.java
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.io.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.Logger;
-
-import org.osgi.framework.*;
-
-import com.jcraft.jsch.*;
-
-/**
- * A SSH implementation of the ProtocolProviderService.
- *
- * @author Shobhit Jindal
- */
-public class ProtocolProviderServiceSSHImpl
- extends AbstractProtocolProviderService
-{
- private static final Logger logger
- = Logger.getLogger(ProtocolProviderServiceSSHImpl.class);
-
- /**
- * The name of this protocol.
- */
- public static final String SSH_PROTOCOL_NAME = ProtocolNames.SSH;
-
-// /**
-// * The identifier for SSH Stack
-// * Java Secure Channel JSch
-// */
-// JSch jsch = new JSch();
-
- /**
- * The test command given after each command to determine the reply length
- * of the command
- */
- //private final String testCommand =
- // Resources.getString("testCommand");
-
- /**
- * A reference to the protocol provider of UIService
- */
- private static ServiceReference ppUIServiceRef;
-
- /**
- * Connection timeout to a remote server in milliseconds
- */
- private static int connectionTimeout = 30000;
-
- /**
- * A reference to UI Service
- */
- private static UIService uiService;
-
- /**
- * The id of the account that this protocol provider represents.
- */
- private AccountID accountID = null;
-
- /**
- * We use this to lock access to initialization.
- */
- private final Object initializationLock = new Object();
-
- private OperationSetBasicInstantMessagingSSHImpl basicInstantMessaging;
-
- private OperationSetFileTransferSSHImpl fileTranfer;
-
- /**
- * Indicates whether or not the provider is initialized and ready for use.
- */
- private boolean isInitialized = false;
-
- /**
- * The logo corresponding to the ssh protocol.
- */
- private ProtocolIconSSHImpl sshIcon
- = new ProtocolIconSSHImpl();
-
- /**
- * The registration state of SSH Provider is taken to be registered by
- * default as it doesn't correspond to the state on remote server
- */
- private RegistrationState currentRegistrationState
- = RegistrationState.REGISTERED;
-
- /**
- * The default constructor for the SSH protocol provider.
- */
- public ProtocolProviderServiceSSHImpl()
- {
- if (logger.isTraceEnabled())
- logger.trace("Creating a ssh provider.");
-
- try
- {
- // converting to milliseconds
- connectionTimeout = Integer.parseInt(Resources.getString(
- "connectionTimeout")) * 1000;
- }
- catch(NumberFormatException ex)
- {
- logger.error("Connection Timeout set to 30 seconds");
- }
- }
-
- /**
- * Initializes the service implementation, and puts it in a sate where it
- * could interoperate with other services. It is strongly recomended that
- * properties in this Map be mapped to property names as specified by
- * <tt>AccountProperties</tt>.
- *
- * @param userID the user id of the ssh account we're currently
- * initializing
- * @param accountID the identifier of the account that this protocol
- * provider represents.
- *
- * @see net.java.sip.communicator.service.protocol.AccountID
- */
- protected void initialize(
- String userID,
- AccountID accountID)
- {
- synchronized(initializationLock)
- {
- this.accountID = accountID;
-
- //initialize the presence operationset
- OperationSetPersistentPresenceSSHImpl persistentPresence =
- new OperationSetPersistentPresenceSSHImpl(this);
-
- addSupportedOperationSet(
- OperationSetPersistentPresence.class,
- persistentPresence);
- //register it once again for those that simply need presence and
- //won't be smart enough to check for a persistent presence
- //alternative
- addSupportedOperationSet(
- OperationSetPresence.class,
- persistentPresence);
-
- //initialize the IM operation set
- basicInstantMessaging = new
- OperationSetBasicInstantMessagingSSHImpl(
- this);
- addSupportedOperationSet(
- OperationSetBasicInstantMessaging.class,
- basicInstantMessaging);
-
- //initialze the file transfer operation set
- fileTranfer = new OperationSetFileTransferSSHImpl(this);
- addSupportedOperationSet(
- OperationSetFileTransfer.class,
- fileTranfer);
-
- isInitialized = true;
- }
- }
-
- /**
- * Determines whether a vaild session exists for the contact of remote
- * machine.
- *
- * @param sshContact ID of SSH Contact
- *
- * @return <tt>true</tt> if the session is connected
- * <tt>false</tt> otherwise
- */
- public boolean isSessionValid(ContactSSH sshContact)
- {
- Session sshSession = sshContact.getSSHSession();
- if( sshSession != null)
- if(sshSession.isConnected())
- return true;
-
- // remove reference to an unconnected SSH Session, if any
- sshContact.setSSHSession(null);
- return false;
- }
-
- /**
- * Determines whether the contact is connected to shell of remote machine
- * as a precheck for any further operation
- *
- * @param sshContact ID of SSH Contact
- *
- * @return <tt>true</tt> if the contact is connected
- * <tt>false</tt> if the contact is not connected
- */
- public boolean isShellConnected(ContactSSH sshContact)
- {
- // a test command may also be run here
-
- if(isSessionValid(sshContact))
- {
- return(sshContact.getShellChannel() != null);
- }
-
- /*
- * Above should be return(sshContact.getShellChannel() != null
- * && sshContact.getShellChannel().isConnected());
- *
- * but incorrect reply from stack for isConnected()
- */
-
- return false;
- }
-
- /**
- * Creates a shell channel to the remote machine
- * a new jsch session is also created if the current one is invalid
- *
- * @param sshContact the contact of the remote machine
- * @param firstMessage the first message
- */
- public void connectShell(
- final ContactSSH sshContact,
- final Message firstMessage)
- {
- sshContact.setConnectionInProgress(true);
-
- final Thread newConnection = new Thread((new Runnable()
- {
- public void run()
- {
- OperationSetPersistentPresenceSSHImpl persistentPresence
- = (OperationSetPersistentPresenceSSHImpl)sshContact
- .getParentPresenceOperationSet();
-
- persistentPresence.changeContactPresenceStatus(
- sshContact,
- SSHStatusEnum.CONNECTING);
-
- try
- {
- if(!isSessionValid(sshContact))
- createSSHSessionAndLogin(sshContact);
-
- createShellChannel(sshContact);
-
- //initializing the reader and writers of ssh contact
-
- persistentPresence.changeContactPresenceStatus(
- sshContact,
- SSHStatusEnum.CONNECTED);
-
- showWelcomeMessage(sshContact);
-
- sshContact.setMessageType(ContactSSH
- .CONVERSATION_MESSAGE_RECEIVED);
-
- sshContact.setConnectionInProgress(false);
-
- Thread.sleep(1500);
-
- sshContact.setCommandSent(true);
-
- basicInstantMessaging.sendInstantMessage(
- sshContact,
- firstMessage);
- }
- // rigorous Exception Checking in future
- catch (Exception ex)
- {
- persistentPresence.changeContactPresenceStatus(
- sshContact,
- SSHStatusEnum.NOT_AVAILABLE);
-
- ex.printStackTrace();
- }
- finally
- {
- sshContact.setConnectionInProgress(false);
- }
- }
- }));
-
- newConnection.start();
- }
-
- /**
- * Creates a channel for shell type in the current session
- * channel types = shell, sftp, exec(X forwarding),
- * direct-tcpip(stream forwarding) etc
- *
- * @param sshContact ID of SSH Contact
- * @throws IOException if the shell channel cannot be created
- */
- public void createShellChannel(ContactSSH sshContact)
- throws IOException
- {
- try
- {
- Channel shellChannel = sshContact.getSSHSession()
- .openChannel("shell");
-
- //initalizing the reader and writers of ssh contact
- sshContact.initializeShellIO(shellChannel.getInputStream(),
- shellChannel.getOutputStream());
-
- ((ChannelShell)shellChannel).setPtyType(
- sshContact.getSSHConfigurationForm().getTerminalType());
-
- //initializing the shell
- shellChannel.connect(1000);
-
- sshContact.setShellChannel(shellChannel);
-
- sshContact.sendLine("export PS1=");
- }
- catch (JSchException ex)
- {
- sshContact.setSSHSession(null);
- throw new IOException("Unable to create shell channel to remote" +
- " server");
- }
- }
-
- /**
- * Closes the Shell channel are associated IO Streams
- *
- * @param sshContact ID of SSH Contact
- * @throws JSchException if something went wrong in JSch
- * @throws IOException if I/O exception occurred
- */
- public void closeShellChannel(ContactSSH sshContact) throws
- JSchException,
- IOException
- {
- sshContact.closeShellIO();
- sshContact.getShellChannel().disconnect();
- sshContact.setShellChannel(null);
- }
-
- /**
- * Creates a SSH Session with a remote machine and tries to login
- * according to the details specified by Contact
- * An appropriate message is shown to the end user in case the login fails
- *
- * @param sshContact ID of SSH Contact
- *
- * @throws JSchException if a JSch is unable to create a SSH Session with
- * the remote machine
- * @throws InterruptedException if the thread is interrupted before session
- * connected or is timed out
- * @throws OperationFailedException if not of above reasons :-)
- */
- public void createSSHSessionAndLogin(ContactSSH sshContact) throws
- JSchException,
- OperationFailedException,
- InterruptedException
- {
- if (logger.isInfoEnabled())
- logger.info("Creating a new SSH Session to "
- + sshContact.getHostName());
-
- // creating a new JSch Stack identifier for contact
- JSch jsch = new JSch();
-
- String knownHosts =
- accountID.getAccountPropertyString("KNOWN_HOSTS_FILE");
-
- if(!knownHosts.equals("Optional"))
- jsch.setKnownHosts(knownHosts);
-
- String identitiyKey =
- accountID.getAccountPropertyString("IDENTITY_FILE");
-
- String userName = sshContact.getUserName();
-
- // use the name of system user if the contact has not supplied SSH
- // details
- if(userName.equals(""))
- userName = System.getProperty("user.name");
-
- if(!identitiyKey.equals("Optional"))
- jsch.addIdentity(identitiyKey);
-
- // creating a new session for the contact
- Session session = jsch.getSession(
- userName,
- sshContact.getHostName(),
- sshContact.getSSHConfigurationForm().getPort());
-
- /**
- * Creating and associating User Info with the session
- * User Info passes authentication from sshContact to SSH Stack
- */
- SSHUserInfo sshUserInfo = new SSHUserInfo(sshContact);
-
- session.setUserInfo(sshUserInfo);
-
- /**
- * initializing the session
- */
- session.connect(connectionTimeout);
-
- int count = 0;
-
- // wait for session to get connected
- while(!session.isConnected() && count<=30000)
- {
- Thread.sleep(1000);
- count += 1000;
- if (logger.isTraceEnabled())
- logger.trace("SSH:" + sshContact.getHostName()
- + ": Sleep zzz .. " );
- }
-
- // if timeout have exceeded
- if(count>30000)
- {
- sshContact.setSSHSession(null);
- JOptionPane.showMessageDialog(
- null,
- "SSH Connection attempt to "
- + sshContact.getHostName() + " timed out");
-
- // error codes are not defined yet
- throw new OperationFailedException("SSH Connection attempt to " +
- sshContact.getHostName() + " timed out", 2);
- }
-
- sshContact.setJSch(jsch);
- sshContact.setSSHSession(session);
-
- if (logger.isInfoEnabled())
- logger.info("A new SSH Session to " + sshContact.getHostName()
- + " Created");
- }
-
- /**
- * Closes the SSH Session associated with the contact
- *
- * @param sshContact ID of SSH Contact
- */
- void closeSSHSession(ContactSSH sshContact)
- {
- sshContact.getSSHSession().disconnect();
- sshContact.setSSHSession(null);
- }
-
- /**
- * Presents the login welcome message to user
- *
- * @param sshContact ID of SSH Contact
- * @throws IOException if I/O exception occurred
- */
- public void showWelcomeMessage(ContactSSH sshContact)
- throws IOException
- {
-/* //sending the command
- sshContact.sendLine(testCommand);
-
- String reply = "", line = "";
-
- // message is extracted until the test Command ie echoed back
- while(line.indexOf(testCommand) == -1)
- {
- reply += line + "\n";
- line = sshContact.getLine();
- }
-
- uiService.getPopupDialog().showMessagePopupDialog
- (reply,"Message from " + sshContact.getDisplayName(),
- uiService.getPopupDialog().INFORMATION_MESSAGE);
-
- if(line.startsWith(testCommand))
- while(!sshContact.getLine().contains(testCommand));
-
- //one line output of testCommand
- sshContact.getLine();
-*/
- if (logger.isDebugEnabled())
- logger.debug("SSH: Welcome message shown");
- }
-
- /**
- * Returns a reference to UIServce for accessing UI related services
- *
- * @return uiService a reference to UIService
- */
- public static UIService getUIService()
- {
- return uiService;
- }
-
- /**
- * Returns the AccountID that uniquely identifies the account represented
- * by this instance of the ProtocolProviderService.
- *
- * @return the id of the account represented by this provider.
- */
- public AccountID getAccountID()
- {
- return accountID;
- }
-
- /**
- * Returns the short name of the protocol that the implementation of this
- * provider is based upon (like SIP, Jabber, ICQ/AIM, or others for
- * example).
- *
- * @return a String containing the short name of the protocol this
- * service is implementing (most often that would be a name in
- * ProtocolNames).
- */
- public String getProtocolName()
- {
- return SSH_PROTOCOL_NAME;
- }
-
- /**
- * Returns the state of the registration of this protocol provider with
- * the corresponding registration service.
- *
- * @return ProviderRegistrationState
- */
- public RegistrationState getRegistrationState()
- {
- return currentRegistrationState;
- }
-
- /**
- * Starts the registration process.
- *
- * @param authority the security authority that will be used for
- * resolving any security challenges that may be returned during the
- * registration or at any moment while wer're registered.
- * @throws OperationFailedException with the corresponding code it the
- * registration fails for some reason (e.g. a networking error or an
- * implementation problem).
- */
- public void register(SecurityAuthority authority)
- throws OperationFailedException
- {
- RegistrationState oldState = currentRegistrationState;
- currentRegistrationState = RegistrationState.REGISTERED;
-
- //get a reference to UI Service via its Service Reference
- ppUIServiceRef = SSHActivator.getBundleContext()
- .getServiceReference(UIService.class.getName());
-
- uiService = (UIService)SSHActivator.getBundleContext()
- .getService(ppUIServiceRef);
-
- fireRegistrationStateChanged(
- oldState
- , currentRegistrationState
- , RegistrationStateChangeEvent.REASON_USER_REQUEST
- , null);
-
- }
-
- /**
- * Makes the service implementation close all open sockets and release
- * any resources that it might have taken and prepare for
- * shutdown/garbage collection.
- */
- public void shutdown()
- {
- if(!isInitialized)
- {
- return;
- }
- if (logger.isTraceEnabled())
- logger.trace("Killing the SSH Protocol Provider.");
-
- if(isRegistered())
- {
- try
- {
- //do the unregistration
- unregister();
- }
- catch (OperationFailedException ex)
- {
- //we're shutting down so we need to silence the exception here
- logger.error(
- "Failed to properly unregister before shutting down. "
- + getAccountID()
- , ex);
- }
- }
-
- isInitialized = false;
- }
-
- /**
- * Ends the registration of this protocol provider with the current
- * registration service.
- *
- * @throws OperationFailedException with the corresponding code it the
- * registration fails for some reason (e.g. a networking error or an
- * implementation problem).
- */
- public void unregister()
- throws OperationFailedException
- {
- RegistrationState oldState = currentRegistrationState;
- currentRegistrationState = RegistrationState.UNREGISTERED;
-
- fireRegistrationStateChanged(
- oldState
- , currentRegistrationState
- , RegistrationStateChangeEvent.REASON_USER_REQUEST
- , null);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see net.java.sip.communicator.service.protocol.ProtocolProviderService#
- * isSignallingTransportSecure()
- */
- public boolean isSignalingTransportSecure()
- {
- return false;
- }
-
- /**
- * Returns the "transport" protocol of this instance used to carry the
- * control channel for the current protocol service.
- *
- * @return The "transport" protocol of this instance: TCP.
- */
- public TransportProtocol getTransportProtocol()
- {
- return TransportProtocol.TCP;
- }
-
- /**
- * Returns the ssh protocol icon.
- * @return the ssh protocol icon
- */
- public ProtocolIcon getProtocolIcon()
- {
- return sshIcon;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/Resources.java b/src/net/java/sip/communicator/impl/protocol/ssh/Resources.java
deleted file mode 100644
index 48b9b49..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/Resources.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import net.java.sip.communicator.service.resources.*;
-
-/**
- * @author Shobhit Jindal
- */
-public class Resources
-{
- /**
- * The SSH logo imageID.
- */
- public static ImageID SSH_LOGO = new ImageID("protocolIconSsh");
-
- /**
- * Returns an string corresponding to the given key.
- *
- * @param key The key of the string.
- *
- * @return a string corresponding to the given key.
- */
- public static String getString(String key)
- {
- return SSHActivator.getResources().getI18NString(key);
- }
-
- /**
- * Loads an image from a given image identifier.
- * @param imageID The identifier of the image.
- * @return The image for the given identifier.
- */
- public static byte[] getImage(ImageID imageID)
- {
- return SSHActivator.getResources().getImageInBytes(imageID.getId());
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/SSHAccountID.java b/src/net/java/sip/communicator/impl/protocol/ssh/SSHAccountID.java
deleted file mode 100644
index 8f9dda7..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/SSHAccountID.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * The SSH implementation of a sip-communicator account id.
- * @author Shobhit Jindal
- */
-public class SSHAccountID
- extends AccountID
-{
- /**
- * Creates an account id from the specified id and account properties.
- *
- * @param userID the user identifier correspnding to thi account
- * @param accountProperties any other properties necessary for the account.
- */
- SSHAccountID(String userID, Map<String, String> accountProperties)
- {
- super(userID
- , accountProperties
- , "SSH"
- , "sip-communicator.org");
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/SSHActivator.java b/src/net/java/sip/communicator/impl/protocol/ssh/SSHActivator.java
deleted file mode 100644
index 7108020..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/SSHActivator.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.resources.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.resources.*;
-import org.osgi.framework.*;
-
-/**
- * Loads the SSH provider factory and registers its services in the OSGI
- * bundle context.
- *
- * @author Shobhit Jindal
- */
-public class SSHActivator
- implements BundleActivator
-{
- private static final Logger logger
- = Logger.getLogger(SSHActivator.class);
-
- /**
- * A reference to the registration of our SSH protocol provider
- * factory.
- */
- private ServiceRegistration sshPpFactoryServReg = null;
-
- /**
- * A reference to the SSH protocol provider factory.
- */
- private static ProtocolProviderFactorySSHImpl
- sshProviderFactory = null;
-
- /**
- * The currently valid bundle context.
- */
- private static BundleContext bundleContext = null;
-
- private static ResourceManagementService resourcesService;
-
- /**
- * Called when this bundle is started. In here we'll export the
- * ssh ProtocolProviderFactory implementation so that it could be
- * possible to register accounts with it in SIP Communicator.
- *
- * @param context The execution context of the bundle being started.
- * @throws Exception If this method throws an exception, this bundle is
- * marked as stopped and the Framework will remove this bundle's
- * listeners, unregister all services registered by this bundle, and
- * release all services used by this bundle.
- */
- public void start(BundleContext context)
- throws Exception
- {
- bundleContext = context;
-
- Hashtable<String, String> hashtable = new Hashtable<String, String>();
- hashtable.put(ProtocolProviderFactory.PROTOCOL, "SSH");
-
- sshProviderFactory = new ProtocolProviderFactorySSHImpl();
-
- //reg the ssh provider factory.
- sshPpFactoryServReg = context.registerService(
- ProtocolProviderFactory.class.getName(),
- sshProviderFactory,
- hashtable);
-
- if (logger.isInfoEnabled())
- logger.info("SSH protocol implementation [STARTED].");
- }
-
- /**
- * Returns a reference to the bundle context that we were started with.
- * @return bundleContext a reference to the BundleContext instance
- * that we were started with.
- */
- public static BundleContext getBundleContext()
- {
- return bundleContext;
- }
-
- /**
- * Retrurns a reference to the protocol provider factory that we have
- * registered.
- * @return a reference to the <tt>ProtocolProviderFactoryJabberImpl</tt>
- * instance that we have registered from this package.
- */
- public static ProtocolProviderFactorySSHImpl
- getProtocolProviderFactory()
- {
- return sshProviderFactory;
- }
-
-
- /**
- * Called when this bundle is stopped so the Framework can perform the
- * bundle-specific activities necessary to stop the bundle.
- *
- * @param context The execution context of the bundle being stopped.
- * @throws Exception If this method throws an exception, the bundle is
- * still marked as stopped, and the Framework will remove the bundle's
- * listeners, unregister all services registered by the bundle, and
- * release all services used by the bundle.
- */
- public void stop(BundleContext context)
- throws Exception
- {
- sshProviderFactory.stop();
- sshPpFactoryServReg.unregister();
- if (logger.isInfoEnabled())
- logger.info("SSH protocol implementation [STOPPED].");
- }
-
- /**
- * Returns the <tt>ResourceManagementService</tt>.
- *
- * @return the <tt>ResourceManagementService</tt>.
- */
- public static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- resourcesService =
- ResourceManagementServiceUtils.getService(bundleContext);
- return resourcesService;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/SSHContactInfo.java b/src/net/java/sip/communicator/impl/protocol/ssh/SSHContactInfo.java
deleted file mode 100644
index 47bb484..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/SSHContactInfo.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.text.*;
-
-import javax.swing.*;
-import javax.swing.text.*;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-
-/**
- * @author Shobhit Jindal
- */
-class SSHContactInfo
- extends SIPCommDialog
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- private ContactSSH sshContact;
-
- private JPanel mainPanel = new TransparentPanel();
- private JPanel machinePanel = new TransparentPanel();
- private JPanel detailNamesPanel = new TransparentPanel();
- private JPanel detailFieldsPanel = new TransparentPanel();
- private JPanel detailsPanel = new TransparentPanel();
-
- private JCheckBox addDetailsCheckBox = new SIPCommCheckBox("Add Details");
-
- private JButton doneButton = new JButton("Done");
- private JLabel machineID = new JLabel("Hostname / IP: ");
- private JTextField machineIDField = new JTextField();
- private JLabel userName = new JLabel("User Name: ");
- private JTextField userNameField = new JTextField();
- private JLabel password = new JLabel("Password: ");
- private JTextField passwordField = new JPasswordField();
- private JLabel port = new JLabel("Port: ");
-
- private JFormattedTextField portField;
- private JLabel secs = new JLabel("secs");
- private JLabel statusUpdate = new JLabel("Update Interval: ");
- private JLabel terminalType = new JLabel("Terminal Type: ");
- private JTextField terminalTypeField = new JTextField("SIP Communicator");
- private JSpinner updateTimer = new JSpinner();
-
- private JPanel emptyPanel1 = new TransparentPanel();
-
- private JPanel emptyPanel2 = new TransparentPanel();
-
- private JPanel emptyPanel3 = new TransparentPanel();
-
- private JPanel emptyPanel4 = new TransparentPanel();
-
- private JPanel emptyPanel5 = new TransparentPanel();
-
- private JPanel emptyPanel6 = new TransparentPanel();
-
- private JPanel emptyPanel7 = new TransparentPanel();
-
- private JPanel emptyPanel8 = new TransparentPanel();
-
- private JPanel emptyPanel9 = new TransparentPanel();
-
- private JPanel emptyPanel10 = new TransparentPanel();
-
- private JPanel emptyPanel11 = new TransparentPanel();
-
-// private ContactGroup contactGroup = null;
-
- /**
- * Creates a new instance of SSHContactInfo
- *
- * @param sshContact the concerned contact
- */
- public SSHContactInfo(ContactSSH sshContact) {
- super(true);
-
- this.sshContact = sshContact;
- initForm();
-
- this.getContentPane().add(mainPanel);
-
- this.setSize(370, 325);
-
- this.setResizable(false);
-
- this.setTitle("SSH: Account Details of " + sshContact.getDisplayName());
-
- Toolkit toolkit = Toolkit.getDefaultToolkit();
- Dimension screenSize = toolkit.getScreenSize();
-
- int x = (screenSize.width - this.getWidth()) / 2;
- int y = (screenSize.height - this.getHeight()) / 2;
-
- this.setLocation(x,y);
-
-// ProtocolProviderServiceSSHImpl.getUIService().getConfigurationWindow().
-// addConfigurationForm(this);
- }
-
- /**
- * initialize the form.
- */
- public void initForm() {
- updateTimer.setValue(30);
- MaskFormatter maskFormatter = new MaskFormatter();
- try {
- maskFormatter.setMask("#####");
- } catch (ParseException ex) {
- ex.printStackTrace();
- }
- maskFormatter.setAllowsInvalid(false);
- portField = new JFormattedTextField(maskFormatter);
- portField.setValue(22);
-
- userNameField.setEnabled(false);
- passwordField.setEditable(false);
- portField.setEnabled(false);
- terminalTypeField.setEnabled(false);
- updateTimer.setEnabled(false);
-
- mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
- machinePanel.setLayout(new BoxLayout(machinePanel, BoxLayout.X_AXIS));
- detailNamesPanel.setLayout(new BoxLayout(detailNamesPanel,
- BoxLayout.Y_AXIS));
- detailFieldsPanel.setLayout(new BoxLayout(detailFieldsPanel,
- BoxLayout.Y_AXIS));
- detailsPanel.setLayout(new BoxLayout(detailsPanel, BoxLayout.X_AXIS));
-
- machinePanel.add(machineID);
- machinePanel.add(machineIDField);
-
- detailNamesPanel.add(userName);
- detailNamesPanel.add(emptyPanel1);
- detailNamesPanel.add(password);
- detailNamesPanel.add(emptyPanel2);
- detailNamesPanel.add(port);
- detailNamesPanel.add(emptyPanel3);
- detailNamesPanel.add(statusUpdate);
- detailNamesPanel.add(emptyPanel4);
- detailNamesPanel.add(terminalType);
-
- detailFieldsPanel.add(userNameField);
- detailFieldsPanel.add(emptyPanel5);
- detailFieldsPanel.add(passwordField);
- detailFieldsPanel.add(emptyPanel6);
- detailFieldsPanel.add(portField);
- detailFieldsPanel.add(emptyPanel7);
- detailFieldsPanel.add(updateTimer);
- detailFieldsPanel.add(emptyPanel8);
- detailFieldsPanel.add(terminalTypeField);
-
- detailsPanel.add(detailNamesPanel);
- detailsPanel.add(detailFieldsPanel);
-
- detailsPanel.setBorder(BorderFactory.createTitledBorder("Details"));
-
- mainPanel.add(emptyPanel9);
- mainPanel.add(machinePanel);
- mainPanel.add(addDetailsCheckBox);
- mainPanel.add(detailsPanel);
- mainPanel.add(emptyPanel10);
- mainPanel.add(doneButton);
- mainPanel.add(emptyPanel11);
-
- addDetailsCheckBox.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent event) {
- addDetailsCheckBox.setEnabled(false);
- userNameField.setEnabled(true);
- passwordField.setEditable(true);
- portField.setEnabled(true);
- terminalTypeField.setEnabled(true);
- updateTimer.setEnabled(true);
-
- userNameField.grabFocus();
- }
- });
-
- doneButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent event) {
- if(machineIDField.getText().equals("")) {
- machineIDField.setText("Field needed");
- return;
- }
-
- sshContact.savePersistentDetails();
-
- //add contact to contact list
- ((OperationSetPersistentPresenceSSHImpl)sshContact
- .getParentPresenceOperationSet())
- .addContactToList(
- sshContact.getParentContactGroup(),
- sshContact);
-
- setVisible(false);
- }
- });
- }
-
- /**
- * Return the ssh icon
- *
- * @return the ssh icon
- */
- public byte[] getIcon() {
- return Resources.getImage(Resources.SSH_LOGO);
- }
-
-//
-// public void setContactGroup(ContactGroup contactGroup)
-// {
-// this.contactGroup = contactGroup;
-// }
-//
-// public ContactGroup getContactGroup()
-// {
-// return this.contactGroup;
-// }
-
- /**
- * Sets the UserName of the dialog
- *
- * @param userName to be associated
- */
- public void setUserNameField(String userName) {
- this.userNameField.setText(userName);
- }
-
- /**
- * Sets the Password of the dialog
- *
- * @param password to be associated
- */
- public void setPasswordField(String password) {
- this.passwordField.setText(password);
- }
-
- /**
- * Return the hostname
- *
- * @return the hostname
- */
- public String getHostName() {
- return this.machineIDField.getText();
- }
-
- /**
- * Return the username
- *
- * @return the username
- */
- public String getUserName() {
- return this.userNameField.getText();
- }
-
- /**
- * Return the password
- *
- * @return the password in a clear form
- */
- public String getPassword() {
- return this.passwordField.getText();
- }
-
- /**
- * Return the terminal type
- *
- * @return the terminal type
- */
- public String getTerminalType() {
- return this.terminalTypeField.getText();
- }
-
- /**
- * Return the port
- *
- * @return the port value
- */
- public int getPort() {
- return Integer.parseInt(this.portField.getText().trim());
- }
-
- /**
- * Return the update interval
- *
- * @return the update interval
- */
- public int getUpdateInterval() {
- return Integer.parseInt(String.valueOf(this.updateTimer.getValue()));
- }
-
- /**
- * Sets the HostName of the dialog
- *
- * @param hostName to be associated
- */
- public void setHostNameField(String hostName) {
- this.machineIDField.setText(hostName);
- }
-
- /**
- * Sets the Terminal Type of the dialog
- *
- * @param termType to be associated
- */
- public void setTerminalType(String termType) {
- this.terminalTypeField.setText(termType);
- }
-
- /**
- * Sets the Update Interval of the dialog
- *
- * @param interval to be associated
- */
- public void setUpdateInterval(int interval) {
- this.updateTimer.setValue(interval);
- }
-
- /**
- * Sets the Port of the dialog
- *
- * @param port to be associated
- */
- public void setPort(String port) {
- this.portField.setText(port);
- }
-
- @Override
- protected void close(boolean isEscaped)
- {
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/SSHFileTransferDaemon.java b/src/net/java/sip/communicator/impl/protocol/ssh/SSHFileTransferDaemon.java
deleted file mode 100644
index 3b522ed..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/SSHFileTransferDaemon.java
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.io.*;
-
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.Logger;
-
-import com.jcraft.jsch.*;
-
-/**
- * @author Shobhit Jindal
- */
-public class SSHFileTransferDaemon
- extends Thread
-{
- private static final Logger logger =
- Logger.getLogger(SSHFileTransferDaemon .class);
-
- /**
- * The contact of the remote machine
- */
- private ContactSSH sshContact;
-
- /**
- * The currently valid ssh protocol provider
- */
- private ProtocolProviderServiceSSHImpl ppService;
-
- /**
- * JSch Channel to be used for file transfer
- */
- private Channel fileTransferChannel;
-
- /**
- * The identifier for the Input Stream associated with SCP Channel
- */
- private InputStream scpInputStream = null;
-
- /**
- * The identifier for the Output Stream associated with SCP Channel
- */
- private OutputStream scpOutputStream = null;
-
- /**
- * Identifier of local file
- */
- private String localPath;
-
- /**
- * Identifier of remote file
- */
- private String remotePath;
-
- /**
- * File to be uploaded or saved
- */
- private File file;
-
- /**
- * The file input stream associated with the file to be uploaded
- */
- private FileInputStream fileInputStream;
-
- /**
- * The file output stream associated with the file to be uploaded
- */
- private FileOutputStream fileOutputStream;
-
- /**
- * The boolean which determines whether we are uploading or downloading
- * files
- */
- private boolean uploadFile;
-
- /**
- * The currently valid ssh persistent presence operation set
- */
- private OperationSetPersistentPresenceSSHImpl opSetPersPresence = null;
-
- /**
- * The currently valid ssh instant messaging operation set
- */
- private OperationSetBasicInstantMessagingSSHImpl instantMessaging = null;
-
- /**
- * Creates a new instance of SSHFileTransferDaemon
- *
- *
- * @param sshContact The contact of the remote machine
- * @param ppService The current ssh protocol provider
- */
- public SSHFileTransferDaemon(
- ContactSSH sshContact,
- ProtocolProviderServiceSSHImpl ppService)
- {
- super();
- this.sshContact = sshContact;
- this.opSetPersPresence = (OperationSetPersistentPresenceSSHImpl)
- ppService.getOperationSet(OperationSetPersistentPresence.class);
- this.instantMessaging = (OperationSetBasicInstantMessagingSSHImpl)
- ppService.getOperationSet(
- OperationSetBasicInstantMessaging.class);
- this.ppService = ppService;
- }
-
- /**
- * This method is called when file is to be transfered from local machine
- * to remote machine
- *
- * @param remotePath - the identifier for the remote file
- * @param localPath - the identifier for the local file
- */
- public void uploadFile(
- String remotePath,
- String localPath)
- {
- this.uploadFile = true;
- this.remotePath = remotePath;
- this.localPath = localPath;
-
- file = new File(localPath);
-
- start();
- }
-
- /**
- * This method is called when a file is to be downloaded from remote machine
- * to local machine
- *
- * @param remotePath - the identifier for the remote file
- * @param localPath - the identifier for the local file
- */
- public void downloadFile(
- String remotePath,
- String localPath)
- {
- this.uploadFile = false;
- this.remotePath = remotePath;
- this.localPath = localPath;
-
- file = new File(localPath);
-
- start();
- }
-
- /**
- * Background thread for the file transfer
- */
- @Override
- public void run()
- {
- //oldStatus to be resumed earlier
- PresenceStatus oldStatus = sshContact.getPresenceStatus();
-
- opSetPersPresence.changeContactPresenceStatus(
- sshContact,
- SSHStatusEnum.CONNECTING);
-
- try
- {
- //create a new JSch session if current is invalid
- if( !ppService.isSessionValid(sshContact))
- ppService.createSSHSessionAndLogin(sshContact);
-
- fileTransferChannel = sshContact.getSSHSession()
- .openChannel("exec");
- String command;
-
- // -p = Preserves modification times, access times, and modes from
- // the original file
- if(uploadFile)
- command = "scp -p -t " + remotePath;
- else
- command = "scp -f " + remotePath;
-
- //the command to be executed on the remote terminal
- ((ChannelExec)fileTransferChannel).setCommand(command);
-
- scpInputStream = fileTransferChannel.getInputStream();
- scpOutputStream = fileTransferChannel.getOutputStream();
-
- fileTransferChannel.connect();
-
- //file transfer is setup
- opSetPersPresence.changeContactPresenceStatus(
- sshContact,
- SSHStatusEnum.FILE_TRANSFER);
-
- if(uploadFile)
- {
- instantMessaging.deliverMessage(
- instantMessaging.createMessage(
- "Uploading " + file.getName() + " to server"),
- sshContact);
-
- upload();
- }
- else
- {
- instantMessaging.deliverMessage(
- instantMessaging.createMessage(
- "Downloading " + file.getName() + " from server"),
- sshContact);
-
- download();
- }
-
- }
- catch(Exception ex)
- {
- //presently errors(any type) are directly logged directly in chat
- instantMessaging.deliverMessage(
- instantMessaging.createMessage(ex.getMessage()),
- sshContact);
-
- logger.error(ex.getMessage());
-
- try
- {
- if(fileInputStream!=null)
- {
- fileInputStream.close();
- }
-
- if(fileOutputStream!=null)
- {
- fileOutputStream.close();
- }
- }
- catch(Exception e)
- {}
- }
-
- // restore old status
- opSetPersPresence.changeContactPresenceStatus(
- sshContact,
- oldStatus);
- }
-
- /**
- * Check for error in reading stream of remote machine
- *
- * @return 0 for success, 1 for error, 2 for fatal error, -1 otherwise
- * @throws IOException when the network goes down
- */
- private int checkAck(InputStream inputStream)
- throws IOException
- {
- int result = inputStream.read();
-
- // read error message
- if(result==1 || result==2)
- {
- StringBuffer buffer = new StringBuffer();
-
- int ch;
-
- do
- {
- //read a line of message
- ch = inputStream.read();
- buffer.append((char)ch);
-
- }while(ch != '\n');
-
- ProtocolProviderServiceSSHImpl
- .getUIService()
- .getPopupDialog()
- .showMessagePopupDialog(
- buffer.toString(),
- "File Transfer Error: "
- + sshContact.getDisplayName(),
- PopupDialog.ERROR_MESSAGE);
-
- logger.error(buffer.toString());
- }
-
- return result;
- }
-
- /**
- * Uploads the file to the remote server
- *
- * @throws IOException when the network goes down
- * @throws OperationFailedException when server behaves unexpectedly
- */
- private void upload()
- throws IOException,
- OperationFailedException
- {
- fileInputStream = new FileInputStream(file);
-
- byte[] buffer = new byte[1024];
- int result, bytesRead;
-
- if( (result = checkAck(scpInputStream)) !=0)
- throw new OperationFailedException("Error in Ack", result);
-
- // send "C0644 filesize filename", where filename should not include '/'
- long filesize= file.length();
- String command = "C0644 " + filesize + " ";
-
-// if(lfile.lastIndexOf('/')>0)
-// {
-// command+=lfile.substring(lfile.lastIndexOf('/')+1);
-// }
-// else
-// {
-// command+=lfile;
-// }
-
- command += file.getName() + "\n";
- if (logger.isTraceEnabled())
- logger.trace(command);
- scpOutputStream.write(command.getBytes());
- scpOutputStream.flush();
-
- if( (result = checkAck(scpInputStream)) !=0)
- throw new OperationFailedException("Error in Ack", result);
-
- while(true)
- {
- bytesRead = fileInputStream.read(buffer, 0, buffer.length);
- if(bytesRead <= 0)
- break;
-
- scpOutputStream.write(buffer, 0, bytesRead); //out.flush();
- }
- fileInputStream.close();
- fileInputStream = null;
-
- // send '\0'
- buffer[0]=0; scpOutputStream.write(buffer, 0, 1);
- scpOutputStream.flush();
-
- if( (result = checkAck(scpInputStream)) !=0)
- throw new OperationFailedException("Error in Ack", result);
-
- scpInputStream.close();
- scpOutputStream.close();
-
- fileTransferChannel.disconnect();
-
- instantMessaging.deliverMessage(
- instantMessaging.createMessage(file.getName()
- + " uploaded to Server"),
- sshContact);
- }
-
- /**
- * Downloads a file from the remote machine
- *
- * @throws IOException when the network goes down
- * @throws OperationFailedException when server behaves unexpectedly
- */
- private void download()
- throws IOException,
- OperationFailedException
- {
- fileOutputStream = new FileOutputStream(file);
-
- int result;
-
- byte[] buffer = new byte[1024];
-
- // send '\0'
- buffer[0]=0;
-
- scpOutputStream.write(buffer, 0, 1);
- scpOutputStream.flush();
-
- int ch = checkAck(scpInputStream);
-
- if(ch!='C')
- {
- throw new OperationFailedException("Invalid reply from server", 12);
- }
-
- // read '0644 '
- scpInputStream.read(buffer, 0, 5);
-
- long filesize=0L;
- while(true)
- {
- if(scpInputStream.read(buffer, 0, 1) < 0)
- {
- // error
- break;
- }
- if(buffer[0]==' ')break;
- filesize=filesize*10L+buffer[0]-'0';
- }
-
- String file=null;
- for(int i=0;true;i++)
- {
- scpInputStream.read(buffer, i, 1);
- if(buffer[i]==(byte)0x0a)
- {
- file=new String(buffer, 0, i);
- break;
- }
- }
-
- //System.out.println("filesize="+filesize+", file="+file);
-
- // send '\0'
- buffer[0]=0;
- scpOutputStream.write(buffer, 0, 1);
- scpOutputStream.flush();
-
- // read a content of lfile
- int foo;
- while(true)
- {
- if(buffer.length<filesize)
- foo=buffer.length;
- else
- foo=(int)filesize;
-
- foo = scpInputStream.read(buffer, 0, foo);
- if(foo<0)
- break;
-
- fileOutputStream.write(buffer, 0, foo);
- filesize-=foo;
- if(filesize==0L) break;
- }
- fileOutputStream.close();
- fileOutputStream=null;
-
- if( (result = checkAck(scpInputStream)) !=0)
- throw new OperationFailedException("Error in Ack", result);
-
- // send '\0'
- buffer[0]=0;
- scpOutputStream.write(buffer, 0, 1);
- scpOutputStream.flush();
-
- scpInputStream.close();
- scpOutputStream.close();
-
- fileTransferChannel.disconnect();
-
- instantMessaging.deliverMessage(
- instantMessaging.createMessage(
- this.file.getName() + " downloaded from Server"),
- sshContact);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/SSHReaderDaemon.java b/src/net/java/sip/communicator/impl/protocol/ssh/SSHReaderDaemon.java
deleted file mode 100644
index 2c33b5d..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/SSHReaderDaemon.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.io.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- *
- * @author Shobhit Jindal
- */
-public class SSHReaderDaemon
- extends Thread
-{
-
- /**
- * A Buffer to aggregate replies to be sent as one message
- */
- private StringBuffer replyBuffer;
-
- /**
- * The identifier of Contact representing the remote machine
- */
- private ContactSSHImpl sshContact;
-
- /**
- * The identifier of the message received from server
- */
- private String message;
-
- /**
- * An identifier representing the state of Reader Daemon
- */
- private boolean isActive = false;
-
- /**
- * This OperationSet delivers incoming message
- */
- private OperationSetBasicInstantMessagingSSHImpl instantMessaging;
-
- /**
- * Input Stream of remote user to be read
- */
- private InputStream shellInputStream;
-
- /**
- * Buffered Reader associated with above input stream
- */
- private InputStreamReader shellReader;
-
-// /**
-// * This OperationSet delivers incoming message
-// */
-// private OperationSetPersistentPresenceSSHImpl persistentPresence;
-
- /**
- * Bytes available in Input Stream before reading
- */
- private int bytesAvailable;
-
- private int bytesRead;
-
- int bufferCount;
-
- char buf;
-
- /**
- * Creates a new instance of SSHReaderDaemon
- */
- public SSHReaderDaemon(ContactSSH sshContact)
- {
- this.sshContact = (ContactSSHImpl)sshContact;
- instantMessaging =
- (OperationSetBasicInstantMessagingSSHImpl)
- sshContact
- .getProtocolProvider()
- .getOperationSet(
- OperationSetBasicInstantMessaging.class);
- }
-
- /**
- * Reads the remote machine, updating the chat window as necessary
- * in a background thread
- */
- @Override
- public void run()
- {
- shellInputStream = sshContact.getShellInputStream();
- shellReader = sshContact.getShellReader();
- replyBuffer = new StringBuffer();
-
-
- try
- {
- do
- {
- bytesAvailable = shellInputStream.available();
-
- if(bytesAvailable == 0 )
- {
- // wait if more data is available
- // for a slower connection this value need to be raised
- // to avoid splitting of messages
- Thread.sleep(250);
- continue;
- }
-
- bufferCount = 0;
-
-// if(replyBuffer > 0)
-
- do
- {
- // store the responses in a buffer
- storeMessage(replyBuffer);
-
- Thread.sleep(250);
-
- bytesAvailable = shellInputStream.available();
-
- }while(bytesAvailable > 0 && bufferCount<16384);
-
- message = replyBuffer.toString();
-
- if(sshContact.isCommandSent())
- {
- // if the response is as a result of a command sent
- sshContact.setMessageType(
- ContactSSH.CONVERSATION_MESSAGE_RECEIVED);
-
- message = message.substring(message.indexOf('\n') + 1);
-
- sshContact.setCommandSent(false);
- }
- else
- {
- // server sent an asynchronous message to the terminal
- // display it as a system message
- sshContact.setMessageType(
- ContactSSH.SYSTEM_MESSAGE_RECEIVED);
-
- //popup disabled
-// JOptionPane.showMessageDialog(
-// null,
-// message,
-// "Message from " + sshContact.getDisplayName(),
-// JOptionPane.INFORMATION_MESSAGE);
- }
-
- instantMessaging.deliverMessage(
- instantMessaging.createMessage(message),
- sshContact);
-
- replyBuffer.delete(0, replyBuffer.length());
-
- }while(isActive);
- }
- catch(Exception ex)
- {
- ex.printStackTrace();
- }
- }
-
- /**
- * Stores the response from server in a temporary buffer
- * the bytes available are determined before the function is called
- *
- * @param replyBuffer to store the response from server
- *
- * @throws IOException if the network goes down
- */
- private void storeMessage(StringBuffer replyBuffer) throws IOException
- {
- do
- {
- buf = (char)shellInputStream.read();
-
-// System.out.println(String.valueOf(buf)+ " " + (int)buf);
-
- replyBuffer.append(String.valueOf(buf));
-
-// logger.debug(shellReader.readLine());
-
- bufferCount++;
-
- bytesAvailable--;
-
- }while(bytesAvailable>0 && bufferCount<32700);
- }
-
- public void isActive(boolean isActive)
- {
- this.isActive = isActive;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/SSHStatusEnum.java b/src/net/java/sip/communicator/impl/protocol/ssh/SSHStatusEnum.java
deleted file mode 100644
index 0877399..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/SSHStatusEnum.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * An implementation of <tt>PresenceStatus</tt> that enumerates all states that
- * a SSH contact can fall into.
- *
- * @author Shobhit Jindal
- */
-public class SSHStatusEnum
- extends PresenceStatus
-{
-
- /**
- * Indicates an Offline status or status with 0 connectivity.
- */
- public static final SSHStatusEnum OFFLINE
- = new SSHStatusEnum(
- 0,
- "Offline",
- ProtocolIconSSHImpl
- .getImageInBytes("service.protocol.ssh.OFFLINE_STATUS_ICON"));
-
- /**
- * The Not Available status. Indicates that the user has connectivity
- * but might not be able to immediately act (i.e. even less immediately
- * than when in an Away status ;-P ) upon initiation of communication.
- *
- */
- public static final SSHStatusEnum NOT_AVAILABLE
- = new SSHStatusEnum(
- 35,
- "Not Available",
- ProtocolIconSSHImpl
- .getImageInBytes("service.protocol.ssh.NA_STATUS_ICON"));
-
- /**
- * The Connecting status. Indicate that the user is connecting to remote
- * server
- */
- public static final SSHStatusEnum CONNECTING
- = new SSHStatusEnum(
- 55,
- "Connecting",
- ProtocolIconSSHImpl
- .getImageInBytes("service.protocol.ssh.CONNECTING_ICON"));
-
- /**
- * The Online status. Indicate that the user is able and willing to
- * communicate.
- */
- public static final SSHStatusEnum ONLINE
- = new SSHStatusEnum(
- 65,
- "Online",
- ProtocolIconSSHImpl
- .getImageInBytes("service.protocol.ssh.SSH_16x16"));
-
-
- /**
- * The Connecting status. Indicate that the user is connecting to remote
- * server
- */
- public static final SSHStatusEnum CONNECTED
- = new SSHStatusEnum(
- 70,
- "Connecting",
- ProtocolIconSSHImpl
- .getImageInBytes("service.protocol.ssh.CONNECTED_ICON"));
-
- /**
- * The File Transfer status. Indicate that the user is transfering a file
- * to/from a remote server
- */
- public static final SSHStatusEnum FILE_TRANSFER
- = new SSHStatusEnum(
- 75,
- "Transfering File",
- ProtocolIconSSHImpl
- .getImageInBytes("service.protocol.ssh.FILE_TRANSFER_ICON"));
-
- /**
- * Initialize the list of supported status states.
- */
- private static List<PresenceStatus> supportedStatusSet = new LinkedList<PresenceStatus>();
- static
- {
- supportedStatusSet.add(OFFLINE);
-// supportedStatusSet.add(NOT_AVAILABLE);
- supportedStatusSet.add(ONLINE);
-// supportedStatusSet.add(CONNECTING);
- }
-
- /**
- * Creates an instance of <tt>SSHPresneceStatus</tt> with the
- * specified parameters.
- * @param status the connectivity level of the new presence status instance
- * @param statusName the name of the presence status.
- * @param statusIcon the icon associated with this status
- */
- private SSHStatusEnum(int status,
- String statusName,
- byte[] statusIcon)
- {
- super(status, statusName, statusIcon);
- }
-
- /**
- * Returns an iterator over all status instances supproted by the ssh
- * provider.
- * @return an <tt>Iterator</tt> over all status instances supported by the
- * ssh provider.
- */
- static Iterator<PresenceStatus> supportedStatusSet()
- {
- return supportedStatusSet.iterator();
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/SSHUserInfo.java b/src/net/java/sip/communicator/impl/protocol/ssh/SSHUserInfo.java
deleted file mode 100644
index 082b05f..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/SSHUserInfo.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.java.sip.communicator.impl.protocol.ssh;
-
-import javax.swing.*;
-
-import com.jcraft.jsch.*;
-
-/**
- * SSHUserInfo passes authentication details to JSch SSH Stack
- *
- * @author Shobhit Jindal
- */
-class SSHUserInfo
- implements UserInfo,
- UIKeyboardInteractive
-{
- /**
- * The Contact of the remote machine
- */
- private ContactSSH sshContact;
-
- /**
- * Identifier for failure of authentication
- * more explanation below in promptPassword function
- */
- private boolean failedOnce = false;
-
- /**
- * Password field for requesting auth details from user
- */
- JTextField passwordField=new JPasswordField(20);
-
- /**
- * Creates a UserInfo instance
- *
- * @param sshContact the contact concerned
- */
- SSHUserInfo(ContactSSH sshContact)
- {
- this.sshContact = sshContact;
- }
-
- /**
- * Returns the password of account associated with this contact
- *
- * @return the password of account associated with this contact
- */
- public String getPassword()
- {
- return sshContact.getPassword();
- }
-
- /**
- * Prompt for accepting the cipher information of the remote server
- *
- * @param str the string to display
- *
- * @return the user's answer
- */
- public boolean promptYesNo(String str)
- {
- Object[] options={ "yes", "no" };
- int foo=JOptionPane.showOptionDialog(null,
- str,
- "Warning",
- JOptionPane.DEFAULT_OPTION,
- JOptionPane.QUESTION_MESSAGE,
- null, options, options[0]);
- return foo==0;
- }
-
- /**
- * Passphrase authentication presently not implemented
- *
- * @return null
- */
- public String getPassphrase()
- { return null; }
-
- /**
- * Passphrase authentication presently not implemented
- *
- * @return true
- */
- public boolean promptPassphrase(String message)
- { return true; }
-
- /**
- * Asks user to re-enter password information in case of an auth failure
- *
- * @param message the message to display
- *
- * @return the user's answer
- */
- public boolean promptPassword(String message)
- {
- /**
- * Auth always fails for the first time for Redhat based machines.
- * Trying again with the same password
- */
- if(!failedOnce)
- {
- failedOnce = true;
- return true;
- }
-
- Object[] ob={passwordField};
- int result=JOptionPane.showConfirmDialog(null, ob, "Auth Failed: "
- + message,
- JOptionPane.OK_CANCEL_OPTION);
-
- if(result==JOptionPane.OK_OPTION)
- {
- sshContact.setPassword(passwordField.getText());
- return true;
- }
-
- return false;
- }
-
- /**
- * Shows a message from server
- *
- * @param message The message to display
- */
- public void showMessage(String message)
- {
- JOptionPane.showMessageDialog(null, message);
- }
-
- /**
- * Keyboard Interactive Auth - not implemented
- */
- public String[] promptKeyboardInteractive(
- String destination,
- String name,
- String instruction,
- String[] prompt,
- boolean[] echo)
- {
- String response[] = new String[prompt.length];
- response[0] = sshContact.getPassword();
- return response;
- }
-
-
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/ssh.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/ssh/ssh.provider.manifest.mf
deleted file mode 100644
index eb9472f..0000000
--- a/src/net/java/sip/communicator/impl/protocol/ssh/ssh.provider.manifest.mf
+++ /dev/null
@@ -1,20 +0,0 @@
-Bundle-Activator: net.java.sip.communicator.impl.protocol.ssh.SSHActivator
-Bundle-Name: SSH Protocol Provider
-Bundle-Description: A bundle providing support for the SSH protocol.
-Bundle-Vendor: jitsi.org
-Bundle-Version: 0.0.1
-Bundle-SymbolicName: net.java.sip.communicator.protocol.ssh
-Import-Package: org.osgi.framework,
- javax.crypto,
- javax.crypto.interfaces,
- javax.crypto.spec,
- javax.swing,
- javax.swing.border,
- javax.swing.text,
- org.jitsi.service.configuration,
- net.java.sip.communicator.service.gui,
- net.java.sip.communicator.service.protocol,
- net.java.sip.communicator.service.protocol.event,
- org.jitsi.service.resources, net.java.sip.communicator.service.resources,
- net.java.sip.communicator.util,
- net.java.sip.communicator.plugin.desktoputil
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/AbstractContactGroupYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/AbstractContactGroupYahooImpl.java
deleted file mode 100644
index 0514c16..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/AbstractContactGroupYahooImpl.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * The Yahoo implementation of the service.protocol.ContactGroup interface. There
- * are two types of groups possible here. <tt>RootContactGroupYahooImpl</tt>
- * which is the root node of the ContactList itself and
- * <tt>ContactGroupYahooImpl</tt> which represents standard groups. The
- * reason for having those 2 is that generally, Yahoo groups may not contain
- * subgroups. A contact list on the other hand may not directly contain buddies.
- *
- *
- * The reason for having an abstract class is only - being able to esily
- * recognize our own (Yahoo) contacts.
- * @author Damian Minkov
- */
-public abstract class AbstractContactGroupYahooImpl
- implements ContactGroup
-{
-
-
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomInvitationYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomInvitationYahooImpl.java
deleted file mode 100644
index e849f6c..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomInvitationYahooImpl.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * The Yahoo implementation of the <tt>AdHocChatRoomInvitation</tt> interface.
- *
- * @author Rupert Burchardi
- * @author Valentin Martinet
- */
-public class AdHocChatRoomInvitationYahooImpl
- implements AdHocChatRoomInvitation
-{
- /**
- * Corresponding chat room instance.
- */
- private AdHocChatRoom chatRoom;
- /**
- * The name of the inviter
- */
- private String inviter;
-
- /**
- * The invitation reason.
- */
- private String reason;
-
-
- /**
- * Creates an instance of the <tt>ChatRoomInvitationMsnImpl</tt> by
- * specifying the targetChatRoom, the inviter, the reason.
- *
- * @param targetChatRoom The <tt>AdHocChatRoom</tt> for which the invitation
- * is
- * @param inviter The <tt>Contact</tt>, which sent the invitation
- * @param reason The Reason for the invitation
- */
- public AdHocChatRoomInvitationYahooImpl( AdHocChatRoom targetChatRoom,
- String inviter,
- String reason)
- {
- this.chatRoom = targetChatRoom;
- this.inviter = inviter;
- this.reason = reason;
- }
-
- /**
- * Returns the corresponding chat room.
- * @return The ad-hoc chat room
- */
- public AdHocChatRoom getTargetAdHocChatRoom()
- {
- return chatRoom;
- }
-
- /**
- * Returns the corresponding inviter.
- * @return The name of the inviter
- */
- public String getInviter()
- {
- return inviter;
- }
-
- /**
- * Returns the invitation reason.
- * @return the invitation reason
- */
- public String getReason()
- {
- return reason;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomYahooImpl.java
deleted file mode 100644
index 2775f6f..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomYahooImpl.java
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.io.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-import ymsg.network.*;
-
-/**
- * Represents a Yahoo ad-hoc chat room, where multiple chat users could
- * communicate in a many-to-many fashion.
- *
- * @author Rupert Burchardi
- * @author Valentin Martinet
- */
-public class AdHocChatRoomYahooImpl
- implements AdHocChatRoom
-{
- private static final Logger logger = Logger
- .getLogger(AdHocChatRoomYahooImpl.class);
-
- /**
- * Listeners that will be notified of changes in member status in the room
- * such as member joined, left or being kicked or dropped.
- */
- private Vector<AdHocChatRoomParticipantPresenceListener> memberListeners
- = new Vector<AdHocChatRoomParticipantPresenceListener>();
-
- /**
- * Listeners that will be notified every time a new message is received on
- * this ad-hoc chat room.
- */
- private Vector<AdHocChatRoomMessageListener> messageListeners
- = new Vector<AdHocChatRoomMessageListener>();
-
- /**
- * The protocol provider that created us
- */
- private ProtocolProviderServiceYahooImpl provider = null;
-
- /**
- * The operation set that created us.
- */
- private OperationSetAdHocMultiUserChatYahooImpl opSetMuc = null;
-
- /**
- * The list of participants of this chat room.
- */
- private Hashtable<String, Contact> participants
- = new Hashtable<String, Contact>();
-
- /**
- * The nickname of this chat room local user participant.
- */
- private String nickname;
-
- /**
- * The yahoo conference model of this ad-hoc chat room, its the
- * representation of an ad-hoc chat room in the lib for this protocol.
- */
- private YahooConference yahooConference = null;
-
- /**
- * Creates an instance of a chat room that has been.
- *
- * @param multiUserChat
- * MultiUserChat
- * @param provider
- * a reference to the currently valid jabber protocol provider.
- */
- public AdHocChatRoomYahooImpl( YahooConference multiUserChat,
- ProtocolProviderServiceYahooImpl provider)
- {
- this.yahooConference = multiUserChat;
- this.provider = provider;
- this.opSetMuc = (OperationSetAdHocMultiUserChatYahooImpl) provider
- .getOperationSet(OperationSetAdHocMultiUserChat.class);
- }
-
- /**
- * Registers <tt>listener</tt> so that it would receive events every time a
- * new message is received on this chat room.
- *
- * @param listener A <tt>MessageListener</tt> that would be notified every
- * time a new message is received on this chat room.
- */
- public void addMessageListener(AdHocChatRoomMessageListener listener)
- {
- synchronized (messageListeners)
- {
- if (!messageListeners.contains(listener))
- messageListeners.add(listener);
- }
- }
-
- /**
- * Removes <tt>listener</tt> so that it won't receive any further message
- * events from this room.
- *
- * @param listener The <tt>MessageListener</tt> to remove from this room
- */
- public void removeMessageListener(AdHocChatRoomMessageListener listener)
- {
- synchronized (messageListeners)
- {
- messageListeners.remove(listener);
- }
- }
-
- /**
- * Adds a listener that will be notified of changes in our status in the
- * room.
- *
- * @param listener A participant status listener.
- */
- public void addParticipantPresenceListener(
- AdHocChatRoomParticipantPresenceListener listener)
- {
- synchronized (memberListeners)
- {
- if (!memberListeners.contains(listener))
- memberListeners.add(listener);
- }
- }
-
- /**
- * Removes a listener that was being notified of changes in the status of
- * other chat room participants.
- *
- * @param listener A participant status listener.
- */
- public void removeParticipantPresenceListener(
- AdHocChatRoomParticipantPresenceListener listener)
- {
- synchronized (memberListeners)
- {
- memberListeners.remove(listener);
- }
- }
-
- /**
- * Create a Message instance for sending a simple text messages with default
- * (text/plain) content type and encoding.
- *
- * @param messageText
- * the string content of the message.
- * @return Message the newly created message
- */
- public Message createMessage(String messageText)
- {
- Message msg = new MessageYahooImpl(messageText,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING, null);
- return msg;
- }
-
- /**
- * Returns a <tt>List</tt> of <tt>Contact</tt>s corresponding to all members
- * currently participating in this room.
- *
- * @return a <tt>List</tt> of <tt>Contact</tt> corresponding to all room
- * members.
- */
- public List<Contact> getParticipants()
- {
- return new LinkedList<Contact>(participants.values());
- }
-
- /**
- * Updates the member list of the chat room.
- *
- */
- public void updateParticipantsList()
- {
- Iterator<?> it = yahooConference.getMembers().iterator();
-
- while (it.hasNext())
- {
- YahooUser user = (YahooUser) it.next();
- Contact contact;
- OperationSetPersistentPresenceYahooImpl presenceOpSet
- = (OperationSetPersistentPresenceYahooImpl) this
- .getParentProvider().getOperationSet(
- OperationSetPersistentPresence.class);
-
- contact = presenceOpSet.findContactByID(user.getId());
-
- if(!participants.containsKey(contact.getDisplayName()))
- {
- participants.put(contact.getDisplayName(), contact);
- }
- }
- }
-
- /**
- * Returns the identifier of this <tt>AdHocChatRoom</tt>.
- *
- * @return a <tt>String</tt> containing the identifier of this
- * <tt>AdHocChatRoom</tt>.
- */
- public String getIdentifier()
- {
- return yahooConference.getName();
- }
-
- /**
- * Returns the number of participants that are currently in this ad-hoc chat
- * room.
- *
- * @return the number of <tt>Contact</tt>s, currently participating in
- * this ad-hoc room.
- */
- public int getParticipantsCount()
- {
- return yahooConference.getMembers().size();
- }
-
- /**
- * Returns the name of this <tt>AdHocChatRoom</tt>.
- *
- * @return a <tt>String</tt> containing the name of this
- * <tt>AdHocChatRoom</tt>.
- */
- public String getName()
- {
- return yahooConference.getName();
- }
-
- /**
- * Returns the protocol provider service that created us.
- *
- * @return the protocol provider service that created us.
- */
- public ProtocolProviderService getParentProvider()
- {
- return provider;
- }
-
- /**
- * Returns the local user's nickname in the context of this chat room or
- * <tt>null</tt> if not currently joined.
- *
- * @return the nickname currently being used by the local user in the
- * context of the local ad-hoc chat room.
- */
-
- public String getUserNickname()
- {
- if(nickname == null)
- nickname = provider.getYahooSession().getLoginIdentity().getId();
-
- return nickname;
- }
-
- /**
- * Invites another user to this room. If we're not joined nothing will
- * happen.
- *
- * @param userAddress The identifier of the contact (email address or yahoo
- * id)
- * @param reason The invite reason, which is send to the invitee.
- */
- public void invite(String userAddress, String reason)
- {
- try
- {
- provider.getYahooSession().extendConference(yahooConference,
- userAddress, reason);
- }
- catch (IOException ioe)
- {
- if (logger.isDebugEnabled())
- logger.debug("Failed to invite the user: " + userAddress
- + " Error: " + ioe);
- }
- }
-
- /**
- * Indicates whether or not this chat room is corresponding to a server
- * channel. Note: Returns always <code>false</code>.
- *
- * @return Always <code>false</code> since system chat room can't be joined
- * with current yahoo library.
- */
- public boolean isSystem()
- {
- return false;
- }
-
- /**
- * Joins this chat room with the nickname of the local user so that the user
- * would start receiving events and messages for it.
- *
- * @throws OperationFailedException with the corresponding code if an error
- * occurs while joining the room.
- */
- public void join() throws OperationFailedException
- {
- this.nickname = provider.getAccountID().getUserID();
- try
- {
- provider.getYahooSession().acceptConferenceInvite(yahooConference);
-
- // We don't specify a reason.
- opSetMuc.fireLocalUserPresenceEvent(this,
- LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOINED,
- null);
- }
- catch (Exception e)
- {
- if (logger.isDebugEnabled())
- logger.debug("Couldn't join the chat room: "
- + yahooConference.getName() + e);
- }
- }
-
- /**
- * Leave this chat room. Once this method is called, the user won't be
- * listed as a member of the chat room any more and no further chat events
- * will be delivered. Depending on the underlying protocol and
- * implementation leave() might cause the room to be destroyed if it has
- * been created by the local user.
- */
- public void leave()
- {
- try
- {
- provider.getYahooSession().leaveConference(yahooConference);
-
- Iterator< Map.Entry<String, Contact>> membersSet
- = participants.entrySet().iterator();
-
- while (membersSet.hasNext())
- {
- Map.Entry<String, Contact> memberEntry = membersSet.next();
- Contact participant = memberEntry.getValue();
-
- fireParticipantPresenceEvent(participant,
- AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT,
- "Local user has left the chat room.");
- }
- }
- catch (IOException ioe)
- {
- if (logger.isDebugEnabled())
- logger.debug("Failed to leave the chat room: "
- + yahooConference.getName() + " Error: " + ioe);
- }
-
- participants.clear();
- }
-
- /**
- * Sends the <tt>message</tt> to the destination indicated by the
- * <tt>to</tt> contact.
- *
- * @param message The <tt>Message</tt> to send.
- * @throws OperationFailedException if the underlying stack is not
- * registered or initialized or if the chat room is not joined.
- */
- public void sendMessage(Message message) throws OperationFailedException
- {
- assertConnected();
-
- try
- {
- provider.getYahooSession().sendConferenceMessage(yahooConference,
- message.getContent());
-
- AdHocChatRoomMessageDeliveredEvent msgDeliveredEvt
- = new AdHocChatRoomMessageDeliveredEvent(
- this,
- new Date(),
- message,
- ChatRoomMessageDeliveredEvent.CONVERSATION_MESSAGE_DELIVERED);
-
- fireMessageEvent(msgDeliveredEvt);
- }
- catch (Exception e)
- {
- if (logger.isDebugEnabled())
- logger.debug("Failed to send a conference message.");
- }
- }
-
- /**
- * Notifies all interested listeners that a
- * <tt>AdHocChatRoomMessageDeliveredEvent</tt>,
- * <tt>AdHocChatRoomMessageReceivedEvent</tt> or a
- * <tt>AdHocChatRoomMessageDeliveryFailedEvent</tt> has been fired.
- * @param evt The specific event
- */
- public void fireMessageEvent(EventObject evt)
- {
- Iterator<AdHocChatRoomMessageListener> listeners = null;
- synchronized (messageListeners)
- {
- listeners = new ArrayList<AdHocChatRoomMessageListener>(
- messageListeners).iterator();
- }
-
- while (listeners.hasNext())
- {
- AdHocChatRoomMessageListener listener = listeners.next();
-
- if (evt instanceof AdHocChatRoomMessageDeliveredEvent)
- {
- listener.messageDelivered(
- (AdHocChatRoomMessageDeliveredEvent) evt);
- }
- else if (evt instanceof AdHocChatRoomMessageReceivedEvent)
- {
- listener.messageReceived(
- (AdHocChatRoomMessageReceivedEvent) evt);
- }
- else if (evt instanceof AdHocChatRoomMessageDeliveryFailedEvent)
- {
- listener.messageDeliveryFailed(
- (AdHocChatRoomMessageDeliveryFailedEvent) evt);
- }
- }
- }
-
- /**
- * Creates the corresponding AdHocChatRoomParticipantPresenceChangeEvent and
- * notifies all <tt>AdHocChatRoomParticipantPresenceListener</tt>s that a
- * Contact has joined or left this <tt>AdHocChatRoom</tt>.
- *
- * @param participant the <tt>Contact</tt> that this
- * @param eventID the identifier of the event
- * @param eventReason the reason of the event
- */
- public void fireParticipantPresenceEvent(Contact participant, String eventID,
- String eventReason)
- {
- AdHocChatRoomParticipantPresenceChangeEvent evt
- = new AdHocChatRoomParticipantPresenceChangeEvent(this,
- participant,
- eventID,
- eventReason);
-
- if (logger.isTraceEnabled())
- logger.trace("Will dispatch the following ChatRoom event: " + evt);
-
- Iterator<AdHocChatRoomParticipantPresenceListener> listeners = null;
- synchronized (memberListeners)
- {
- listeners = new ArrayList<AdHocChatRoomParticipantPresenceListener>
- (memberListeners).iterator();
- }
-
- while (listeners.hasNext())
- {
- AdHocChatRoomParticipantPresenceListener listener = listeners.next();
-
- listener.participantPresenceChanged(evt);
- }
- }
-
- /**
- * Finds the participant of this ad-hoc chat room corresponding to the
- * given address.
- *
- * @param address the address to search for.
- * @return the participant of this chat room corresponding to the given
- * nick name.
- */
- public Contact findParticipantForAddress(String address)
- {
- Iterator<Contact> participantsIter
- = this.participants.values().iterator();
-
- while (participantsIter.hasNext())
- {
- Contact contact = participantsIter.next();
-
- if (contact.getAddress().equals(address))
- {
- return contact;
- }
- }
-
- return null;
- }
-
- /**
- * Removes the specified ad-hoc chat room participant from the participants
- * list of this ad-hoc chat room.
- * @param participant The member, who should be removed from the ad-hoc chat room
- * participants list.
- */
- public void removeChatRoomParticipant(Contact participant)
- {
- if(participant == null)
- return;
-
- participants.remove(participant.getDisplayName());
-
- fireParticipantPresenceEvent(participant,
- AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT, null);
- }
-
- /**
- * Adds a participant to the ad-hoc chat room participant list.
- * @param participant The participant, who should be added to the ad-hoc
- * chat room participant list.
- */
- public void addChatRoomParticipant(Contact participant)
- {
- if (participant == null)
- return;
-
- if (!participants.containsKey(participant.getDisplayName()))
- {
- participants.put(participant.getDisplayName(), participant);
-
- fireParticipantPresenceEvent(participant,
- AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_JOINED,
- null);
- }
- }
-
- /**
- * Returns the yahoo conference model of this chat room.
- * @return The yahoo conference.
- */
- public YahooConference getYahooConference()
- {
- return yahooConference;
- }
-
- /**
- * Utility method throwing an exception if the stack is not properly
- * initialized.
- * @throws java.lang.IllegalStateException if the underlying stack is
- * not registered and initialized.
- */
- private void assertConnected() throws IllegalStateException
- {
- if (provider == null)
- throw new IllegalStateException(
- "The provider must be non-null and signed on the "
- +"service before being able to communicate.");
- if (!provider.isRegistered())
- throw new IllegalStateException(
- "The provider must be signed on the service before "
- +"being able to communicate.");
- }
-
- /**
- * Determines whether this chat room should be stored in the configuration
- * file or not. If the chat room is persistent it still will be shown after a
- * restart in the chat room list. A non-persistent chat room will be only in
- * the chat room list until the the program is running.
- *
- * @return true if this chat room is persistent, false otherwise
- */
- public boolean isPersistent()
- {
- return false;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/ContactGroupYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/ContactGroupYahooImpl.java
deleted file mode 100644
index 1f73aac..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/ContactGroupYahooImpl.java
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import ymsg.network.*;
-
-/**
- * The Yahoo implementation of the ContactGroup interface. Intances of this class
- * (contrary to <tt>RootContactGroupYahooImpl</tt>) may only contain buddies
- * and cannot have sub groups. Note that instances of this class only use the
- * corresponding smack source group for reading their names and only
- * initially fill their <tt>buddies</tt> <tt>java.util.List</tt> with
- * the ContactYahooImpl objects corresponding to those contained in the source
- * group at the moment it is being created. They would, however, never try to
- * sync or update their contents ulteriorly. This would have to be done through
- * the addContact()/removeContact() methods.
- * The content of buddies is created on creating of the group and when the smack
- * source group is changed.
- *
- * @author Damian Minkov
- * @author Emil Ivov
- */
-public class ContactGroupYahooImpl
- extends AbstractContactGroupYahooImpl
-{
- private final Map<String, Contact> buddies
- = new Hashtable<String, Contact>();
-
- private boolean isResolved = false;
-
- /**
- * The Yahoo Group corresponding to this contact group.
- */
- private YahooGroup yahooGroup = null;
-
- /**
- * a list that would always remain empty. We only use it so that we're able
- * to extract empty iterators
- */
- private final List<ContactGroup> dummyGroupsList
- = new LinkedList<ContactGroup>();
-
- private String tempId = null;
-
- private final ServerStoredContactListYahooImpl ssclCallback;
-
- /**
- * Creates an Yahoo group using the specified <tt>YahooGroup</tt> as
- * a source. The newly created group will always return the name of the
- * underlying RosterGroup and would thus automatically adapt to changes.
- * It would, however, not receive or try to poll for modifications of the
- * buddies it contains and would therefore have to be updated manually by
- * ServerStoredContactListImpl update will only be done if source group
- * is changed.
-
- * @param yahooGroup the Yahoo Group correspoinding to the group
- * @param groupMembers the group members that we should add to the group.
- * @param ssclCallback a callback to the server stored contact list
- * we're creating.
- * @param isResolved a boolean indicating whether or not the group has been
- * resolved against the server.
- */
- ContactGroupYahooImpl(
- YahooGroup yahooGroup,
- Vector<YahooUser> groupMembers,
- ServerStoredContactListYahooImpl ssclCallback,
- boolean isResolved)
- {
- this.yahooGroup = yahooGroup;
- this.isResolved = isResolved;
- this.ssclCallback = ssclCallback;
-
- for (YahooUser yahooUser : groupMembers)
- {
- //only add the contact if it doesn't already exist in some other
- //group. this would be necessary if Yahoo! one day start allowing
- //the same contact in more than one group, which is not quite
- //unlikely since most of the other protocols do it.
- if(ssclCallback.findContactByYahooUser(yahooUser) != null)
- {
- continue;
- }
-
-
- addContact(
- new ContactYahooImpl(yahooUser,ssclCallback, true, true));
- }
- }
-
- ContactGroupYahooImpl( String id,
- ServerStoredContactListYahooImpl ssclCallback)
- {
- this.tempId = id;
- this.isResolved = false;
- this.ssclCallback = ssclCallback;
- }
-
-
- /**
- * Returns the number of <tt>Contact</tt> members of this
- * <tt>ContactGroup</tt>
- *
- * @return an int indicating the number of <tt>Contact</tt>s,
- * members of this <tt>ContactGroup</tt>.
- */
- public int countContacts()
- {
- return buddies.size();
- }
-
- /**
- * Returns a reference to the root group which in Yahoo is the parent of
- * any other group since the protocol does not support subgroups.
- * @return a reference to the root group.
- */
- public ContactGroup getParentContactGroup()
- {
- return ssclCallback.getRootGroup();
- }
-
- /**
- * Adds the specified contact to the end of this group.
- * @param contact the new contact to add to this group
- */
- void addContact(ContactYahooImpl contact)
- {
- buddies.put(contact.getAddress().toLowerCase(), contact);
- }
-
-
- /**
- * Removes the specified contact from this contact group
- * @param contact the contact to remove.
- */
- void removeContact(ContactYahooImpl contact)
- {
- buddies.remove(contact.getAddress().toLowerCase());
- }
-
- /**
- * Returns an Iterator over all contacts, member of this
- * <tt>ContactGroup</tt>.
- *
- * @return a java.util.Iterator over all contacts inside this
- * <tt>ContactGroup</tt>. In case the group doesn't contain any
- * memebers it will return an empty iterator.
- */
- public Iterator<Contact> contacts()
- {
- return buddies.values().iterator();
- }
-
- /**
- * Returns the <tt>Contact</tt> with the specified address or
- * identifier.
- * @param id the addres or identifier of the <tt>Contact</tt> we are
- * looking for.
- * @return the <tt>Contact</tt> with the specified id or address.
- */
- public Contact getContact(String id)
- {
- return this.findContact(id);
- }
-
- /**
- * Returns the name of this group.
- * @return a String containing the name of this group.
- */
- public String getGroupName()
- {
- if(isResolved)
- return ServerStoredContactListYahooImpl
- .replaceIllegalChars(yahooGroup.getName());
- else
- return tempId;
- }
-
- /**
- * Determines whether the group may contain subgroups or not.
- *
- * @return always false since only the root group may contain subgroups.
- */
- public boolean canContainSubgroups()
- {
- return false;
- }
-
- /**
- * Returns the subgroup with the specified index (i.e. always null since
- * this group may not contain subgroups).
- *
- * @param index the index of the <tt>ContactGroup</tt> to retrieve.
- * @return always null
- */
- public ContactGroup getGroup(int index)
- {
- return null;
- }
-
- /**
- * Returns the subgroup with the specified name.
- * @param groupName the name of the <tt>ContactGroup</tt> to retrieve.
- * @return the <tt>ContactGroup</tt> with the specified index.
- */
- public ContactGroup getGroup(String groupName)
- {
- return null;
- }
-
- /**
- * Returns an empty iterator. Subgroups may only be present in the root
- * group.
- *
- * @return an empty iterator
- */
- public Iterator<ContactGroup> subgroups()
- {
- return dummyGroupsList.iterator();
- }
-
- /**
- * Returns the number of subgroups contained by this group, which is
- * always 0 since sub groups in the protocol may only be contained
- * by the root group - <tt>RootContactGroupImpl</tt>.
- * @return a 0 int.
- */
- public int countSubgroups()
- {
- return 0;
- }
-
- /**
- * Returns a hash code value for the object, which is actually the hashcode
- * value of the groupname.
- *
- * @return a hash code value for this ContactGroup.
- */
- @Override
- public int hashCode()
- {
- return getGroupName().hashCode();
- }
-
- /**
- * Indicates whether some other object is "equal to" this group.
- *
- * @param obj the reference object with which to compare.
- * @return <tt>true</tt> if this object is the same as the obj
- * argument; <tt>false</tt> otherwise.
- */
- @Override
- public boolean equals(Object obj)
- {
- if( obj == this )
- return true;
-
- if (obj == null
- || !(obj instanceof ContactGroupYahooImpl) )
- return false;
-
- if(!((ContactGroup)obj).getGroupName().equals(getGroupName()))
- return false;
-
- if(getProtocolProvider() != ((ContactGroup)obj).getProtocolProvider())
- return false;
-
- //since Yahoo does not support having two groups with the same name
- // at this point we could bravely state that the groups are the same
- // and not bother to compare buddies. (gotta check that though)
- return true;
- }
-
- /**
- * Returns the protocol provider that this group belongs to.
- * @return a reference to the ProtocolProviderService instance that this
- * ContactGroup belongs to.
- */
- public ProtocolProviderService getProtocolProvider()
- {
- return this.ssclCallback.getParentProvider();
- }
-
- /**
- * Returns a string representation of this group, in the form
- * YahooGroup.GroupName[size]{ buddy1.toString(), buddy2.toString(), ...}.
- * @return a String representation of the object.
- */
- @Override
- public String toString()
- {
- StringBuffer buff = new StringBuffer("YahooGroup.");
- buff.append(getGroupName());
- buff.append(", childContacts="+countContacts()+":[");
-
- Iterator<Contact> contacts = contacts();
- while (contacts.hasNext())
- {
- Contact contact = contacts.next();
- buff.append(contact.toString());
- if(contacts.hasNext())
- buff.append(", ");
- }
- return buff.append("]").toString();
- }
-
- /**
- * Returns the contact encapsulating with the spcieified name or
- * null if no such contact was found.
- *
- * @param id the id for the contact we're looking for.
- * @return the <tt>ContactYahooImpl</tt> corresponding to the specified
- * screnname or null if no such contact existed.
- */
- ContactYahooImpl findContact(String id)
- {
- if(id == null)
- return null;
- return (ContactYahooImpl)buddies.get(id.toLowerCase());
- }
-
- /**
- * Determines whether or not this contact group is being stored by the
- * server. Non persistent contact groups exist for the sole purpose of
- * containing non persistent contacts.
- * @return true if the contact group is persistent and false otherwise.
- */
- public boolean isPersistent()
- {
- return true;
- }
-
- /**
- * Returns null as no persistent data is required and the contact address is
- * sufficient for restoring the contact.
- * <p>
- * @return null as no such data is needed.
- */
- public String getPersistentData()
- {
- return null;
- }
-
- /**
- * Determines whether or not this contact group has been resolved against
- * the server. Unresolved group are used when initially loading a contact
- * list that has been stored in a local file until the presence operation
- * set has managed to retrieve all the contact list from the server and has
- * properly mapped contacts and groups to their corresponding on-line
- * buddies.
- * @return true if the contact has been resolved (mapped against a buddy)
- * and false otherwise.
- */
- public boolean isResolved()
- {
- return isResolved;
- }
-
- /**
- * Resolve this contact group against the specified group
- * @param yahooGroup the server stored group
- */
- @SuppressWarnings("unchecked") //jymsg legacy code
- void setResolved(YahooGroup yahooGroup)
- {
- if(isResolved)
- return;
-
- this.isResolved = true;
-
- this.yahooGroup = yahooGroup;
-
- Vector<YahooUser> contacts = yahooGroup.getMembers();
- for (YahooUser item : contacts)
- {
- ContactYahooImpl contact =
- ssclCallback.findContactById(item.getId());
- if(contact != null)
- {
- contact.setResolved(item);
-
- ssclCallback.fireContactResolved(this, contact);
- }
- else
- {
- ContactYahooImpl newContact =
- new ContactYahooImpl(item, ssclCallback, true, true);
- addContact(newContact);
-
- ssclCallback.fireContactAdded(this, newContact);
- }
- }
- }
-
- /**
- * Returns a <tt>String</tt> that uniquely represnets the group. In this we
- * use the name of the group as an identifier. This may cause problems
- * though, in clase the name is changed by some other application between
- * consecutive runs of the sip-communicator.
- *
- * @return a String representing this group in a unique and persistent
- * way.
- */
- public String getUID()
- {
- return getGroupName();
- }
-
- /**
- * The source group we are encapsulating
- * @return YahooGroup
- */
- YahooGroup getSourceGroup()
- {
- return yahooGroup;
- }
-
- /**
- * Change the source group
- * change the buddies
- *
- * @param newGroup YahooGroup
- */
- void setSourceGroup(YahooGroup newGroup)
- {
- this.yahooGroup = newGroup;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/ContactYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/ContactYahooImpl.java
deleted file mode 100644
index b23ee3d..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/ContactYahooImpl.java
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.yahooconstants.*;
-import net.java.sip.communicator.util.*;
-import ymsg.network.*;
-
-/**
- * The Yahoo implementation of the service.protocol.Contact interface.
- * @author Damian Minkov
- * @author Emil Ivov
- */
-public class ContactYahooImpl
- extends AbstractContact
-{
- private static final Logger logger =
- Logger.getLogger(ContactYahooImpl.class);
-
- private YahooUser contact = null;
- private byte[] image = null;
- private PresenceStatus status = YahooStatusEnum.OFFLINE;
- private ServerStoredContactListYahooImpl ssclCallback = null;
- private boolean isPersistent = false;
- private boolean isResolved = false;
- private boolean isVolatile = false;
-
- private String yahooID = null;
- private String id = null;
-
- private String statusMessage = null;
-
- /**
- * Creates an YahooContactImpl with custom yahooID
- * @param yahooID sets the contact Id if its different from the YahooUser id
- * @param contact the contact object that we will be encapsulating.
- * @param ssclCallback a reference to the ServerStoredContactListImpl
- * instance that created us.
- * @param isPersistent determines whether this contact is persistent or not.
- * @param isResolved specifies whether the contact has been resolved against
- * the server contact list
- */
- ContactYahooImpl(
- String yahooID,
- YahooUser contact,
- ServerStoredContactListYahooImpl ssclCallback,
- boolean isPersistent,
- boolean isResolved)
- {
- this.yahooID = yahooID;
-
- this.contact = contact;
- this.ssclCallback = ssclCallback;
- this.isPersistent = isPersistent;
- this.isResolved = isResolved;
-
- if(contact != null)
- id = contact.getId();
- else if(yahooID != null)
- id = YahooSession.getYahooUserID(yahooID);
- }
-
- /**
- * Creates an YahooContactImpl
- * @param contact the contact object that we will be encapsulating.
- * @param ssclCallback a reference to the ServerStoredContactListImpl
- * instance that created us.
- * @param isPersistent determines whether this contact is persistent or not.
- * @param isResolved specifies whether the contact has been resolved against
- * the server contact list
- */
- ContactYahooImpl(
- YahooUser contact,
- ServerStoredContactListYahooImpl ssclCallback,
- boolean isPersistent,
- boolean isResolved)
- {
- this(null, contact, ssclCallback, isPersistent, isResolved);
- }
-
- /**
- * Creates volatile or unresolved contact
- */
- ContactYahooImpl(
- String id,
- ServerStoredContactListYahooImpl ssclCallback,
- boolean isResolved,
- boolean isPersistent,
- boolean isVolatile)
- {
- this.yahooID = id;
- this.ssclCallback = ssclCallback;
- this.isPersistent = isPersistent;
- this.isResolved = isResolved;
- this.isVolatile = isVolatile;
-
- if(id != null)
- this.id = YahooSession.getYahooUserID(yahooID);
- }
-
- /**
- * Returns the Yahoo Userid of this contact
- * @return the Yahoo Userid of this contact
- */
- public String getAddress()
- {
- // if the contact is volatile or with custom id return it
- if(yahooID != null)
- return yahooID;
- // otherwise return the supplied contact id
- else
- return contact.getId();
- }
-
- /**
- * Returns the custom yahooID if set
- */
- String getYahooID()
- {
- return yahooID;
- }
-
- /**
- * Returns the contact Id.
- * If contact missing the yahooID without @yahoo.com part is returned
- */
- String getID()
- {
- return id;
- }
-
- /**
- * Returns whether the contact is volatile.
- */
- boolean isVolatile()
- {
- return isVolatile;
- }
-
- /**
- * Returns an avatar if one is already present or <tt>null</tt> in case it
- * is not in which case it the method also queues the contact for image
- * updates.
- *
- * @return the avatar of this contact or <tt>null</tt> if no avatar is
- * currently available.
- */
- public byte[] getImage()
- {
- return getImage(true);
- }
-
- /**
- * Returns a reference to the image assigned to this contact. If no image
- * is present and the retrieveIfNecessary flag is true, we schedule the
- * image for retrieval from the server.
- *
- * @param retrieveIfNecessary specifies whether the method should queue
- * this contact for avatar update from the server.
- *
- * @return a reference to the image currently stored by this contact.
- */
- public byte[] getImage(boolean retrieveIfNecessary)
- {
- try
- {
- if(retrieveIfNecessary)
- {
- if(ssclCallback.getParentProvider() == null
- || !ssclCallback.getParentProvider().isRegistered())
- {
- throw new IllegalStateException(
- "The provider must be signed on the service before "
- +"being able to communicate.");
- }
-
- YahooSession ses = ssclCallback.getParentProvider().
- getYahooSession();
- if(image == null && ses != null)
- ses.requestPicture(id);
- }
- }
- catch (Exception e)
- {
- if (logger.isInfoEnabled())
- logger.info("Error requesting image!", e);
- }
-
- if(logger.isDebugEnabled())
- logger.debug("returning picture " + image);
-
- return image;
- }
-
- /**
- * Used to set the image of the contact if it is updated
- *
- * @param image a photo/avatar associated with this contact.
- */
- protected void setImage(byte[] image)
- {
- if (logger.isInfoEnabled())
- logger.info("setting image " + image);
-
- this.image = image;
- }
-
- /**
- * Returns a string representation of this contact, containing most of its
- * representative details.
- *
- * @return a string representation of this contact.
- */
- @Override
- public String toString()
- {
- StringBuffer buff = new StringBuffer("YahooContact[ id=");
- buff.append(getAddress()).append("]");
-
- return buff.toString();
- }
-
- /**
- * Sets the status that this contact is currently in. The method is to
- * only be called as a result of a status update received from the server.
- *
- * @param status the YahooStatusEnum that this contact is currently in.
- */
- void updatePresenceStatus(PresenceStatus status)
- {
- this.status = status;
- }
-
- /**
- * Returns the status of the contact as per the last status update we've
- * received for it. Note that this method is not to perform any network
- * operations and will simply return the status received in the last
- * status update message. If you want a reliable way of retrieving someone's
- * status, you should use the <tt>queryContactStatus()</tt> method in
- * <tt>OperationSetPresence</tt>.
- * @return the PresenceStatus that we've received in the last status update
- * pertaining to this contact.
- */
- public PresenceStatus getPresenceStatus()
- {
- return status;
- }
-
- /**
- * Returns a String that could be used by any user interacting modules for
- * referring to this contact. An alias is not necessarily unique but is
- * often more human readable than an address (or id).
- * @return a String that can be used for referring to this contact when
- * interacting with the user.
- */
- public String getDisplayName()
- {
- return getAddress();
- }
-
- /**
- * Returns a reference to the contact group that this contact is currently
- * a child of or null if the underlying protocol does not suppord persistent
- * presence.
- * @return a reference to the contact group that this contact is currently
- * a child of or null if the underlying protocol does not suppord persistent
- * presence.
- */
- public ContactGroup getParentContactGroup()
- {
- return ssclCallback.findContactGroup(this);
- }
-
-
- /**
- * Returns a reference to the protocol provider that created the contact.
- * @return a refererence to an instance of the ProtocolProviderService
- */
- public ProtocolProviderService getProtocolProvider()
- {
- return ssclCallback.getParentProvider();
- }
-
- /**
- * Determines whether or not this contact is being stored by the server.
- * Non persistent contacts are common in the case of simple, non-persistent
- * presence operation sets. They could however also be seen in persistent
- * presence operation sets when for example we have received an event
- * from someone not on our contact list. Non persistent contacts are
- * volatile even when coming from a persistent presence op. set. They would
- * only exist until the application is closed and will not be there next
- * time it is loaded.
- * @return true if the contact is persistent and false otherwise.
- */
- public boolean isPersistent()
- {
- return isPersistent;
- }
-
- /**
- * Specifies whether this contact is to be considered persistent or not. The
- * method is to be used _only_ when a non-persistent contact has been added
- * to the contact list and its encapsulated VolatileBuddy has been repalced
- * with a standard buddy.
- * @param persistent true if the buddy is to be considered persistent and
- * false for volatile.
- */
- void setPersistent(boolean persistent)
- {
- this.isPersistent = persistent;
- }
-
- /**
- * Resolve this contact against the given entry
- * @param entry the server stored entry
- */
- void setResolved(YahooUser entry)
- {
- if(isResolved)
- return;
-
- this.isResolved = true;
- contact = entry;
- isVolatile = false;
- }
-
- /**
- * Returns the persistent data
- * @return the persistent data
- */
- public String getPersistentData()
- {
- return null;
- }
-
- /**
- * Determines whether or not this contact has been resolved against the
- * server. Unresolved contacts are used when initially loading a contact
- * list that has been stored in a local file until the presence operation
- * set has managed to retrieve all the contact list from the server and has
- * properly mapped contacts to their on-line buddies.
- * @return true if the contact has been resolved (mapped against a buddy)
- * and false otherwise.
- */
- public boolean isResolved()
- {
- return isResolved;
- }
-
- public void setPersistentData(String persistentData)
- {
- }
-
- /**
- * Get source contact
- * @return YahooContact
- */
- YahooUser getSourceContact()
- {
- return contact;
- }
-
- /**
- * Return the current status message of this contact.
- *
- * @return the current status message
- */
- public String getStatusMessage()
- {
- return statusMessage;
- }
-
- /**
- * Sets the current status message for this contact
- * @param statusMessage the message
- */
- protected void setStatusMessage(String statusMessage)
- {
- this.statusMessage = statusMessage;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/FileTransferImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/FileTransferImpl.java
deleted file mode 100644
index 3f42079..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/FileTransferImpl.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.io.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * The Filetransfer imeplementation for yahoo.
- * @author Damian Minkov
- */
-public class FileTransferImpl
- extends AbstractFileTransfer
-
-{
- private ProtocolProviderServiceYahooImpl yahooProvider;
- private String id = null;
- private Contact contact = null;
- private File file = null;
- private int direction = -1;
- private long transferedBytes;
-
- public FileTransferImpl(ProtocolProviderServiceYahooImpl yahooProvider,
- String id, Contact contact, File file, int direction)
- {
- this.yahooProvider = yahooProvider;
- this.id = id;
- this.contact = contact;
- this.file = file;
- this.direction = direction;
- }
-
- /**
- * Cancels this file transfer. When this method is called transfer should
- * be interrupted.
- */
- @Override
- public void cancel()
- {
- yahooProvider.getYahooSession().cancelRunningFileTransfer(id);
- }
-
- /**
- * Returns the number of bytes already transfered through this file transfer.
- *
- * @return the number of bytes already transfered through this file transfer
- */
- @Override
- public long getTransferedBytes()
- {
- return transferedBytes;
- }
-
- /**
- * Uniquie ID that is identifying the FileTransfer
- * if the request has been accepted.
- *
- * @return the id.
- */
- public String getID()
- {
- return id;
- }
-
- /**
- * The file transfer direction.
- * @return returns the direction of the file transfer : IN or OUT.
- */
- public int getDirection()
- {
- return direction;
- }
-
- /**
- * Returns the file that is transfered.
- *
- * @return the file
- */
- public File getLocalFile()
- {
- return file;
- }
-
- /**
- * Returns the contact that we are transfering files with.
- * @return the contact.
- */
- public Contact getContact()
- {
- return contact;
- }
-
- /**
- * @param transferedBytes the transferedBytes to set
- */
- public void setTransferedBytes(long transferedBytes)
- {
- this.transferedBytes = transferedBytes;
- }
-
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/IncomingFileTransferRequestYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/IncomingFileTransferRequestYahooImpl.java
deleted file mode 100644
index 25561d0..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/IncomingFileTransferRequestYahooImpl.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.io.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-
-/**
- * Implementation of the incoming file transfer request.
- *
- * @author Damian Minkov
- */
-public class IncomingFileTransferRequestYahooImpl
- implements IncomingFileTransferRequest
-{
- private String id;
-
- /**
- * The yahoo provider.
- */
- private ProtocolProviderServiceYahooImpl yahooProvider;
-
- private final OperationSetFileTransferYahooImpl fileTransferOpSet;
-
- private Contact sender;
-
- private Date date;
-
- private String fileName;
-
- private long fileSize;
-
- public IncomingFileTransferRequestYahooImpl(
- ProtocolProviderServiceYahooImpl yahooProvider,
- OperationSetFileTransferYahooImpl fileTransferOpSet,
- Contact sender,
- Date date,
- String fileName,
- String fileSize,
- String id)
- {
- this.yahooProvider = yahooProvider;
- this.fileTransferOpSet = fileTransferOpSet;
- this.sender = sender;
- this.date = date;
- this.fileName = fileName;
-
- try
- {
- this.fileSize = Long.valueOf(fileSize);
- }
- catch (NumberFormatException e)
- {}
-
- this.id = id;
- }
-
- /**
- * Unique ID that is identifying the request and then the FileTransfer
- * if the request has been accepted.
- *
- * @return the id.
- */
- public String getID()
- {
- return id;
- }
-
- /**
- * Returns a String that represents the name of the file that is being
- * received.
- * If there is no name, returns null.
- * @return a String that represents the name of the file
- */
- public String getFileName()
- {
- return fileName;
- }
-
- /**
- * Returns a String that represents the description of the file that is
- * being received.
- * If there is no description available, returns null.
- *
- * @return a String that represents the description of the file
- */
- public String getFileDescription()
- {
- return "";
- }
-
- /**
- * Returns a long that represents the size of the file that is being
- * received.
- * If there is no file size available, returns null.
- *
- * @return a long that represents the size of the file
- */
- public long getFileSize()
- {
- return fileSize;
- }
-
- /**
- * Returns a String that represents the name of the sender of the file
- * being received.
- * If there is no sender name available, returns null.
- *
- * @return a String that represents the name of the sender
- */
- public Contact getSender()
- {
- return sender;
- }
-
- /**
- * Function called to accept and receive the file.
- *
- * @param file the file to accept
- * @return the <tt>FileTransfer</tt> object managing the transfer
- */
- public FileTransfer acceptFile(File file)
- {
- AbstractFileTransfer incomingTransfer = null;
-
- incomingTransfer =
- new FileTransferImpl(yahooProvider,
- id, sender, file, FileTransfer.IN);
-
- yahooProvider.getYahooSession().fileTransferAccept(id, file);
-
- FileTransferCreatedEvent event
- = new FileTransferCreatedEvent(incomingTransfer, new Date());
-
- fileTransferOpSet.fireFileTransferCreated(event);
-
- incomingTransfer.fireStatusChangeEvent(
- FileTransferStatusChangeEvent.PREPARING);
-
- return incomingTransfer;
- }
-
- /**
- * Function called to refuse the file.
- */
- public void rejectFile()
- {
- yahooProvider.getYahooSession().fileTransferReject(id);
-
- fileTransferOpSet.fireFileTransferRequestRejected(
- new FileTransferRequestEvent(
- fileTransferOpSet, this, this.getDate()));
- }
-
- /**
- * @return the date
- */
- public Date getDate()
- {
- return date;
- }
-
- /**
- * Returns the thumbnail contained in this request.
- *
- * @return the thumbnail contained in this request
- */
- public byte[] getThumbnail()
- {
- return null;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/MessageYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/MessageYahooImpl.java
deleted file mode 100644
index e35a3c1..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/MessageYahooImpl.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * A simple implementation of the <tt>Message</tt> interface. Right now the
- * message only supports test contents and no binary data.
- *
- * @author Damian Minkov
- * @author Lubomir Marinov
- */
-public class MessageYahooImpl
- extends AbstractMessage
-{
-
- /**
- * Creates an instance of this Message with the specified parameters.
- *
- * @param content the text content of the message.
- * @param contentType a MIME string indicating the content type of the
- * <tt>content</tt> String.
- * @param contentEncoding a MIME String indicating the content encoding of
- * the <tt>content</tt> String.
- * @param subject the subject of the message or null for empty.
- */
- public MessageYahooImpl(String content, String contentType,
- String contentEncoding, String subject)
- {
- super(content, contentType, contentEncoding, subject);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java
deleted file mode 100644
index dd5f73f..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.io.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-import ymsg.network.*;
-import ymsg.network.event.*;
-
-/**
- * A Yahoo implementation of the ad-hoc multi user chat operation set.
- *
- * @author Rupert Burchardi
- * @author Valentin Martinet
- * @author Yana Stamcheva
- */
-public class OperationSetAdHocMultiUserChatYahooImpl
-implements OperationSetAdHocMultiUserChat
-{
- private static final Logger logger =
- Logger.getLogger(OperationSetAdHocMultiUserChatYahooImpl.class);
-
- /**
- * A list of listeners subscribed for invitations multi user chat events.
- */
- private final List<AdHocChatRoomInvitationListener> invitationListeners
- = new Vector<AdHocChatRoomInvitationListener>();
-
- /**
- * A list of listeners subscribed for events indicating rejection of a multi
- * user chat invitation sent by us.
- */
- private final List<AdHocChatRoomInvitationRejectionListener>
- invitationRejectionListeners
- = new Vector<AdHocChatRoomInvitationRejectionListener>();
-
- /**
- * Listeners that will be notified of changes in our status in the room such
- * as us being kicked, banned, or granted admin permissions.
- */
- private final List<LocalUserAdHocChatRoomPresenceListener> presenceListeners
- = new Vector<LocalUserAdHocChatRoomPresenceListener>();
-
- /**
- * A list of the rooms that are currently open by this account.
- */
- private final Hashtable<String, AdHocChatRoomYahooImpl> chatRoomCache
- = new Hashtable<String, AdHocChatRoomYahooImpl>();
-
- /**
- * The currently valid Yahoo protocol provider service implementation.
- */
- private final ProtocolProviderServiceYahooImpl yahooProvider;
-
- /**
- * The operation set for the basic instant messaging, provides some message
- * format functions.
- */
- private final OperationSetBasicInstantMessagingYahooImpl opSetBasic;
-
- /**
- * Instantiates the user operation set with a currently valid instance of
- * the Yahoo protocol provider.
- *
- * @param yahooProvider a currently valid instance of
- * ProtocolProviderServiceYahooImpl.
- */
- OperationSetAdHocMultiUserChatYahooImpl(
- ProtocolProviderServiceYahooImpl yahooProvider)
- {
- this.yahooProvider = yahooProvider;
-
- yahooProvider
- .addRegistrationStateChangeListener(new RegistrationStateListener());
-
- opSetBasic =
- (OperationSetBasicInstantMessagingYahooImpl) yahooProvider
- .getOperationSet(OperationSetBasicInstantMessaging.class);
- }
-
- /**
- * Adds a listener to invitation notifications.
- *
- * @param listener An invitation listener.
- */
- public void addInvitationListener(AdHocChatRoomInvitationListener listener)
- {
- synchronized (invitationListeners)
- {
- if (!invitationListeners.contains(listener))
- invitationListeners.add(listener);
- }
- }
-
- /**
- * Removes a listener that was being notified of changes in our status in a
- * room such as us being kicked, banned or dropped.
- *
- * @param listener the <tt>LocalUserAdHocChatRoomPresenceListener</tt>.
- */
- public void removeInvitationListener(
- AdHocChatRoomInvitationListener listener)
- {
- synchronized (invitationListeners)
- {
- invitationListeners.remove(listener);
- }
- }
-
- /**
- * Subscribes <tt>listener</tt> so that it would receive events indicating
- * rejection of a multi user chat invitation that we've sent earlier.
- *
- * @param listener the listener that we'll subscribe for invitation
- * rejection events.
- */
-
- public void addInvitationRejectionListener(
- AdHocChatRoomInvitationRejectionListener listener)
- {
- synchronized (invitationRejectionListeners)
- {
- if (!invitationRejectionListeners.contains(listener))
- invitationRejectionListeners.add(listener);
- }
- }
-
- /**
- * Removes <tt>listener</tt> from the list of invitation listeners
- * registered to receive invitation rejection events.
- *
- * @param listener the invitation listener to remove.
- */
- public void removeInvitationRejectionListener(
- AdHocChatRoomInvitationRejectionListener listener)
- {
- synchronized (invitationRejectionListeners)
- {
- invitationRejectionListeners.remove(listener);
- }
- }
-
- /**
- * Adds a listener that will be notified of changes in our status in a chat
- * room such as us being kicked, banned or dropped.
- *
- * @param listener the <tt>LocalUserAdHocChatRoomPresenceListener</tt>.
- */
- public void addPresenceListener(
- LocalUserAdHocChatRoomPresenceListener listener)
- {
- synchronized (presenceListeners)
- {
- if (!presenceListeners.contains(listener))
- presenceListeners.add(listener);
- }
- }
-
- /**
- * Removes a listener that was being notified of changes in our status in a
- * room such as us being kicked, banned or dropped.
- *
- * @param listener the <tt>LocalUserChatRoomPresenceListener</tt>.
- */
- public void removePresenceListener(
- LocalUserAdHocChatRoomPresenceListener listener)
- {
- synchronized (presenceListeners)
- {
- presenceListeners.remove(listener);
- }
- }
-
- /**
- * Creates a room with the named <tt>roomName</tt> and according to the
- * specified <tt>roomProperties</tt> on the server that this protocol
- * provider is currently connected to. Note the roomProperties also contain
- * users that we like to invite to the chatRoom, this is required in the
- * yahoo protocol.
- *
- * @param roomName the name of the <tt>AdHocChatRoom</tt> to create.
- * @param roomProperties properties specifying how the room should be
- * created.
- *
- * @throws OperationFailedException if the room couldn't be created for some
- * reason (e.g. room already exists; user already joined to an
- * existent room or user has no permissions to create a chat
- * room).
- *
- * @return ChatRoom the chat room that we've just created.
- */
- public AdHocChatRoom createAdHocChatRoom(String roomName,
- Map<String, Object> roomProperties)
- throws OperationFailedException
- {
- return createAdHocChatRoom(roomName, (String[]) null, "");
- }
-
- /**
- * Creates an ad-hoc room with the named <tt>adHocRoomName</tt> and in
- * including to the specified <tt>contacts</tt>. When the method returns the
- * ad-hoc room the local user will have joined it.
- *
- * @return the ad-hoc room that has been just created
- * @param adHocRoomName the name of the room to be created
- * @param contacts the list of contacts ID
- * @param reason the reason for contacts' invitation
- * @throws OperationFailedException if the room couldn't be created for
- * some reason
- */
- public AdHocChatRoom createAdHocChatRoom( String adHocRoomName,
- List<String> contacts,
- String reason)
- throws OperationFailedException
- {
- String[] contactsToInvite = new String[contacts.size()];
- for(int i=0; i<contacts.size(); i++)
- {
- contactsToInvite[i] = contacts.get(i);
- }
- return createAdHocChatRoom(
- adHocRoomName, contactsToInvite, reason);
- }
-
- /**
- * Creates an ad-hoc room with the named <tt>adHocRoomName</tt> and in
- * including to the specified <tt>contacts</tt>. When the method returns the
- * ad-hoc room the local user will have joined it.
- *
- * @param roomName name of the chatroom
- * @param invitedContacts contacts to be invited to this room
- * @param reason reason of this invitation
- * @return AdHocChatRoom the ad-hoc room that has been just created
- * @throws OperationFailedException
- */
- private AdHocChatRoom createAdHocChatRoom(
- String roomName,
- String[] invitedContacts,
- String reason)
- throws OperationFailedException
- {
- if (invitedContacts == null)
- invitedContacts = new String[0];
-
- AdHocChatRoom chatRoom = null;
-
- try
- {
- YahooConference conference =
- yahooProvider.getYahooSession().createConference(
- invitedContacts, // users invited to this conference
- reason, // invite message / topic
- yahooProvider.getYahooSession().getLoginIdentity());
-
- chatRoom = createLocalChatRoomInstance(conference);
- }
- catch (Exception e)
- {
- String errorMessage
- = "Failed to create chat room with name: " + roomName;
-
- if (logger.isDebugEnabled())
- logger.debug(errorMessage, e);
- throw new OperationFailedException(errorMessage,
- OperationFailedException.CHAT_ROOM_NOT_JOINED, e);
- }
- chatRoom.join();
- return chatRoom;
- }
-
- /**
- * Creates a <tt>AdHocChatRoom</tt> instance from the specified Yahoo
- * conference.
- *
- * @param yahooConference The chat room model from the yahoo lib.
- *
- * @return AdHocChatRoom the chat room that we've just created.
- */
- private AdHocChatRoomYahooImpl createLocalChatRoomInstance(
- YahooConference yahooConference)
- {
- synchronized (chatRoomCache)
- {
- AdHocChatRoomYahooImpl newChatRoom
- = new AdHocChatRoomYahooImpl(yahooConference, yahooProvider);
-
- chatRoomCache.put(yahooConference.getName(), newChatRoom);
-
- return newChatRoom;
- }
- }
-
- /**
- * Creates a <tt>AdHocChatRoom</tt> instance (where the inviter is
- * represented by inviterID parameter) from the specified Yahoo conference.
- *
- * @param yahooConference The chat room model from the yahoo lib.
- * @param inviterID inviter's Yahoo ID which has to be added as room member
- *
- * @return AdHocChatRoom the chat room that we've just created.
- */
- private AdHocChatRoomYahooImpl createLocalChatRoomInstance(
- YahooConference yahooConference, String inviterID)
- {
- synchronized (chatRoomCache)
- {
- AdHocChatRoomYahooImpl newChatRoom
- = new AdHocChatRoomYahooImpl(yahooConference, yahooProvider);
-
- OperationSetPersistentPresenceYahooImpl opSetPresence =
- (OperationSetPersistentPresenceYahooImpl) yahooProvider
- .getOperationSet(OperationSetPersistentPresence.class);
-
- newChatRoom.addChatRoomParticipant(
- opSetPresence.findContactByID(inviterID));
- chatRoomCache.put(yahooConference.getName(), newChatRoom);
-
- return newChatRoom;
- }
- }
-
- /**
- * Returns the <tt>AdHocChatRoomYahooImpl</tt> corresponding to the given
- * <tt>conference</tt> if such exists, otherwise returns null.
- *
- * @param conference the <tt>YahooConference</tt>, for which we're searching
- * correspondence
- * @return the <tt>AdHocChatRoomYahooImpl</tt> corresponding to the given
- * <tt>conference</tt> if such exists, otherwise returns null
- */
- private AdHocChatRoomYahooImpl getLocalChatRoomInstance(
- YahooConference conference)
- {
- synchronized (chatRoomCache)
- {
- for (AdHocChatRoomYahooImpl chatRoom : chatRoomCache.values())
- {
- if (chatRoom.getYahooConference().equals(conference))
- return chatRoom;
- }
- }
-
- return null;
- }
-
- /**
- * Informs the sender of an invitation that we decline their invitation.
- *
- * @param invitation the connection to use for sending the rejection.
- * @param rejectReason the reason to reject the given invitation
- */
- public void rejectInvitation(AdHocChatRoomInvitation invitation,
- String rejectReason)
- {
- AdHocChatRoomYahooImpl chatRoom =
- (AdHocChatRoomYahooImpl) invitation.getTargetAdHocChatRoom();
-
- try
- {
- yahooProvider.getYahooSession().declineConferenceInvite(
- chatRoom.getYahooConference(), rejectReason);
- }
- catch (IOException e)
- {
- if (logger.isDebugEnabled())
- logger.debug("Failed to reject Invitation: " + e);
- }
- }
-
- /**
- * Delivers a <tt>AdHocChatRoomInvitationReceivedEvent</tt> to all
- * registered <tt>AdHocChatRoomInvitationListener</tt>s.
- *
- * @param targetChatRoom the room that invitation refers to
- * @param inviter the inviter that sent the invitation
- * @param reason the reason why the inviter sent the invitation
- */
- public void fireInvitationEvent(AdHocChatRoom targetChatRoom,
- String inviter, String reason)
- {
- AdHocChatRoomInvitationYahooImpl invitation =
- new AdHocChatRoomInvitationYahooImpl(targetChatRoom, inviter,
- reason);
-
- AdHocChatRoomInvitationReceivedEvent evt =
- new AdHocChatRoomInvitationReceivedEvent(this, invitation,
- new Date(System.currentTimeMillis()));
-
- Iterable<AdHocChatRoomInvitationListener> listeners;
- synchronized (invitationListeners)
- {
- listeners
- = new ArrayList<AdHocChatRoomInvitationListener>(
- invitationListeners);
- }
-
- for (AdHocChatRoomInvitationListener listener : listeners)
- listener.invitationReceived(evt);
- }
-
- /**
- * Delivers a <tt>AdHocChatRoomInvitationRejectedEvent</tt> to all
- * registered <tt>AdHocChatRoomInvitationRejectionListener</tt>s.
- *
- * @param sourceChatRoom the room that invitation refers to
- * @param invitee the name of the invitee that rejected the invitation
- * @param reason the reason of the rejection
- */
- public void fireInvitationRejectedEvent(AdHocChatRoom sourceChatRoom,
- String invitee, String reason)
- {
- AdHocChatRoomInvitationRejectedEvent evt =
- new AdHocChatRoomInvitationRejectedEvent(
- this, sourceChatRoom, invitee,
- reason, new Date(System.currentTimeMillis()));
-
- Iterable<AdHocChatRoomInvitationRejectionListener> listeners;
- synchronized (invitationRejectionListeners)
- {
- listeners
- = new ArrayList<AdHocChatRoomInvitationRejectionListener>(
- invitationRejectionListeners);
- }
-
- for (AdHocChatRoomInvitationRejectionListener listener : listeners)
- listener.invitationRejected(evt);
- }
-
- /**
- * Delivers a <tt>LocalUserAdHocChatRoomPresenceChangeEvent</tt> to all
- * registered <tt>LocalUserAdHocChatRoomPresenceListener</tt>s.
- *
- * @param chatRoom the <tt>ChatRoom</tt> which has been joined, left, etc.
- * @param eventType the type of this event; one of LOCAL_USER_JOINED,
- * LOCAL_USER_LEFT, etc.
- * @param reason the reason
- */
- public void fireLocalUserPresenceEvent(AdHocChatRoom chatRoom,
- String eventType, String reason)
- {
- LocalUserAdHocChatRoomPresenceChangeEvent evt =
- new LocalUserAdHocChatRoomPresenceChangeEvent(
- this, chatRoom, eventType,
- reason);
-
- Iterable<LocalUserAdHocChatRoomPresenceListener> listeners;
- synchronized (presenceListeners)
- {
- listeners =
- new ArrayList<LocalUserAdHocChatRoomPresenceListener>(
- presenceListeners);
- }
-
- for (LocalUserAdHocChatRoomPresenceListener listener : listeners)
- listener.localUserAdHocPresenceChanged(evt);
- }
-
- /**
- * Create a Message instance for sending arbitrary MIME-encoding content.
- *
- * @param content content value
- * @param contentType the MIME-type for <tt>content</tt>
- * @param contentEncoding encoding used for <tt>content</tt>
- * @param subject a <tt>String</tt> subject or <tt>null</tt> for now
- * subject.
- * @return the newly created message.
- * @throws UnsupportedEncodingException missing utf-8 in platform we use.
- */
- private Message createMessage(byte[] content, String contentType,
- String contentEncoding, String subject)
- throws UnsupportedEncodingException
- {
- return new MessageYahooImpl(new String(content, "UTF-8"), contentType,
- contentEncoding, subject);
- }
-
- /**
- * Creates a message by a given message text.
- *
- * @param messageText The message text.
- * @return the newly created message.
- */
- public Message createMessage(String messageText)
- {
- return new MessageYahooImpl(messageText,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING, null);
- }
-
- /**
- * Our listener that will tell us when we're registered to yahoo network.
- *
- */
- private class RegistrationStateListener
- implements RegistrationStateChangeListener
- {
- /**
- * The method is called by a ProtocolProvider implementation whenever a
- * change in the registration state of the corresponding provider had
- * occurred.
- *
- * @param evt ProviderStatusChangeEvent the event describing the status
- * change.
- */
- public void registrationStateChanged(RegistrationStateChangeEvent evt)
- {
- if (evt.getNewState() == RegistrationState.REGISTERED)
- {
- yahooProvider.getYahooSession().addSessionListener(
- new YahooMessageListener());
- }
- }
- }
-
- /**
- * Our group chat message listener, it extends the SessionAdapter from the
- * the Yahoo library.
- *
- */
- private class YahooMessageListener
- extends SessionAdapter
- {
-
- @Override
- public void conferenceInviteDeclinedReceived(SessionConferenceEvent ev)
- {
- if (logger.isDebugEnabled())
- logger.debug("Group Chat invite declined received. "
- + ev.toString());
- try
- {
- AdHocChatRoom chatRoom = getLocalChatRoomInstance(ev.getRoom());
-
- fireInvitationRejectedEvent(chatRoom, ev.getFrom(), ev
- .getMessage());
- }
- catch (Exception e)
- {
- if (logger.isDebugEnabled())
- logger.debug("Error: " + e);
- }
- }
-
- @Override
- public void conferenceInviteReceived(SessionConferenceEvent ev)
- {
- if (logger.isDebugEnabled())
- logger.debug("Conference Invite Received: " + ev.toString());
-
- try
- {
- AdHocChatRoom chatRoom = getLocalChatRoomInstance(ev.getRoom());
-
- if (chatRoom == null)
- {
- chatRoom =
- createLocalChatRoomInstance(ev.getRoom(), ev.getFrom());
-
- fireInvitationEvent(
- chatRoom, ev.getFrom(), ev.getMessage());
- }
-
- }
- catch (Exception e)
- {
- if (logger.isDebugEnabled())
- logger.debug("Error: " + e);
- }
- }
-
- @Override
- public void conferenceLogoffReceived(SessionConferenceEvent ev)
- {
- if (logger.isDebugEnabled())
- logger.debug("Conference Logoff Received: " + ev.toString());
-
- try
- {
- AdHocChatRoomYahooImpl chatRoom
- = getLocalChatRoomInstance(ev.getRoom());
-
- if (chatRoom != null)
- {
- Contact participant =
- chatRoom.findParticipantForAddress(ev.getFrom());
-
- chatRoom.removeChatRoomParticipant(participant);
- }
- }
- catch (Exception e)
- {
- logger
- .debug("Failed to remove a user from the chat room. " + e);
- }
- }
-
- @Override
- public void conferenceLogonReceived(SessionConferenceEvent ev)
- {
- if (logger.isDebugEnabled())
- logger.debug("Conference Logon Received: " + ev.toString());
-
- try
- {
- AdHocChatRoomYahooImpl chatRoom
- = getLocalChatRoomInstance(ev.getRoom());
-
- if (chatRoom != null)
- {
- OperationSetPersistentPresenceYahooImpl presenceOpSet =
- (OperationSetPersistentPresenceYahooImpl) chatRoom
- .getParentProvider().getOperationSet(
- OperationSetPersistentPresence.class);
-
- Contact participant =
- presenceOpSet.findContactByID(ev.getFrom());
-
- chatRoom.addChatRoomParticipant(participant);
- }
- }
- catch (Exception e)
- {
- if (logger.isDebugEnabled())
- logger.debug("Failed to add a user to the chat room. " + e);
- }
- }
-
- @Override
- public void conferenceMessageReceived(SessionConferenceEvent ev)
- {
- if (logger.isDebugEnabled())
- logger.debug("Conference Message Received: " + ev.toString());
-
- try
- {
- String formattedMessage = ev.getMessage();
- if (logger.isDebugEnabled())
- logger.debug("original message received : " + formattedMessage);
-
- formattedMessage = opSetBasic.decodeMessage(formattedMessage);
- if (logger.isDebugEnabled())
- logger.debug("formatted Message : " + formattedMessage);
- // As no indications in the protocol is it html or not. No harm
- // to set all messages html - doesn't affect the appearance of
- // the gui
-
- Message newMessage =
- createMessage(
- formattedMessage.getBytes("UTF-8"),
- OperationSetBasicInstantMessaging.HTML_MIME_TYPE,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING,
- null);
-
- AdHocChatRoomYahooImpl chatRoom =
- getLocalChatRoomInstance(ev.getRoom());
-
- if (chatRoom != null)
- {
- Contact member =
- chatRoom.findParticipantForAddress(ev.getFrom());
-
- AdHocChatRoomMessageReceivedEvent msgReceivedEvent =
- new AdHocChatRoomMessageReceivedEvent(
- chatRoom,
- member,
- new Date(),
- newMessage,
- AdHocChatRoomMessageReceivedEvent
- .CONVERSATION_MESSAGE_RECEIVED);
-
- chatRoom.fireMessageEvent(msgReceivedEvent);
- }
- }
- catch (Exception e)
- {
- logger
- .debug("Error while receiving a multi user chat message: "
- + e);
- }
-
- }
-
- @Override
- public void connectionClosed(SessionEvent ev)
- {
- if (logger.isDebugEnabled())
- logger.debug("Connection Closed: " + ev.toString());
- }
- }
-
- public List<AdHocChatRoom> getAdHocChatRooms()
- {
- return new ArrayList<AdHocChatRoom>(chatRoomCache.values());
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetBasicInstantMessagingYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetBasicInstantMessagingYahooImpl.java
deleted file mode 100644
index 84059de..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetBasicInstantMessagingYahooImpl.java
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.io.*;
-import java.util.*;
-import java.util.regex.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-import ymsg.network.event.*;
-import ymsg.support.*;
-
-/**
- * A straightforward implementation of the basic instant messaging operation
- * set.
- *
- * @author Damian Minkov
- * @author Symphorien Wanko
- * @author Keio Kraaner
- */
-public class OperationSetBasicInstantMessagingYahooImpl
- extends AbstractOperationSetBasicInstantMessaging
- implements OperationSetInstantMessageFiltering
-{
- /**
- * Logger for this class
- */
- private static final Logger logger =
- Logger.getLogger(OperationSetBasicInstantMessagingYahooImpl.class);
-
- /**
- * Yahoo has limit of message length. If exceeded
- * message is not delivered and no notification is received for that.
- */
- private static final int MAX_MESSAGE_LENGTH = 800; // 949
-
- /**
- * A regexp that is used to escape some chars in messages.
- */
- private static final Pattern MESSAGE_CHARS_ESCAPE = Pattern.compile("([.()^&$*|])");
-
- /**
- * A list of filters registered for message events.
- */
- private final List<EventFilter> eventFilters = new ArrayList<EventFilter>();
-
- /**
- * The provider that created us.
- */
- private ProtocolProviderServiceYahooImpl yahooProvider = null;
-
- /**
- * Message decoder allows to convert Yahoo formated messages, which can
- * contains some specials characters, to HTML or to plain text.
- */
- private final MessageDecoder messageDecoder = new MessageDecoder();
-
- /**
- * A reference to the persistent presence operation set that we use
- * to match incoming messages to <tt>Contact</tt>s and vice versa.
- */
- private OperationSetPersistentPresenceYahooImpl opSetPersPresence = null;
- private static final Pattern FONT_SIZE_0_PATTERN = Pattern.compile("(<font) (.*) size=\"0\">");
- private static final Pattern FONT_SIZE_INT_PATTERN = Pattern.compile("(<font) (.*) size=\"(\\d+)\">");
-
- /**
- * Creates an instance of this operation set.
- * @param provider a ref to the <tt>ProtocolProviderServiceImpl</tt>
- * that created us and that we'll use for retrieving the underlying aim
- * connection.
- */
- OperationSetBasicInstantMessagingYahooImpl(
- ProtocolProviderServiceYahooImpl provider)
- {
- this.yahooProvider = provider;
- provider.addRegistrationStateChangeListener(
- new RegistrationStateListener());
- }
-
- /**
- * Determines wheter the protocol provider (or the protocol itself) support
- * sending and receiving offline messages. Most often this method would
- * return true for protocols that support offline messages and false for
- * those that don't. It is however possible for a protocol to support these
- * messages and yet have a particular account that does not (i.e. feature
- * not enabled on the protocol server). In cases like this it is possible
- * for this method to return true even when offline messaging is not
- * supported, and then have the sendMessage method throw an
- * OperationFailedException with code - OFFLINE_MESSAGES_NOT_SUPPORTED.
- *
- * @return <tt>true</tt> if the protocol supports offline messages and
- * <tt>false</tt> otherwise.
- */
- public boolean isOfflineMessagingSupported()
- {
- return true;
- }
-
- /**
- * Determines wheter the protocol supports the supplied content type
- *
- * @param contentType the type we want to check
- * @return <tt>true</tt> if the protocol supports it and
- * <tt>false</tt> otherwise.
- */
- public boolean isContentTypeSupported(String contentType)
- {
- if(contentType.equals(DEFAULT_MIME_TYPE) ||
- contentType.equals(HTML_MIME_TYPE))
- return true;
- else
- return false;
- }
-
- @Override
- public Message createMessage(String content, String contentType,
- String encoding, String subject)
- {
- return new MessageYahooImpl(content, contentType, encoding, subject);
- }
-
- /**
- * Sends the <tt>message</tt> to the destination indicated by the
- * <tt>to</tt> contact.
- *
- * @param to the <tt>Contact</tt> to send <tt>message</tt> to
- * @param message the <tt>Message</tt> to send.
- * @throws IllegalStateException if the underlying stack is
- * not registered and initialized.
- * @throws IllegalArgumentException if <tt>to</tt> is not an
- * instance of ContactImpl.
- */
- public void sendInstantMessage(Contact to, Message message)
- throws IllegalStateException, IllegalArgumentException
- {
- assertConnected();
-
- if( !(to instanceof ContactYahooImpl) )
- throw new IllegalArgumentException(
- "The specified contact is not a Yahoo contact."
- + to);
-
- try
- {
- String toUserID = ((ContactYahooImpl) to).getID();
-
- MessageDeliveredEvent msgDeliveryPendingEvt =
- new MessageDeliveredEvent(message, to, new Date());
-
- MessageDeliveredEvent[] msgDeliveryPendingEvts = messageDeliveryPendingTransform(msgDeliveryPendingEvt);
-
- if (msgDeliveryPendingEvts == null || msgDeliveryPendingEvts.length == 0)
- return;
-
- for (MessageDeliveredEvent event : msgDeliveryPendingEvts)
- {
- byte[] msgBytesToBeSent =
- event.getSourceMessage().getContent().trim()
- .getBytes("UTF-8");
-
- // split the message in parts with max allowed length
- // and send them all
- do
- {
- if (msgBytesToBeSent.length > MAX_MESSAGE_LENGTH)
- {
- byte[] tmp1 = new byte[MAX_MESSAGE_LENGTH];
- System.arraycopy(msgBytesToBeSent, 0, tmp1, 0,
- MAX_MESSAGE_LENGTH);
-
- byte[] tmp2 =
- new byte[msgBytesToBeSent.length
- - MAX_MESSAGE_LENGTH];
- System.arraycopy(msgBytesToBeSent, MAX_MESSAGE_LENGTH,
- tmp2, 0, tmp2.length);
-
- msgBytesToBeSent = tmp2;
-
- yahooProvider.getYahooSession().sendMessage(toUserID,
- new String(tmp1, "UTF-8"));
- }
- else
- {
- yahooProvider.getYahooSession().sendMessage(toUserID,
- new String(msgBytesToBeSent, "UTF-8"));
- }
-
- MessageDeliveredEvent msgDeliveredEvt =
- new MessageDeliveredEvent(message, to, new Date());
-
- if (msgDeliveredEvt != null)
- fireMessageEvent(msgDeliveredEvt);
- }
- while (msgBytesToBeSent.length > MAX_MESSAGE_LENGTH);
- }
- }
- catch (IOException ex)
- {
- logger.fatal("Cannot Send Message! " + ex.getMessage());
- MessageDeliveryFailedEvent evt =
- new MessageDeliveryFailedEvent(
- message,
- to,
- MessageDeliveryFailedEvent.NETWORK_FAILURE);
-
- if (evt != null)
- fireMessageEvent(evt);
- }
- }
-
- /**
- * Utility method throwing an exception if the stack is not properly
- * initialized.
- * @throws IllegalStateException if the underlying stack is
- * not registered and initialized.
- */
- private void assertConnected() throws IllegalStateException
- {
- if (yahooProvider == null)
- throw new IllegalStateException(
- "The provider must be non-null and signed on the "
- +"service before being able to communicate.");
- if (!yahooProvider.isRegistered())
- throw new IllegalStateException(
- "The provider must be signed on the service before "
- +"being able to communicate.");
- }
-
- /**
- * Our listener that will tell us when we're registered to
- */
- private class RegistrationStateListener
- implements RegistrationStateChangeListener
- {
- /**
- * The method is called by a ProtocolProvider implementation whenver
- * a change in the registration state of the corresponding provider had
- * occurred.
- * @param evt ProviderStatusChangeEvent the event describing the status
- * change.
- */
- public void registrationStateChanged(RegistrationStateChangeEvent evt)
- {
- if (logger.isDebugEnabled())
- logger.debug("The provider changed state from: "
- + evt.getOldState()
- + " to: " + evt.getNewState());
-
- if (evt.getNewState() == RegistrationState.REGISTERED)
- {
- opSetPersPresence =
- (OperationSetPersistentPresenceYahooImpl) yahooProvider
- .getOperationSet(OperationSetPersistentPresence.class);
-
- yahooProvider.getYahooSession().
- addSessionListener(new YahooMessageListener());
- }
- }
- }
-
- /**
- * Delivers the specified event to all registered message listeners.
- * @param evt the <tt>EventObject</tt> that we'd like delivered to all
- * registered message listerners.
- */
- @Override
- protected void fireMessageEvent(EventObject evt)
- {
- // check if this event should be filtered out
- Iterator<EventFilter> filters;
- synchronized (eventFilters)
- {
- filters = new ArrayList<EventFilter>(eventFilters).iterator();
- }
- // return if a filter has filtered this event out
- boolean filtered = false;
- while (filters.hasNext())
- {
- try
- {
- if (filters.next().filterEvent(evt))
- {
- filtered = true;
- }
- }
- catch(Exception exc)
- {
- logger.error("An exception occurred while filtering an event.",
- exc);
- }
- }
-
- if (filtered)
- {
- if (logger.isTraceEnabled())
- logger.trace("Message event filtered.");
- return;
- }
-
- super.fireMessageEvent(evt);
- }
-
- /**
- * This class provides methods to listen for yahoo events which interest us.
- */
- private class YahooMessageListener
- extends SessionAdapter
- {
- /**
- * Overrides <tt>messageReceived</tt> from <tt>SessionAdapter</tt>,
- * called when we receive a new intant message.
- *
- * @param ev Event with information on the received message
- */
- @Override
- public void messageReceived(SessionEvent ev)
- {
- handleNewMessage(ev);
- }
-
- /**
- * Overrides <tt>offlineMessageReceived</tt> from <tt>SessionAdapter</tt>,
- * called when we receive a message which has been sent to us
- * when we were offline.
- *
- * @param ev Event with information on the received message
- */
- @Override
- public void offlineMessageReceived(SessionEvent ev)
- {
- handleNewMessage(ev);
- }
-
- /**
- * Overrides <tt>newMailReceived</tt> from <tt>SessionAdapter</tt>,
- * called when yahoo alert us that there is a new message in our mailbox.
- * There is two types of notification, the first one provides only
- * the number of unread mails and the second gives informations about
- * a precise new mail. Here, we care about only the second case in which
- * we should always have the email of the sender of the mail.
- *
- * @param ev Event with information on the received email
- */
- @Override
- public void newMailReceived(SessionNewMailEvent ev)
- {
- // why, if I provide mail@yahoo.FR when registering my account,
- // SC later tells me that my email address is mail@yahoo.COM ??
- // because of this users will always be sent on yahoo.com mail
- // login page rather than their usual (yahoo.XXX) login page.
- String myEmail = yahooProvider.getAccountID().getAccountAddress();
-
- // we don't process incoming email event without source address.
- // it allows us to avoid some spams
- if ((ev.getEmailAddress() == null)
- || (ev.getEmailAddress().indexOf('@') < 0))
- {
- return;
- }
-
- String yahooMailLogon = "http://mail."
- + myEmail.substring(myEmail.indexOf('@') + 1);
-
- yahooMailLogon = "&nbsp;&nbsp;&nbsp;&nbsp;<a href=\""
- + yahooMailLogon + "\">"
- + yahooMailLogon + "</a>";
-
- // FIXME Escape HTML!
- String newMail = YahooActivator.getResources().getI18NString(
- "service.gui.NEW_MAIL",
- new String[]{ev.getFrom(),
- "&lt;" + ev.getEmailAddress() + "&gt;",
- ev.getSubject(),
- "&nbsp;&nbsp;&nbsp;&nbsp;"+yahooMailLogon}) ;
-
- Message newMailMessage = new MessageYahooImpl(
- newMail,
- HTML_MIME_TYPE,
- DEFAULT_MIME_ENCODING,
- null);
-
- Contact sourceContact = opSetPersPresence.
- findContactByID(ev.getEmailAddress());
-
- if (sourceContact == null)
- {
- if (logger.isDebugEnabled())
- logger.debug("received a new mail from an unknown contact: "
- + ev.getFrom()
- + " &lt;" + ev.getEmailAddress() + "&gt;");
- //create the volatile contact
- sourceContact = opSetPersPresence
- .createVolatileContact(ev.getEmailAddress());
- }
- MessageReceivedEvent msgReceivedEvt
- = new MessageReceivedEvent(
- newMailMessage, sourceContact, new Date(),
- MessageReceivedEvent.SYSTEM_MESSAGE_RECEIVED);
-
- fireMessageEvent(msgReceivedEvt);
- }
-
- /**
- * Handle incoming message by creating an appropriate Sip Communicator
- * <tt>Message</tt> and firing a <tt>MessageReceivedEvent</tt>
- * to interested listeners.
- *
- * @param ev The original <tt>SessionEvent</tt> which noticed us
- * of an incoming message.
- */
- private void handleNewMessage(SessionEvent ev)
- {
- if (logger.isDebugEnabled())
- logger.debug("Message received : " + ev);
-
- // to keep things simple, we can decodeToText()
- //String formattedMessage = processLinks(
- // messageDecoder.decodeToText(ev.getMessage()));
-
- String formattedMessage = ev.getMessage();
- if (logger.isDebugEnabled())
- logger.debug("original message received : " + formattedMessage);
-
- formattedMessage = decodeMessage(formattedMessage);
-
- if (logger.isDebugEnabled())
- logger.debug("formatted Message : " + formattedMessage);
- // As no indications in the protocol is it html or not. No harm
- // to set all messages html - doesn't affect the appearance of the
- // gui
- Message newMessage =
- createMessage(formattedMessage, HTML_MIME_TYPE,
- DEFAULT_MIME_ENCODING, null);
-
- Contact sourceContact = opSetPersPresence.
- findContactByID(ev.getFrom());
-
- if(sourceContact == null)
- {
- if (logger.isDebugEnabled())
- logger.debug("received a message from an unknown contact: "
- + ev.getFrom());
- //create the volatile contact
- sourceContact = opSetPersPresence
- .createVolatileContact(ev.getFrom());
- }
-
- MessageReceivedEvent msgReceivedEvt
- = new MessageReceivedEvent(
- newMessage, sourceContact , new Date());
-
- // msgReceivedEvt = messageReceivedTransform(msgReceivedEvt);
-
- if (msgReceivedEvt != null)
- fireMessageEvent(msgReceivedEvt);
- }
- }
-
- /**
- * Decode the received chat message.
- * If the message contains \u001b the following text is decoded by
- * the MessageDecoder of yahoo api
- * Then make http links clickable and fix the font size of html code
- *
- * @param message the chat message
- * @return a decoded message.
- */
- String decodeMessage(String message)
- {
- message = messageDecoder.decodeToHTML(message);
- message = processLinks(message);
- message =
- FONT_SIZE_0_PATTERN.matcher(message)
- .replaceAll("$1 $2 size=\"10\">");
- message =
- FONT_SIZE_INT_PATTERN.matcher(message)
- .replaceAll("$1 $2 style=\"font-size: $3px;\">");
- return message;
- }
-
- /**
- * Format links in the given message. Skips all links, which are already in
- * HTML format and converts all other links.
- *
- * @param message The source message string.
- * @return The message string with properly formatted links.
- */
- public String processLinks(String message)
- {
- StringBuffer msgBuffer = new StringBuffer();
-
- // We match two groups of Strings. The first group is the group of any
- // String. The second group is a well formatted HTML link.
- Pattern p = Pattern.compile("(.*?)(<a[\\s][^<]*(/>|</a>))",
- Pattern.CASE_INSENSITIVE);
-
- Matcher m = p.matcher(message);
-
- int lastMatchIndex = 0;
- while (m.find())
- {
- lastMatchIndex = m.end();
-
- String matchGroup1 = m.group(1);
- String matchGroup2 = m.group(2);
-
- String formattedString = formatLinksToHTML(matchGroup1);
-
- m.appendReplacement(msgBuffer,
- replaceSpecialRegExpChars(formattedString) + matchGroup2);
- }
-
- String tailString = message.substring(lastMatchIndex);
-
- String formattedTailString = formatLinksToHTML(tailString);
-
- msgBuffer.append(formattedTailString);
-
- return msgBuffer.toString();
- }
-
- /**
- * Replaces some chars that are special in a regular expression.
- *
- * @param text The initial text.
- * @return the formatted text
- */
- private static String replaceSpecialRegExpChars(String text)
- {
- return MESSAGE_CHARS_ESCAPE.matcher(text).replaceAll("\\\\$1");
- }
-
- /**
- * Goes through the given text and converts all links to HTML links.
- * <p>
- * For example all occurrences of http://jitsi.org/ will be
- * replaced by <a href="http://jitsi.org/">
- * http://jitsi.org/</a>. The same is true for all strings
- * starting with "www".
- *
- * @param text the text on which the regular expression would be performed
- * @return the initial text containing only HTML links
- */
- private static String formatLinksToHTML(String text)
- {
- String wwwURL = "(www\\." + // Matches the "www" string.
- "[^/?#<\"'\\s]+" + // Matches at least one char of
- // any type except / ? # < " '
- // and space.
- "[\\.]" + // Matches the second point of the link.
- "[^?#<\"'\\s]+" + // Matches at least one char of
- // any type except ? # < " '
- // and space.
- "(\\?[^#<\"'\\s]*)?" +
- "(#.*)?)";
-
- String protocolURL
- = "([^\"'<>:/?#\\s]+" + // Matches at least one char of
- // any type except " ' < > : / ? #
- // and space.
- "://" + // Matches the :// delimiter in links
- "[^/?#<\"'\\s]*" + // Matches any number of times any char
- // except / ? # < " ' and space.
- "[^?#<\"'\\s]*" + // Matches any number of times any char
- // except ? # < " ' and space.
- "(\\?[^#<\"'\\s]*)?" +
- "(#.*)?)";
-
- String url = '(' + wwwURL + '|' + protocolURL + ')';
-
- Pattern p = Pattern.compile(url, Pattern.CASE_INSENSITIVE);
-
- Matcher m = p.matcher(text);
-
- StringBuffer linkBuffer = new StringBuffer();
-
- while (m.find())
- {
- String linkGroup = m.group();
-
- String replacement;
- if (linkGroup.startsWith("www"))
- {
- replacement = "<A href=\"" + "http://"
- + linkGroup + "\">" + linkGroup + "</A>";
- }
- else
- {
- replacement = "<A href=\"" + linkGroup
- + "\">" + linkGroup + "</A>";
- }
-
- m.appendReplacement(linkBuffer,
- replaceSpecialRegExpChars(replacement));
- }
-
- m.appendTail(linkBuffer);
-
- return linkBuffer.toString();
- }
-
- /**
- * Registers an <tt>EventFilter</tt> with this operation set so that
- * events, that do not need processing, are filtered out.
- *
- * @param filter the <tt>EventFilter</tt> to register.
- */
- public void addEventFilter(EventFilter filter)
- {
- synchronized(eventFilters)
- {
- if(!eventFilters.contains(filter))
- {
- eventFilters.add(filter);
- }
- }
- }
-
- /**
- * Unregisteres an <tt>EventFilter</tt> so that it won't check any more
- * if an event should be filtered out.
- *
- * @param filter the <tt>EventFilter</tt> to unregister.
- */
- public void removeEventFilter(EventFilter filter)
- {
- synchronized(eventFilters)
- {
- eventFilters.remove(filter);
- }
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetFileTransferYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetFileTransferYahooImpl.java
deleted file mode 100644
index 85f25b1..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetFileTransferYahooImpl.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.io.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-import ymsg.network.event.*;
-
-/**
- * The Yahoo protocol filetransfer OperationSet.
- *
- * @author Damian Minkov
- */
-public class OperationSetFileTransferYahooImpl
- implements OperationSetFileTransfer,
- SessionFileTransferListener
-{
- /**
- * The logger for this class.
- */
- private static final Logger logger =
- Logger.getLogger(OperationSetFileTransferYahooImpl.class);
-
- /**
- * The provider that created us.
- */
- private final ProtocolProviderServiceYahooImpl yahooProvider;
-
- /**
- * A list of listeners registered for file transfer events.
- */
- private ArrayList<FileTransferListener> fileTransferListeners
- = new ArrayList<FileTransferListener>();
-
- /**
- * A list of active fileTransfers.
- */
- private Hashtable<String, Object> activeFileTransfers
- = new Hashtable<String, Object>();
-
- /**
- * Constructor
- * @param provider is the provider that created us
- */
- public OperationSetFileTransferYahooImpl(
- ProtocolProviderServiceYahooImpl provider)
- {
- this.yahooProvider = provider;
-
- provider.addRegistrationStateChangeListener(
- new RegistrationStateListener());
- }
-
- /**
- * Sends a file transfer request to the given <tt>toContact</tt> by
- * specifying the local and remote file path and the <tt>fromContact</tt>,
- * sending the file.
- *
- * @param toContact the contact that should receive the file
- * @param file the file to send
- *
- * @return the transfer object
- *
- * @throws IllegalStateException if the protocol provider is not registered
- * or connected
- * @throws IllegalArgumentException if some of the arguments doesn't fit the
- * protocol requirements
- */
- public FileTransfer sendFile( Contact toContact,
- File file)
- throws IllegalStateException,
- IllegalArgumentException
- {
- try
- {
- assertConnected();
-
- if(file.length() > getMaximumFileLength())
- throw new IllegalArgumentException(
- "File length exceeds the allowed one for this protocol");
-
- ArrayList<String> filesToSend = new ArrayList<String>();
- filesToSend.add(file.getCanonicalPath());
- Date sentDate = new Date();
- String id = yahooProvider.getYahooSession().sendFiles(
- filesToSend, toContact.getAddress());
-
- FileTransferImpl ft =
- new FileTransferImpl(yahooProvider,
- id, toContact, file, FileTransfer.OUT);
-
- // Notify all interested listeners that a file transfer has been
- // created.
- FileTransferCreatedEvent event
- = new FileTransferCreatedEvent(ft, sentDate);
-
- fireFileTransferCreated(event);
-
- ft.fireStatusChangeEvent(FileTransferStatusChangeEvent.PREPARING);
-
- return ft;
- }
- catch(IOException e)
- {
- logger.error("Cannot send fileTransfer", e);
- return null;
- }
- }
-
- /**
- * Sends a file transfer request to the given <tt>toContact</tt> by
- * specifying the local and remote file path and the <tt>fromContact</tt>,
- * sending the file.
- *
- * @param toContact the contact that should receive the file
- * @param fromContact the contact sending the file
- * @param remotePath the remote file path
- * @param localPath the local file path
- *
- * @return the transfer object
- *
- * @throws IllegalStateException if the protocol provider is not registered
- * or connected
- * @throws IllegalArgumentException if some of the arguments doesn't fit the
- * protocol requirements
- */
- public FileTransfer sendFile( Contact toContact,
- Contact fromContact,
- String remotePath,
- String localPath)
- throws IllegalStateException,
- IllegalArgumentException
- {
- return this.sendFile(toContact, new File(localPath));
- }
-
- /**
- * Adds the given <tt>FileTransferListener</tt> that would listen for
- * file transfer requests and created file transfers.
- *
- * @param listener the <tt>FileTransferListener</tt> to add
- */
- public void addFileTransferListener(
- FileTransferListener listener)
- {
- synchronized(fileTransferListeners)
- {
- if(!fileTransferListeners.contains(listener))
- {
- this.fileTransferListeners.add(listener);
- }
- }
- }
-
- /**
- * Removes the given <tt>FileTransferListener</tt> that listens for
- * file transfer requests and created file transfers.
- *
- * @param listener the <tt>FileTransferListener</tt> to remove
- */
- public void removeFileTransferListener(
- FileTransferListener listener)
- {
- synchronized(fileTransferListeners)
- {
- this.fileTransferListeners.remove(listener);
- }
- }
-
- /**
- * Utility method throwing an exception if the stack is not properly
- * initialized.
- * @throws java.lang.IllegalStateException if the underlying stack is
- * not registered and initialized.
- */
- private void assertConnected()
- throws IllegalStateException
- {
- if (yahooProvider == null)
- throw new IllegalStateException(
- "The provider must be non-null and signed on the "
- +"service before being able to send a file.");
- else if (!yahooProvider.isRegistered())
- throw new IllegalStateException(
- "The provider must be signed on the service before "
- +"being able to send a file.");
- }
-
- /**
- * Delivers the file transfer to all registered listeners.
- *
- * @param event the <tt>FileTransferEvent</tt> that we'd like delivered to
- * all registered file transfer listeners.
- */
- void fireFileTransferCreated(FileTransferCreatedEvent event)
- {
- activeFileTransfers.put(
- event.getFileTransfer().getID(), event.getFileTransfer());
-
- Iterator<FileTransferListener> listeners = null;
- synchronized (fileTransferListeners)
- {
- listeners = new ArrayList<FileTransferListener>
- (fileTransferListeners).iterator();
- }
-
- while (listeners.hasNext())
- {
- FileTransferListener listener = listeners.next();
- listener.fileTransferCreated(event);
- }
- }
-
- /**
- * Delivers the specified event to all registered file transfer listeners.
- *
- * @param event the <tt>EventObject</tt> that we'd like delivered to all
- * registered file transfer listeners.
- */
- void fireFileTransferRequestRejected(FileTransferRequestEvent event)
- {
- Iterator<FileTransferListener> listeners = null;
- synchronized (fileTransferListeners)
- {
- listeners = new ArrayList<FileTransferListener>
- (fileTransferListeners).iterator();
- }
-
- while (listeners.hasNext())
- {
- FileTransferListener listener = listeners.next();
-
- listener.fileTransferRequestRejected(event);
- }
- }
-
- /**
- * Delivers the specified event to all registered file transfer listeners.
- *
- * @param event the <tt>EventObject</tt> that we'd like delivered to all
- * registered file transfer listeners.
- */
- private void fireFileTransferRequest(FileTransferRequestEvent event)
- {
- Iterator<FileTransferListener> listeners = null;
- synchronized (fileTransferListeners)
- {
- listeners = new ArrayList<FileTransferListener>
- (fileTransferListeners).iterator();
- }
-
- while (listeners.hasNext())
- {
- FileTransferListener listener = listeners.next();
-
- listener.fileTransferRequestReceived(event);
- }
- }
-
- /**
- * Delivers the specified event to all registered file transfer listeners.
- *
- * @param event the <tt>EventObject</tt> that we'd like delivered to all
- * registered file transfer listeners.
- */
- void fireFileTransferRequestCanceled(FileTransferRequestEvent event)
- {
- Iterator<FileTransferListener> listeners = null;
- synchronized (fileTransferListeners)
- {
- listeners = new ArrayList<FileTransferListener>
- (fileTransferListeners).iterator();
- }
-
- while (listeners.hasNext())
- {
- FileTransferListener listener = listeners.next();
-
- listener.fileTransferRequestCanceled(event);
- }
- }
-
- private int getStateMapping(int s)
- {
- switch(s)
- {
- case SessionFileTransferEvent.REFUSED :
- return FileTransferStatusChangeEvent.REFUSED;
- case SessionFileTransferEvent.CANCEL :
- return FileTransferStatusChangeEvent.CANCELED;
- case SessionFileTransferEvent.FAILED :
- return FileTransferStatusChangeEvent.FAILED;
- case SessionFileTransferEvent.IN_PROGRESS :
- return FileTransferStatusChangeEvent.IN_PROGRESS;
- case SessionFileTransferEvent.RECEIVED :
- return FileTransferStatusChangeEvent.COMPLETED;
- case SessionFileTransferEvent.SENT :
- return FileTransferStatusChangeEvent.COMPLETED;
- default: return FileTransferStatusChangeEvent.WAITING;
- }
- }
-
- /**
- * Starting point for incoming filetransfer.
- * @param ev
- */
- public void fileTransferRequestReceived(SessionFileTransferEvent ev)
- {
- OperationSetPersistentPresenceYahooImpl opSetPersPresence
- = (OperationSetPersistentPresenceYahooImpl)
- yahooProvider.getOperationSet(
- OperationSetPersistentPresence.class);
-
- Contact sender = opSetPersPresence.findContactByID(ev.getFrom());
-
- if(sender == null)
- return;
-
- Date recvDate = new Date();
-
- for(int i = 0; i < ev.getFileNames().size(); i++)
- {
- String fileName = ev.getFileNames().get(i);
- String fileSize = ev.getFileSizes().get(i);
-
- IncomingFileTransferRequest req =
- new IncomingFileTransferRequestYahooImpl(
- yahooProvider, this, sender, recvDate,
- fileName, fileSize,
- ev.getId());
-
- activeFileTransfers.put(ev.getId(), req);
- fireFileTransferRequest(
- new FileTransferRequestEvent(this, req, recvDate));
- }
- }
-
- /**
- * Status changed for filetransfer.
- * @param ev
- */
- public void statusChanged(SessionFileTransferEvent ev)
- {
- if(ev.getId() == null)
- return;
-
- Object ftObj = activeFileTransfers.get(ev.getId());
-
- if(ftObj == null)
- {
- logger.warn("File Transfer or request not found. " + ev.getId() + "/ " + ev.getState());
- return;
- }
-
- int newState = ev.getState();
-
- if(newState == SessionFileTransferEvent.CANCEL
- || newState == SessionFileTransferEvent.FAILED
- || newState == SessionFileTransferEvent.RECEIVED
- || newState == SessionFileTransferEvent.REFUSED
- || newState == SessionFileTransferEvent.SENT)
- {
- // this is an final state so remove it from active filetransfers
- activeFileTransfers.remove(ev.getId());
- }
-
- if(ftObj instanceof IncomingFileTransferRequest)
- {
- if(newState == SessionFileTransferEvent.REFUSED)
- {
- IncomingFileTransferRequestYahooImpl req =
- (IncomingFileTransferRequestYahooImpl)ftObj;
- fireFileTransferRequestCanceled(
- new FileTransferRequestEvent(this, req, req.getDate()));
- return;
- }
- }
-
- if(!(ftObj instanceof FileTransferImpl))
- {
- logger.warn("File Transfer not found." + ftObj);
- return;
- }
-
- FileTransferImpl ft = (FileTransferImpl)ftObj;
-
- if( newState == SessionFileTransferEvent.IN_PROGRESS)
- {
- // if we start sending progress fire that we are in progress
- if(ev.getProgress() == 0)
- ft.fireStatusChangeEvent(
- FileTransferStatusChangeEvent.IN_PROGRESS);
-
- ft.setTransferedBytes(ev.getProgress());
- ft.fireProgressChangeEvent(
- System.currentTimeMillis(), ev.getProgress());
- }
- else
- ft.fireStatusChangeEvent(getStateMapping(newState));
- }
-
- /**
- * Returns the maximum file length supported by the protocol in bytes.
- * Supports up to 256MB.
- *
- * @return the file length that is supported.
- */
- public long getMaximumFileLength()
- {
- return 268435456l;// = 256*1024*1024;
- }
-
- /**
- * Our listener that will tell us when we're registered to
- */
- private class RegistrationStateListener
- implements RegistrationStateChangeListener
- {
- /**
- * The method is called by a ProtocolProvider implementation whenever
- * a change in the registration state of the corresponding provider had
- * occurred.
- * @param evt ProviderStatusChangeEvent the event describing the status
- * change.
- */
- public void registrationStateChanged(RegistrationStateChangeEvent evt)
- {
- if (logger.isDebugEnabled())
- logger.debug("The provider changed state from: "
- + evt.getOldState()
- + " to: " + evt.getNewState());
-
- if (evt.getNewState() == RegistrationState.REGISTERED)
- {
- yahooProvider.getYahooSession().addSessionFileListener(
- OperationSetFileTransferYahooImpl.this);
- }
- else if (evt.getNewState() == RegistrationState.UNREGISTERED)
- {
- YahooSession ys = yahooProvider.getYahooSession();
- if(ys != null)
- ys.removeSessionFileListener(
- OperationSetFileTransferYahooImpl.this);
- }
- }
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetPersistentPresenceYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetPersistentPresenceYahooImpl.java
deleted file mode 100644
index a99bdb7..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetPersistentPresenceYahooImpl.java
+++ /dev/null
@@ -1,954 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.io.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.service.protocol.yahooconstants.*;
-import net.java.sip.communicator.util.*;
-import ymsg.network.*;
-import ymsg.network.event.*;
-
-/**
- * The Yahoo implementation of a Persistent Presence Operation set. This class
- * manages our own presence status as well as subscriptions for the presence
- * status of our buddies. It also offers methods for retrieving and modifying
- * the buddy contact list and adding listeners for changes in its layout.
- *
- * @author Damian Minkov
- */
-public class OperationSetPersistentPresenceYahooImpl
- extends AbstractOperationSetPersistentPresence<ProtocolProviderServiceYahooImpl>
-{
- private static final Logger logger =
- Logger.getLogger(OperationSetPersistentPresenceYahooImpl.class);
-
- /**
- * Contains our current status message. Note that this field would only
- * be changed once the server has confirmed the new status message and
- * not immediately upon setting a new one..
- */
- private String currentStatusMessage = "";
-
- /**
- * The presence status that we were last notified of entering.
- * The initial one is OFFLINE
- */
- private PresenceStatus currentStatus = YahooStatusEnum.OFFLINE;
-
- /**
- * Sometimes status changes are received before the contact list is inited
- * here we store such events so we can show them correctly
- */
-// private Hashtable earlyStatusChange = new Hashtable();
-
- /**
- * The array list we use when returning from the getSupportedStatusSet()
- * method.
- */
- private static final List<PresenceStatus> supportedPresenceStatusSet = new ArrayList<PresenceStatus>();
- static{
- supportedPresenceStatusSet.add(YahooStatusEnum.AVAILABLE);
- supportedPresenceStatusSet.add(YahooStatusEnum.BE_RIGHT_BACK);
- supportedPresenceStatusSet.add(YahooStatusEnum.BUSY);
- supportedPresenceStatusSet.add(YahooStatusEnum.IDLE);
- supportedPresenceStatusSet.add(YahooStatusEnum.INVISIBLE);
- supportedPresenceStatusSet.add(YahooStatusEnum.NOT_AT_DESK);
- supportedPresenceStatusSet.add(YahooStatusEnum.NOT_AT_HOME);
- supportedPresenceStatusSet.add(YahooStatusEnum.NOT_IN_OFFICE);
- supportedPresenceStatusSet.add(YahooStatusEnum.OFFLINE);
- supportedPresenceStatusSet.add(YahooStatusEnum.ON_THE_PHONE);
- supportedPresenceStatusSet.add(YahooStatusEnum.ON_VACATION);
- supportedPresenceStatusSet.add(YahooStatusEnum.OUT_TO_LUNCH);
- supportedPresenceStatusSet.add(YahooStatusEnum.STEPPED_OUT);
- }
-
- /**
- * A map containing bindings between SIP Communicator's yahoo presence status
- * instances and Yahoo status codes
- */
- private static final Map<PresenceStatus, Long> scToYahooModesMappings
- = new Hashtable<PresenceStatus, Long>();
- static{
- scToYahooModesMappings.put(YahooStatusEnum.AVAILABLE,
- StatusConstants.STATUS_AVAILABLE);
- scToYahooModesMappings.put(YahooStatusEnum.BE_RIGHT_BACK,
- StatusConstants.STATUS_BRB);
- scToYahooModesMappings.put(YahooStatusEnum.BUSY,
- StatusConstants.STATUS_BUSY);
- scToYahooModesMappings.put(YahooStatusEnum.IDLE,
- StatusConstants.STATUS_IDLE);
- scToYahooModesMappings.put(YahooStatusEnum.INVISIBLE,
- StatusConstants.STATUS_INVISIBLE);
- scToYahooModesMappings.put(YahooStatusEnum.NOT_AT_DESK,
- StatusConstants.STATUS_NOTATDESK);
- scToYahooModesMappings.put(YahooStatusEnum.NOT_AT_HOME,
- StatusConstants.STATUS_NOTATHOME);
- scToYahooModesMappings.put(YahooStatusEnum.NOT_IN_OFFICE,
- StatusConstants.STATUS_NOTINOFFICE);
- scToYahooModesMappings.put(YahooStatusEnum.OFFLINE,
- StatusConstants.STATUS_OFFLINE);
- scToYahooModesMappings.put(YahooStatusEnum.ON_THE_PHONE,
- StatusConstants.STATUS_ONPHONE);
- scToYahooModesMappings.put(YahooStatusEnum.ON_VACATION,
- StatusConstants.STATUS_ONVACATION);
- scToYahooModesMappings.put(YahooStatusEnum.OUT_TO_LUNCH,
- StatusConstants.STATUS_OUTTOLUNCH);
- scToYahooModesMappings.put(YahooStatusEnum.STEPPED_OUT,
- StatusConstants.STATUS_STEPPEDOUT);
- }
-
- /**
- * The server stored contact list that will be encapsulating smack's
- * buddy list.
- */
- private ServerStoredContactListYahooImpl ssContactList = null;
-
- /**
- * Listens for events that are fired while registering to server.
- * After we are registered instance is cleared and never used.
- */
- private EarlyEventListener earlyEventListener = null;
-
- /**
- * Status events are received before subscription one.
- * And when subscription is received we deliver
- * and the status events.
- */
- private StatusUpdater statusUpdater = new StatusUpdater();
-
- public OperationSetPersistentPresenceYahooImpl(
- ProtocolProviderServiceYahooImpl provider)
- {
- super(provider);
-
- ssContactList = new ServerStoredContactListYahooImpl( this , provider);
-
- parentProvider.addRegistrationStateChangeListener(
- new RegistrationStateListener());
- }
-
- /**
- * Registers a listener that would receive events upong changes in server
- * stored groups.
- *
- * @param listener a ServerStoredGroupChangeListener impl that would
- * receive events upong group changes.
- */
- @Override
- public void addServerStoredGroupChangeListener(ServerStoredGroupListener
- listener)
- {
- ssContactList.addGroupListener(listener);
- }
-
- /**
- * Creates a group with the specified name and parent in the server
- * stored contact list.
- *
- * @param parent the group where the new group should be created
- * @param groupName the name of the new group to create.
- * @throws OperationFailedException if such group already exists
- */
- public void createServerStoredContactGroup(ContactGroup parent,
- String groupName)
- throws OperationFailedException
- {
- assertConnected();
-
- if (!parent.canContainSubgroups())
- throw new IllegalArgumentException(
- "The specified contact group cannot contain child groups. Group:"
- + parent );
-
- ssContactList.createGroup(groupName);
- }
-
- /**
- * Creates a non persistent contact for the specified address. This would
- * also create (if necessary) a group for volatile contacts that would not
- * be added to the server stored contact list. The volatile contact would
- * remain in the list until it is really added to the contact list or
- * until the application is terminated.
- * @param id the address of the contact to create.
- * @return the newly created volatile <tt>ContactImpl</tt>
- */
- public ContactYahooImpl createVolatileContact(String id)
- {
- return ssContactList.createVolatileContact(id);
- }
-
- /**
- * Creates and returns a unresolved contact from the specified
- * <tt>address</tt> and <tt>persistentData</tt>.
- *
- * @param address an identifier of the contact that we'll be creating.
- * @param persistentData a String returned Contact's getPersistentData()
- * method during a previous run and that has been persistently stored
- * locally.
- * @param parentGroup the group where the unresolved contact is supposed
- * to belong to.
- * @return the unresolved <tt>Contact</tt> created from the specified
- * <tt>address</tt> and <tt>persistentData</tt>
- */
- public Contact createUnresolvedContact(String address,
- String persistentData,
- ContactGroup parentGroup)
- {
- if(! (parentGroup instanceof ContactGroupYahooImpl ||
- parentGroup instanceof RootContactGroupYahooImpl) )
- throw new IllegalArgumentException(
- "Argument is not an yahoo contact group (group="
- + parentGroup + ")");
-
- ContactYahooImpl contact =
- ssContactList.createUnresolvedContact(parentGroup, address);
-
- contact.setPersistentData(persistentData);
-
- return contact;
- }
-
- /**
- * Creates and returns a unresolved contact from the specified
- * <tt>address</tt> and <tt>persistentData</tt>.
- *
- * @param address an identifier of the contact that we'll be creating.
- * @param persistentData a String returned Contact's getPersistentData()
- * method during a previous run and that has been persistently stored
- * locally.
- * @return the unresolved <tt>Contact</tt> created from the specified
- * <tt>address</tt> and <tt>persistentData</tt>
- */
- public Contact createUnresolvedContact(String address,
- String persistentData)
- {
- return createUnresolvedContact( address
- , persistentData
- , getServerStoredContactListRoot());
- }
-
- /**
- * Creates and returns a unresolved contact group from the specified
- * <tt>address</tt> and <tt>persistentData</tt>.
- *
- * @param groupUID an identifier, returned by ContactGroup's
- * getGroupUID, that the protocol provider may use in order to create
- * the group.
- * @param persistentData a String returned ContactGroups's
- * getPersistentData() method during a previous run and that has been
- * persistently stored locally.
- * @param parentGroup the group under which the new group is to be
- * created or null if this is group directly underneath the root.
- * @return the unresolved <tt>ContactGroup</tt> created from the
- * specified <tt>uid</tt> and <tt>persistentData</tt>
- */
- public ContactGroup createUnresolvedContactGroup(String groupUID,
- String persistentData, ContactGroup parentGroup)
- {
- return ssContactList.createUnresolvedContactGroup(groupUID);
- }
-
- /**
- * Returns a reference to the contact with the specified ID in case we
- * have a subscription for it and null otherwise/
- *
- * @param contactID a String identifier of the contact which we're
- * seeking a reference of.
- * @return a reference to the Contact with the specified
- * <tt>contactID</tt> or null if we don't have a subscription for the
- * that identifier.
- */
- public Contact findContactByID(String contactID)
- {
- return ssContactList.findContactById(contactID);
- }
-
- /**
- * Returns the status message that was confirmed by the serfver
- *
- * @return the last status message that we have requested and the aim
- * server has confirmed.
- */
- public String getCurrentStatusMessage()
- {
- return currentStatusMessage;
- }
-
- /**
- * Returns the protocol specific contact instance representing the local
- * user.
- *
- * @return the Contact (address, phone number, or uin) that the Provider
- * implementation is communicating on behalf of.
- */
- public Contact getLocalContact()
- {
- return null;
- }
-
- /**
- * Returns a PresenceStatus instance representing the state this provider
- * is currently in.
- *
- * @return the PresenceStatus last published by this provider.
- */
- public PresenceStatus getPresenceStatus()
- {
- return currentStatus;
- }
-
- /**
- * Returns the root group of the server stored contact list.
- *
- * @return the root ContactGroup for the ContactList stored by this
- * service.
- */
- public ContactGroup getServerStoredContactListRoot()
- {
- return ssContactList.getRootGroup();
- }
-
- /**
- * Returns the set of PresenceStatus objects that a user of this service
- * may request the provider to enter.
- *
- * @return Iterator a PresenceStatus array containing "enterable" status
- * instances.
- */
- public Iterator<PresenceStatus> getSupportedStatusSet()
- {
- return supportedPresenceStatusSet.iterator();
- }
-
- /**
- * Removes the specified contact from its current parent and places it
- * under <tt>newParent</tt>.
- *
- * @param contactToMove the <tt>Contact</tt> to move
- * @param newParent the <tt>ContactGroup</tt> where <tt>Contact</tt>
- * would be placed.
- */
- public void moveContactToGroup(Contact contactToMove,
- ContactGroup newParent)
- {
- assertConnected();
-
- if( !(contactToMove instanceof ContactYahooImpl) )
- throw new IllegalArgumentException(
- "The specified contact is not an yahoo contact." + contactToMove);
- if( !(newParent instanceof ContactGroupYahooImpl) )
- throw new IllegalArgumentException(
- "The specified group is not an yahoo contact group."
- + newParent);
-
- ssContactList.moveContact((ContactYahooImpl)contactToMove,
- (ContactGroupYahooImpl)newParent);
- }
-
- /**
- * Requests the provider to enter into a status corresponding to the
- * specified paramters.
- *
- * @param status the PresenceStatus as returned by
- * getRequestableStatusSet
- * @param statusMessage the message that should be set as the reason to
- * enter that status
- * @throws IllegalArgumentException if the status requested is not a
- * valid PresenceStatus supported by this provider.
- * @throws IllegalStateException if the provider is not currently
- * registered.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * publishing the status fails due to a network error.
- */
- public void publishPresenceStatus(PresenceStatus status,
- String statusMessage) throws
- IllegalArgumentException, IllegalStateException,
- OperationFailedException
- {
- assertConnected();
-
- if (!(status instanceof YahooStatusEnum))
- throw new IllegalArgumentException(
- status + " is not a valid Yahoo status");
-
- if(status.equals(YahooStatusEnum.OFFLINE))
- {
- parentProvider.unregister();
- return;
- }
-
- try
- {
- if(statusMessage != null && statusMessage.length() != 0)
- {
- boolean isAvailable = false;
-
- if(status.equals(YahooStatusEnum.AVAILABLE))
- isAvailable = true;
-
- // false - away
- // true - available
- parentProvider.getYahooSession().
- setStatus(statusMessage, isAvailable);
- }
-
- parentProvider.getYahooSession().setStatus(
- scToYahooModesMappings.get(status).longValue());
-
- fireProviderStatusChangeEvent(currentStatus, status);
- }
- catch(IOException ex)
- {
- throw new OperationFailedException("Failed to set Status",
- OperationFailedException.NETWORK_FAILURE);
- }
- }
-
- /**
- * Get the PresenceStatus for a particular contact.
- *
- * @param contactIdentifier the identifier of the contact whose status
- * we're interested in.
- * @return PresenceStatus the <tt>PresenceStatus</tt> of the specified
- * <tt>contact</tt>
- * @throws IllegalArgumentException if <tt>contact</tt> is not a contact
- * known to the underlying protocol provider
- * @throws IllegalStateException if the underlying protocol provider is
- * not registered/signed on a public service.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * retrieving the status fails due to errors experienced during
- * network communication
- */
- public PresenceStatus queryContactStatus(String contactIdentifier) throws
- IllegalArgumentException, IllegalStateException,
- OperationFailedException
- {
-
- ContactYahooImpl contact = ssContactList.findContactById(contactIdentifier);
- if(contact == null)
- {
- if (logger.isInfoEnabled())
- logger.info("Contact not found id :" + contactIdentifier);
- return null;
- }
- else
- return yahooStatusToPresenceStatus(contact.getSourceContact().getStatus());
- }
-
- /**
- * Removes the specified group from the server stored contact list.
- *
- * @param group the group to remove.
- */
- public void removeServerStoredContactGroup(ContactGroup group)
- {
- assertConnected();
-
- if( !(group instanceof ContactGroupYahooImpl) )
- throw new IllegalArgumentException(
- "The specified group is not an yahoo contact group: " + group);
-
- ssContactList.removeGroup(((ContactGroupYahooImpl)group));
- }
-
- /**
- * Removes the specified group change listener so that it won't receive
- * any further events.
- *
- * @param listener the ServerStoredGroupChangeListener to remove
- */
- @Override
- public void removeServerStoredGroupChangeListener(ServerStoredGroupListener
- listener)
- {
- ssContactList.removeGroupListener(listener);
- }
-
- /**
- * Renames the specified group from the server stored contact list.
- *
- * @param group the group to rename.
- * @param newName the new name of the group.
- */
- public void renameServerStoredContactGroup(ContactGroup group,
- String newName)
- {
- assertConnected();
-
- if( !(group instanceof ContactGroupYahooImpl) )
- throw new IllegalArgumentException(
- "The specified group is not an yahoo contact group: " + group);
-
- throw new UnsupportedOperationException("Renaming group not supported!");
- //ssContactList.renameGroup((ContactGroupYahooImpl)group, newName);
- }
-
- /**
- * Handler for incoming authorization requests.
- *
- * @param handler an instance of an AuthorizationHandler for
- * authorization requests coming from other users requesting
- * permission add us to their contact list.
- */
- public void setAuthorizationHandler(AuthorizationHandler handler)
- {
- ssContactList.setAuthorizationHandler(handler);
-
- // we got a handler. Lets process if something has came
- // during login process
- if(earlyEventListener != null)
- {
- earlyEventListener.processEarlyAuthorizations();
- earlyEventListener = null;
- }
- }
-
- /**
- * Persistently adds a subscription for the presence status of the
- * contact corresponding to the specified contactIdentifier and indicates
- * that it should be added to the specified group of the server stored
- * contact list.
- *
- * @param parent the parent group of the server stored contact list
- * where the contact should be added. <p>
- * @param contactIdentifier the contact whose status updates we are
- * subscribing for.
- * @throws IllegalArgumentException if <tt>contact</tt> or
- * <tt>parent</tt> are not a contact known to the underlying protocol
- * provider.
- * @throws IllegalStateException if the underlying protocol provider is
- * not registered/signed on a public service.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * subscribing fails due to errors experienced during network
- * communication
- */
- public void subscribe(ContactGroup parent, String contactIdentifier) throws
- IllegalArgumentException, IllegalStateException,
- OperationFailedException
- {
- assertConnected();
-
- if(! (parent instanceof ContactGroupYahooImpl) )
- throw new IllegalArgumentException(
- "Argument is not an yahoo contact group (group=" + parent + ")");
-
- ssContactList.addContact((ContactGroupYahooImpl)parent, contactIdentifier);
- }
-
- /**
- * Adds a subscription for the presence status of the contact
- * corresponding to the specified contactIdentifier.
- *
- * @param contactIdentifier the identifier of the contact whose status
- * updates we are subscribing for. <p>
- * @throws IllegalArgumentException if <tt>contact</tt> is not a contact
- * known to the underlying protocol provider
- * @throws IllegalStateException if the underlying protocol provider is
- * not registered/signed on a public service.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * subscribing fails due to errors experienced during network
- * communication
- */
- public void subscribe(String contactIdentifier) throws
- IllegalArgumentException, IllegalStateException,
- OperationFailedException
- {
- assertConnected();
-
- ssContactList.addContact(contactIdentifier);
- }
-
- /**
- * Removes a subscription for the presence status of the specified
- * contact.
- *
- * @param contact the contact whose status updates we are unsubscribing
- * from.
- * @throws IllegalArgumentException if <tt>contact</tt> is not a contact
- * known to the underlying protocol provider
- * @throws IllegalStateException if the underlying protocol provider is
- * not registered/signed on a public service.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * unsubscribing fails due to errors experienced during network
- * communication
- */
- public void unsubscribe(Contact contact) throws IllegalArgumentException,
- IllegalStateException, OperationFailedException
- {
- assertConnected();
-
- if(! (contact instanceof ContactYahooImpl) )
- throw new IllegalArgumentException(
- "Argument is not an yahoo contact (contact=" + contact + ")");
-
- ssContactList.removeContact((ContactYahooImpl)contact);
- }
-
- /**
- * Converts the specified yahoo status to one of the status fields of the
- * YahooStatusEnum class.
- *
- * @param status the yahoo Status
- * @return a PresenceStatus instance representation of the yahoo Status
- * parameter. The returned result is one of the YahooStatusEnum fields.
- */
- YahooStatusEnum yahooStatusToPresenceStatus(long status)
- {
- if(status == StatusConstants.STATUS_AVAILABLE)
- return YahooStatusEnum.AVAILABLE;
- else if(status == StatusConstants.STATUS_BRB)
- return YahooStatusEnum.BE_RIGHT_BACK;
- else if(status == StatusConstants.STATUS_BUSY)
- return YahooStatusEnum.BUSY;
- else if(status == StatusConstants.STATUS_NOTATHOME)
- return YahooStatusEnum.NOT_AT_HOME;
- else if(status == StatusConstants.STATUS_NOTATDESK)
- return YahooStatusEnum.NOT_AT_DESK;
- else if(status == StatusConstants.STATUS_NOTINOFFICE)
- return YahooStatusEnum.NOT_IN_OFFICE;
- else if(status == StatusConstants.STATUS_ONPHONE)
- return YahooStatusEnum.ON_THE_PHONE;
- else if(status == StatusConstants.STATUS_ONVACATION)
- return YahooStatusEnum.ON_VACATION;
- else if(status == StatusConstants.STATUS_OUTTOLUNCH)
- return YahooStatusEnum.OUT_TO_LUNCH;
- else if(status == StatusConstants.STATUS_STEPPEDOUT)
- return YahooStatusEnum.STEPPED_OUT;
- else if(status == StatusConstants.STATUS_INVISIBLE)
- return YahooStatusEnum.INVISIBLE;
- else if(status == StatusConstants.STATUS_IDLE)
- return YahooStatusEnum.IDLE;
- else if(status == StatusConstants.STATUS_OFFLINE)
- return YahooStatusEnum.OFFLINE;
- // Yahoo supports custom statuses so if such is set just return available
- else
- return YahooStatusEnum.AVAILABLE;
- }
-
- /**
- * Utility method throwing an exception if the stack is not properly
- * initialized.
- * @throws java.lang.IllegalStateException if the underlying stack is
- * not registered and initialized.
- */
- private void assertConnected() throws IllegalStateException
- {
- if (parentProvider == null)
- throw new IllegalStateException(
- "The provider must be non-null and signed on the yahoo "
- +"service before being able to communicate.");
- if (!parentProvider.isRegistered())
- throw new IllegalStateException(
- "The provider must be signed on the yahoo service before "
- +"being able to communicate.");
- }
-
- /**
- * Notify all provider presence listeners of the corresponding event change
- *
- * @param oldStatus
- * the status our stack had so far
- * @param newStatus
- * the status we have from now on
- */
- @Override
- protected void fireProviderStatusChangeEvent(
- PresenceStatus oldStatus,
- PresenceStatus newStatus)
- {
- if (!oldStatus.equals(newStatus))
- {
- currentStatus = newStatus;
-
- super.fireProviderStatusChangeEvent(oldStatus, newStatus);
- }
- }
-
- /**
- * Statuses have been received durring login process
- * so we will init them once we are logged in
- */
- private void initContactStatuses()
- {
- YahooGroup[] groups = parentProvider.getYahooSession().getGroups();
-
- for (YahooGroup item : groups)
- {
- @SuppressWarnings("unchecked")
- Iterable<YahooUser> members = item.getMembers();
-
- for (YahooUser user : members)
- {
- ContactYahooImpl sourceContact =
- ssContactList.findContactById(user.getId());
-
- if(sourceContact != null)
- handleContactStatusChange(sourceContact, user);
- }
- }
- }
-
- /**
- * Our listener that will tell us when we're registered to server
- * and is ready to accept us as a listener.
- */
- private class RegistrationStateListener
- implements RegistrationStateChangeListener
- {
- /**
- * The method is called by a ProtocolProvider implementation whenever
- * a change in the registration state of the corresponding provider had
- * occurred.
- * @param evt ProviderStatusChangeEvent the event describing the status
- * change.
- */
- public void registrationStateChanged(RegistrationStateChangeEvent evt)
- {
- if (logger.isDebugEnabled())
- logger.debug("The yahoo provider changed state from: "
- + evt.getOldState()
- + " to: " + evt.getNewState());
-
- if(evt.getNewState() == RegistrationState.REGISTERING)
- {
- // add new listener waiting for events during login process
- earlyEventListener
- = new EarlyEventListener(parentProvider.getYahooSession());
- }
- else if(evt.getNewState() == RegistrationState.REGISTERED)
- {
- parentProvider.getYahooSession().
- addSessionListener(new StatusChangedListener());
-
- ssContactList.setYahooSession(parentProvider.getYahooSession());
-
- initContactStatuses();
-
- addSubscriptionListener(statusUpdater);
-
- if(earlyEventListener != null)
- {
- earlyEventListener.dispose();
- earlyEventListener = null;
- }
- }
- else if(evt.getNewState() == RegistrationState.UNREGISTERED
- || evt.getNewState() == RegistrationState.AUTHENTICATION_FAILED
- || evt.getNewState() == RegistrationState.CONNECTION_FAILED)
- {
- //since we are disconnected, we won't receive any further status
- //updates so we need to change by ourselves our own status as
- //well as set to offline all contacts in our contact list that
- //were online
- PresenceStatus oldStatus = currentStatus;
- currentStatus = YahooStatusEnum.OFFLINE;
-
- fireProviderStatusChangeEvent(oldStatus, currentStatus);
-
- removeSubscriptionListener(statusUpdater);
-
- //send event notifications saying that all our buddies are
- //offline. The protocol does not implement top level buddies
- //nor subgroups for top level groups so a simple nested loop
- //would be enough.
- Iterator<ContactGroup> groupsIter =
- getServerStoredContactListRoot().subgroups();
- while(groupsIter.hasNext())
- {
- ContactGroup group = groupsIter.next();
- Iterator<Contact> contactsIter = group.contacts();
-
- while(contactsIter.hasNext())
- {
- ContactYahooImpl contact
- = (ContactYahooImpl)contactsIter.next();
-
- PresenceStatus oldContactStatus
- = contact.getPresenceStatus();
-
- if(!oldContactStatus.isOnline())
- continue;
-
- contact.updatePresenceStatus(YahooStatusEnum.OFFLINE);
-
- fireContactPresenceStatusChangeEvent(
- contact
- , contact.getParentContactGroup()
- , oldContactStatus, YahooStatusEnum.OFFLINE);
- }
- }
-
- // clear listener
- if(earlyEventListener != null)
- {
- earlyEventListener.dispose();
- earlyEventListener = null;
- }
- }
- }
- }
-
- private void handleContactStatusChange(YahooUser yFriend)
- {
- ContactYahooImpl sourceContact =
- ssContactList.findContactById(yFriend.getId());
-
- if(sourceContact == null)
- {
- if(parentProvider.getAccountID().getUserID().
- equals(yFriend.getId()))
- {
- // thats my own status
- if (logger.isTraceEnabled())
- logger.trace("Own status changed to " + yFriend.getStatus());
- PresenceStatus oldStatus = currentStatus;
- currentStatus =
- yahooStatusToPresenceStatus(yFriend.getStatus());
- fireProviderStatusChangeEvent(oldStatus, currentStatus);
-
- return;
- }
- // strange
- else
- return;
- }
-
- handleContactStatusChange(sourceContact, yFriend);
- }
-
- void handleContactStatusChange(ContactYahooImpl sourceContact, YahooUser yFriend)
- {
- PresenceStatus oldStatus
- = sourceContact.getPresenceStatus();
-
- PresenceStatus newStatus = yahooStatusToPresenceStatus(yFriend.getStatus());
-
- // statuses maybe the same and only change in status message
- sourceContact.setStatusMessage(yFriend.getCustomStatusMessage());
-
- // when old and new status are the same do nothing - no change
- if(oldStatus.equals(newStatus))
- {
- if (logger.isDebugEnabled())
- logger.debug("old(" + oldStatus + ") and new("+ newStatus + ") statuses are the same!");
- return;
- }
-
- sourceContact.updatePresenceStatus(newStatus);
-
- ContactGroup parent
- = ssContactList.findContactGroup(sourceContact);
-
- if (logger.isDebugEnabled())
- logger.debug("Will Dispatch the contact status event.");
- fireContactPresenceStatusChangeEvent(sourceContact, parent,
- oldStatus, newStatus);
- }
-
- private class StatusChangedListener
- extends SessionAdapter
- {
- @Override
- public void friendsUpdateReceived(SessionFriendEvent evt)
- {
- if (logger.isDebugEnabled())
- logger.debug("Received a status update for contact " + evt);
-
- if(evt.getFriend() != null)
- {
- handleContactStatusChange(evt.getFriend());
- }
- else if(evt.getFriends() != null)
- {
- YahooUser[] yfs = evt.getFriends();
- for (int i = 0; i < yfs.length; i++)
- handleContactStatusChange(yfs[i]);
- }
- }
- }
-
- /**
- * Updates the statuses of newly created persistent contacts
- */
- private class StatusUpdater
- extends SubscriptionAdapter
- {
- @Override
- public void subscriptionCreated(SubscriptionEvent evt)
- {
- ContactYahooImpl contact =
- (ContactYahooImpl)evt.getSourceContact();
-
- if(!contact.isPersistent() || !contact.isResolved())
- return;
-
- handleContactStatusChange(contact, contact.getSourceContact());
- }
- }
-
- private class EarlyEventListener
- extends SessionAdapter
- {
- private final List<SessionAuthorizationEvent> receivedAuthorizations
- = new Vector<SessionAuthorizationEvent>();
-
- /**
- * The <code>YahooSession</code> this instance is listening to because
- * the <code>YahooSession</code> isn't available in
- * <code>parentProvider</code> after
- * {@link RegistrationState#UNREGISTERED} and then this listener cannot
- * be removed.
- */
- private final YahooSession yahooSession;
-
- public EarlyEventListener(YahooSession yahooSession)
- {
- this.yahooSession = yahooSession;
- this.yahooSession.addSessionListener(this);
- }
-
- @Override
- public void authorizationReceived(SessionAuthorizationEvent ev)
- {
- if(ev.isAuthorizationRequest())
- {
- if (logger.isTraceEnabled())
- logger.trace("authorizationRequestReceived from " +
- ev.getFrom());
- receivedAuthorizations.add(ev);
- }
- }
-
- public void dispose()
- {
- yahooSession.removeSessionListener(this);
- }
-
- public void processEarlyAuthorizations()
- {
- for (SessionAuthorizationEvent e : receivedAuthorizations)
- {
- ssContactList.processAuthorizationRequest(e);
- }
- }
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetTypingNotificationsYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetTypingNotificationsYahooImpl.java
deleted file mode 100644
index 81e266a..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetTypingNotificationsYahooImpl.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-import ymsg.network.event.*;
-
-/**
- * Maps SIP Communicator typing notifications to those going and coming from
- * smack lib.
- *
- * @author Damian Minkov
- */
-public class OperationSetTypingNotificationsYahooImpl
- extends AbstractOperationSetTypingNotifications<ProtocolProviderServiceYahooImpl>
-{
- private static final Logger logger =
- Logger.getLogger(OperationSetTypingNotificationsYahooImpl.class);
-
- /**
- * An active instance of the opSetPersPresence operation set. We're using
- * it to map incoming events to contacts in our contact list.
- */
- private OperationSetPersistentPresenceYahooImpl opSetPersPresence = null;
-
- /**
- * @param provider a ref to the <tt>ProtocolProviderServiceImpl</tt>
- * that created us and that we'll use for retrieving the underlying aim
- * connection.
- */
- OperationSetTypingNotificationsYahooImpl(
- ProtocolProviderServiceYahooImpl provider)
- {
- super(provider);
-
- provider.addRegistrationStateChangeListener(new ProviderRegListener());
- }
-
- /**
- * Sends a notification to <tt>notifiedContatct</tt> that we have entered
- * <tt>typingState</tt>.
- *
- * @param notifiedContact the <tt>Contact</tt> to notify
- * @param typingState the typing state that we have entered.
- *
- * @throws java.lang.IllegalStateException if the underlying stack is
- * not registered and initialized.
- * @throws java.lang.IllegalArgumentException if <tt>notifiedContact</tt> is
- * not an instance belonging to the underlying implementation.
- */
- public void sendTypingNotification(Contact notifiedContact, int typingState)
- throws IllegalStateException, IllegalArgumentException
- {
- assertConnected();
-
- if( !(notifiedContact instanceof ContactYahooImpl) )
- throw new IllegalArgumentException(
- "The specified contact is not an yahoo contact."
- + notifiedContact);
-
- if(typingState == OperationSetTypingNotifications.STATE_TYPING)
- {
-
- parentProvider.getYahooSession().
- keyTyped(notifiedContact.getAddress(),
- parentProvider.getAccountID().getUserID());
- }
- else
- if(typingState == OperationSetTypingNotifications.STATE_STOPPED ||
- typingState == OperationSetTypingNotifications.STATE_PAUSED)
- {
- parentProvider.getYahooSession().
- stopTyping(notifiedContact.getAddress(),
- parentProvider.getAccountID().getUserID());
- }
- }
-
- private class TypingListener
- extends SessionAdapter
- {
- @Override
- public void notifyReceived(SessionNotifyEvent evt)
- {
- if(evt.isTyping())
- {
- String typingUserID = evt.getFrom();
-
- if(typingUserID != null)
- {
- Contact sourceContact =
- opSetPersPresence.findContactByID(typingUserID);
-
- if(sourceContact == null)
- return;
-
- // typing on
- fireTypingNotificationsEvent(
- sourceContact,
- (evt.getMode() == 1) ? STATE_TYPING : STATE_STOPPED);
- }
- }
- }
- }
-
- /**
- * Our listener that will tell us when we're registered and
- * ready to accept us as a listener.
- */
- private class ProviderRegListener
- implements RegistrationStateChangeListener
- {
- /**
- * The method is called by a ProtocolProvider implementation whenever
- * a change in the registration state of the corresponding provider had
- * occurred.
- * @param evt ProviderStatusChangeEvent the event describing the status
- * change.
- */
- public void registrationStateChanged(RegistrationStateChangeEvent evt)
- {
- if (logger.isDebugEnabled())
- logger.debug("The provider changed state from: "
- + evt.getOldState()
- + " to: " + evt.getNewState());
- if (evt.getNewState() == RegistrationState.REGISTERED)
- {
- opSetPersPresence =
- (OperationSetPersistentPresenceYahooImpl) parentProvider
- .getOperationSet(OperationSetPersistentPresence.class);
-
- parentProvider
- .getYahooSession().addSessionListener(new TypingListener());
- }
- }
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolIconYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolIconYahooImpl.java
deleted file mode 100644
index 34befc9..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolIconYahooImpl.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.io.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.resources.*;
-import org.osgi.framework.*;
-
-/**
- * Represents the Yahoo protocol icon. Implements the <tt>ProtocolIcon</tt>
- * interface in order to provide an Yahoo icon image in two different sizes.
- *
- * @author Yana Stamcheva
- */
-public class ProtocolIconYahooImpl
- implements ProtocolIcon
-{
- private static Logger logger = Logger.getLogger(ProtocolIconYahooImpl.class);
-
- private static ResourceManagementService resourcesService;
-
- /**
- * A hash table containing the protocol icon in different sizes.
- */
- private static Hashtable<String, byte[]> iconsTable
- = new Hashtable<String, byte[]>();
- static
- {
- iconsTable.put(ProtocolIcon.ICON_SIZE_16x16,
- getImageInBytes("service.protocol.yahoo.YAHOO_16x16"));
-
- iconsTable.put(ProtocolIcon.ICON_SIZE_32x32,
- getImageInBytes("service.protocol.yahoo.YAHOO_32x32"));
-
- iconsTable.put(ProtocolIcon.ICON_SIZE_48x48,
- getImageInBytes("service.protocol.yahoo.YAHOO_48x48"));
-
- iconsTable.put(ProtocolIcon.ICON_SIZE_64x64,
- getImageInBytes("service.protocol.yahoo.YAHOO_64x64"));
- }
-
- /**
- * A hash table containing the protocol icon in different sizes.
- */
- private static Hashtable<String, String> iconPathsTable
- = new Hashtable<String, String>();
- static
- {
- iconPathsTable.put(ProtocolIcon.ICON_SIZE_16x16,
- getResources().getImagePath("service.protocol.yahoo.YAHOO_16x16"));
-
- iconPathsTable.put(ProtocolIcon.ICON_SIZE_32x32,
- getResources().getImagePath("service.protocol.yahoo.YAHOO_32x32"));
-
- iconPathsTable.put(ProtocolIcon.ICON_SIZE_48x48,
- getResources().getImagePath("service.protocol.yahoo.YAHOO_48x48"));
-
- iconPathsTable.put(ProtocolIcon.ICON_SIZE_64x64,
- getResources().getImagePath("service.protocol.yahoo.YAHOO_64x64"));
- }
-
- /**
- * Implements the <tt>ProtocolIcon.getSupportedSizes()</tt> method. Returns
- * an iterator to a set containing the supported icon sizes.
- * @return an iterator to a set containing the supported icon sizes
- */
- public Iterator<String> getSupportedSizes()
- {
- return iconsTable.keySet().iterator();
- }
-
- /**
- * Returns TRUE if a icon with the given size is supported, FALSE-otherwise.
- */
- public boolean isSizeSupported(String iconSize)
- {
- return iconsTable.containsKey(iconSize);
- }
-
- /**
- * Returns the icon image in the given size.
- * @param iconSize the icon size; one of ICON_SIZE_XXX constants
- */
- public byte[] getIcon(String iconSize)
- {
- return iconsTable.get(iconSize);
- }
-
- /**
- * Returns a path to the icon with the given size.
- * @param iconSize the size of the icon we're looking for
- * @return the path to the icon with the given size
- */
- public String getIconPath(String iconSize)
- {
- return iconPathsTable.get(iconSize);
- }
-
- /**
- * Returns the icon image used to represent the protocol connecting state.
- * @return the icon image used to represent the protocol connecting state
- */
- public byte[] getConnectingIcon()
- {
- return getImageInBytes("yahooConnectingIcon");
- }
-
- /**
- * Returns the byte representation of the image corresponding to the given
- * identifier.
- *
- * @param imageID the identifier of the image
- * @return the byte representation of the image corresponding to the given
- * identifier.
- */
- public static byte[] getImageInBytes(String imageID)
- {
- InputStream in = getResources().getImageInputStream(imageID);
-
- if (in == null)
- return null;
- byte[] image = null;
- try
- {
- image = new byte[in.available()];
-
- in.read(image);
- }
- catch (IOException e)
- {
- logger.error("Failed to load image:" + imageID, e);
- }
-
- return image;
- }
-
- public static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- {
- ServiceReference serviceReference = YahooActivator.getBundleContext()
- .getServiceReference(ResourceManagementService.class.getName());
-
- if(serviceReference == null)
- return null;
-
- resourcesService = (ResourceManagementService)
- YahooActivator.getBundleContext().getService(serviceReference);
- }
-
- return resourcesService;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderFactoryYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderFactoryYahooImpl.java
deleted file mode 100644
index 358286c..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderFactoryYahooImpl.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-import org.osgi.framework.*;
-
-/**
- * The Yahoo implementation of the ProtocolProviderFactory.
- * @author Damian Minkov
- */
-public class ProtocolProviderFactoryYahooImpl
- extends ProtocolProviderFactory
-{
-
- /**
- * Creates an instance of the ProtocolProviderFactoryYahooImpl.
- */
- protected ProtocolProviderFactoryYahooImpl()
- {
- super(YahooActivator.getBundleContext(), ProtocolNames.YAHOO);
- }
-
- /**
- * Initializes and creates an account corresponding to the specified
- * accountProperties and registers the resulting ProtocolProvider in the
- * <tt>context</tt> BundleContext parameter. This method has a persistent
- * effect. Once created the resulting account will remain installed until
- * removed through the uninstall account method.
- *
- * @param userIDStr the user identifier for the new account
- * @param accountProperties a set of protocol (or implementation)
- * specific properties defining the new account.
- * @return the AccountID of the newly created account
- */
- @Override
- public AccountID installAccount( String userIDStr,
- Map<String, String> accountProperties)
- {
- BundleContext context
- = YahooActivator.getBundleContext();
- if (context == null)
- throw new NullPointerException("The specified BundleContext was null");
-
- if (userIDStr == null)
- throw new NullPointerException("The specified AccountID was null");
-
- if (accountProperties == null)
- throw new NullPointerException("The specified property map was null");
-
- accountProperties.put(USER_ID, userIDStr);
-
- AccountID accountID = new YahooAccountID(userIDStr, accountProperties);
-
- //make sure we haven't seen this account id before.
- if( registeredAccounts.containsKey(accountID) )
- throw new IllegalStateException(
- "An account for id " + userIDStr + " was already installed!");
-
- //first store the account and only then load it as the load generates
- //an osgi event, the osgi event triggers (through the UI) a call to
- //the register() method and it needs to access the configuration service
- //and check for a password.
- this.storeAccount(accountID, false);
-
- accountID = loadAccount(accountProperties);
-
- return accountID;
- }
-
- @Override
- protected AccountID createAccountID(String userID, Map<String, String> accountProperties)
- {
- return new YahooAccountID(userID, accountProperties);
- }
-
- @Override
- protected ProtocolProviderService createService(String userID,
- AccountID accountID)
- {
- ProtocolProviderServiceYahooImpl service =
- new ProtocolProviderServiceYahooImpl();
-
- service.initialize(userID, accountID);
- return service;
- }
-
- @Override
- public void modifyAccount( ProtocolProviderService protocolProvider,
- Map<String, String> accountProperties)
- throws NullPointerException
- {
- BundleContext context
- = YahooActivator.getBundleContext();
-
- if (context == null)
- throw new NullPointerException(
- "The specified BundleContext was null");
-
- if (protocolProvider == null)
- throw new NullPointerException(
- "The specified Protocol Provider was null");
-
- YahooAccountID accountID
- = (YahooAccountID) protocolProvider.getAccountID();
-
- // If the given accountID doesn't correspond to an existing account
- // we return.
- if(!registeredAccounts.containsKey(accountID))
- return;
-
- ServiceRegistration registration = registeredAccounts.get(accountID);
-
- // kill the service
- if (registration != null)
- registration.unregister();
-
- if (accountProperties == null)
- throw new NullPointerException(
- "The specified property map was null");
-
- accountProperties.put(USER_ID, accountID.getUserID());
-
- if (!accountProperties.containsKey(PROTOCOL))
- accountProperties.put(PROTOCOL, ProtocolNames.YAHOO);
-
- accountID.setAccountProperties(accountProperties);
-
- // First store the account and only then load it as the load generates
- // an osgi event, the osgi event triggers (trhgough the UI) a call to
- // the register() method and it needs to acces the configuration service
- // and check for a password.
- this.storeAccount(accountID);
-
- Hashtable<String, String> properties = new Hashtable<String, String>();
- properties.put(PROTOCOL, ProtocolNames.YAHOO);
- properties.put(USER_ID, accountID.getUserID());
-
- ((ProtocolProviderServiceYahooImpl)protocolProvider)
- .initialize(accountID.getUserID(), accountID);
-
- // We store again the account in order to store all properties added
- // during the protocol provider initialization.
- this.storeAccount(accountID);
-
- registration
- = context.registerService(
- ProtocolProviderService.class.getName(),
- protocolProvider,
- properties);
-
- registeredAccounts.put(accountID, registration);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java
deleted file mode 100644
index 264aaab..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java
+++ /dev/null
@@ -1,574 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.io.*;
-
-import net.java.sip.communicator.service.dns.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-import ymsg.network.*;
-import ymsg.network.event.*;
-
-/**
- * An implementation of the protocol provider service over the Yahoo protocol
- *
- * @author Damian Minkov
- */
-public class ProtocolProviderServiceYahooImpl
- extends AbstractProtocolProviderService
-{
- /**
- * This class logger.
- */
- private static final Logger logger =
- Logger.getLogger(ProtocolProviderServiceYahooImpl.class);
-
- /**
- * The current yahoo session.
- */
- private YahooSession yahooSession = null;
-
- /**
- * indicates whether or not the provider is initialized and ready for use.
- */
- private boolean isInitialized = false;
-
- /**
- * We use this to lock access to initialization.
- */
- private final Object initializationLock = new Object();
-
- /**
- * The identifier of the account that this provider represents.
- */
- private AccountID accountID = null;
-
- /**
- * Used when we need to re-register
- */
- private SecurityAuthority authority = null;
-
- /**
- * The persistent presence operations set.
- */
- private OperationSetPersistentPresenceYahooImpl persistentPresence = null;
-
- /**
- * Typing notifications operations set.
- */
- private OperationSetTypingNotificationsYahooImpl typingNotifications = null;
-
- /**
- * The logo corresponding to the msn protocol.
- */
- private ProtocolIconYahooImpl yahooIcon
- = new ProtocolIconYahooImpl();
-
- /**
- * The connection listener.
- */
- private YahooConnectionListener connectionListener = null;
-
- /**
- * Returns the state of the registration of this protocol provider
- * @return the <tt>RegistrationState</tt> that this provider is
- * currently in or null in case it is in a unknown state.
- */
- public RegistrationState getRegistrationState()
- {
- if(yahooSession != null &&
- yahooSession.getSessionStatus() == StatusConstants.MESSAGING)
- return RegistrationState.REGISTERED;
- else
- return RegistrationState.UNREGISTERED;
- }
-
- /**
- * Starts the registration process. Connection details such as
- * registration server, user name/number are provided through the
- * configuration service through implementation specific properties.
- *
- * @param authority the security authority that will be used for resolving
- * any security challenges that may be returned during the
- * registration or at any moment while wer're registered.
- * @throws OperationFailedException with the corresponding code it the
- * registration fails for some reason (e.g. a networking error or an
- * implementation problem).
- */
- public void register(final SecurityAuthority authority)
- throws OperationFailedException
- {
- if(authority == null)
- throw new IllegalArgumentException(
- "The register method needs a valid non-null authority impl "
- + " in order to be able and retrieve passwords.");
-
- this.authority = authority;
-
- connectAndLogin(authority, SecurityAuthority.AUTHENTICATION_REQUIRED);
- }
-
- /**
- * Connects and logins to the server
- * @param authority SecurityAuthority
- * @param authReasonCode the authentication reason code, which should
- * indicate why are making an authentication request
- * @throws OperationFailedException if login parameters
- * as server port are not correct
- */
- private void connectAndLogin( SecurityAuthority authority,
- int authReasonCode)
- throws OperationFailedException
- {
- synchronized(initializationLock)
- {
- //verify whether a password has already been stored for this account
- String password = YahooActivator.
- getProtocolProviderFactory().loadPassword(getAccountID());
-
- // If the password hasn't been saved or the reason is one of those
- // listed below we need to ask the user for credentials again.
- if (password == null
- || authReasonCode == SecurityAuthority.WRONG_PASSWORD
- || authReasonCode == SecurityAuthority.WRONG_USERNAME)
- {
- //create a default credentials object
- UserCredentials credentials = new UserCredentials();
- credentials.setUserName(getAccountID().getUserID());
-
- //request a password from the user
- credentials = authority.obtainCredentials(
- getAccountID().getDisplayName(),
- credentials,
- authReasonCode);
-
- // in case user has canceled the login window
- if(credentials == null)
- {
- fireRegistrationStateChanged(
- getRegistrationState(),
- RegistrationState.UNREGISTERED,
- RegistrationStateChangeEvent.REASON_USER_REQUEST, "");
- return;
- }
-
- //extract the password the user passed us.
- char[] pass = credentials.getPassword();
-
- // the user didn't provide us a password (canceled the operation)
- if(pass == null)
- {
- fireRegistrationStateChanged(
- getRegistrationState(),
- RegistrationState.UNREGISTERED,
- RegistrationStateChangeEvent.REASON_USER_REQUEST, "");
- return;
- }
- password = new String(pass);
-
- if (credentials.isPasswordPersistent())
- {
- YahooActivator.getProtocolProviderFactory()
- .storePassword(getAccountID(), password);
- }
- }
-
- yahooSession = new YahooSession();
- connectionListener = new YahooConnectionListener();
- yahooSession.addSessionListener(connectionListener);
-
- try
- {
- fireRegistrationStateChanged(
- getRegistrationState(),
- RegistrationState.REGISTERING,
- RegistrationStateChangeEvent.REASON_NOT_SPECIFIED, null);
-
- yahooSession.login(getAccountID().getUserID(), password);
-
- if(yahooSession.getSessionStatus()==StatusConstants.MESSAGING)
- {
- persistentPresence.fireProviderStatusChangeEvent(
- persistentPresence.getPresenceStatus(),
- persistentPresence.yahooStatusToPresenceStatus(
- yahooSession.getStatus()));
-
- fireRegistrationStateChanged(
- getRegistrationState(),
- RegistrationState.REGISTERED,
- RegistrationStateChangeEvent.REASON_NOT_SPECIFIED, null);
- }
- else
- {
- fireRegistrationStateChanged(
- getRegistrationState(),
- RegistrationState.UNREGISTERED,
- RegistrationStateChangeEvent.REASON_NOT_SPECIFIED, null);
- }
- }
- catch (LoginRefusedException ex)
- {
- if(ex.getStatus() == StatusConstants.STATUS_BADUSERNAME)
- {
- fireRegistrationStateChanged(
- getRegistrationState(),
- RegistrationState.AUTHENTICATION_FAILED,
- RegistrationStateChangeEvent.REASON_NON_EXISTING_USER_ID,
- null);
-
- reregister(SecurityAuthority.WRONG_USERNAME);
- }
- else if(ex.getStatus() == StatusConstants.STATUS_BAD)
- {
- YahooActivator.getProtocolProviderFactory()
- .storePassword(getAccountID(), null);
-
- fireRegistrationStateChanged(
- getRegistrationState(),
- RegistrationState.AUTHENTICATION_FAILED,
- RegistrationStateChangeEvent.REASON_AUTHENTICATION_FAILED,
- null);
-
- // Try to re-register and ask the user to retype the password.
- reregister(SecurityAuthority.WRONG_PASSWORD);
- }
- else if(ex.getStatus() == StatusConstants.STATUS_LOCKED)
- {
- fireRegistrationStateChanged(
- getRegistrationState(),
- RegistrationState.AUTHENTICATION_FAILED,
- RegistrationStateChangeEvent.REASON_RECONNECTION_RATE_LIMIT_EXCEEDED,
- null);
- }
- }
- catch (IOException ex)
- {
- fireRegistrationStateChanged(
- getRegistrationState(),
- RegistrationState.CONNECTION_FAILED,
- RegistrationStateChangeEvent.REASON_NOT_SPECIFIED, null);
- }
- catch (DnssecRuntimeException ex)
- {
- fireRegistrationStateChanged(
- getRegistrationState(),
- RegistrationState.UNREGISTERED,
- RegistrationStateChangeEvent.REASON_USER_REQUEST, null);
- }
- }
- }
-
- /**
- * Reconnects if fails fire connection failed.
- * @param reasonCode the appropriate <tt>SecurityAuthority</tt> reasonCode,
- * which would specify the reason for which we're re-calling the login.
- */
- void reregister(int reasonCode)
- {
- try
- {
- connectAndLogin(authority, reasonCode);
- }
- catch (OperationFailedException ex)
- {
- fireRegistrationStateChanged(
- getRegistrationState(),
- RegistrationState.CONNECTION_FAILED,
- RegistrationStateChangeEvent.REASON_NOT_SPECIFIED, null);
- }
- }
-
- /**
- * Ends the registration of this protocol provider with the service.
- */
- public void unregister()
- {
- unregisterInternal(true);
- }
-
- /**
- * Unregister and fire the event if requested
- * @param fireEvent boolean
- */
- void unregisterInternal(boolean fireEvent)
- {
- RegistrationState currRegState = getRegistrationState();
-
- if(fireEvent)
- fireRegistrationStateChanged(
- currRegState,
- RegistrationState.UNREGISTERING,
- RegistrationStateChangeEvent.REASON_USER_REQUEST,
- null);
-
- try
- {
- if(connectionListener != null && yahooSession != null)
- {
- yahooSession.removeSessionListener(connectionListener);
- connectionListener = null;
- }
-
- if((yahooSession != null)
- && (yahooSession.getSessionStatus() == StatusConstants.MESSAGING))
- yahooSession.logout();
- }
- catch(Exception ex)
- {
- logger.error("Cannot logout! ", ex);
- }
-
- yahooSession = null;
-
- if(fireEvent)
- fireRegistrationStateChanged(
- currRegState,
- RegistrationState.UNREGISTERED,
- RegistrationStateChangeEvent.REASON_USER_REQUEST,
- null);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see net.java.sip.communicator.service.protocol.ProtocolProviderService#
- * isSignallingTransportSecure()
- */
- public boolean isSignalingTransportSecure()
- {
- return false;
- }
-
- /**
- * Returns the "transport" protocol of this instance used to carry the
- * control channel for the current protocol service.
- *
- * @return The "transport" protocol of this instance: TCP.
- */
- public TransportProtocol getTransportProtocol()
- {
- return TransportProtocol.TCP;
- }
-
- /**
- * Returns the short name of the protocol that the implementation of this
- * provider is based upon (like SIP, Msn, ICQ/AIM, or others for
- * example).
- *
- * @return a String containing the short name of the protocol this
- * service is taking care of.
- */
- public String getProtocolName()
- {
- return ProtocolNames.YAHOO;
- }
-
- /**
- * Initialized the service implementation, and puts it in a sate where it
- * could interoperate with other services. It is strongly recomended that
- * properties in this Map be mapped to property names as specified by
- * <tt>AccountProperties</tt>.
- *
- * @param screenname the account id/uin/screenname of the account that
- * we're about to create
- * @param accountID the identifier of the account that this protocol
- * provider represents.
- *
- * @see net.java.sip.communicator.service.protocol.AccountID
- */
- protected void initialize(String screenname,
- AccountID accountID)
- {
- synchronized(initializationLock)
- {
- this.accountID = accountID;
-
- addSupportedOperationSet(
- OperationSetInstantMessageTransform.class,
- new OperationSetInstantMessageTransformImpl());
-
- //initialize the presence operationset
- persistentPresence
- = new OperationSetPersistentPresenceYahooImpl(this);
- addSupportedOperationSet(
- OperationSetPersistentPresence.class,
- persistentPresence);
- //register it once again for those that simply need presence
- addSupportedOperationSet(
- OperationSetPresence.class,
- persistentPresence);
-
- //initialize the IM operation set
- addSupportedOperationSet(
- OperationSetBasicInstantMessaging.class,
- new OperationSetBasicInstantMessagingYahooImpl(this));
-
- //initialize the multi user chat operation set
- addSupportedOperationSet(
- OperationSetAdHocMultiUserChat.class,
- new OperationSetAdHocMultiUserChatYahooImpl(this));
-
- //initialize the typing notifications operation set
- typingNotifications
- = new OperationSetTypingNotificationsYahooImpl(this);
- addSupportedOperationSet(
- OperationSetTypingNotifications.class,
- typingNotifications);
-
- addSupportedOperationSet(
- OperationSetFileTransfer.class,
- new OperationSetFileTransferYahooImpl(this));
-
- isInitialized = true;
- }
- }
-
- /**
- * Makes the service implementation close all open sockets and release
- * any resources that it might have taken and prepare for
- * shutdown/garbage collection.
- */
- public void shutdown()
- {
- synchronized(initializationLock){
- unregisterInternal(false);
- yahooSession = null;
- isInitialized = false;
- }
- }
-
- /**
- * Returns true if the provider service implementation is initialized and
- * ready for use by other services, and false otherwise.
- *
- * @return true if the provider is initialized and ready for use and false
- * otherwise
- */
- public boolean isInitialized()
- {
- return isInitialized;
- }
-
- /**
- * Returns the AccountID that uniquely identifies the account represented
- * by this instance of the ProtocolProviderService.
- * @return the id of the account represented by this provider.
- */
- public AccountID getAccountID()
- {
- return accountID;
- }
-
- /**
- * Returns the Yahoo<tt>Session</tt>opened by this provider
- * @return a reference to the <tt>Session</tt> last opened by this
- * provider.
- */
- YahooSession getYahooSession()
- {
- return yahooSession;
- }
-
- /**
- * Creates a RegistrationStateChange event corresponding to the specified
- * old and new states and notifies all currently registered listeners.
- *
- * @param oldState the state that the provider had before the change
- * occurred
- * @param newState the state that the provider is currently in.
- * @param reasonCode a value corresponding to one of the REASON_XXX fields
- * of the RegistrationStateChangeEvent class, indicating the reason for
- * this state transition.
- * @param reason a String further explaining the reason code or null if
- * no such explanation is necessary.
- */
- @Override
- public void fireRegistrationStateChanged( RegistrationState oldState,
- RegistrationState newState,
- int reasonCode,
- String reason)
- {
- if(newState.equals(RegistrationState.UNREGISTERED))
- {
- unregisterInternal(false);
- yahooSession = null;
- }
-
- super.fireRegistrationStateChanged(oldState, newState, reasonCode, reason);
- }
-
- /**
- * Listens when we are logged in the server
- * or incoming exception in the lib impl.
- */
- private class YahooConnectionListener
- extends SessionAdapter
- {
- /**
- * Yahoo has logged us off the system, or the connection was lost
- *
- * @param ev the event
- */
- @Override
- public void connectionClosed(SessionEvent ev)
- {
- if(isRegistered())
- fireRegistrationStateChanged(
- getRegistrationState(),
- RegistrationState.CONNECTION_FAILED,
- RegistrationStateChangeEvent.REASON_NOT_SPECIFIED, null);
- }
-
- /**
- * Some exception has occurred in stack.
- * @param ev
- */
- @Override
- public void inputExceptionThrown(SessionExceptionEvent ev)
- {
- if(ev.getException() instanceof YMSG9BadFormatException)
- {
- logger.error("Yahoo protocol exception occured exception",
- ev.getException());
- logger.error("Yahoo protocol exception occured exception cause",
- ev.getException().getCause());
- }
- else
- logger.error(
- "Yahoo protocol exception occured", ev.getException());
-
- unregisterInternal(false);
- if(isRegistered())
- fireRegistrationStateChanged(
- getRegistrationState(),
- RegistrationState.UNREGISTERED,
- RegistrationStateChangeEvent.REASON_INTERNAL_ERROR, null);
- }
- }
-
- /**
- * Returns the yahoo protocol icon.
- * @return the yahoo protocol icon
- */
- public ProtocolIcon getProtocolIcon()
- {
- return yahooIcon;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/RootContactGroupYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/RootContactGroupYahooImpl.java
deleted file mode 100644
index 856bb30..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/RootContactGroupYahooImpl.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * A dummy ContactGroup implementation representing the ContactList root for
- * Yahoo contact lists.
- * @author Damian Minkov
- */
-public class RootContactGroupYahooImpl
- extends AbstractContactGroupYahooImpl
-{
- private String ROOT_CONTACT_GROUP_NAME = "ContactListRoot";
- private List<ContactGroup> subGroups = new LinkedList<ContactGroup>();
- private boolean isResolved = false;
-
- /**
- * An empty list that we use when returning an iterator.
- */
- private List<Contact> dummyContacts = new LinkedList<Contact>();
-
- private final ProtocolProviderServiceYahooImpl protocolProvider;
-
- /**
- * Creates a ContactGroup instance.
- */
- RootContactGroupYahooImpl(ProtocolProviderServiceYahooImpl protocolProvider)
- {
- this.protocolProvider = protocolProvider;
- }
-
- /**
- * The ContactListRoot is the only group that can contain subgroups.
- *
- * @return true (always)
- */
- public boolean canContainSubgroups()
- {
- return true;
- }
-
- /**
- * Returns the name of this group which is always
- * <tt>ROOT_CONTACT_GROUP_NAME</tt>.
- *
- * @return a String containing the name of this group.
- */
- public String getGroupName()
- {
- return ROOT_CONTACT_GROUP_NAME;
- }
-
- /**
- * Adds the specified group to the end of the list of sub groups.
- * @param group the group to add.
- */
- void addSubGroup(ContactGroupYahooImpl group)
- {
- subGroups.add(group);
- }
-
- /**
- * Removes the specified from the list of sub groups
- * @param group the group to remove.
- */
- void removeSubGroup(ContactGroupYahooImpl group)
- {
- removeSubGroup(subGroups.indexOf(group));
- }
-
- /**
- * Removes the sub group with the specified index.
- * @param index the index of the group to remove
- */
- void removeSubGroup(int index)
- {
- subGroups.remove(index);
- }
-
- /**
- * Returns the number of subgroups contained by this
- * <tt>RootContactGroupImpl</tt>.
- *
- * @return an int indicating the number of subgroups that this
- * ContactGroup contains.
- */
- public int countSubgroups()
- {
- return subGroups.size();
- }
-
- /**
- * Returns null as this is the root contact group.
- * @return null as this is the root contact group.
- */
- public ContactGroup getParentContactGroup()
- {
- return null;
- }
-
- /**
- * Returns the subgroup with the specified index.
- *
- * @param index the index of the <tt>ContactGroup</tt> to retrieve.
- * @return the <tt>ContactGroup</tt> with the specified index.
- */
- public ContactGroup getGroup(int index)
- {
- return subGroups.get(index);
- }
-
- /**
- * Returns the subgroup with the specified name.
- * @param groupName the name of the <tt>ContactGroup</tt> to retrieve.
- * @return the <tt>ContactGroup</tt> with the specified index.
- */
- public ContactGroup getGroup(String groupName)
- {
- Iterator<ContactGroup> subgroups = subgroups();
- while (subgroups.hasNext())
- {
- ContactGroup grp = subgroups.next();
-
- if (grp.getGroupName().equals(groupName))
- return grp;
- }
-
- return null;
- }
-
- /**
- * Returns an iterator over the sub groups that this
- * <tt>ContactGroup</tt> contains.
- *
- * @return a java.util.Iterator over the <tt>ContactGroup</tt>
- * children of this group (i.e. subgroups).
- */
- public Iterator<ContactGroup> subgroups()
- {
- return subGroups.iterator();
- }
-
- /**
- * Returns the number, which is always 0, of <tt>Contact</tt> members
- * of this <tt>ContactGroup</tt>
- * @return an int indicating the number of <tt>Contact</tt>s, members
- * of this <tt>ContactGroup</tt>.
- */
- public int countContacts()
- {
- return dummyContacts.size();
- }
-
- /**
- * Returns an Iterator over all contacts, member of this
- * <tt>ContactGroup</tt>.
- * @return a java.util.Iterator over all contacts inside this
- * <tt>ContactGroup</tt>
- */
- public Iterator<Contact> contacts()
- {
- return dummyContacts.iterator();
- }
-
- /**
- * Returns the <tt>Contact</tt> with the specified address or
- * identifier.
- * @param id the addres or identifier of the <tt>Contact</tt> we are
- * looking for.
- * @return the <tt>Contact</tt> with the specified id or address.
- */
- public Contact getContact(String id)
- {
- //no contacts in the root group for this yahoo impl.
- return null;
- }
-
-
- /**
- * Returns a string representation of the root contact group that contains
- * all subgroups and subcontacts of this group.
- *
- * @return a string representation of this root contact group.
- */
- @Override
- public String toString()
- {
- StringBuffer buff = new StringBuffer(getGroupName());
- buff.append(".subGroups=" + countSubgroups() + ":\n");
-
- Iterator<ContactGroup> subGroups = subgroups();
- while (subGroups.hasNext())
- {
- ContactGroup group = subGroups.next();
- buff.append(group.toString());
- if (subGroups.hasNext())
- buff.append("\n");
- }
- return buff.toString();
- }
-
- /**
- * Returns the protocol provider that this group belongs to.
- * @return a regerence to the ProtocolProviderService instance that this
- * ContactGroup belongs to.
- */
- public ProtocolProviderService getProtocolProvider()
- {
- return protocolProvider;
- }
-
- /**
- * Determines whether or not this contact group is being stored by the
- * server. Non persistent contact groups exist for the sole purpose of
- * containing non persistent contacts.
- * @return true if the contact group is persistent and false otherwise.
- */
- public boolean isPersistent()
- {
- return true;
- }
-
- /**
- * Returns null as no persistent data is required and the group name is
- * sufficient for restoring the contact.
- * <p>
- * @return null as no such data is needed.
- */
- public String getPersistentData()
- {
- return null;
- }
-
- /**
- * Determines whether or not this group has been resolved against the
- * server. Unresolved groups are used when initially loading a contact
- * list that has been stored in a local file until the presence operation
- * set has managed to retrieve all the contact list from the server and has
- * properly mapped groups to their on-line buddies.
- * @return true if the group has been resolved (mapped against a buddy)
- * and false otherwise.
- */
- public boolean isResolved()
- {
- return isResolved;
- }
-
- /**
- * Returns a <tt>String</tt> that uniquely represnets the group. In this we
- * use the name of the group as an identifier. This may cause problems
- * though, in clase the name is changed by some other application between
- * consecutive runs of the sip-communicator.
- *
- * @return a String representing this group in a unique and persistent
- * way.
- */
- public String getUID()
- {
- return getGroupName();
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/ServerStoredContactListYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/ServerStoredContactListYahooImpl.java
deleted file mode 100644
index e732b84..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/ServerStoredContactListYahooImpl.java
+++ /dev/null
@@ -1,1274 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.io.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-import ymsg.network.*;
-import ymsg.network.event.*;
-
-/**
- * This class encapsulates the Roster class. Once created, it will
- * register itself as a listener to the encapsulated Roster and modify it's
- * local copy of Contacts and ContactGroups every time an event is generated
- * by the underlying framework. The class would also generate
- * corresponding sip-communicator events to all events coming from smack.
- *
- * @author Damian Minkov
- * @author Emil Ivov
- */
-public class ServerStoredContactListYahooImpl
-{
- private static final Logger logger =
- Logger.getLogger(ServerStoredContactListYahooImpl.class);
-
- /**
- * If there is no group and we add contact with no parent
- * a default group is created with name : DEFAULT_GROUP_NAME
- */
- private static final String DEFAULT_GROUP_NAME = "General";
-
- /**
- * The root contagroup. The container for all yahoo buddies and groups.
- */
- private final RootContactGroupYahooImpl rootGroup;
-
- /**
- * The operation set that created us and that we could use when dispatching
- * subscription events.
- */
- private final OperationSetPersistentPresenceYahooImpl parentOperationSet;
-
- /**
- * The provider that is on top of us.
- */
- private final ProtocolProviderServiceYahooImpl yahooProvider;
-
- private YahooSession yahooSession = null;
-
- /**
- * Listeners that would receive event notifications for changes in group
- * names or other properties, removal or creation of groups.
- */
- private Vector<ServerStoredGroupListener> serverStoredGroupListeners
- = new Vector<ServerStoredGroupListener>();
-
- private ContactListModListenerImpl contactListModListenerImpl
- = new ContactListModListenerImpl();
-
- /**
- * Handler for incoming authorization requests.
- */
- private AuthorizationHandler handler = null;
-
- private Hashtable<String, String> addedCustomYahooIds
- = new Hashtable<String, String>();
-
- /**
- * Creates a ServerStoredContactList wrapper for the specified BuddyList.
- *
- * @param parentOperationSet the operation set that created us and that
- * we could use for dispatching subscription events
- * @param provider the provider that has instantiated us.
- */
- ServerStoredContactListYahooImpl(
- OperationSetPersistentPresenceYahooImpl parentOperationSet,
- ProtocolProviderServiceYahooImpl provider)
- {
- //We need to init these as early as possible to ensure that the provider
- //and the operationsset would not be null in the incoming events.
- this.parentOperationSet = parentOperationSet;
-
- this.yahooProvider = provider;
- this.rootGroup = new RootContactGroupYahooImpl(this.yahooProvider);
- }
-
- /**
- * Handler for incoming authorization requests.
- *
- * @param handler an instance of an AuthorizationHandler for
- * authorization requests coming from other users requesting
- * permission add us to their contact list.
- */
- public void setAuthorizationHandler(AuthorizationHandler handler)
- {
- this.handler = handler;
- }
-
- /**
- * Returns the root group of the contact list.
- *
- * @return the root ContactGroup for the ContactList
- */
- public ContactGroup getRootGroup()
- {
- return rootGroup;
- }
-
- /**
- * Registers the specified group listener so that it would receive events
- * on group modification/creation/destruction.
- * @param listener the ServerStoredGroupListener to register for group
- * events
- */
- void addGroupListener(ServerStoredGroupListener listener)
- {
- synchronized(serverStoredGroupListeners)
- {
- if(!serverStoredGroupListeners.contains(listener))
- serverStoredGroupListeners.add(listener);
- }
- }
-
- /**
- * Removes the specified group listener so that it won't receive further
- * events on group modification/creation/destruction.
- * @param listener the ServerStoredGroupListener to unregister
- */
- void removeGroupListener(ServerStoredGroupListener listener)
- {
- synchronized(serverStoredGroupListeners)
- {
- this.serverStoredGroupListeners.remove(listener);
- }
- }
-
- /**
- * Creates the corresponding event and notifies all
- * <tt>ServerStoredGroupListener</tt>s that the source group has been
- * removed, changed, renamed or whatever happened to it.
- * @param group the ContactGroup that has been created/modified/removed
- * @param eventID the id of the event to generate.
- */
- private void fireGroupEvent(ContactGroupYahooImpl group, int eventID)
- {
- //bail out if no one's listening
- if(parentOperationSet == null){
- if (logger.isDebugEnabled())
- logger.debug("No presence op. set available. Bailing out.");
- return;
- }
-
- ServerStoredGroupEvent evt = new ServerStoredGroupEvent(
- group
- , eventID
- , parentOperationSet.getServerStoredContactListRoot()
- , yahooProvider
- , parentOperationSet);
-
- if (logger.isTraceEnabled())
- logger.trace("Will dispatch the following grp event: " + evt);
-
- Iterable<ServerStoredGroupListener> listeners;
- synchronized (serverStoredGroupListeners)
- {
- listeners
- = new ArrayList<ServerStoredGroupListener>(
- serverStoredGroupListeners);
- }
-
- for (ServerStoredGroupListener listener : listeners)
- {
- try{
- if (eventID == ServerStoredGroupEvent.GROUP_REMOVED_EVENT)
- listener.groupRemoved(evt);
- else if (eventID == ServerStoredGroupEvent.GROUP_RENAMED_EVENT)
- listener.groupNameChanged(evt);
- else if (eventID == ServerStoredGroupEvent.GROUP_CREATED_EVENT)
- listener.groupCreated(evt);
- else if (eventID == ServerStoredGroupEvent.GROUP_RESOLVED_EVENT)
- listener.groupResolved(evt);
- }catch(Exception ex){
- logger.warn("Unhandled Exception! ", ex);
- }
- }
- }
-
- /**
- * Make the parent persistent presence operation set dispatch a contact
- * removed event.
- * @param parentGroup the group where that the removed contact belonged to.
- * @param contact the contact that was removed.
- */
- private void fireContactRemoved( ContactGroup parentGroup,
- ContactYahooImpl contact)
- {
- //bail out if no one's listening
- if(parentOperationSet == null){
- if (logger.isDebugEnabled())
- logger.debug("No presence op. set available. Bailing out.");
- return;
- }
-
- //dispatch
- parentOperationSet.fireSubscriptionEvent(
- contact, parentGroup, SubscriptionEvent.SUBSCRIPTION_REMOVED);
- }
-
- /**
- * Make the parent persistent presence operation set dispatch a subscription
- * moved event.
- * @param oldParentGroup the group where the source contact was located
- * before being moved
- * @param newParentGroup the group that the source contact is currently in.
- * @param contact the contact that was added
- */
- private void fireContactMoved( ContactGroup oldParentGroup,
- ContactGroupYahooImpl newParentGroup,
- ContactYahooImpl contact)
- {
- //bail out if no one's listening
- if(parentOperationSet == null){
- if (logger.isDebugEnabled())
- logger.debug("No presence op. set available. Bailing out.");
- return;
- }
-
- //dispatch
- parentOperationSet.fireSubscriptionMovedEvent(
- contact, oldParentGroup, newParentGroup);
- }
-
- /**
- * Returns a reference to the provider that created us.
- * @return a reference to a ProtocolProviderServiceImpl instance.
- */
- ProtocolProviderServiceYahooImpl getParentProvider()
- {
- return yahooProvider;
- }
-
- /**
- * Returns the ConntactGroup with the specified name or null if no such
- * group was found.
- * <p>
- * @param name the name of the group we're looking for.
- * @return a reference to the ContactGroupYahooImpl instance we're looking
- * for or null if no such group was found.
- */
- public ContactGroupYahooImpl findContactGroup(String name)
- {
- String nameToLookFor = replaceIllegalChars(name);
- Iterator<ContactGroup> contactGroups = rootGroup.subgroups();
-
- while(contactGroups.hasNext())
- {
- ContactGroupYahooImpl contactGroup
- = (ContactGroupYahooImpl) contactGroups.next();
-
- if (contactGroup.getGroupName().equals(nameToLookFor))
- return contactGroup;
- }
-
- return null;
- }
-
- /**
- * Returns the Contact with the specified id or null if
- * no such id was found.
- *
- * @param id the id of the contact to find.
- * @return the <tt>Contact</tt> carrying the specified
- * <tt>screenName</tt> or <tt>null</tt> if no such contact exits.
- */
- public ContactYahooImpl findContactById(String id)
- {
- Iterator<ContactGroup> contactGroups = rootGroup.subgroups();
- ContactYahooImpl result = null;
-
- while(contactGroups.hasNext())
- {
- ContactGroupYahooImpl contactGroup
- = (ContactGroupYahooImpl) contactGroups.next();
-
- result = contactGroup.findContact(id);
-
- if (result != null)
- return result;
- }
-
- return null;
- }
-
- /**
- * Returns the Contact corresponding to the specified <tt>YahooUser</tt>
- * or null if no such id was found.
- *
- * @param yahooUser the YahooUser of the contact to find.
- * @return the <tt>Contact</tt> carrying the specified
- * <tt>screenName</tt> or <tt>null</tt> if no such contact exits.
- */
- public ContactYahooImpl findContactByYahooUser(YahooUser yahooUser)
- {
- return findContactById(yahooUser.getId().toLowerCase());
- }
-
- /**
- * Returns the ContactGroup containing the specified contact or null
- * if no such group or contact exist.
- *
- * @param child the contact whose parent group we're looking for.
- * @return the <tt>ContactGroup</tt> containing the specified
- * <tt>contact</tt> or <tt>null</tt> if no such groupo or contact
- * exist.
- */
- public ContactGroup findContactGroup(ContactYahooImpl child)
- {
- Iterator<ContactGroup> contactGroups = rootGroup.subgroups();
- String contactAddress = child.getAddress();
-
- while(contactGroups.hasNext())
- {
- ContactGroupYahooImpl contactGroup
- = (ContactGroupYahooImpl) contactGroups.next();
-
- if( contactGroup.findContact(contactAddress)!= null)
- return contactGroup;
- }
-
- return null;
- }
-
- /**
- * Adds a new contact with the specified screenname to the list under a
- * default location.
- * @param id the id of the contact to add.
- * @throws OperationFailedException
- */
- public void addContact(String id)
- throws OperationFailedException
- {
- ContactGroupYahooImpl parent = getFirstPersistentGroup();
-
- if(parent == null)
- {
- // if there is no group create it
- parent = createUnresolvedContactGroup(DEFAULT_GROUP_NAME);
- }
-
- addContact(parent, id);
- }
-
- /**
- * Adds a new contact with the specified screenname to the list under the
- * specified group.
- * @param id the id of the contact to add.
- * @param parent the group under which we want the new contact placed.
- * @throws OperationFailedException if the contact already exist
- */
- public void addContact(final ContactGroupYahooImpl parent, String id)
- throws OperationFailedException
- {
- if (logger.isTraceEnabled())
- logger.trace("Adding contact " + id + " to parent=" + parent);
-
- //if the contact is already in the contact list and is not volatile,
- //then only broadcast an event
- ContactYahooImpl existingContact = findContactById(id);
-
- if( existingContact != null
- && existingContact.isPersistent() )
- {
- if (logger.isDebugEnabled())
- logger.debug("Contact " + id + " already exists.");
- throw new OperationFailedException(
- "Contact " + id + " already exists.",
- OperationFailedException.SUBSCRIPTION_ALREADY_EXISTS);
- }
-
- if(id.indexOf("@") > -1 )
- addedCustomYahooIds.put(YahooSession.getYahooUserID(id), id);
-
- try
- {
- yahooSession.addFriend(YahooSession.getYahooUserID(id),
- parent.getGroupName());
- }
- catch(IOException ex)
- {
- throw new OperationFailedException(
- "Contact cannot be added " + id,
- OperationFailedException.NETWORK_FAILURE);
- }
- }
-
- /**
- * Creates a non persistent contact for the specified address. This would
- * also create (if necessary) a group for volatile contacts that would not
- * be added to the server stored contact list. This method would have no
- * effect on the server stored contact list.
- * @param id the address of the contact to create.
- * @return the newly created volatile <tt>ContactImpl</tt>
- */
- ContactYahooImpl createVolatileContact(String id)
- {
- if (logger.isTraceEnabled())
- logger.trace("Creating volatile contact " + id);
- ContactYahooImpl newVolatileContact =
- new ContactYahooImpl(id, this, false, false, true);
-
- //Check whether a volatile group already exists and if not create one
- ContactGroupYahooImpl theVolatileGroup = getNonPersistentGroup();
-
- //if the parent group is null then create it
- if (theVolatileGroup == null)
- {
- theVolatileGroup = new VolatileContactGroupYahooImpl(
- YahooActivator.getResources().getI18NString(
- "service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME"),
- this);
-
- theVolatileGroup.addContact(newVolatileContact);
-
- this.rootGroup.addSubGroup(theVolatileGroup);
-
- fireGroupEvent(theVolatileGroup
- , ServerStoredGroupEvent.GROUP_CREATED_EVENT);
- }
- else
- {
- theVolatileGroup.addContact(newVolatileContact);
-
- fireContactAdded(theVolatileGroup, newVolatileContact);
- }
-
- return newVolatileContact;
- }
-
-
- /**
- * Creates a non resolved contact for the specified address and inside the
- * specified group. The newly created contact would be added to the local
- * contact list as a standard contact but when an event is received from the
- * server concerning this contact, then it will be reused and only its
- * isResolved field would be updated instead of creating the whole contact
- * again.
- *
- * @param parentGroup the group where the unersolved contact is to be
- * created
- * @param id the Address of the contact to create.
- * @return the newly created unresolved <tt>ContactImpl</tt>
- */
- ContactYahooImpl createUnresolvedContact(ContactGroup parentGroup,
- String id)
- {
- if (logger.isTraceEnabled())
- logger.trace("Creating unresolved contact " + id
- + " to parent=" + parentGroup);
-
- ContactYahooImpl existingContact = findContactById(id);
-
- if( existingContact != null)
- {
- return existingContact;
- }
-
- ContactYahooImpl newUnresolvedContact
- = new ContactYahooImpl(id, this, false, true, false);
-
- if(parentGroup instanceof ContactGroupYahooImpl)
- ((ContactGroupYahooImpl)parentGroup).
- addContact(newUnresolvedContact);
-
- fireContactAdded(parentGroup, newUnresolvedContact);
-
- return newUnresolvedContact;
- }
-
- /**
- * Creates a non resolved contact group for the specified name. The newly
- * created group would be added to the local contact list as any other group
- * but when an event is received from the server concerning this group, then
- * it will be reused and only its isResolved field would be updated instead
- * of creating the whole group again.
- * <p>
- * @param groupName the name of the group to create.
- * @return the newly created unresolved <tt>ContactGroupImpl</tt>
- */
- ContactGroupYahooImpl createUnresolvedContactGroup(String groupName)
- {
- ContactGroupYahooImpl existingGroup = findContactGroup(groupName);
-
- if( existingGroup != null )
- {
- if (logger.isDebugEnabled())
- logger.debug("ContactGroup " + groupName + " already exists.");
- return existingGroup;
- }
-
- ContactGroupYahooImpl newUnresolvedGroup =
- new ContactGroupYahooImpl(groupName, this);
-
- this.rootGroup.addSubGroup(newUnresolvedGroup);
-
- fireGroupEvent(newUnresolvedGroup
- , ServerStoredGroupEvent.GROUP_CREATED_EVENT);
-
- return newUnresolvedGroup;
- }
-
- /**
- * Creates the specified group on the server stored contact list.
- * @param groupName a String containing the name of the new group.
- * @throws OperationFailedException with code CONTACT_GROUP_ALREADY_EXISTS
- * if the group we're trying to create is already in our contact list.
- */
- public void createGroup(String groupName)
- throws OperationFailedException
- {
- if (logger.isTraceEnabled())
- logger.trace("Creating group: " + groupName);
-
- ContactGroupYahooImpl existingGroup = findContactGroup(groupName);
-
- if( existingGroup != null && existingGroup.isPersistent() )
- {
- if (logger.isDebugEnabled())
- logger.debug("ContactGroup " + groupName + " already exists.");
- throw new OperationFailedException(
- "ContactGroup " + groupName + " already exists.",
- OperationFailedException.CONTACT_GROUP_ALREADY_EXISTS);
- }
-
- // create unresolved group if friend is added - group will be resolved
- createUnresolvedContactGroup(groupName);
- }
-
- /**
- * Removes the specified group from the buddy list.
- * @param groupToRemove the group that we'd like removed.
- */
- @SuppressWarnings("unchecked") //jymsg legacy code
- public void removeGroup(ContactGroupYahooImpl groupToRemove)
- {
- // to remove group just remove all the contacts in it
-
- if (logger.isTraceEnabled())
- logger.trace("removing group " + groupToRemove);
-
- // if its not persistent group just remove it
- if(!groupToRemove.isPersistent() || !groupToRemove.isResolved())
- {
- rootGroup.removeSubGroup(groupToRemove);
- fireGroupEvent(groupToRemove,
- ServerStoredGroupEvent.GROUP_REMOVED_EVENT);
- return;
- }
-
- Vector<YahooUser> contacts
- = groupToRemove.getSourceGroup().getMembers();
-
- if(contacts.size() == 0)
- {
- // the group is empty just remove it
- rootGroup.removeSubGroup(groupToRemove);
- fireGroupEvent(groupToRemove,
- ServerStoredGroupEvent.GROUP_REMOVED_EVENT);
- return;
- }
-
- /*
- * ContactGroupYahooImpl#getGroupName() isn't a plain getter so
- * performance-wise we're better off not calling it multiple times in
- * the following loop.
- */
- String groupToRemoveName = groupToRemove.getGroupName();
-
- for (YahooUser item : contacts)
- {
- try
- {
- yahooSession.removeFriend(item.getId(), groupToRemoveName);
- }
- catch(IOException ex)
- {
- if (logger.isInfoEnabled())
- logger.info("Cannot Remove contact " + item.getId());
- }
- }
- }
-
- /**
- * Removes a contact from the serverside list
- * Event will come for successful operation
- * @param contactToRemove ContactYahooImpl
- */
- void removeContact(ContactYahooImpl contactToRemove)
- {
- if (logger.isTraceEnabled())
- logger.trace("Removing yahoo contact "
- + contactToRemove.getSourceContact());
-
- if(contactToRemove.isVolatile())
- {
- ContactGroupYahooImpl parent =
- (ContactGroupYahooImpl)contactToRemove.getParentContactGroup();
-
- parent.removeContact(contactToRemove);
- fireContactRemoved(parent, contactToRemove);
- return;
- }
-
- try
- {
- yahooSession.removeFriend(
- contactToRemove.getSourceContact().getId(),
- contactToRemove.getParentContactGroup().getGroupName());
- }
- catch(IOException ex)
- {
- if (logger.isInfoEnabled())
- logger.info("Cannot Remove contact " + contactToRemove);
- }
- }
-
- /**
- * Renames the specified group according to the specified new name..
- * @param groupToRename the group that we'd like removed.
- * @param newName the new name of the group
- */
- public void renameGroup(ContactGroupYahooImpl groupToRename, String newName)
- {
- // not working
- /*
- try
- {
- yahooSession.renameGroup(groupToRename.getGroupName(), newName);
- }
- catch(IOException ex)
- {
- if (logger.isInfoEnabled())
- logger.info("Cannot rename group " + groupToRename);
- }
-
- fireGroupEvent(groupToRename,
- ServerStoredGroupEvent.GROUP_RENAMED_EVENT);
- */
- }
-
- /**
- * Moves the specified <tt>contact</tt> to the group indicated by
- * <tt>newParent</tt>.
- * @param contact the contact that we'd like moved under the new group.
- * @param newParent the group where we'd like the parent placed.
- */
- public void moveContact(ContactYahooImpl contact,
- ContactGroupYahooImpl newParent)
- {
- String userID = contact.getID();
- try
- {
- contactListModListenerImpl.
- waitForMove(userID,
- contact.getParentContactGroup().getGroupName());
-
- yahooSession.addFriend(
- userID,
- newParent.getGroupName());
- }
- catch(IOException ex)
- {
- contactListModListenerImpl.removeWaitForMove(userID);
- logger.error("Contact cannot be added " + ex.getMessage());
- }
- }
-
- /**
- * Returns the volatile group
- *
- * @return ContactGroupYahooImpl
- */
- private ContactGroupYahooImpl getNonPersistentGroup()
- {
- for (int i = 0; i < getRootGroup().countSubgroups(); i++)
- {
- ContactGroupYahooImpl gr =
- (ContactGroupYahooImpl)getRootGroup().getGroup(i);
-
- if(!gr.isPersistent())
- return gr;
- }
-
- return null;
- }
-
- /**
- * Returns the first persistent group
- *
- * @return ContactGroupIcqImpl
- */
- private ContactGroupYahooImpl getFirstPersistentGroup()
- {
- for (int i = 0; i < getRootGroup().countSubgroups(); i++)
- {
- ContactGroupYahooImpl gr =
- (ContactGroupYahooImpl)getRootGroup().getGroup(i);
-
- if(gr.isPersistent())
- return gr;
- }
-
- return null;
- }
-
- /**
- * Make the parent persistent presence operation set dispatch a contact
- * added event.
- * @param parentGroup the group where the new contact was added
- * @param contact the contact that was added
- */
- void fireContactAdded( ContactGroup parentGroup,
- ContactYahooImpl contact)
- {
- //bail out if no one's listening
- if(parentOperationSet == null){
- if (logger.isDebugEnabled())
- logger.debug("No presence op. set available. Bailing out.");
- return;
- }
-
- //dispatch
- parentOperationSet.fireSubscriptionEvent(
- contact, parentGroup, SubscriptionEvent.SUBSCRIPTION_CREATED);
- }
-
- /**
- * Make the parent persistent presence operation set dispatch a contact
- * resolved event.
- * @param parentGroup the group that the resolved contact belongs to.
- * @param contact the contact that was resolved
- */
- void fireContactResolved( ContactGroup parentGroup,
- ContactYahooImpl contact)
- {
- //bail out if no one's listening
- if(parentOperationSet == null){
- if (logger.isDebugEnabled())
- logger.debug("No presence op. set available. Bailing out.");
- return;
- }
-
- //dispatch
- parentOperationSet.fireSubscriptionEvent(
- contact, parentGroup, SubscriptionEvent.SUBSCRIPTION_RESOLVED);
- }
-
- /**
- * When the protocol is online this method is used to fill or resolve
- * the current contact list
- */
- @SuppressWarnings("unchecked") //jymsg legacy code
- private void initList()
- {
- if (logger.isTraceEnabled())
- logger.trace("Start init list of "
- + yahooProvider.getAccountID().getUserID());
-
- for (YahooGroup item : yahooSession.getGroups())
- {
- ContactGroupYahooImpl group = findContactGroup(item.getName());
-
- if(group == null)
- {
- // create the group as it doesn't exist
- group = new ContactGroupYahooImpl(
- item, item.getMembers(), this, true);
-
- rootGroup.addSubGroup(group);
-
- //tell listeners about the added group
- fireGroupEvent(group,
- ServerStoredGroupEvent.GROUP_CREATED_EVENT);
- }
- else
- {
- // the group exist so just resolved. The group will check and
- // create or resolve its entries
- group.setResolved(item);
-
- //fire an event saying that the group has been resolved
- fireGroupEvent(group
- , ServerStoredGroupEvent.GROUP_RESOLVED_EVENT);
-
- /** @todo if something to delete . delete it */
- }
-
- if (logger.isTraceEnabled())
- logger.trace("Init of group done! : " + group);
- }
- }
-
- /**
- * @param name Name of the group to search
- * @return The yahoo group with given name
- */
- private YahooGroup findGroup(String name)
- {
- for (YahooGroup elem : yahooSession.getGroups())
- {
- if(elem.getName().equals(name))
- return elem;
- }
- return null;
- }
-
- /**
- * Process incoming authorization requests.
- * @param ev the event to process.
- */
- void processAuthorizationRequest(SessionAuthorizationEvent ev)
- {
- if(handler == null)
- return;
-
- Contact srcContact = findContactById(ev.getFrom());
-
- // if there is no such contact we create it as
- // volatile so we can fire notification
- // and then if accepted add it in the protocol
- // so we can receive its states
- boolean isCurrentlyCreated = false;
- if(srcContact == null)
- {
- srcContact = createVolatileContact(ev.getFrom());
- isCurrentlyCreated = true;
- }
-
- AuthorizationRequest authRequest = new AuthorizationRequest();
- authRequest.setReason(ev.getMessage());
-
- AuthorizationResponse authResponse =
- handler.processAuthorisationRequest(
- authRequest, srcContact);
-
- if (authResponse.getResponseCode() == AuthorizationResponse.IGNORE)
- {
- return;
- }
- else if (authResponse.getResponseCode() == AuthorizationResponse.REJECT)
- {
- removeContact((ContactYahooImpl)srcContact);
- try
- {
- yahooSession.rejectFriendAuthorization(
- ev, ev.getFrom(), authResponse.getReason());
- }
- catch(IOException ex)
- {
- logger.error("cannot send auth deny", ex);
- }
-
- return;
- }
-
- // else we accepted it
- try
- {
- yahooSession.acceptFriendAuthorization(ev, ev.getFrom());
- }
- catch(IOException ex)
- {
- logger.error("cannot send auth deny", ex);
- }
-
- if(isCurrentlyCreated)
- try
- {
- addContact(ev.getFrom());
- }
- catch (OperationFailedException ex)
- {
- logger.error("Cannot add friend", ex);
- }
- }
-
- /**
- * Imulates firing adding contact in group and moving contact to group.
- * When moving contact it is first adding to the new group then
- * it is removed from the old one.
- */
- private class ContactListModListenerImpl
- extends SessionAdapter
- {
- private final Hashtable<String, Object> waitMove
- = new Hashtable<String, Object>();
-
- public void waitForMove(String id, String oldParent)
- {
- waitMove.put(id, oldParent);
- }
-
- public void removeWaitForMove(String id)
- {
- waitMove.remove(id);
- }
-
- /**
- * Successfully added a friend
- * friend - YahooUser of friend
- * group - name of group added to
- * @param ev fired event
- */
- @Override
- public void friendAddedReceived(SessionFriendEvent ev)
- {
- if (logger.isTraceEnabled())
- logger.trace("Receive event for adding a friend : " + ev);
-
- ContactGroupYahooImpl group =
- findContactGroup(ev.getGroup());
-
- if(group == null){
- if (logger.isTraceEnabled())
- logger.trace("Group not found!" + ev.getGroup());
- return;
- }
-
- String contactID = ev.getFriend().getId();
- ContactYahooImpl contactToAdd = findContactById(contactID);
-
- // if group is note resolved resolve it
- // this means newly created group
- if(!group.isResolved())
- {
- // if the contact is volatile me must remove it
- // as new one will be created
- if(contactToAdd != null && contactToAdd.isVolatile())
- {
- ContactGroupYahooImpl parent
- = (ContactGroupYahooImpl)contactToAdd
- .getParentContactGroup();
-
- parent.removeContact(contactToAdd);
- fireContactRemoved(parent, contactToAdd);
- }
-
- YahooGroup gr = findGroup(ev.getGroup());
-
- if(gr != null)
- group.setResolved(gr);
-
- // contact will be added when resolving the group
-
- return;
- }
-
-
- boolean isVolatile = false;
-
- if(contactToAdd == null)
- {
- if(addedCustomYahooIds.containsKey(contactID))
- {
- String expectedContactID =
- addedCustomYahooIds.remove(contactID);
-
- contactToAdd =
- new ContactYahooImpl(expectedContactID, ev.getFriend(),
- ServerStoredContactListYahooImpl.this, true, true);
- }
- else
- {
- contactToAdd =
- new ContactYahooImpl(ev.getFriend(),
- ServerStoredContactListYahooImpl.this, true, true);
- }
- }
- else
- {
- isVolatile = contactToAdd.isVolatile();
- }
-
- //first check is contact is moving from a group
- Object isWaitingForMove = waitMove.get(contactID);
-
- if(isWaitingForMove != null && isWaitingForMove instanceof String)
- {
- // waits for move into group
- // will remove it from old group and will wait for event remove
- // from group, then will fire moved to group event
- String oldParent = (String)isWaitingForMove;
-
- group.addContact(contactToAdd);
- waitMove.put(contactID, group.getSourceGroup());
- try
- {
- yahooSession.removeFriend(contactID, oldParent);
- }
- catch(IOException ex)
- {
- if (logger.isInfoEnabled())
- logger.info("Cannot Remove(till moving) contact :" +
- contactToAdd + " from group " + oldParent);
- }
- return;
- }
-
- if(isVolatile)
- {
- // we must remove the volatile buddy as we will add
- // the persistent one.
- // Volatile buddy is moving from the volatile group
- // to the new one
- ContactGroupYahooImpl parent =
- (ContactGroupYahooImpl)contactToAdd.getParentContactGroup();
-
- parent.removeContact(contactToAdd);
- fireContactRemoved(parent, contactToAdd);
-
- contactToAdd.setPersistent(true);
- contactToAdd.setResolved(ev.getFriend());
-
- group.addContact(contactToAdd);
-
- fireContactAdded(group, contactToAdd);
- waitMove.remove(contactID);
-
- return;
- }
-
- group.addContact(contactToAdd);
- fireContactAdded(group, contactToAdd);
- }
-
- /**
- * Successfully removed a friend
- * friend - YahooUser of friend
- * group - name of group removed from
- * @param ev fired event
- */
- @Override
- public void friendRemovedReceived(SessionFriendEvent ev)
- {
- if (logger.isTraceEnabled())
- logger.trace("Receive event for removing a friend : " + ev);
-
- String contactID = ev.getFriend().getId();
-
- // first check is this part of move action
- Object waitForMoveObj = waitMove.get(contactID);
- if(waitForMoveObj != null && waitForMoveObj instanceof YahooGroup)
- {
- // first get the group - oldParent
- ContactGroupYahooImpl oldParent
- = findContactGroup(ev.getGroup());
- ContactYahooImpl contactToRemove
- = oldParent.findContact(contactID);
-
- oldParent.removeContact(contactToRemove);
- waitMove.remove(contactID);
-
- ContactGroupYahooImpl newParent =
- findContactGroup(((YahooGroup)waitForMoveObj).getName());
-
- fireContactMoved(oldParent, newParent, contactToRemove);
- return;
- }
-
- ContactYahooImpl contactToRemove = findContactById(contactID);
-
- // strange we cannot find the contact to be removed
- if(contactToRemove == null)
- return;
-
- ContactGroupYahooImpl parentGroup =
- (ContactGroupYahooImpl)contactToRemove.
- getParentContactGroup();
- parentGroup.removeContact(contactToRemove);
- fireContactRemoved(parentGroup, contactToRemove);
-
- // check if the group is deleted. If the contact is the last one in
- // the group. The group is also deleted
- if(findGroup(ev.getGroup()) == null)
- {
- rootGroup.removeSubGroup(parentGroup);
- fireGroupEvent(parentGroup,
- ServerStoredGroupEvent.GROUP_REMOVED_EVENT);
- }
- }
-
- /**
- * Someone wants to add us to their friends list
- * to - the target (us!)
- * from - the user who wants to add us
- * message - the request message text
- * @param ev fired event
- */
- @Override
- public void contactRequestReceived(SessionEvent ev)
- {
- if (logger.isInfoEnabled())
- logger.info("contactRequestReceived : " + ev);
-
- if(handler == null || ev.getFrom() == null)
- return;
-
- ContactYahooImpl contact = findContactById(ev.getFrom());
-
- if(contact == null)
- contact = createVolatileContact(ev.getFrom());
-
- AuthorizationRequest request = new AuthorizationRequest();
- request.setReason(ev.getMessage());
-
- AuthorizationResponse resp =
- handler.processAuthorisationRequest(request, contact);
-
- if (resp.getResponseCode() == AuthorizationResponse.REJECT)
- {
- try{
- yahooSession.rejectContact(ev, resp.getReason());
- }catch(IOException ex){
- logger.error("Cannot send reject : " + ex.getMessage());
- }
- }
- }
-
- /**
- * Someone has rejected our attempts to add them to our friends list
- * from - the user who rejected us
- * message - rejection message text
- * @param ev fired event
- */
- @Override
- public void contactRejectionReceived(SessionEvent ev)
- {
- if (logger.isInfoEnabled())
- logger.info("contactRejectionReceived : " + ev);
-
- if(handler == null)
- return;
-
- ContactYahooImpl contact = findContactById(ev.getFrom());
-
- AuthorizationResponse resp =
- new AuthorizationResponse(AuthorizationResponse.REJECT,
- ev.getMessage());
- handler.processAuthorizationResponse(resp, contact);
- }
-
- /**
- * Invoked on picture received.
- * @param ev fired event
- */
- @Override
- public void pictureReceived(SessionPictureEvent ev)
- {
- ContactYahooImpl contact = findContactById(ev.getFrom());
-
- if(contact == null)
- return;
-
- contact.setImage(ev.getPictureData());
-
- parentOperationSet.fireContactPropertyChangeEvent(
- ContactPropertyChangeEvent.PROPERTY_IMAGE,
- contact, null, ev.getPictureData());
- }
-
- /**
- * Process Authorization responses
- * @param ev the event to process
- */
- @Override
- public void authorizationReceived(SessionAuthorizationEvent ev)
- {
- if(ev.isAuthorizationAccepted())
- {
- if (logger.isTraceEnabled())
- logger.trace("authorizationAccepted from " + ev.getFrom());
- Contact srcContact = findContactById(ev.getFrom());
-
- if(srcContact == null)
- if (logger.isTraceEnabled())
- logger.trace("No contact found");
- else
- handler.processAuthorizationResponse(
- new AuthorizationResponse(
- AuthorizationResponse.ACCEPT,
- ev.getMessage()),
- srcContact);
- }
- else if(ev.isAuthorizationDenied())
- {
- if (logger.isTraceEnabled())
- logger.trace("authorizationDenied from " + ev.getFrom());
- Contact srcContact = findContactById(ev.getFrom());
-
- if(srcContact == null)
- if (logger.isTraceEnabled())
- logger.trace("No contact found");
- else
- {
- handler.processAuthorizationResponse(
- new AuthorizationResponse(
- AuthorizationResponse.REJECT,
- ev.getMessage()),
- srcContact);
- try
- {
- removeContact((ContactYahooImpl)srcContact);
- } catch (Exception ex)
- {
- logger.error("cannot remove denied contact : " +
- srcContact, ex);
- }
- }
- }
- else if(ev.isAuthorizationRequest())
- {
- if (logger.isTraceEnabled())
- logger.trace("authorizationRequestReceived from "
- + ev.getFrom());
- processAuthorizationRequest(ev);
- }
- }
- }
-
- /**
- * Sets the yahoo session instance of the lib
- * which comunicates with the server
- * @param session YahooSession
- */
- void setYahooSession(YahooSession session)
- {
- this.yahooSession = session;
- session.addSessionListener(contactListModListenerImpl);
- initList();
- }
-
- /**
- * It seems that ymsg (or the Yahoo! service itself as the problem also
- * appears with libpurple) would return illegal chars for names that were
- * entered in cyrillic. We use this method to translate their names into
- * something that we could actually display and store here.
- *
- * @param ymsgString the <tt>String</tt> containing illegal chars.
- *
- * @return a String where all illegal chars are converted into human
- * readable ones
- */
- static String replaceIllegalChars(String ymsgString)
- {
- return ymsgString.replace((char)26, '?');
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/VolatileContactGroupYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/VolatileContactGroupYahooImpl.java
deleted file mode 100644
index e2c589a..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/VolatileContactGroupYahooImpl.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * The Yahoo implementation of the Volatile ContactGroup interface.
- *
- * @author Damian Minkov
- */
-public class VolatileContactGroupYahooImpl
- extends ContactGroupYahooImpl
-{
- /**
- * This contact group name
- */
- private String contactGroupName = null;
-
- /**
- * Creates an Yahoo group using the specified group name
- * @param groupName String groupname
- * @param ssclCallback a callback to the server stored contact list
- * we're creating.
- */
- VolatileContactGroupYahooImpl(
- String groupName,
- ServerStoredContactListYahooImpl ssclCallback)
- {
- super(groupName, ssclCallback);
- this.contactGroupName = groupName;
- }
-
- /**
- * Returns the name of this group.
- * @return a String containing the name of this group.
- */
- @Override
- public String getGroupName()
- {
- return contactGroupName;
- }
-
- /**
- * Returns a string representation of this group, in the form
- * YahooGroup.GroupName[size]{ buddy1.toString(), buddy2.toString(), ...}.
- * @return a String representation of the object.
- */
- @Override
- public String toString()
- {
- StringBuffer buff = new StringBuffer("VolatileYahooGroup.");
- buff.append(getGroupName());
- buff.append(", childContacts="+countContacts()+":[");
-
- Iterator<Contact> contacts = contacts();
-
- while (contacts.hasNext())
- {
- Contact contact = contacts.next();
-
- buff.append(contact.toString());
- if(contacts.hasNext())
- buff.append(", ");
- }
- return buff.append("]").toString();
- }
-
- /**
- * Determines whether or not this contact group is being stored by the
- * server. Non persistent contact groups exist for the sole purpose of
- * containing non persistent contacts.
- * @return true if the contact group is persistent and false otherwise.
- */
- @Override
- public boolean isPersistent()
- {
- return false;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/YahooAccountID.java b/src/net/java/sip/communicator/impl/protocol/yahoo/YahooAccountID.java
deleted file mode 100644
index 0eb0e86..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/YahooAccountID.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * The Yahoo implementation of a sip-communicator AccountID
- *
- * @author Damian Minkov
- */
-public class YahooAccountID
- extends AccountID
-{
- /**
- * Creates an account id from the specified id and account properties.
- * @param id the id identifying this account
- * @param accountProperties any other properties necessary for the account.
- */
- YahooAccountID(String id, Map<String, String> accountProperties )
- {
- super(YahooSession.getYahooUserID(id),
- accountProperties, ProtocolNames.YAHOO, "yahoo.com");
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/YahooActivator.java b/src/net/java/sip/communicator/impl/protocol/yahoo/YahooActivator.java
deleted file mode 100644
index 1e7ca01..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/YahooActivator.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-import org.jitsi.service.configuration.*;
-import org.jitsi.service.resources.*;
-import org.osgi.framework.*;
-
-/**
- * Loads the Yahoo provider factory and registers it with service in the OSGI
- * bundle context.
- *
- * @author Damian Minkov
- */
-public class YahooActivator
- implements BundleActivator
-{
- private ServiceRegistration yahooPpFactoryServReg = null;
- private static BundleContext bundleContext = null;
- private static ConfigurationService configurationService = null;
-
- private static ProtocolProviderFactoryYahooImpl yahooProviderFactory = null;
-
- private static ResourceManagementService resourcesService;
-
- /**
- * Called when this bundle is started so the Framework can perform the
- * bundle-specific activities necessary to start this bundle.
- *
- * @param context The execution context of the bundle being started.
- * @throws Exception If this method throws an exception, this bundle is
- * marked as stopped and the Framework will remove this bundle's
- * listeners, unregister all services registered by this bundle, and
- * release all services used by this bundle.
- */
- public void start(BundleContext context) throws Exception
- {
- bundleContext = context;
-
- Hashtable<String, String> hashtable = new Hashtable<String, String>();
- hashtable.put(ProtocolProviderFactory.PROTOCOL, ProtocolNames.YAHOO);
-
- yahooProviderFactory = new ProtocolProviderFactoryYahooImpl();
-
- //reg the yahoo account man.
- yahooPpFactoryServReg = context.registerService(
- ProtocolProviderFactory.class.getName(),
- yahooProviderFactory,
- hashtable);
- }
-
- /**
- * Returns a reference to a ConfigurationService implementation currently
- * registered in the bundle context or null if no such implementation was
- * found.
- *
- * @return ConfigurationService a currently valid implementation of the
- * configuration service.
- */
- public static ConfigurationService getConfigurationService()
- {
- if(configurationService == null)
- {
- ServiceReference confReference
- = bundleContext.getServiceReference(
- ConfigurationService.class.getName());
- configurationService
- = (ConfigurationService) bundleContext.getService(confReference);
- }
- return configurationService;
- }
-
- /**
- * Returns a reference to the bundle context that we were started with.
- * @return a reference to the BundleContext instance that we were started
- * witn.
- */
- public static BundleContext getBundleContext()
- {
- return bundleContext;
- }
-
- /**
- * Retrurns a reference to the protocol provider factory that we have
- * registered.
- * @return a reference to the <tt>ProtocolProviderFactoryYahooImpl</tt>
- * instance that we have registered from this package.
- */
- static ProtocolProviderFactoryYahooImpl getProtocolProviderFactory()
- {
- return yahooProviderFactory;
- }
-
- /**
- * Called when this bundle is stopped so the Framework can perform the
- * bundle-specific activities necessary to stop the bundle.
- *
- * @param context The execution context of the bundle being stopped.
- * @throws Exception If this method throws an exception, the bundle is
- * still marked as stopped, and the Framework will remove the bundle's
- * listeners, unregister all services registered by the bundle, and
- * release all services used by the bundle.
- */
- public void stop(BundleContext context) throws Exception
- {
- yahooProviderFactory.stop();
- yahooPpFactoryServReg.unregister();
- }
-
- public static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- {
- ServiceReference serviceReference = bundleContext
- .getServiceReference(ResourceManagementService.class.getName());
-
- if(serviceReference == null)
- return null;
-
- resourcesService = (ResourceManagementService) bundleContext
- .getService(serviceReference);
- }
-
- return resourcesService;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/YahooSession.java b/src/net/java/sip/communicator/impl/protocol/yahoo/YahooSession.java
deleted file mode 100644
index f24e50c..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/YahooSession.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.yahoo;
-
-import java.io.*;
-
-import ymsg.network.*;
-
-/**
- * Extends The Yahoo session to have access to some
- * protected functionality
- * Not working for now.
- *
- * @author Damian Minkov
- */
-public class YahooSession
- extends Session
-{
- /**
- * Renames a group. Not working for now
- */
- public void renameGroup(String oldName, String newName)
- throws IOException
- {
- transmitGroupRename(oldName, newName);
- }
-
- /**
- * Removes the server part from the given id
- */
- public static String getYahooUserID(String id)
- {
- return (id.indexOf("@") > -1 )
- ? id.substring(0, id.indexOf("@"))
- : id;
- }
-
- /**
- * Sending typing notifications
- * @param to user we are notifing
- * @param from our user id
- */
- void keyTyped(String to, String from)
- {
- try {
- transmitNotify(to, from, true, " ", NOTIFY_TYPING);
- }catch(IOException e){}
- }
-
- /**
- * Sending stop typing notifications
- * @param to user we are notifing
- * @param from our user id
- */
- void stopTyping(String to, String from)
- {
- try {
- transmitNotify(to, from, false, " ", NOTIFY_TYPING);
- }catch(IOException e){}
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/yahoo.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/yahoo/yahoo.provider.manifest.mf
deleted file mode 100644
index 39e23bf..0000000
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/yahoo.provider.manifest.mf
+++ /dev/null
@@ -1,22 +0,0 @@
-Bundle-Activator: net.java.sip.communicator.impl.protocol.yahoo.YahooActivator
-Bundle-Name: Yahoo Protocol Provider Implementation
-Bundle-Description: An Yahoo implementation of the Protocol Provider Service.
-Bundle-Vendor: jitsi.org
-Bundle-Version: 0.0.1
-Bundle-SymbolicName: net.java.sip.communicator.protocol.yahoo
-Import-Package: org.osgi.framework,
- javax.net.ssl,
- javax.swing,
- javax.swing.text,
- javax.xml.parsers,
- javax.naming,
- javax.naming.directory,
- org.xml.sax,
- sun.security.action,
- org.jitsi.service.configuration,
- org.jitsi.service.resources, net.java.sip.communicator.service.resources,
- net.java.sip.communicator.util,
- net.java.sip.communicator.service.dns,
- net.java.sip.communicator.service.protocol,
- net.java.sip.communicator.service.protocol.yahooconstants,
- net.java.sip.communicator.service.protocol.event
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/BonjourService.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/BonjourService.java
deleted file mode 100644
index 8258da7..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/BonjourService.java
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-import net.java.sip.communicator.impl.protocol.zeroconf.jmdns.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Class dealing with JmDNS and treating all the
- * incoming connections on the bonjour port
- * @author Christian Vincenot
- */
-public class BonjourService extends Thread
- implements ServiceListener,
- DNSListener
-{
- private static final Logger logger =
- Logger.getLogger(BonjourService.class);
-
- private int port = 5298;
- private ServerSocket sock = null;
- private String id = null;
- private JmDNS jmdns=null;
- private final Map<String, Object> props = new Hashtable<String, Object>();
- private ServiceInfo service = null;
- private boolean dead = false;
-
- private final List<ContactZeroconfImpl> contacts
- = new Vector<ContactZeroconfImpl>();
-
- private ProtocolProviderServiceZeroconfImpl pps;
- OperationSetPersistentPresenceZeroconfImpl opSetPersPresence;
-
- private ZeroconfAccountID acc;
-
- /* Should maybe better get the status directly from OperationSetPresence */
- private PresenceStatus status = ZeroconfStatusEnum.OFFLINE;
-
- /**
- * Returns the corresponding ProtocolProviderService
- * @return corresponding ProtocolProviderService
- */
- public ProtocolProviderServiceZeroconfImpl getPPS()
- {
- return pps;
- }
-
- /**
- * Returns the id of this service.
- * @return returns the id of this service.
- */
- String getID()
- {
- return id;
- }
-
- /**
- * Creates a new instance of the Bonjour service thread
- * @param port TCP Port number on which to try to start the Bonjour service
- * @param pps ProtocolProviderService instance
- * which is creating this BonjourService
- */
- public BonjourService(int port,
- ProtocolProviderServiceZeroconfImpl pps)
- {
- this.acc = (ZeroconfAccountID) pps.getAccountID();
- this.port = port;
- this.id = acc.getUserID();
- this.pps = pps;
-
- opSetPersPresence =
- (OperationSetPersistentPresenceZeroconfImpl) pps
- .getOperationSet(OperationSetPersistentPresence.class);
-
- // Gaim
- props.put("1st", (acc.getFirst() == null)? "":acc.getFirst());
- props.put("email", (acc.getMail() == null)? "":acc.getMail());
- props.put("jid", this.id);
- props.put("last", (acc.getLast() == null)?"":acc.getLast());
- props.put("msg", opSetPersPresence.getCurrentStatusMessage());
- props.put("status", "avail");
-
- //iChat
- props.put("phsh","000");
- //props.put("status","avail");
- //props.put("port.p2pj", "5298");
- props.put("vc", "C!");
- //props.put("1st", "John");
- props.put("txtvers","1");
-
- //XEP-0174 (Final paper)
- props.put("ext","");
- props.put("nick", (acc.getFirst() == null)? this.id:acc.getFirst());
- props.put("ver", "1");
- props.put("node", "SIP Communicator");
-
- //Ours
- props.put("client", "SIP Communicator");
-
- changeStatus(opSetPersPresence.getPresenceStatus());
-
- sock = createSocket(port);
- if (sock == null)
- return;
-
- port = sock.getLocalPort();
-
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF: ServerSocket bound to port "+port);
-
- props.put("port.p2pj", Integer.toString(port));
- this.setDaemon(true);
- this.start();
- }
-
- /* TODO: Better exception checking to avoid sudden exit and bonjour
- * service shutdown */
-
- /**
- * Walk?
- */
- @Override
- public void run()
- {
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF: Bonjour Service Thread up and running!");
-
- /* Put jmDNS in DEBUD Mode :
- * Following verbosity levels can be chosen :
- * "INFO" , "WARNING", "SEVERE", "ALL", "FINE", "FINER", "FINEST", etc
- */
- //System.setProperty("jmdns.debug", "0");
-
- while (dead == false)
- {
- if (sock == null || sock.isClosed())
- {
- sock = createSocket(port);
- /* What should we do now? TEMPORARY: shutdown()*/
- if (sock == null) shutdown();
- port = sock.getLocalPort();
- props.put("port.p2pj", Integer.toString(port));
- //TODO: update JmDNS in case the port had to be changed!
- }
- try
- {
- Socket connection = sock.accept();
- ContactZeroconfImpl contact = getContact(null,
- connection.getInetAddress());
- /*if (status.equals(ZeroconfStatusEnum.OFFLINE)
- || status.equals(ZeroconfStatusEnum.INVISIBLE) */
- if (dead == true) break;
-
- if ((contact == null)
- || (contact.getClientThread() != null))
- {
- if (contact == null)
- logger.error("ZEROCONF: Connexion from "
- + "unknown contact ["
- + connection.getInetAddress()
- +"]. REJECTING!");
- else if (contact.getClientThread() == null)
- logger.error("ZEROCONF: Redundant chat "
- + "channel ["
- + contact
- +"]. REJECTING!");
- connection.close();
- }
- else new ClientThread(connection, this);
- }
- catch(Exception e)
- {
- logger.error(e);
- }
- }
-
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF: Going Offline - "
- +"BonjourService Thread exiting!");
- }
-
- /**
- * Might be used for shutdown...
- */
- public void shutdown()
- {
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF: Shutdown!");
-
- dead = true;
- try
- { sock.close(); }
- catch (Exception ex)
- { logger.error(ex); }
-
- changeStatus(ZeroconfStatusEnum.OFFLINE);
- if(jmdns != null)
- jmdns.close();
- }
-
- private ServerSocket createSocket(int port)
- {
- ServerSocket sock=null;
- try
- {
- sock = new ServerSocket(port);
- }
- catch(Exception e)
- {
- logger.error("ZEROCONF: Couldn't bind socket to port "
- +port+"! Switching to an other port...");
- try
- {
- sock = new ServerSocket(0);
- }
- catch (IOException ex)
- {
- logger.error("ZEROCONF: FATAL ERROR => "
- +"Couldn't bind to a port!!", ex);
- }
- }
-
- return sock;
- }
-
- /**
- * Changes the status of the local user.
- * @param stat New presence status
- */
- public void changeStatus(PresenceStatus stat)
- {
- /* [old_status == new_status ?] => NOP */
- if (stat.equals(status))
- return;
-
- /* [new_status == OFFLINE ?] => clean up everything */
- if (stat.equals(ZeroconfStatusEnum.OFFLINE))
- {
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF: Going OFFLINE");
- //jmdns.unregisterAllServices();
- jmdns.removeServiceListener("_presence._tcp.local.", this);
- jmdns.close();
- jmdns=null;
- //dead = true;
-
- // Erase all contacts by putting them OFFLINE
- opSetPersPresence.changePresenceStatusForAllContacts(
- opSetPersPresence.getServerStoredContactListRoot(), stat);
-
- try
- {
- sleep(1000);
- } catch (InterruptedException ex)
- {
- logger.error(ex);
- }
- }
-
- /* [old_status == OFFLINE ?] => register service */
- else if (status.equals(ZeroconfStatusEnum.OFFLINE))
- {
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF: Getting out of OFFLINE state");
- props.put("status", stat.getStatusName());
- service = new ServiceInfo("_presence._tcp.local.", id,
- port, 0, 0, props);
-
- try
- {
- jmdns = new JmDNS();
- jmdns.registerServiceType("_presence._tcp.local.");
- jmdns.addServiceListener("_presence._tcp.local.", this);
- jmdns.registerService(service);
-
- /* In case the ID had to be changed */
- id = service.getName();
- }
- catch (Exception ex)
- { logger.error(ex); }
-
- //dead = false;
-
- /* Normal status change */
- }
- else
- {
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF : Changing status");
-
- props.put("status", stat.getStatusName());
-
- /* FIXME: Not totally race condition free since the 3 calls aren't
- * atomic, but that's not really critical since there's little
- * change chance of concurrent local contact change, and this
- * wouldn't have big consequences.
- */
- ServiceInfo info =
- jmdns.getLocalService(id.toLowerCase()+"._presence._tcp.local.");
- if (info == null)
- logger.error("ZEROCONF/JMDNS: PROBLEM GETTING "
- +"LOCAL SERVICEINFO !!");
-
- byte[] old = info.getTextBytes();
- info.setProps(props);
- jmdns.updateInfos(info, old);
- }
-
- status = stat;
- }
-
- private class AddThread extends Thread
- {
- private String type, name;
- public AddThread(String type, String name)
- {
- this.setDaemon(true);
- this.type = type;
- this.name = name;
- this.start();
- }
-
- @Override
- public void run()
- {
- ServiceInfo service = null;
- while ((service == null) && (dead == false)
- && !status.equals(ZeroconfStatusEnum.OFFLINE))
- {
- service = jmdns.getServiceInfo(type, name, 10000);
- if (service == null)
- logger.error("BONJOUR: ERROR - Service Info of "
- + name +" not found in cache!!");
- try
- {
- sleep(2);
- }
- catch (InterruptedException ex)
- {
- logger.error(ex);
- }
- }
- if ((dead == false) && !status.equals(ZeroconfStatusEnum.OFFLINE))
- jmdns.requestServiceInfo(type, name);
- //} else handleResolvedService(name, type, service);
- }
- }
-
- /* Service Listener Implementation */
-
- /**
- * A service has been added.
- *
- * @param event The ServiceEvent providing the name and fully qualified type
- * of the service.
- */
- public void serviceAdded(ServiceEvent event)
- {
- /* WARNING: DONT PUT ANY BLOCKING CALLS OR FLAWED LOOPS IN THIS METHOD.
- * JmDNS calls this method without creating a new thread, so if this
- * method doesn't return, jmDNS will hang !!
- */
-
- String name = event.getName();
- String type = event.getType();
-
- if (name.equals(id))
- return;
-
- if (logger.isDebugEnabled())
- logger.debug("BONJOUR: "+name
- +"["+type+"] detected! Trying to get information...");
- try
- {
- sleep(2);
- }
- catch (InterruptedException ex)
- {
- logger.error(ex);
- }
-
- jmdns.printServices();
-
- new AddThread(type, name);
- }
-
-
-
- /**
- * A service has been removed.
- *
- * @param event The ServiceEvent providing the name and fully qualified type
- * of the service.
- */
- public void serviceRemoved(ServiceEvent event)
- {
- String name = event.getName();
- if (name.equals(id))
- return;
-
- ContactZeroconfImpl contact = getContact(name, null);
-
- if(contact == null)
- return;
-
- opSetPersPresence.changePresenceStatusForContact(contact,
- ZeroconfStatusEnum.OFFLINE);
- if (logger.isDebugEnabled())
- logger.debug("BONJOUR: Received announcement that "
- +name+" went offline!");
-
- }
-
- /**
- * A service has been resolved. Its details are now available in the
- * ServiceInfo record.
- *
- * @param event The ServiceEvent providing the name, the fully qualified
- * type of the service, and the service info record,
- * or null if the service could not be resolved.
- */
- public void serviceResolved(ServiceEvent event)
- {
- String contactID = event.getName();
- String type = event.getType();
- ServiceInfo info = event.getInfo();
-
- if (logger.isDebugEnabled())
- logger.debug("BONJOUR: Information about "
- +contactID+" discovered");
-
- handleResolvedService(contactID, type, info);
- }
-
- private void handleResolvedService(String contactID,
- String type,
- ServiceInfo info)
- {
- if (contactID.equals(id))
- return;
-
- if (info.getAddress().toString().length() > 15)
- {
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF: Temporarily ignoring IPv6 addresses!");
- return;
- }
-
- ContactZeroconfImpl newFriend;
-
- synchronized(this)
- {
- if (getContact(contactID, info.getAddress()) != null)
- {
- if (logger.isDebugEnabled())
- logger.debug("Contact "
- +contactID+" already in contact list! Skipping.");
- return;
- };
- if (logger.isDebugEnabled())
- logger.debug("ZEROCNF: ContactID " + contactID +
- " Address " + info.getAddress());
-
- if (logger.isDebugEnabled())
- logger.debug(" Address=>"+info.getAddress()
- +":"+info.getPort());
-
- for (Iterator<String> names = info.getPropertyNames();
- names.hasNext();)
- {
- String prop = names.next();
- if (logger.isDebugEnabled())
- logger.debug(" "+prop+"=>"
- +info.getPropertyString(prop));
- }
-
- /* Creating the contact */
- String name = info.getPropertyString("1st");
- if (info.getPropertyString("last") != null)
- name += " "+ info.getPropertyString("last");
-
- int port = Integer.valueOf(
- info.getPropertyString("port.p2pj")).intValue();
-
- if (port < 1)
- {
- logger.error("ZEROCONF: Flawed contact announced himself"
- +"without necessary parameters : "+contactID);
- return;
- }
-
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF: Detected client "+name);
-
- newFriend =
- opSetPersPresence.createVolatileContact(
- contactID, this, name,
- info.getAddress(), port);
- }
- /* Try to detect which client type it is */
- int clientType = ContactZeroconfImpl.XMPP;
- if (info.getPropertyString("client") != null
- && info.getPropertyString("client").
- compareToIgnoreCase("SIP Communicator") == 0)
- clientType = ContactZeroconfImpl.SIPCOM;
-
- else if ((info.getPropertyString("jid") != null)
- && (info.getPropertyString("node") == null))
- clientType = ContactZeroconfImpl.GAIM;
-
- else if (info.getPropertyString("jid") == null)
- clientType = ContactZeroconfImpl.ICHAT;
-
- newFriend.setClientType(clientType);
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF: CLIENT TYPE "+clientType);
-
- ZeroconfStatusEnum status =
- ZeroconfStatusEnum.statusOf(info.getPropertyString("status"));
- opSetPersPresence.
- changePresenceStatusForContact(newFriend,
- status == null?ZeroconfStatusEnum.ONLINE:status);
-
- // Listening for changes
- jmdns.addListener(this, new DNSQuestion(info.getQualifiedName(),
- DNSConstants.TYPE_SRV,
- DNSConstants.CLASS_UNIQUE));
- }
-
- /**
- * Callback called by JmDNS to inform the
- * BonjourService of a potential status change of some contacts.
- * @param jmdns JmDNS instance responsible for this
- * @param now Timestamp
- * @param record DNSRecord which changed
- */
- public synchronized void updateRecord( JmDNS jmdns,
- long now,
- DNSRecord record)
- {
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF/JMDNS: Received record update for "+record);
-
- int clazz = record.getClazz();
- int type = record.getType();
-
- /* Check the info returned by JmDNS since we can't really trust its
- * filtering. */
- if (!(((type & DNSConstants.TYPE_TXT) != 0) &&
- ((clazz & DNSConstants.CLASS_IN) != 0) &&
- record.isUnique() &&
- record.getName().endsWith("_presence._tcp.local.")))
- return;
-
- String name = record.getName().replaceAll("._presence._tcp.local.","");
- ContactZeroconfImpl contact;
-
- synchronized(this)
- {
- contact = getContact(name, null);
-
- if (contact == null) { //return;
- logger.error("ZEROCONF: BUG in jmDNS => Received update without "
- +"previous contact annoucement. Trying to add contact");
- new AddThread("_presence._tcp.local.", name);
- return;
- }
- }
-
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF: "+ name
- + " changed status. Requesting fresh data!");
-
- /* Since a record was updated, we can be sure that we can do a blocking
- * getServiceInfo without risk. (Still, we use the method with timeout
- * to avoid bad surprises). If some problems of status change refresh
- * appear, we'll have to fall back on the method with callback as we've
- * done for "ServiceAdded".
- */
-
- ServiceInfo info = jmdns.getServiceInfo("_presence._tcp.local.", name,
- 1000);
- if (info == null)
- {
- logger.error("ZEROCONF/JMDNS: Problem!! The service "
- +"information was not in cache. See comment in "
- +"BonjourService.java:updateRecord !!");
- return;
- }
-
- /* Let's change what we can : status, message, etc */
- ZeroconfStatusEnum status =
- ZeroconfStatusEnum.statusOf(info.getPropertyString("status"));
-
- opSetPersPresence.
- changePresenceStatusForContact(contact,
- status == null ? ZeroconfStatusEnum.ONLINE:status);
-
- }
-
- /**
- * Returns an Iterator over all contacts.
- *
- * @return a java.util.Iterator over all contacts
- */
- public Iterator<ContactZeroconfImpl> contacts()
- {
- return contacts.iterator();
- }
-
- /**
- * Adds a contact to the locally stored list of contacts
- * @param contact Zeroconf Contact to add to the local list
- */
- public void addContact(ContactZeroconfImpl contact)
- {
- if (contact == null)
- throw new IllegalArgumentException("contact");
-
- synchronized(contacts)
- {
- contacts.add(contact);
- }
- }
- /**
- * Returns the <tt>Contact</tt> with the specified identifier or IP address.
- *
- * @param id the identifier of the <tt>Contact</tt> we are
- * looking for.
- * @param ip the IP address of the <tt>Contact</tt> we are looking for.
- * @return the <tt>Contact</tt> with the specified id or address.
- */
- public ContactZeroconfImpl getContact(String id, InetAddress ip)
- {
- if (id == null && ip == null) return null;
-
- synchronized(contacts)
- {
- Iterator<ContactZeroconfImpl> contactsIter = contacts();
-
- while (contactsIter.hasNext())
- {
- ContactZeroconfImpl contact = contactsIter.next();
- //System.out.println("ZEROCNF: Comparing "+id+ " "+ip+
- //" with "+ contact.getAddress()+ " " + contact.getIpAddress());
- if (((contact.getAddress().equals(id)) || (id == null))
- && ((contact.getIpAddress().equals(ip)) || (ip == null)))
- return contact;
-
- }
- }
- //System.out.println("ZEROCNF: ERROR - " +
- //"Couldn't find contact to get ["+id+" / "+ip+"]");
- return null;
- }
-
- /**
- * Removes the <tt>Contact</tt> with the specified identifier or IP address.
- *
- *
- * @param id the identifier of the <tt>Contact</tt> we are
- * looking for.
- * @param ip the IP address of the <tt>Contact</tt> we are looking for.
- */
- public void removeContact(String id, InetAddress ip)
- {
- synchronized(contacts)
- {
- Iterator<ContactZeroconfImpl> contactsIter = contacts();
- while (contactsIter.hasNext())
- {
- ContactZeroconfImpl contact = contactsIter.next();
- if (((contact.getAddress().equals(id)) || (id == null))
- &&((contact.getIpAddress().equals(ip)) || (ip == null)))
- {
- if (contact.getClientThread() != null)
- contact.getClientThread().cleanThread();
- contacts.remove(contact);
- return;
- }
- };
- }
- logger.error(
- "ZEROCONF: ERROR - Couldn't find contact to delete ["+id+" / "+ip+"]");
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/ClientThread.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/ClientThread.java
deleted file mode 100644
index 4367eed..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/ClientThread.java
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf;
-
-import java.io.*;
-import java.net.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Class creating a thread responsible for handling the chat
- * with the remote user on the other end of the socket
- *
- * @author Christian Vincenot
- */
-public class ClientThread
- extends Thread
-{
- private static final Logger logger = Logger.getLogger(ClientThread.class);
-
- private OperationSetBasicInstantMessagingZeroconfImpl opSetBasicIM;
- private OperationSetTypingNotificationsZeroconfImpl opSetTyping;
- private Socket sock;
- private InetAddress remoteIPAddress;
- private OutputStream out;
- private DataInputStream in;
- private BonjourService bonjourService;
- private ContactZeroconfImpl contact=null;
- private boolean streamState = false;
-
- private String messagesQueue=null;
-
- /**
- * Sets the contact with which we're chatting in this ClientThread
- * @param contact Zeroconf contact with which we're chatting
- */
- protected void setContact(ContactZeroconfImpl contact)
- {
- this.contact = contact;
- }
-
- /**
- * Set the stream as opened. This means that the
- * conversation with the client is really opened
- * from now on (the XML greetings are over)
- */
- protected void setStreamOpen()
- {
- synchronized(this)
- {
- this.streamState = true;
- }
- }
-
- /**
- * Says if the stream between the local user and the remote user
- * is in an opened state (greetings are over and we can chat)
- * @return Returns true if the stream is "opened" (ie, ready for chat)
- */
- protected boolean isStreamOpened()
- {
- synchronized(this)
- {
- return this.streamState;
- }
- }
-
- /**
- * Creates a new instance of ClientThread reponsible
- * for handling the conversation with the remote user.
- * @param sock Socket created for chatting
- * @param bonjourService BonjourService which spawned this ClientThread
- */
- public ClientThread(Socket sock, BonjourService bonjourService)
- {
- this.sock = sock;
- this.remoteIPAddress = sock.getInetAddress();
- this.bonjourService = bonjourService;
- this.opSetBasicIM =
- (OperationSetBasicInstantMessagingZeroconfImpl) bonjourService
- .getPPS().getOperationSet(
- OperationSetBasicInstantMessaging.class);
-
- this.opSetTyping =
- (OperationSetTypingNotificationsZeroconfImpl) bonjourService
- .getPPS()
- .getOperationSet(OperationSetTypingNotifications.class);
- this.setDaemon(true);
-
- try
- {
- out = sock.getOutputStream();
- in = new DataInputStream(sock.getInputStream());
- }
- catch (IOException e)
- {
- logger.error("Creating ClientThread: Couldn't get I/O for "
- +"the connection", e);
- //System.exit(1);
- return;
- }
-
- this.start();
- }
-
- /*
- * Read a message from the socket.
- * TODO: clean the code a bit and optimize it.
- */
- private String readMessage()
- {
- String line;
- byte[] bytes = new byte[10];
-
- try
- {
- int i=0;
-
- while (i < 9)
- {
- i += in.read(bytes,0,9-i);
- }
-
- line = new String(bytes);
- bytes = new byte[1];
- if ((line.getBytes())[0] == '\n')
- line = line.substring(1);
-
- if (line.startsWith("<message"))
- {
- while (true)
- {
- bytes[0] = in.readByte();
- line += new String(bytes);
-
- if ((line.endsWith("</message>"))
- || (line.endsWith("stream>")))
- return line;
- }
- }
- else
- {
- while (true)
- {
- bytes[0] = in.readByte();
- line += new String(bytes);
- if ( ">".compareTo(new String(bytes)) == 0 )
- return line;
- }
- }
- }
- catch (IOException e)
- {
- logger.error("Couldn't get I/O for the connection", e);
- //System.exit(1);
- }
-
- return null;
- }
-
- /*
- * Parse the payload and extract the information.
- * TODO: If needed, fill in the remaining fields of MessageZeroconfImpl
- * like the baloon icon color, color/size/font of the text.
- */
- private MessageZeroconfImpl parseMessage(String str)
- {
- if (str.startsWith("<?xml") || str.startsWith("<stream"))
- return new MessageZeroconfImpl
- (null, null, MessageZeroconfImpl.STREAM_OPEN);
-
- if (str.endsWith("stream>"))
- return new MessageZeroconfImpl
- (null, null, MessageZeroconfImpl.STREAM_CLOSE);
-
- if ((str.indexOf("<delivered/>") > 0) && (str.indexOf("<body>") < 0))
- return new MessageZeroconfImpl
- (null, null, MessageZeroconfImpl.DELIVERED);
-
- if (!str.startsWith("<message"))
- return new MessageZeroconfImpl
- (null, null, MessageZeroconfImpl.UNDEF);
-
- /* TODO: Parse Enconding (& contact id to be able to double-check
- * the source of a message)
- *
- * TODO: Check that the fields are outside of <body>..</body>
- */
-
- if ((str.indexOf("<body>") < 0) || (str.indexOf("</body>") < 0))
- return new MessageZeroconfImpl
- (null, null, MessageZeroconfImpl.UNDEF);
-
- String temp =
- str.substring(str.indexOf("<body>")+6, str.indexOf("</body>"));
-
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF: received message ["+temp+"]");
-
- int messageType = MessageZeroconfImpl.MESSAGE;
-
- if ((str.indexOf("<id>") >= 0) && (str.indexOf("</id>") >= 0))
- messageType = MessageZeroconfImpl.TYPING;
-
- MessageZeroconfImpl msg =
- new MessageZeroconfImpl(
- temp,
- null,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE,
- messageType);
-
- return msg;
- }
-
- private int handleMessage(MessageZeroconfImpl msg)
- {
-
- switch(msg.getType())
- {
- /* STREAM INIT */
- case MessageZeroconfImpl.STREAM_OPEN:
- if (contact == null)
- contact = bonjourService.getContact(null, remoteIPAddress);
- if (!isStreamOpened())
- {
- sendHello();
- setStreamOpen();
- }
- if (messagesQueue != null)
- {
- write(messagesQueue);
- messagesQueue = null;
- }
- break;
-
- /* ACK */
- case MessageZeroconfImpl.DELIVERED : break;
-
- /* NORMAL MESSAGE */
- case MessageZeroconfImpl.MESSAGE:
- if (!isStreamOpened())
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF: client on the other side "
- +"isn't polite (sending messages without "
- +"saying hello :P");
- if (contact == null)
- //TODO: Parse contact id to double-check
- contact = bonjourService.getContact(null, remoteIPAddress);
-
- /* TODO: If we want to implement invisible status, we'll have to
- * make this test less restrictive to handle messages from
- * unannounced clients.
- */
- if (contact == null)
- {
- logger.error("ZEROCONF: ERROR - Couldn't identify "
- +"contact. Closing socket.");
- return -1;
- }
- else if (contact.getClientThread() == null)
- contact.setClientThread(this);
-
- opSetBasicIM.fireMessageReceived(msg, contact);
-
- opSetTyping.fireTypingNotificationsEvent(contact,
- OperationSetTypingNotificationsZeroconfImpl.STATE_STOPPED);
- break;
-
- case MessageZeroconfImpl.TYPING:
- if (!isStreamOpened())
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF: client on the other side "
- +"isn't polite (sending messages without "
- +"saying hello :P");
- if (contact == null)
- //TODO: Parse contact id to double-check
- contact = bonjourService.getContact(null, remoteIPAddress);
- opSetTyping.fireTypingNotificationsEvent(contact,
- OperationSetTypingNotificationsZeroconfImpl.STATE_TYPING);
-
- /* TODO: code a private runnable class to be used as timeout
- * to set the typing state to STATE_PAUSED when a few seconds
- * without news have passed.
- */
-
- break;
-
- case MessageZeroconfImpl.STREAM_CLOSE:
- sendBye();
- contact.setClientThread(null);
- return 1;
-
- case MessageZeroconfImpl.UNDEF:
- logger.error("ZEROCONF: received strange message. SKIPPING!");
- break;
- }
-
- //System.out.println("RECEIVED MESSAGE "+ msg.getContent()+
- //" from "+contact.getAddress() + "!!!!!!!!!!!!!!");
- return 0;
- }
-
-
- private void write(String string)
- {
- //System.out.println("Writing " + string + "!!!!!!!!!");
- byte[] bytes = string.getBytes();
- try
- {
- out.write(bytes);
- out.flush();
- }
- catch (IOException e)
- {
- logger.error("Couldn't get I/O for the connection");
- if (contact != null)
- {
- contact.setClientThread(null);
- }
-
- try
- {
- sock.close();
- }
- catch (IOException ex)
- {
- logger.error(ex);
- }
-
- }
- }
-
- /**
- * Say hello :)
- */
- protected void sendHello()
- {
- switch(contact.getClientType())
- {
- case ContactZeroconfImpl.GAIM:
- case ContactZeroconfImpl.ICHAT:
- case ContactZeroconfImpl.SIPCOM:
- write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
- write("<stream:stream xmlns=\"jabber:client\" "
- +"xmlns:stream=\"http://etherx.jabber.org/streams\">");
- break;
- case ContactZeroconfImpl.XMPP:
- write("<stream:stream"
- +"xmlns='jabber:client'"
- +"xmlns:stream='http://etherx.jabber.org/streams'"
- +"from='"+bonjourService.getID()+"'"
- +"to='"+contact.getAddress()+"'"
- +"version='1.0'>\n");
- break;
- }
-
- /* Legacy: OLD XMPP (XEP-0174 Draft) */
- //write("<stream:stream to='"+sock.getInetAddress().getHostAddress()
- //+"' xmlns='jabber:client' stream='http://etherx.jabber.org/streams'>");
- }
-
- private void sendBye()
- {
- write("</stream:stream>\n");
- }
-
- private String toXHTML(MessageZeroconfImpl msg)
- {
- switch(contact.getClientType())
- {
- case ContactZeroconfImpl.XMPP:
- return new String("<message to='"
- +contact.getAddress()+"' from='"
- +bonjourService.getID()+"'>"
- + "<body>"+msg.getContent()+"</body>"
- + "</message>\n");
-
- case ContactZeroconfImpl.SIPCOM:
-
- case ContactZeroconfImpl.ICHAT:
- return new String(
- "<message to='"+sock.getInetAddress().getHostAddress()
- +"' type='chat' id='"+bonjourService.getID()+"'>"
- + "<body>"+msg.getContent()+"</body>"
- + "<html xmlns='http://www.w3.org/1999/xhtml'>"
- + "<body ichatballooncolor='#7BB5EE' "
- + "ichattextcolor='#000000'>"
- + "<font face='Helvetica' ABSZ='12' color='#000000'>"
- + msg.getContent()
- + "</font>"
- + "</body>"
- + "</html>"
- + "<x xmlns='jabber:x:event'>"
- + "<offline/>"
- + "<delivered/>"
- + "<composing/>"
- + (msg.getType()==MessageZeroconfImpl.TYPING?"<id></id>":"")
- + "</x>"
- + "</message>");
-
- case ContactZeroconfImpl.GAIM:
- default:
- return new String(
- "<message to='"+contact.getAddress()
- +"' from='"+bonjourService.getID()
- + "' type='chat'><body>"+msg.getContent()+"</body>"
- + "<html xmlns='http://www.w3.org/1999/xhtml'><body><font>"
- + msg.getContent()
- + "</font></body></html><x xmlns='jabber:x:event'><composing/>"
- + (msg.getType()==MessageZeroconfImpl.TYPING?"<id></id>":"")
- + "</x></message>\n");
- }
- }
-
-
- /**
- * Send a message to the remote user
- * @param msg Message to send
- */
- public void sendMessage(MessageZeroconfImpl msg)
- {
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF: Sending messag ["
- +msg.getContent()+"] to "
- + contact.getDisplayName());
- if (!isStreamOpened())
- {
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF: Stream not opened... "
- +"will send the message later");
- messagesQueue += toXHTML(msg);
- }
- else write(toXHTML(msg));
- }
-
- /**
- * Walk?
- */
- @Override
- public void run()
- {
- if (logger.isDebugEnabled())
- logger.debug("Bonjour: NEW CONNEXION from "
- + sock.getInetAddress().getCanonicalHostName()
- +" / "+sock.getInetAddress().getHostAddress());
- String input;
- MessageZeroconfImpl msg=null;
-
-
- input = readMessage();
- msg = parseMessage(input);
-
- while (handleMessage(msg) == 0 && !sock.isClosed())
- {
- input = readMessage();
- msg = parseMessage(input);
- }
-
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF : OUT OF LOOP !! Closed chat.");
- cleanThread();
- }
-
- /**
- * Clean-up the thread to exit
- */
- public void cleanThread()
- {
- /* I wonder if that's ok... */
- if (sock != null && sock.isClosed() == false)
- {
- sendBye();
- try
- {
- sock.close();
- }
- catch (IOException ex)
- {
- logger.error(ex);
- }
- }
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/ContactGroupZeroconfImpl.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/ContactGroupZeroconfImpl.java
deleted file mode 100644
index 568e087..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/ContactGroupZeroconfImpl.java
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * A simple, straightforward implementation of a zeroconf ContactGroup. Since
- * the Zeroconf protocol, we simply store all group details
- * in class fields. You should know that when implementing a real protocol,
- * the contact group implementation would rather encapsulate group objects from
- * the protocol stack and group property values should be returned by consulting
- * the encapsulated object.
- *
- * @author Christian Vincenot
- * @author Maxime Catelin
- * @author Jonathan Martin
- */
-public class ContactGroupZeroconfImpl
- implements ContactGroup
-{
-
- /**
- * The name of this Zeroconf contact group.
- */
- private String groupName = null;
-
- /**
- * The list of this group's members.
- */
- private Vector<Contact> contacts = new Vector<Contact>();
-
- /**
- * The list of sub groups belonging to this group.
- */
- private Vector<ContactGroup> subGroups = new Vector<ContactGroup>();
-
- /**
- * The group that this group belongs to (or null if this is the root group).
- */
- private ContactGroupZeroconfImpl parentGroup = null;
-
- /**
- * Determines whether this group is really in the contact list or whether
- * it is here only temporarily and will be gone next time we restart.
- */
- private boolean isPersistent = false;
-
- /**
- * The protocol provider that created us.
- */
- private ProtocolProviderServiceZeroconfImpl parentProvider = null;
-
- /**
- * Determines whether this group has been resolved on the server.
- * Unresolved groups are groups that were available on previous runs and
- * that the meta contact list has stored. During all next runs, when
- * bootstrapping, the meta contact list would create these groups as
- * unresolved. Once a protocol provider implementation confirms that the
- * groups are still on the server, it would issue an event indicating that
- * the groups are now resolved.
- */
- private boolean isResolved = true;
-
- /**
- * An id uniquely identifying the group. For many protocols this could be
- * the group name itself.
- */
- private String uid = null;
- private static final String UID_SUFFIX = ".uid";
-
- /**
- * Creates a ContactGroupZeroconfImpl with the specified name.
- *
- * @param groupName the name of the group.
- * @param parentProvider the protocol provider that created this group.
- */
- public ContactGroupZeroconfImpl(
- String groupName,
- ProtocolProviderServiceZeroconfImpl parentProvider)
- {
- this.groupName = groupName;
- this.uid = groupName + UID_SUFFIX;
- this.parentProvider = parentProvider;
- }
-
- /**
- * Determines whether the group may contain subgroups or not.
- *
- * @return always true in this implementation.
- */
- public boolean canContainSubgroups()
- {
- return true;
- }
-
- /**
- * Returns the protocol provider that this group belongs to.
- * @return a regerence to the ProtocolProviderService instance that this
- * ContactGroup belongs to.
- */
- public ProtocolProviderService getProtocolProvider()
- {
- return parentProvider;
- }
-
- /**
- * Returns an Iterator over all contacts, member of this
- * <tt>ContactGroup</tt>.
- *
- * @return a java.util.Iterator over all contacts inside this
- * <tt>ContactGroup</tt>
- */
- public Iterator<Contact> contacts()
- {
- return contacts.iterator();
- }
-
- /**
- * Adds the specified contact to this group.
- * @param contactToAdd the ContactZeroconfImpl to add to this group.
- */
- public void addContact(ContactZeroconfImpl contactToAdd)
- {
- this.contacts.add(contactToAdd);
- contactToAdd.setParentGroup(this);
- }
-
- /**
- * Returns the number of <tt>Contact</tt> members of this
- * <tt>ContactGroup</tt>
- *
- * @return an int indicating the number of <tt>Contact</tt>s, members of
- * this <tt>ContactGroup</tt>.
- */
- public int countContacts()
- {
- return contacts.size();
- }
-
- /**
- * Returns the number of subgroups contained by this
- * <tt>ContactGroup</tt>.
- *
- * @return the number of subGroups currently added to this group.
- */
- public int countSubgroups()
- {
- return subGroups.size();
- }
-
- /**
- * Adds the specified contact group to the contained by this group.
- * @param subgroup the ContactGroupZeroconfImpl to add as a
- * subgroup to this group.
- */
- public void addSubgroup(ContactGroupZeroconfImpl subgroup)
- {
- this.subGroups.add(subgroup);
- subgroup.setParentGroup(this);
- }
-
- /**
- * Sets the group that is the new parent of this group
- * @param parent ContactGroupZeroconfImpl
- */
- void setParentGroup(ContactGroupZeroconfImpl parent)
- {
- this.parentGroup = parent;
- }
-
- /**
- * Returns the contact group that currently contains this group or null if
- * this is the root contact group.
- * @return the contact group that currently contains this group or null if
- * this is the root contact group.
- */
- public ContactGroup getParentContactGroup()
- {
- return this.parentGroup;
- }
-
- /**
- * Removes the specified contact group from the this group's subgroups.
- * @param subgroup the ContactGroupZeroconfImpl subgroup to remove.
- */
- public void removeSubGroup(ContactGroupZeroconfImpl subgroup)
- {
- this.subGroups.remove(subgroup);
- subgroup.setParentGroup(null);
- }
-
- /**
- * Returns the group that is parent of the specified zeroconfGroup or null
- * if no parent was found.
- * @param zeroconfGroup the group whose parent we're looking for.
- * @return the ContactGroupZeroconfImpl instance that zeroconfGroup
- * belongs to or null if no parent was found.
- */
- public ContactGroupZeroconfImpl findGroupParent(
- ContactGroupZeroconfImpl zeroconfGroup)
- {
- if ( subGroups.contains(zeroconfGroup) )
- return this;
-
- Iterator<ContactGroup> subGroupsIter = subgroups();
- while (subGroupsIter.hasNext())
- {
- ContactGroupZeroconfImpl subgroup
- = (ContactGroupZeroconfImpl) subGroupsIter.next();
-
- ContactGroupZeroconfImpl parent
- = subgroup.findGroupParent(zeroconfGroup);
-
- if(parent != null)
- return parent;
- }
- return null;
- }
-
- /**
- * Returns the group that is parent of the specified zeroconfContact or
- * null if no parent was found.
- *
- * @param zeroconfContact the contact whose parent we're looking for.
- * @return the ContactGroupZeroconfImpl instance that zeroconfContact
- * belongs to or <tt>null</tt> if no parent was found.
- */
- public ContactGroupZeroconfImpl findContactParent(
- ContactZeroconfImpl zeroconfContact)
- {
- if ( contacts.contains(zeroconfContact) )
- return this;
-
- Iterator<ContactGroup> subGroupsIter = subgroups();
- while (subGroupsIter.hasNext())
- {
- ContactGroupZeroconfImpl subgroup
- = (ContactGroupZeroconfImpl) subGroupsIter.next();
-
- ContactGroupZeroconfImpl parent
- = subgroup.findContactParent(zeroconfContact);
-
- if(parent != null)
- return parent;
- }
- return null;
- }
-
-
-
- /**
- * Returns the <tt>Contact</tt> with the specified address or identifier.
- *
- * @param id the addres or identifier of the <tt>Contact</tt> we are
- * looking for.
- * @return the <tt>Contact</tt> with the specified id or address.
- */
- public Contact getContact(String id)
- {
- Iterator<Contact> contactsIter = contacts();
- while (contactsIter.hasNext())
- {
- ContactZeroconfImpl contact =
- (ContactZeroconfImpl)contactsIter.next();
-
- if (contact.getAddress().equals(id))
- return contact;
-
- }
- return null;
- }
-
- /**
- * Returns the subgroup with the specified index.
- *
- * @param index the index of the <tt>ContactGroup</tt> to retrieve.
- * @return the <tt>ContactGroup</tt> with the specified index.
- */
- public ContactGroup getGroup(int index)
- {
- return subGroups.get(index);
- }
-
- /**
- * Returns the subgroup with the specified name.
- *
- * @param groupName the name of the <tt>ContactGroup</tt> to retrieve.
- * @return the <tt>ContactGroup</tt> with the specified index.
- */
- public ContactGroup getGroup(String groupName)
- {
- Iterator<ContactGroup> groupsIter = subgroups();
- while (groupsIter.hasNext())
- {
- ContactGroupZeroconfImpl contactGroup
- = (ContactGroupZeroconfImpl) groupsIter.next();
- if (contactGroup.getGroupName().equals(groupName))
- return contactGroup;
-
- }
- return null;
-
- }
-
- /**
- * Returns the name of this group.
- *
- * @return a String containing the name of this group.
- */
- public String getGroupName()
- {
- return this.groupName;
- }
-
- /**
- * Sets this group a new name.
- * @param newGrpName a String containing the new name of this group.
- */
- public void setGroupName(String newGrpName)
- {
- this.groupName = newGrpName;
- }
-
- /**
- * Returns an iterator over the sub groups that this
- * <tt>ContactGroup</tt> contains.
- *
- * @return a java.util.Iterator over the <tt>ContactGroup</tt> children
- * of this group (i.e. subgroups).
- */
- public Iterator<ContactGroup> subgroups()
- {
- return subGroups.iterator();
- }
-
- /**
- * Removes the specified contact from this group.
- * @param contact the ContactZeroconfImpl to remove from this group
- */
- public void removeContact(ContactZeroconfImpl contact)
- {
- this.contacts.remove(contact);
- }
-
- /**
- * Returns the contact with the specified id or null if no such contact
- * exists.
- * @param id the id of the contact we're looking for.
- * @return ContactZeroconfImpl
- */
- public ContactZeroconfImpl findContactByID(String id)
- {
- //first go through the contacts that are direct children.
- Iterator<Contact> contactsIter = contacts();
-
- while(contactsIter.hasNext())
- {
- ContactZeroconfImpl mContact =
- (ContactZeroconfImpl)contactsIter.next();
-
- if( mContact.getAddress().equals(id) )
- return mContact;
- }
-
- //if we didn't find it here, let's try in the subougroups
- Iterator<ContactGroup> groupsIter = subgroups();
-
- while( groupsIter.hasNext() )
- {
- ContactGroupZeroconfImpl mGroup =
- (ContactGroupZeroconfImpl)groupsIter.next();
-
- ContactZeroconfImpl mContact = mGroup.findContactByID(id);
-
- if (mContact != null)
- return mContact;
- }
-
- return null;
- }
-
-
- /**
- * Returns a String representation of this group and the contacts it
- * contains (may turn out to be a relatively long string).
- * @return a String representing this group and its child contacts.
- */
- @Override
- public String toString()
- {
-
- StringBuffer buff = new StringBuffer(getGroupName());
- buff.append(".subGroups=" + countSubgroups() + ":\n");
-
- Iterator<ContactGroup> subGroups = subgroups();
- while (subGroups.hasNext())
- {
- ContactGroupZeroconfImpl group =
- (ContactGroupZeroconfImpl)subGroups.next();
- buff.append(group.toString());
- if (subGroups.hasNext())
- buff.append("\n");
- }
-
- buff.append("\nChildContacts="+countContacts()+":[");
-
- Iterator<Contact> contacts = contacts();
- while (contacts.hasNext())
- {
- ContactZeroconfImpl contact = (ContactZeroconfImpl) contacts.next();
- buff.append(contact.toString());
- if(contacts.hasNext())
- buff.append(", ");
- }
- return buff.append("]").toString();
- }
-
- /**
- * Specifies whether or not this contact group is being stored by the server.
- * Non persistent contact groups are common in the case of simple,
- * non-persistent presence operation sets. They could however also be seen
- * in persistent presence operation sets when for example we have received
- * an event from someone not on our contact list and the contact that we
- * associated with that user is placed in a non persistent group. Non
- * persistent contact groups are volatile even when coming from a persistent
- * presence op. set. They would only exist until the application is closed
- * and will not be there next time it is loaded.
- *
- * @param isPersistent true if the contact group is to be persistent and
- * false otherwise.
- */
- public void setPersistent(boolean isPersistent)
- {
- this.isPersistent = isPersistent;
- }
-
- /**
- * Determines whether or not this contact group is being stored by the
- * server. Non persistent contact groups exist for the sole purpose of
- * containing non persistent contacts.
- * @return true if the contact group is persistent and false otherwise.
- */
- public boolean isPersistent()
- {
- return isPersistent;
- }
-
- /**
- * Returns null as no persistent data is required and the contact address is
- * sufficient for restoring the contact.
- * <p>
- * @return null as no such data is needed.
- */
- public String getPersistentData()
- {
- return null;
- }
-
- /**
- * Determines whether or not this contact has been resolved against the
- * server. Unresolved contacts are used when initially loading a contact
- * list that has been stored in a local file until the presence operation
- * set has managed to retrieve all the contact list from the server and has
- * properly mapped contacts to their on-line buddies.
- * @return true if the contact has been resolved (mapped against a buddy)
- * and false otherwise.
- */
- public boolean isResolved()
- {
- return isResolved;
- }
-
- /**
- * Makes the group resolved or unresolved.
- *
- * @param resolved true to make the group resolved; false to
- * make it unresolved
- */
- public void setResolved(boolean resolved)
- {
- this.isResolved = resolved;
- }
-
- /**
- * Returns a <tt>String</tt> that uniquely represnets the group inside
- * the current protocol. The string MUST be persistent (it must not change
- * across connections or runs of the application). In many cases (Jabber,
- * ICQ) the string may match the name of the group as these protocols
- * only allow a single level of contact groups and there is no danger of
- * having the same name twice in the same contact list. Other protocols
- * (no examples come to mind but that doesn't bother me ;) ) may be
- * supporting mutilple levels of grooups so it might be possible for group
- * A and group B to both contain groups named C. In such cases the
- * implementation must find a way to return a unique identifier in this
- * method and this UID should never change for a given group.
- *
- * @return a String representing this group in a unique and persistent
- * way.
- */
- public String getUID()
- {
- return uid;
- }
-
- /**
- * Ugly but tricky conversion method.
- * @param uid the uid we'd like to get a name from
- * @return the name of the group with the specified <tt>uid</tt>.
- */
- static String createNameFromUID(String uid)
- {
- return uid.substring(0, uid.length() - (UID_SUFFIX.length()));
- }
-
- /**
- * Indicates whether some other object is "equal to" this one which in terms
- * of contact groups translates to having the equal names and matching
- * subgroups and child contacts. The resolved status of contactgroups and
- * contacts is deliberately ignored so that groups and/or contacts would
- * be assumed equal even if it differs.
- * <p>
- * @param obj the reference object with which to compare.
- * @return <code>true</code> if this contact group has the equal child
- * contacts and subgroups to those of the <code>obj</code> argument.
- */
- @Override
- public boolean equals(Object obj)
- {
- if(obj == null
- || !(obj instanceof ContactGroupZeroconfImpl))
- return false;
-
- ContactGroupZeroconfImpl zeroconfGroup
- = (ContactGroupZeroconfImpl)obj;
-
- if(!zeroconfGroup.getGroupName().equals(getGroupName()) ||
- !zeroconfGroup.getUID().equals(getUID()) ||
- zeroconfGroup.countContacts() != countContacts() ||
- zeroconfGroup.countSubgroups() != countSubgroups())
- return false;
-
- //traverse child contacts
- Iterator<Contact> theirContacts = zeroconfGroup.contacts();
-
- while(theirContacts.hasNext())
- {
- ContactZeroconfImpl theirContact
- = (ContactZeroconfImpl)theirContacts.next();
-
- ContactZeroconfImpl ourContact
- = (ContactZeroconfImpl)getContact(theirContact.getAddress());
-
- if(ourContact == null
- || !ourContact.equals(theirContact))
- return false;
- }
-
- //traverse subgroups
- Iterator<ContactGroup> theirSubgroups = zeroconfGroup.subgroups();
-
- while(theirSubgroups.hasNext())
- {
- ContactGroupZeroconfImpl theirSubgroup
- = (ContactGroupZeroconfImpl)theirSubgroups.next();
-
- ContactGroupZeroconfImpl ourSubgroup
- = (ContactGroupZeroconfImpl)getGroup(
- theirSubgroup.getGroupName());
-
- if(ourSubgroup == null
- || !ourSubgroup.equals(theirSubgroup))
- return false;
- }
-
- return true;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/ContactZeroconfImpl.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/ContactZeroconfImpl.java
deleted file mode 100644
index c22cf29..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/ContactZeroconfImpl.java
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf;
-
-import java.net.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * A simple, straightforward implementation of a zeroconf Contact. Since
- * the Zeroconf protocol is not a real one, we simply store all contact details
- * in class fields. You should know that when implementing a real protocol,
- * the contact implementation would rather encapsulate contact objects from
- * the protocol stack and group property values should be returned after
- * consulting the encapsulated object.
- *
- * @author Christian Vincenot
- * @author Maxime Catelin
- * @author Jonathan Martin
- */
-public class ContactZeroconfImpl
- extends AbstractContact
-{
- private static final Logger logger
- = Logger.getLogger(ContactZeroconfImpl.class);
-
-
- /**
- * The id of the contact.
- */
- private String contactID = null;
-
- /**
- * The ClientThread attached to this contact if we're already chatting
- * with him.
- */
- private ClientThread thread = null;
-
- /*
- * Type of Client.
- */
- /**
- * Gaim/Pidgin client type
- */
- public static final int GAIM = 1;
- /**
- * iChat client type
- */
- public static final int ICHAT = 2;
- /**
- * XMPP - XEP-0174 client type
- */
- public static final int XMPP = 3;
- /**
- * Another SIP Communicator client
- */
- public static final int SIPCOM = 4;
- private int clientType = XMPP;
-
-
- /**
- * The provider that created us.
- */
- private ProtocolProviderServiceZeroconfImpl parentProvider = null;
-
-
- /*
- * The Bonjour Service who discovered this contact.
- * TODO: This could probably be avoided using only the
- * Protocol Provider.
- */
- private BonjourService bonjourService;
-
- /**
- * The group that belong to.
- */
- private ContactGroupZeroconfImpl parentGroup = null;
-
- /**
- * The presence status of the contact.
- */
- private PresenceStatus presenceStatus = ZeroconfStatusEnum.OFFLINE;
-
- /**
- * Determines whether this contact is persistent,
- * i.e. member of the contact list or whether it is here only temporarily.
- * Chris: should be set to false here
- */
- private boolean isPersistent = false;
-
- /**
- * Determines whether the contact has been resolved (i.e. we have a
- * confirmation that it is still on the server contact list).
- */
- private boolean isResolved = true;
-
- /**
- * IP Address
- */
- private InetAddress ipAddress;
-
- /**
- * Port on which Bonjour is listening.
- */
- private int port;
-
- /**
- * Name announced by Bonjour.
- */
- private String name;
-
- /**
- * Contact personal message
- */
- private String message;
-
-
- /**
- * Creates an instance of a meta contact with the specified string used
- * as a name and identifier.
- * @param bonjourId ID of the contact
- * @param bonjourService BonjourService responsible for handling chat with
- * this contact
- * @param name Display name of this contact
- * @param ipAddress IP address of this contact
- * @param port Port declared by this contact for direct point-to-point chat
- * @param parentProvider the provider that created us.
- */
- public ContactZeroconfImpl(
- String bonjourId,
- ProtocolProviderServiceZeroconfImpl parentProvider,
- BonjourService bonjourService,
- String name,
- InetAddress ipAddress,
- int port)
- {
- this.contactID = bonjourId;
- this.parentProvider = parentProvider;
- this.bonjourService = bonjourService;
- this.name = name;
- this.ipAddress = ipAddress;
- this.port = port;
- bonjourService.addContact(this);
- }
-
- /**
- * This method is only called when the contact is added to a new
- * <tt>ContactGroupZeroconfImpl</tt> by the
- * <tt>ContactGroupZeroconfImpl</tt> itself.
- *
- * @param newParentGroup the <tt>ContactGroupZeroconfImpl</tt> that is now
- * parent of this <tt>ContactZeroconfImpl</tt>
- */
- void setParentGroup(ContactGroupZeroconfImpl newParentGroup)
- {
- this.parentGroup = newParentGroup;
- }
-
- /**
- * Return the BonjourService
- * @return BonjourService
- */
- public BonjourService getBonjourService()
- {
- return bonjourService;
- }
-
- /**
- * Return the ClientThread responsible for handling with this contact
- * @return ClientThread corresponding to the chat with this contact or null
- * if no chat was started
- */
- protected ClientThread getClientThread()
- {
- return thread;
- }
-
- /**
- * Set the ClientThread responsible for handling with this contact
- * @param thread ClientThread corresponding to the chat with this contact
- * or null if the chat is over
- */
- protected void setClientThread(ClientThread thread)
- {
- this.thread = thread;
- }
-
- /**
- * Return the type of client
- * @return Type of client used by this contact
- */
- public int getClientType()
- {
- return clientType;
- }
-
- /**
- * Sets the type of client
- * @param clientType Type of client used by this contact
- */
- public void setClientType(int clientType)
- {
- this.clientType = clientType;
- }
-
- /**
- * Returns a String that can be used for identifying the contact.
- *
- * @return a String id representing and uniquely identifying the contact.
- */
- public String getAddress()
- {
- return contactID;
- }
-
- /**
- * Returns a String that could be used by any user interacting modules
- * for referring to this contact.
- *
- * @return a String that can be used for referring to this contact when
- * interacting with the user.
- */
- public String getDisplayName()
- {
- return name;
- }
-
- /**
- * Returns the IP address declared by this Contact
- * @return IP address declared by this Contact
- */
- public InetAddress getIpAddress()
- {
- return ipAddress;
- }
-
- /**
- * Returns the TCP port declared by this Contact for direct chat
- * @return the TCP port declared by this Contact for direct chat
- */
- public int getPort()
- {
- return port;
- }
-
-
- /**
- * Returns the status/private message displayed by this contact
- * @return the status/private message displayed by this contact
- */
- public String getMessage()
- {
- return message;
- }
-
- /**
- * Sets the status/private message displayed by this contact
- * @param message the status/private message displayed by this contact
- */
- public void setMessage(String message)
- {
- this.message = message;
- }
-
-
- /**
- * Returns a byte array containing an image (most often a photo or an
- * avatar) that the contact uses as a representation.
- *
- * @return byte[] an image representing the contact.
- */
- public byte[] getImage()
- {
- return null;
- }
-
- /**
- * Returns the status of the contact.
- *
- * @return always ZeroconfStatusEnum.
- */
- public PresenceStatus getPresenceStatus()
- {
- return this.presenceStatus;
- }
-
- /**
- * Sets <tt>zeroconfPresenceStatus</tt> as the PresenceStatus that this
- * contact is currently in.
- * @param zeroconfPresenceStatus the <tt>ZeroconfPresenceStatus</tt>
- * currently valid for this contact.
- */
- public void setPresenceStatus(PresenceStatus zeroconfPresenceStatus)
- {
- this.presenceStatus = zeroconfPresenceStatus;
-
- if (zeroconfPresenceStatus == ZeroconfStatusEnum.OFFLINE) {
- try
- {
- bonjourService.opSetPersPresence.unsubscribe(this);
- }
- catch (Exception ex)
- {
- logger.error(ex);
- }
- }
- }
-
- /**
- * Returns a reference to the protocol provider that created the contact.
- *
- * @return a refererence to an instance of the ProtocolProviderService
- */
- public ProtocolProviderService getProtocolProvider()
- {
- return parentProvider;
- }
-
- /**
- * Determines whether or not this contact represents our own identity.
- *
- * @return true in case this is a contact that represents ourselves and
- * false otherwise.
- */
- public boolean isLocal()
- {
- return false;
- }
-
- /**
- * Returns the group that contains this contact.
- * @return a reference to the <tt>ContactGroupZeroconfImpl</tt> that
- * contains this contact.
- */
- public ContactGroup getParentContactGroup()
- {
- return this.parentGroup;
- }
-
- /**
- * Returns a string representation of this contact, containing most of its
- * representative details.
- *
- * @return a string representation of this contact.
- */
- @Override
- public String toString()
- {
- StringBuffer buff
- = new StringBuffer("ContactZeroconfImpl[ DisplayName=")
- .append(getDisplayName()).append("]");
-
- return buff.toString();
- }
-
- /**
- * Determines whether or not this contact is being stored by the server.
- * Non persistent contacts are common in the case of simple, non-persistent
- * presence operation sets. They could however also be seen in persistent
- * presence operation sets when for example we have received an event
- * from someone not on our contact list. Non persistent contacts are
- * volatile even when coming from a persistent presence op. set. They would
- * only exist until the application is closed and will not be there next
- * time it is loaded.
- *
- * @return true if the contact is persistent and false otherwise.
- */
- public boolean isPersistent()
- {
- return isPersistent;
- }
-
- /**
- * Specifies whether or not this contact is being stored by the server.
- * Non persistent contacts are common in the case of simple, non-persistent
- * presence operation sets. They could however also be seen in persistent
- * presence operation sets when for example we have received an event
- * from someone not on our contact list. Non persistent contacts are
- * volatile even when coming from a persistent presence op. set. They would
- * only exist until the application is closed and will not be there next
- * time it is loaded.
- *
- * @param isPersistent true if the contact is persistent and false
- * otherwise.
- */
- public void setPersistent(boolean isPersistent)
- {
- this.isPersistent = isPersistent;
- }
-
-
- /**
- * Returns null as no persistent data is required and the contact address is
- * sufficient for restoring the contact.
- * <p>
- * @return null as no such data is needed.
- */
- public String getPersistentData()
- {
- return null;
- }
-
- /**
- * Determines whether or not this contact has been resolved against the
- * server. Unresolved contacts are used when initially loading a contact
- * list that has been stored in a local file until the presence operation
- * set has managed to retrieve all the contact list from the server and has
- * properly mapped contacts to their on-line buddies.
- *
- * @return true if the contact has been resolved (mapped against a buddy)
- * and false otherwise.
- */
- public boolean isResolved()
- {
- return isResolved;
- }
-
- /**
- * Makes the contact resolved or unresolved.
- *
- * @param resolved true to make the contact resolved; false to
- * make it unresolved
- */
- public void setResolved(boolean resolved)
- {
- this.isResolved = resolved;
- }
-
- /**
- * Returns the persistent presence operation set that this contact belongs
- * to.
- *
- * @return the <tt>OperationSetPersistentPresenceZeroconfImpl</tt> that
- * this contact belongs to.
- */
- public OperationSetPersistentPresenceZeroconfImpl
- getParentPresenceOperationSet()
- {
- return (OperationSetPersistentPresenceZeroconfImpl)parentProvider
- .getOperationSet(OperationSetPersistentPresence.class);
- }
-
- /**
- * Return the current status message of this contact.
- *
- * @return null as the protocol has currently no support of status messages
- */
- public String getStatusMessage()
- {
- return null;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/MessageZeroconfImpl.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/MessageZeroconfImpl.java
deleted file mode 100644
index 3621edc..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/MessageZeroconfImpl.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * Very simple message implementation for the Zeroconf protocol.
- *
- * @author Christian Vincenot
- * @author Maxime Catelin
- * @author Jonathan Martin
- * @author Lubomir Marinov
- */
-public class MessageZeroconfImpl
- extends AbstractMessage
-{
-
- /**
- * Message Type.
- */
- private int type;
-
- /**
- * Message type indicating that a stream is being created
- */
- public static final int STREAM_OPEN = 0x1;
-
- /**
- * Normal chat message
- */
- public static final int MESSAGE = 0x2;
-
- /**
- * Typing notification
- */
- public static final int TYPING = 0x3;
-
- /**
- * Message indicating that the stream is being closed
- */
- public static final int STREAM_CLOSE = 0x4;
-
- /**
- * Message indicating that the previsous message was delivered successfully
- */
- public static final int DELIVERED = 0x5;
-
- /**
- * Undefined message
- */
- public static final int UNDEF = 0x6;
-
- /*
- * The Baloon Icon color. (we probably won't ever use it)
- */
- private int baloonColor = 0x7BB5EE;
-
- /*
- * The Text Color.
- */
- private int textColor = 0x000000;
-
- /*
- * The font of the message.
- */
- private String textFont = "Helvetica";
-
- /*
- * The size of the caracters composing the message.
- */
- private int textSize = 12;
-
- /*
- * The source contact id announced in the message. TODO: Could be set &
- * checked to identify more precisely the contact in case several users
- * would be sharing the same IP.
- */
- private String contactID;
-
- /**
- * Creates a message instance according to the specified parameters.
- *
- * @param content the message body
- * @param contentEncoding message encoding or null for UTF8
- * @param contentType of the message
- * @param type Type of message
- */
- public MessageZeroconfImpl(String content, String contentEncoding,
- String contentType, int type)
- {
- super(content, contentType, contentEncoding, null);
-
- this.type = type;
- }
-
- /**
- * Creates a message instance according to the specified parameters.
- *
- * @param type Type of message
- * @param content the message body
- * @param contentEncoding message encoding or null for UTF8
- */
- public MessageZeroconfImpl(String content, String contentEncoding, int type)
- {
- this(content, contentEncoding,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE, type);
- }
-
- /**
- * Returns the type of message. Always text/plain for Zeroconf, so null.
- *
- * @return null
- */
- public int getType()
- {
- return type;
- }
-
- /**
- * Gets the baloon color declared in messages sent by iChat-like clients
- *
- * @return baloon color
- */
- public int getBaloonColor()
- {
- return baloonColor;
- }
-
- /**
- * Sets the baloon color declared in messages sent by iChat-like clients
- *
- * @param baloonColor baloon color
- */
- public void setBaloonColor(int baloonColor)
- {
- this.baloonColor = baloonColor;
- }
-
- /**
- * Returns the text color
- *
- * @return Text color
- */
- public int getTextColor()
- {
- return textColor;
- }
-
- /**
- * Sets the text color
- *
- * @param textColor Text color
- */
- public void setTextColor(int textColor)
- {
- this.textColor = textColor;
- }
-
- /**
- * Returns the text font
- *
- * @return Text font
- */
- public String getTextFont()
- {
- return textFont;
- }
-
- /**
- * Sets the text color
- *
- * @param textFont Text font
- */
- public void setTextFont(String textFont)
- {
- this.textFont = textFont;
- }
-
- /**
- * Returns the text size
- *
- * @return Text size
- */
- public int getTextSize()
- {
- return textSize;
- }
-
- /**
- * Sets the text size
- *
- * @param textSize Text size
- */
- public void setTextSize(int textSize)
- {
- this.textSize = textSize;
- }
-
- /**
- * Returns the contact's ID
- *
- * @return String representing the contact's ID
- */
- public String getContactID()
- {
- return contactID;
- }
-
- /**
- * Sets the contact's ID
- *
- * @param contactID String representing the contact's ID
- */
- public void setContactID(String contactID)
- {
- this.contactID = contactID;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/OperationSetBasicInstantMessagingZeroconfImpl.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/OperationSetBasicInstantMessagingZeroconfImpl.java
deleted file mode 100644
index d49118b..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/OperationSetBasicInstantMessagingZeroconfImpl.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf;
-
-import java.io.*;
-import java.net.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Instant messaging functionalities for the Zeroconf protocol.
- *
- * @author Christian Vincenot
- *
- */
-public class OperationSetBasicInstantMessagingZeroconfImpl
- extends AbstractOperationSetBasicInstantMessaging
-{
- private static final Logger logger
- = Logger.getLogger(OperationSetBasicInstantMessagingZeroconfImpl.class);
-
- /**
- * The currently valid persistent presence operation set..
- */
- private final OperationSetPersistentPresenceZeroconfImpl opSetPersPresence;
-
- /**
- * The protocol provider that created us.
- */
- private final ProtocolProviderServiceZeroconfImpl parentProvider;
-
- /**
- * Creates an instance of this operation set keeping a reference to the
- * parent protocol provider and presence operation set.
- *
- * @param provider The provider instance that creates us.
- * @param opSetPersPresence the currently valid
- * <tt>OperationSetPersistentPresenceZeroconfImpl</tt> instance.
- */
- public OperationSetBasicInstantMessagingZeroconfImpl(
- ProtocolProviderServiceZeroconfImpl provider,
- OperationSetPersistentPresenceZeroconfImpl opSetPersPresence)
- {
- this.opSetPersPresence = opSetPersPresence;
- this.parentProvider = provider;
- }
-
- @Override
- public Message createMessage(String content, String contentType,
- String encoding, String subject)
- {
- return new MessageZeroconfImpl(content, encoding, contentType,
- MessageZeroconfImpl.MESSAGE);
- }
-
- /**
- * Sends the <tt>message</tt> to the destination indicated by the
- * <tt>to</tt> contact.
- *
- * @param to the <tt>Contact</tt> to send <tt>message</tt> to
- * @param message the <tt>Message</tt> to send.
- * @throws IllegalStateException if the underlying Zeroconf stack is not
- * registered and initialized.
- * @throws IllegalArgumentException if <tt>to</tt> is not an instance
- * belonging to the underlying implementation.
- */
- public void sendInstantMessage(Contact to, Message message) throws
- IllegalStateException, IllegalArgumentException
- {
- if( !(to instanceof ContactZeroconfImpl) )
- throw new IllegalArgumentException(
- "The specified contact is not a Zeroconf contact."
- + to);
-
- MessageZeroconfImpl msg =
- (MessageZeroconfImpl)createMessage(message.getContent());
-
- deliverMessage(msg, (ContactZeroconfImpl)to);
- }
-
- /**
- * In case the to the <tt>to</tt> Contact corresponds to another zeroconf
- * protocol provider registered with SIP Communicator, we deliver
- * the message to them, in case the <tt>to</tt> Contact represents us, we
- * fire a <tt>MessageReceivedEvent</tt>, and if <tt>to</tt> is simply
- * a contact in our contact list, then we simply echo the message.
- *
- * @param message the <tt>Message</tt> the message to deliver.
- * @param to the <tt>Contact</tt> that we should deliver the message to.
- */
- private void deliverMessage(Message message, ContactZeroconfImpl to)
- {
- ClientThread thread = to.getClientThread();
- try
- {
- if (thread == null)
- {
- Socket sock;
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF: Creating a chat connexion to "
- +to.getIpAddress()+":"+to.getPort());
- sock = new Socket(to.getIpAddress(), to.getPort());
- thread = new ClientThread(sock, to.getBonjourService());
- thread.setStreamOpen();
- thread.setContact(to);
- to.setClientThread(thread);
- thread.sendHello();
- if (to.getClientType() == ContactZeroconfImpl.GAIM)
- {
- try
- {
- Thread.sleep(300);
- }
- catch (InterruptedException ex)
- {
- logger.error(ex);
- }
- }
- }
-
- //System.out.println("ZEROCONF: Message content => "+
- //message.getContent());
- thread.sendMessage((MessageZeroconfImpl) message);
-
- fireMessageDelivered(message, to);
- }
- catch (IOException ex)
- {
- logger.error(ex);
- }
- }
-
- /**
- * Notifies all registered message listeners that a message has been
- * received.
- *
- * @param message the <tt>Message</tt> that has been received.
- * @param from the <tt>Contact</tt> that <tt>message</tt> was received from.
- */
- @Override
- public void fireMessageReceived(Message message, Contact from)
- {
- super.fireMessageReceived(message, from);
- }
-
- /**
- * Determines whether the protocol provider (or the protocol itself) support
- * sending and receiving offline messages. Most often this method would
- * return true for protocols that support offline messages and false for
- * those that don't. It is however possible for a protocol to support these
- * messages and yet have a particular account that does not (i.e. feature
- * not enabled on the protocol server). In cases like this it is possible
- * for this method to return true even when offline messaging is not
- * supported, and then have the sendMessage method throw an
- * OperationFailedException with code - OFFLINE_MESSAGES_NOT_SUPPORTED.
- *
- * @return <tt>true</tt> if the protocol supports offline messages and
- * <tt>false</tt> otherwise.
- */
- public boolean isOfflineMessagingSupported()
- {
- return true;
- }
-
- /**
- * Determines whether the protocol supports the supplied content type
- *
- * @param contentType the type we want to check
- * @return <tt>true</tt> if the protocol supports it and
- * <tt>false</tt> otherwise.
- */
- public boolean isContentTypeSupported(String contentType)
- {
- return contentType.equals(DEFAULT_MIME_TYPE);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/OperationSetPersistentPresenceZeroconfImpl.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/OperationSetPersistentPresenceZeroconfImpl.java
deleted file mode 100644
index 412512e..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/OperationSetPersistentPresenceZeroconfImpl.java
+++ /dev/null
@@ -1,852 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf;
-
-import java.net.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * A Zeroconf implementation of a persistent presence operation set. In order
- * to simulate server persistence, this operation set would simply accept all
- * unresolved contacts and resolve them immediately. A real world protocol
- * implementation would save it on a server using methods provided by the
- * protocol stack.
- *
- * @author Christian Vincenot
- * @author Maxime Catelin
- * @author Jonathan Martin
- */
-public class OperationSetPersistentPresenceZeroconfImpl
- extends AbstractOperationSetPersistentPresence<ProtocolProviderServiceZeroconfImpl>
-{
- private static final Logger logger =
- Logger.getLogger(OperationSetPersistentPresenceZeroconfImpl.class);
-
- /**
- * The root of the zeroconf contact list.
- */
- private ContactGroupZeroconfImpl contactListRoot = null;
-
- /**
- * The currently active status message.
- */
- private String statusMessage = "The truth is out there...";
-
- /**
- * Our default presence status.
- */
- private PresenceStatus presenceStatus = ZeroconfStatusEnum.OFFLINE;
-
- /**
- * The <tt>AuthorizationHandler</tt> instance that we'd have to transmit
- * authorization requests to for approval.
- */
- private AuthorizationHandler authorizationHandler = null;
-
- /**
- * Creates an instance of this operation set keeping a reference to the
- * specified parent <tt>provider</tt>.
- * @param provider the ProtocolProviderServiceZeroconfImpl instance that
- * created us.
- */
- public OperationSetPersistentPresenceZeroconfImpl(
- ProtocolProviderServiceZeroconfImpl provider)
- {
- super(provider);
-
- contactListRoot = new ContactGroupZeroconfImpl("RootGroup", provider);
-
- //add our unregistration listener
- parentProvider.addRegistrationStateChangeListener(
- new UnregistrationListener());
- }
-
- /**
- * Creates a group with the specified name and parent in the server
- * stored contact list.
- *
- * @param parent the group where the new group should be created
- * @param groupName the name of the new group to create.
- */
- public void createServerStoredContactGroup(ContactGroup parent,
- String groupName)
- {
- ContactGroupZeroconfImpl newGroup
- = new ContactGroupZeroconfImpl(groupName, parentProvider);
-
- ((ContactGroupZeroconfImpl)parent).addSubgroup(newGroup);
-
- this.fireServerStoredGroupEvent(
- newGroup, ServerStoredGroupEvent.GROUP_CREATED_EVENT);
- }
-
- /**
- * A Zeroconf Provider method to use for fast filling of a contact list.
- *
- * @param contactGroup the group to add
- */
- public void addZeroconfGroup(ContactGroupZeroconfImpl contactGroup)
- {
- contactListRoot.addSubgroup(contactGroup);
- }
-
- /**
- * A Zeroconf Provider method to use for fast filling of a contact list.
- * This method would add both the group and fire an event.
- *
- * @param parent the group where <tt>contactGroup</tt> should be added.
- * @param contactGroup the group to add
- */
- public void addZeroconfGroupAndFireEvent(
- ContactGroupZeroconfImpl parent
- , ContactGroupZeroconfImpl contactGroup)
- {
- parent.addSubgroup(contactGroup);
-
- this.fireServerStoredGroupEvent(
- contactGroup, ServerStoredGroupEvent.GROUP_CREATED_EVENT);
- }
-
-
- /**
- * Returns a reference to the contact with the specified ID in case we
- * have a subscription for it and null otherwise/
- *
- * @param contactID a String identifier of the contact which we're
- * seeking a reference of.
- * @return a reference to the Contact with the specified
- * <tt>contactID</tt> or null if we don't have a subscription for the
- * that identifier.
- */
- public Contact findContactByID(String contactID)
- {
- return contactListRoot.findContactByID(contactID);
- }
-
- /**
- * Sets the specified status message.
- * @param statusMessage a String containing the new status message.
- */
- public void setStatusMessage(String statusMessage)
- {
- this.statusMessage = statusMessage;
- }
-
- /**
- * Returns the status message that was last set through
- * setCurrentStatusMessage.
- *
- * @return the last status message that we have requested and the aim
- * server has confirmed.
- */
- public String getCurrentStatusMessage()
- {
- return statusMessage;
- }
-
- /**
- * Returns a PresenceStatus instance representing the state this provider
- * is currently in.
- *
- * @return the PresenceStatus last published by this provider.
- */
- public PresenceStatus getPresenceStatus()
- {
- return presenceStatus;
- }
-
- /**
- * Returns the root group of the server stored contact list.
- *
- * @return the root ContactGroup for the ContactList stored by this
- * service.
- */
- public ContactGroup getServerStoredContactListRoot()
- {
- return contactListRoot;
- }
-
- /**
- * Returns the set of PresenceStatus objects that a user of this service
- * may request the provider to enter.
- *
- * @return Iterator a PresenceStatus array containing "enterable" status
- * instances.
- */
- public Iterator<PresenceStatus> getSupportedStatusSet()
- {
- return ZeroconfStatusEnum.supportedStatusSet();
- }
-
- /**
- * Removes the specified contact from its current parent and places it
- * under <tt>newParent</tt>.
- *
- * @param contactToMove the <tt>Contact</tt> to move
- * @param newParent the <tt>ContactGroup</tt> where <tt>Contact</tt>
- * would be placed.
- */
- public void moveContactToGroup(Contact contactToMove,
- ContactGroup newParent)
- {
- ContactZeroconfImpl zeroconfContact
- = (ContactZeroconfImpl)contactToMove;
-
- ContactGroupZeroconfImpl parentZeroconfGroup
- = findContactParent(zeroconfContact);
-
- parentZeroconfGroup.removeContact(zeroconfContact);
-
- //if this is a volatile contact then we haven't really subscribed to
- //them so we'd need to do so here
- if(!zeroconfContact.isPersistent())
- {
- //first tell everyone that the volatile contact was removed
- fireSubscriptionEvent(zeroconfContact
- , parentZeroconfGroup
- , SubscriptionEvent.SUBSCRIPTION_REMOVED);
-
- try
- {
- //now subscribe
- this.subscribe(newParent, contactToMove.getAddress());
-
- //now tell everyone that we've added the contact
- fireSubscriptionEvent(zeroconfContact
- , newParent
- , SubscriptionEvent.SUBSCRIPTION_CREATED);
- }
- catch (Exception ex)
- {
- logger.error("Failed to move contact "
- + zeroconfContact.getAddress()
- , ex);
- }
- }
- else
- {
- ( (ContactGroupZeroconfImpl) newParent)
- .addContact(zeroconfContact);
-
- fireSubscriptionMovedEvent(contactToMove
- , parentZeroconfGroup
- , newParent);
- }
- }
-
- /**
- * Requests the provider to enter into a status corresponding to the
- * specified paramters.
- *
- * @param status the PresenceStatus as returned by
- * getRequestableStatusSet
- * @param statusMessage the message that should be set as the reason to
- * enter that status
- * @throws IllegalArgumentException if the status requested is not a
- * valid PresenceStatus supported by this provider.
- * @throws IllegalStateException if the provider is not currently
- * registered.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * publishing the status fails due to a network error.
- */
- public void publishPresenceStatus(PresenceStatus status,
- String statusMessage)
- throws IllegalArgumentException,
- IllegalStateException,
- OperationFailedException
- {
- PresenceStatus oldPresenceStatus = this.presenceStatus;
- this.presenceStatus = status;
- this.statusMessage = statusMessage;
-
- //ICI: changer le statut du plugin Zeroconf!!
- parentProvider.getBonjourService().changeStatus(status);
-
- this.fireProviderStatusChangeEvent(oldPresenceStatus);
-
- }
-
- /**
- * Get the PresenceStatus for a particular contact.
- *
- * @param contactIdentifier the identifier of the contact whose status
- * we're interested in.
- * @return PresenceStatus the <tt>PresenceStatus</tt> of the specified
- * <tt>contact</tt>
- * @throws IllegalArgumentException if <tt>contact</tt> is not a contact
- * known to the underlying protocol provider
- * @throws IllegalStateException if the underlying protocol provider is
- * not registered/signed on a public service.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * retrieving the status fails due to errors experienced during
- * network communication
- */
- public PresenceStatus queryContactStatus(String contactIdentifier)
- throws IllegalArgumentException,
- IllegalStateException,
- OperationFailedException
- {
- return findContactByID(contactIdentifier).getPresenceStatus();
- }
-
- /**
- * Sets the presence status of <tt>contact</tt> to <tt>newStatus</tt>.
- *
- * @param contact the <tt>ContactZeroconfImpl</tt> whose status we'd like
- * to set.
- * @param newStatus the new status we'd like to set to <tt>contact</tt>.
- */
- public void changePresenceStatusForContact(ContactZeroconfImpl contact,
- PresenceStatus newStatus)
- {
- PresenceStatus oldStatus = contact.getPresenceStatus();
- contact.setPresenceStatus(newStatus);
-
- fireContactPresenceStatusChangeEvent(
- contact, findContactParent(contact), oldStatus);
- }
-
- /**
- * Sets the presence status of all <tt>contact</tt>s in our contact list
- * (except those that correspond to another provider registered with SC)
- * to <tt>newStatus</tt>.
- *
- * @param newStatus the new status we'd like to set to <tt>contact</tt>.
- * @param parent the group in which we'd have to update the status of all
- * direct and indirect child contacts.
- */
- protected void changePresenceStatusForAllContacts(ContactGroup parent,
- PresenceStatus newStatus)
- {
- //first set the status for contacts in this group
- Iterator<Contact> childContacts = parent.contacts();
-
- while(childContacts.hasNext())
- {
- ContactZeroconfImpl contact
- = (ContactZeroconfImpl)childContacts.next();
-
- if(findProviderForZeroconfUserID(contact.getAddress()) != null)
- {
- //this is a contact corresponding to another SIP Communicator
- //provider so we won't change it's status here.
- continue;
- }
- PresenceStatus oldStatus = contact.getPresenceStatus();
- contact.setPresenceStatus(newStatus);
-
- fireContactPresenceStatusChangeEvent(
- contact, parent, oldStatus);
- }
-
- //now call this method recursively for all subgroups
- Iterator<ContactGroup> subgroups = parent.subgroups();
-
- while(subgroups.hasNext())
- {
- ContactGroup subgroup = subgroups.next();
- changePresenceStatusForAllContacts(subgroup, newStatus);
- }
- }
-
- /**
- * Returns the group that is parent of the specified zeroconfGroup or null
- * if no parent was found.
- * @param zeroconfGroup the group whose parent we're looking for.
- * @return the ContactGroupZeroconfImpl instance that zeroconfGroup
- * belongs to or null if no parent was found.
- */
- public ContactGroupZeroconfImpl findGroupParent(
- ContactGroupZeroconfImpl zeroconfGroup)
- {
- return contactListRoot.findGroupParent(zeroconfGroup);
- }
-
- /**
- * Returns the group that is parent of the specified zeroconfContact or
- * null if no parent was found.
- * @param zeroconfContact the contact whose parent we're looking for.
- * @return the ContactGroupZeroconfImpl instance that zeroconfContact
- * belongs to or null if no parent was found.
- */
- public ContactGroupZeroconfImpl findContactParent(
- ContactZeroconfImpl zeroconfContact)
- {
- return (ContactGroupZeroconfImpl)zeroconfContact
- .getParentContactGroup();
- }
-
-
- /**
- * Removes the specified group from the server stored contact list.
- *
- * @param group the group to remove.
- *
- * @throws IllegalArgumentException if <tt>group</tt> was not found in this
- * protocol's contact list.
- */
- public void removeServerStoredContactGroup(ContactGroup group)
- throws IllegalArgumentException
- {
- ContactGroupZeroconfImpl zeroconfGroup
- = (ContactGroupZeroconfImpl)group;
-
- ContactGroupZeroconfImpl parent = findGroupParent(zeroconfGroup);
-
- if(parent == null){
- throw new IllegalArgumentException(
- "group " + group
- + " does not seem to belong to this protocol's contact list.");
- }
-
- parent.removeSubGroup(zeroconfGroup);
-
- this.fireServerStoredGroupEvent(
- zeroconfGroup, ServerStoredGroupEvent.GROUP_REMOVED_EVENT);
- }
-
- /**
- * Renames the specified group from the server stored contact list.
- *
- * @param group the group to rename.
- * @param newName the new name of the group.
- */
- public void renameServerStoredContactGroup(ContactGroup group,
- String newName)
- {
- ((ContactGroupZeroconfImpl)group).setGroupName(newName);
-
- this.fireServerStoredGroupEvent(
- group,
- ServerStoredGroupEvent.GROUP_RENAMED_EVENT);
- }
-
- /**
- * Handler for incoming authorization requests.
- *
- * @param handler an instance of an AuthorizationHandler for
- * authorization requests coming from other users requesting
- * permission add us to their contact list.
- */
- public void setAuthorizationHandler(AuthorizationHandler handler)
- {
- this.authorizationHandler = handler;
- }
-
- /**
- * Persistently adds a subscription for the presence status of the
- * contact corresponding to the specified contactIdentifier and indicates
- * that it should be added to the specified group of the server stored
- * contact list.
- *
- * @param parent the parent group of the server stored contact list
- * where the contact should be added. <p>
- * @param contactIdentifier the contact whose status updates we are
- * subscribing for.
- * @throws IllegalArgumentException if <tt>contact</tt> or
- * <tt>parent</tt> are not a contact known to the underlying protocol
- * provider.
- * @throws IllegalStateException if the underlying protocol provider is
- * not registered/signed on a public service.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * subscribing fails due to errors experienced during network
- * communication
- */
- public void subscribe(ContactGroup parent, String contactIdentifier)
- throws IllegalArgumentException,
- IllegalStateException,
- OperationFailedException
- {
- /* ContactZeroconfImpl contact = new ContactZeroconfImpl(
- contactIdentifier,
- parentProvider,
- null, null, null, 0);
-
- ((ContactGroupZeroconfImpl)parent).addContact(contact);
-
- fireSubscriptionEvent(contact,
- parent,
- SubscriptionEvent.SUBSCRIPTION_CREATED);
- //if the newly added contact corresponds to another provider - set their
- //status accordingly
- ProtocolProviderServiceZeroconfImpl gibProvider
- = findProviderForZeroconfUserID(contactIdentifier);
- if(gibProvider != null)
- {
- OperationSetPersistentPresence opSetPresence
- = (OperationSetPersistentPresence)gibProvider.getOperationSet(
- OperationSetPersistentPresence.class);
-
- changePresenceStatusForContact(
- contact
- , (ZeroconfStatusEnum)opSetPresence.getPresenceStatus());
- }
- else
- {
- //otherwise - since we are not a real protocol, we set the contact
- //presence status ourselves
- changePresenceStatusForContact(contact, getPresenceStatus());
- }
-
- //notify presence listeners for the status change.
- fireContactPresenceStatusChangeEvent(contact
- , parent
- , ZeroconfStatusEnum.OFFLINE);
- */}
-
-
-
- /**
- * Adds a subscription for the presence status of the contact
- * corresponding to the specified contactIdentifier.
- *
- * @param contactIdentifier the identifier of the contact whose status
- * updates we are subscribing for. <p>
- * @throws IllegalArgumentException if <tt>contact</tt> is not a contact
- * known to the underlying protocol provider
- * @throws IllegalStateException if the underlying protocol provider is
- * not registered/signed on a public service.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * subscribing fails due to errors experienced during network
- * communication
- */
- public void subscribe(String contactIdentifier)
- throws IllegalArgumentException,
- IllegalStateException,
- OperationFailedException
- {
- subscribe(contactListRoot, contactIdentifier);
- }
-
- /**
- * Removes a subscription for the presence status of the specified
- * contact.
- *
- * @param contact the contact whose status updates we are unsubscribing
- * from.
- * @throws IllegalArgumentException if <tt>contact</tt> is not a contact
- * known to the underlying protocol provider
- * @throws IllegalStateException if the underlying protocol provider is
- * not registered/signed on a public service.
- * @throws OperationFailedException with code NETWORK_FAILURE if
- * unsubscribing fails due to errors experienced during network
- * communication
- */
- public void unsubscribe(Contact contact)
- throws IllegalArgumentException,
- IllegalStateException,
- OperationFailedException
- {
- String name = contact.getAddress();
-
- ContactGroupZeroconfImpl parentGroup
- = (ContactGroupZeroconfImpl)((ContactZeroconfImpl)contact)
- .getParentContactGroup();
-
- //parentGroup.removeContact((ContactZeroconfImpl)contact);
-
- BonjourService service =
- ((ProtocolProviderServiceZeroconfImpl)contact.getProtocolProvider())
- .getBonjourService();
- //TODO: better check with IP
- service.removeContact(name,null);
-
- fireSubscriptionEvent(contact,
- ((ContactZeroconfImpl)contact).getParentContactGroup()
- , SubscriptionEvent.SUBSCRIPTION_REMOVED);
- }
-
- /**
- * Creates and returns a unresolved contact from the specified
- * <tt>address</tt> and <tt>persistentData</tt>. The method will not try
- * to establish a network connection and resolve the newly created Contact
- * against the server. The protocol provider may will later try and resolve
- * the contact. When this happens the corresponding event would notify
- * interested subscription listeners.
- *
- * @param address an identifier of the contact that we'll be creating.
- * @param persistentData a String returned Contact's getPersistentData()
- * method during a previous run and that has been persistently stored
- * locally.
- * @return the unresolved <tt>Contact</tt> created from the specified
- * <tt>address</tt> and <tt>persistentData</tt>
- */
- public Contact createUnresolvedContact(String address,
- String persistentData)
- {
- return createUnresolvedContact(address
- , persistentData
- , getServerStoredContactListRoot());
- }
-
- /**
- * Creates and returns a unresolved contact from the specified
- * <tt>address</tt> and <tt>persistentData</tt>. The method will not try
- * to establish a network connection and resolve the newly created Contact
- * against the server. The protocol provider may will later try and resolve
- * the contact. When this happens the corresponding event would notify
- * interested subscription listeners.
- *
- * @param address an identifier of the contact that we'll be creating.
- * @param persistentData a String returned Contact's getPersistentData()
- * method during a previous run and that has been persistently stored
- * locally.
- * @param parent the group where the unresolved contact is
- * supposed to belong to.
- *
- * @return the unresolved <tt>Contact</tt> created from the specified
- * <tt>address</tt> and <tt>persistentData</tt>
- */
- public Contact createUnresolvedContact(String address,
- String persistentData,
- ContactGroup parent)
- {
- return null;
- }
-
- /**
- * Looks for a zeroconf protocol provider registered for a user id matching
- * <tt>zeroconfUserID</tt>.
- *
- * @param zeroconfUserID the ID of the Zeroconf user whose corresponding
- * protocol provider we'd like to find.
- * @return ProtocolProviderServiceZeroconfImpl a zeroconf protocol
- * provider registered for a user with id <tt>zeroconfUserID</tt> or null
- * if there is no such protocol provider.
- */
- public ProtocolProviderServiceZeroconfImpl
- findProviderForZeroconfUserID(String zeroconfUserID)
- {
- BundleContext bc = ZeroconfActivator.getBundleContext();
-
- String osgiQuery = "(&" +
- "(" + ProtocolProviderFactory.PROTOCOL +
- "=" + ProtocolNames.ZEROCONF + ")" +
- "(" + ProtocolProviderFactory.USER_ID +
- "=" + zeroconfUserID + "))";
-
- ServiceReference[] refs = null;
- try
- {
- refs = bc.getServiceReferences(
- ProtocolProviderService.class.getName(),
- osgiQuery);
- }
- catch (InvalidSyntaxException ex)
- {
- logger.error("Failed to execute the following osgi query: "
- + osgiQuery
- , ex);
- }
-
- if(refs != null && refs.length > 0)
- {
- return (ProtocolProviderServiceZeroconfImpl)bc.getService(refs[0]);
- }
-
- return null;
- }
-
- /**
- * Creates and returns a unresolved contact group from the specified
- * <tt>address</tt> and <tt>persistentData</tt>. The method will not try
- * to establish a network connection and resolve the newly created
- * <tt>ContactGroup</tt> against the server or the contact itself. The
- * protocol provider will later resolve the contact group. When this happens
- * the corresponding event would notify interested subscription listeners.
- *
- * @param groupUID an identifier, returned by ContactGroup's getGroupUID,
- * that the protocol provider may use in order to create the group.
- * @param persistentData a String returned ContactGroups's
- * getPersistentData() method during a previous run and that has been
- * persistently stored locally.
- * @param parentGroup the group under which the new group is to be created
- * or null if this is group directly underneath the root.
- * @return the unresolved <tt>ContactGroup</tt> created from the specified
- * <tt>uid</tt> and <tt>persistentData</tt>
- */
- public ContactGroup createUnresolvedContactGroup(String groupUID,
- String persistentData, ContactGroup parentGroup)
- {
- ContactGroupZeroconfImpl newGroup
- = new ContactGroupZeroconfImpl(
- ContactGroupZeroconfImpl.createNameFromUID(groupUID)
- , parentProvider);
- newGroup.setResolved(false);
-
- //if parent is null then we're adding under root.
- if(parentGroup == null)
- parentGroup = getServerStoredContactListRoot();
-
- ((ContactGroupZeroconfImpl)parentGroup).addSubgroup(newGroup);
-
- this.fireServerStoredGroupEvent(
- newGroup, ServerStoredGroupEvent.GROUP_CREATED_EVENT);
-
- return newGroup;
- }
-
- private class UnregistrationListener
- implements RegistrationStateChangeListener
- {
- /**
- * The method is called by a ProtocolProvider implementation whenver
- * a change in the registration state of the corresponding provider had
- * occurred. The method is particularly interested in events stating
- * that the zeroconf provider has unregistered so that it would fire
- * status change events for all contacts in our buddy list.
- *
- * @param evt ProviderStatusChangeEvent the event describing the status
- * change.
- */
- public void registrationStateChanged(RegistrationStateChangeEvent evt)
- {
-
- if (logger.isDebugEnabled())
- logger.debug("ZEROCONF : The Zeroconf provider changed state from: "
- + evt.getOldState()
- + " to: " + evt.getNewState());
-
- //send event notifications saying that all our buddies are
- //offline. The Zeroconf protocol does not implement top level buddies
- //nor subgroups for top level groups so a simple nested loop
- //would be enough.
- Iterator<ContactGroup> groupsIter
- = getServerStoredContactListRoot().subgroups();
- while (groupsIter.hasNext())
- {
- ContactGroup group = groupsIter.next();
- Iterator<Contact> contactsIter = group.contacts();
-
- while (contactsIter.hasNext())
- {
- ContactZeroconfImpl contact
- = (ContactZeroconfImpl) contactsIter.next();
-
- PresenceStatus oldContactStatus
- = contact.getPresenceStatus();
-
- /* We set contacts to OFFLINE and send an event so that external listeners
- * can be aware that the contacts are reachable anymore. Dunno if that's
- * a good idea. Can be erased if not. Contacts clean is directly done by the
- * contact status change handler.
- */
- if (!oldContactStatus.isOnline())
- {
- //contact.setPresenceStatus(ZeroconfStatusEnum.OFFLINE);
- fireContactPresenceStatusChangeEvent(
- contact
- , contact.getParentContactGroup()
- , oldContactStatus);
- }
- }
- }
- }
- }
-
- /**
- * Returns the volatile group or null if this group has not yet been
- * created.
- *
- * @return a volatile group existing in our contact list or <tt>null</tt>
- * if such a group has not yet been created.
- */
- public ContactGroupZeroconfImpl getNonPersistentGroup()
- {
- for (int i = 0;
- i < getServerStoredContactListRoot().countSubgroups();
- i++)
- {
- ContactGroupZeroconfImpl gr =
- (ContactGroupZeroconfImpl)getServerStoredContactListRoot()
- .getGroup(i);
-
- if(!gr.isPersistent())
- return gr;
- }
-
- return null;
- }
-
-
- /**
- * Creates a non persistent contact for the specified address. This would
- * also create (if necessary) a group for volatile contacts that would not
- * be added to the server stored contact list. This method would have no
- * effect on the server stored contact list.
- * @return the newly created volatile contact.
- * @param bonjourService BonjourService responsible for the chat with this contact
- * @param name Display name of the contact
- * @param ip IP address of the contact
- * @param port Port declared by the contact for direct chat
- * @param contactAddress the address of the volatile contact we'd like to
- * create.
- */
- public ContactZeroconfImpl createVolatileContact(String contactAddress,
- BonjourService bonjourService,
- String name,
- InetAddress ip,
- int port)
- {
- //First create the new volatile contact;
- ContactZeroconfImpl newVolatileContact
- = new ContactZeroconfImpl(contactAddress,
- this.parentProvider, bonjourService, name, ip, port);
- newVolatileContact.setPersistent(false);
-
-
- //Check whether a volatile group already exists and if not create
- //one
- ContactGroupZeroconfImpl theVolatileGroup = getNonPersistentGroup();
-
-
- //if the parent volatile group is null then we create it
- if (theVolatileGroup == null)
- {
- theVolatileGroup = new ContactGroupZeroconfImpl(
- "Bonjour"
- , parentProvider);
- theVolatileGroup.setResolved(false);
- theVolatileGroup.setPersistent(false);
-
- this.contactListRoot.addSubgroup(theVolatileGroup);
-
- fireServerStoredGroupEvent(theVolatileGroup
- , ServerStoredGroupEvent.GROUP_CREATED_EVENT);
- }
-
- //now add the volatile contact instide it
- theVolatileGroup.addContact(newVolatileContact);
- fireSubscriptionEvent(newVolatileContact
- , theVolatileGroup
- , SubscriptionEvent.SUBSCRIPTION_CREATED);
-
- return newVolatileContact;
- }
-
- public Contact getLocalContact()
- {
- return null;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/OperationSetTypingNotificationsZeroconfImpl.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/OperationSetTypingNotificationsZeroconfImpl.java
deleted file mode 100644
index db397b8..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/OperationSetTypingNotificationsZeroconfImpl.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * Implements typing notifications for the Zeroconf protocol. The operation
- * set would simply mirror all outgoing typing notifications and make them
- * appear as incoming events generated by the contact that we are currently
- * writing a message to.
- *
- * @author Christian Vincenot
- * @author Maxime Catelin
- * @author Jonathan Martin
- */
-public class OperationSetTypingNotificationsZeroconfImpl
- extends AbstractOperationSetTypingNotifications<ProtocolProviderServiceZeroconfImpl>
-{
-
- /**
- * Creates a new instance of this operation set and keeps the parent
- * provider as a reference.
- *
- * @param provider a ref to the <tt>ProtocolProviderServiceImpl</tt>
- * that created us and that we'll use for retrieving the underlying aim
- * connection.
- */
- OperationSetTypingNotificationsZeroconfImpl(
- ProtocolProviderServiceZeroconfImpl provider)
- {
- super(provider);
- }
-
- /**
- * Sends a notification to <tt>notifiedContatct</tt> that we have entered
- * <tt>typingState</tt>.
- *
- * @param notifiedContact the <tt>Contact</tt> to notify
- * @param typingState the typing state that we have entered.
- *
- * @throws java.lang.IllegalStateException if the underlying stack is
- * not registered and initialized.
- * @throws java.lang.IllegalArgumentException if <tt>notifiedContact</tt> is
- * not an instance belonging to the underlying implementation.
- */
- public void sendTypingNotification(Contact notifiedContact, int typingState)
- throws IllegalStateException, IllegalArgumentException
- {
- if( !(notifiedContact instanceof ContactZeroconfImpl) )
- throw new IllegalArgumentException(
- "The specified contact is not a Zeroconf contact."
- + notifiedContact);
-
- ContactZeroconfImpl to = (ContactZeroconfImpl)notifiedContact;
-
- ClientThread thread = to.getClientThread();
- if (thread == null) return;/*throw new IllegalStateException(
- "No communication channel opened to chat with this contact");*/
-
- if (typingState != STATE_TYPING)
- return;
-
- MessageZeroconfImpl message =
- new MessageZeroconfImpl("",null, MessageZeroconfImpl.TYPING);
- thread.sendMessage(message);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/ProtocolIconZeroconfImpl.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/ProtocolIconZeroconfImpl.java
deleted file mode 100644
index 4c6ce07..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/ProtocolIconZeroconfImpl.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf;
-
-import java.io.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.resources.*;
-import org.osgi.framework.*;
-
-/**
- * Represents the Zeroconf protocol icon. Implements the <tt>ProtocolIcon</tt>
- * interface in order to provide a Zeroconf logo image in two different sizes.
- *
- * @author Christian Vincenot
- * @author Jonathan Martin
- */
-public class ProtocolIconZeroconfImpl
- implements ProtocolIcon
-{
- private static Logger logger
- = Logger.getLogger(ProtocolIconZeroconfImpl.class);
-
- private static ResourceManagementService resourcesService;
-
- /**
- * A hash table containing the protocol icon in different sizes.
- */
- private static Hashtable<String, byte[]> iconsTable
- = new Hashtable<String, byte[]>();
- static
- {
- iconsTable.put(ProtocolIcon.ICON_SIZE_16x16,
- getImageInBytes("service.protocol.zeroconf.ZEROCONF_16x16"));
-
- iconsTable.put(ProtocolIcon.ICON_SIZE_32x32,
- getImageInBytes("service.protocol.zeroconf.ZEROCONF_32x32"));
-
- iconsTable.put(ProtocolIcon.ICON_SIZE_48x48,
- getImageInBytes("service.protocol.zeroconf.ZEROCONF_48x48"));
-
- iconsTable.put(ProtocolIcon.ICON_SIZE_64x64,
- getImageInBytes("service.protocol.zeroconf.ZEROCONF_64x64"));
- }
-
- /**
- * A hash table containing the protocol icon in different sizes.
- */
- private static Hashtable<String, String> iconPathsTable
- = new Hashtable<String, String>();
- static
- {
- iconPathsTable.put(ProtocolIcon.ICON_SIZE_16x16,
- getResources().getImagePath(
- "service.protocol.zeroconf.ZEROCONF_16x16"));
-
- iconPathsTable.put(ProtocolIcon.ICON_SIZE_32x32,
- getResources().getImagePath(
- "service.protocol.zeroconf.ZEROCONF_32x32"));
-
- iconPathsTable.put(ProtocolIcon.ICON_SIZE_48x48,
- getResources().getImagePath(
- "service.protocol.zeroconf.ZEROCONF_48x48"));
-
- iconPathsTable.put(ProtocolIcon.ICON_SIZE_64x64,
- getResources().getImagePath(
- "service.protocol.zeroconf.ZEROCONF_64x64"));
- }
-
- /**
- * Implements the <tt>ProtocolIcon.getSupportedSizes()</tt> method. Returns
- * an iterator to a set containing the supported icon sizes.
- * @return an iterator to a set containing the supported icon sizes
- */
- public Iterator<String> getSupportedSizes()
- {
- return iconsTable.keySet().iterator();
- }
-
- /**
- * Returns TRUE if a icon with the given size is supported, FALSE-otherwise.
- * @param iconSize Icon size
- * @return True if this size is supported, false otherwise
- */
- public boolean isSizeSupported(String iconSize)
- {
- return iconsTable.containsKey(iconSize);
- }
-
- /**
- * Returns the icon image in the given size.
- * @param iconSize the icon size; one of ICON_SIZE_XXX constants
- * @return Icon image
- */
- public byte[] getIcon(String iconSize)
- {
- return iconsTable.get(iconSize);
- }
-
- /**
- * Returns a path to the icon with the given size.
- * @param iconSize the size of the icon we're looking for
- * @return the path to the icon with the given size
- */
- public String getIconPath(String iconSize)
- {
- return iconPathsTable.get(iconSize);
- }
-
- /**
- * Returns the icon image used to represent the protocol connecting state.
- * @return the icon image used to represent the protocol connecting state
- */
- public byte[] getConnectingIcon()
- {
- return getImageInBytes("zeroconfOnlineIcon");
- }
-
- /**
- * Returns the byte representation of the image corresponding to the given
- * identifier.
- *
- * @param imageID the identifier of the image
- * @return the byte representation of the image corresponding to the given
- * identifier.
- */
- public static byte[] getImageInBytes(String imageID)
- {
- InputStream in = getResources().
- getImageInputStream(imageID);
-
- if (in == null)
- return null;
- byte[] image = null;
- try
- {
- image = new byte[in.available()];
-
- in.read(image);
- }
- catch (IOException e)
- {
- logger.error("Failed to load image:" + imageID, e);
- }
-
- return image;
- }
-
- /**
- * Returns the <tt>ResourceManagementService</tt>.
- *
- * @return the <tt>ResourceManagementService</tt>
- */
- public static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- {
- ServiceReference serviceReference = ZeroconfActivator.bundleContext
- .getServiceReference(ResourceManagementService.class.getName());
-
- if(serviceReference == null)
- return null;
-
- resourcesService
- = (ResourceManagementService)ZeroconfActivator.bundleContext
- .getService(serviceReference);
- }
-
- return resourcesService;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/ProtocolProviderFactoryZeroconfImpl.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/ProtocolProviderFactoryZeroconfImpl.java
deleted file mode 100644
index e68033f..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/ProtocolProviderFactoryZeroconfImpl.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-import org.osgi.framework.*;
-
-/**
- * The Zeroconf protocol provider factory creates instances of the Zeroconf
- * protocol provider service. One Service instance corresponds to one account.
- *
- *
- * @author Christian Vincenot
- * @author Maxime Catelin
- */
-public class ProtocolProviderFactoryZeroconfImpl
- extends ProtocolProviderFactory
-{
-
- /**
- * Creates an instance of the ProtocolProviderFactoryZeroconfImpl.
- */
- public ProtocolProviderFactoryZeroconfImpl()
- {
- super(ZeroconfActivator.getBundleContext(), ProtocolNames.ZEROCONF);
- }
-
- /**
- * Initializaed and creates an account corresponding to the specified
- * accountProperties and registers the resulting ProtocolProvider in the
- * <tt>context</tt> BundleContext parameter.
- *
- * @param userIDStr tha/a user identifier uniquely representing the newly
- * created account within the protocol namespace.
- * @param accountProperties a set of protocol (or implementation)
- * specific properties defining the new account.
- * @return the AccountID of the newly created account.
- */
- @Override
- public AccountID installAccount( String userIDStr,
- Map<String, String> accountProperties)
- {
- BundleContext context
- = ZeroconfActivator.getBundleContext();
- if (context == null)
- throw new NullPointerException(
- "The specified BundleContext was null");
-
- if (userIDStr == null)
- throw new NullPointerException(
- "The specified AccountID was null");
-
- if (accountProperties == null)
- throw new NullPointerException(
- "The specified property map was null");
-
- accountProperties.put(USER_ID, userIDStr);
-
- AccountID accountID =
- new ZeroconfAccountID(userIDStr, accountProperties);
-
- //make sure we haven't seen this account id before.
- if (registeredAccounts.containsKey(accountID))
- throw new IllegalStateException(
- "An account for id " + userIDStr + " was already installed!");
-
- //first store the account and only then load it as the load generates
- //an osgi event, the osgi event triggers (through the UI) a call to the
- //ProtocolProviderService.register() method and it needs to access
- //the configuration service and check for a stored password.
- this.storeAccount(accountID, false);
-
- accountID = loadAccount(accountProperties);
-
- return accountID;
- }
-
- @Override
- protected AccountID createAccountID(String userID, Map<String, String> accountProperties)
- {
- return new ZeroconfAccountID(userID, accountProperties);
- }
-
- @Override
- protected ProtocolProviderService createService(String userID,
- AccountID accountID)
- {
- ProtocolProviderServiceZeroconfImpl service =
- new ProtocolProviderServiceZeroconfImpl();
-
- service.initialize(userID, accountID);
- return service;
- }
-
- @Override
- public void modifyAccount( ProtocolProviderService protocolProvider,
- Map<String, String> accountProperties)
- throws NullPointerException
- {
- // TODO Auto-generated method stub
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/ProtocolProviderServiceZeroconfImpl.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/ProtocolProviderServiceZeroconfImpl.java
deleted file mode 100644
index 7fe916f..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/ProtocolProviderServiceZeroconfImpl.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * An implementation of the protocol provider service over the Zeroconf protocol
- *
- * @author Christian Vincenot
- * @author Maxime Catelin
- */
-public class ProtocolProviderServiceZeroconfImpl
- extends AbstractProtocolProviderService
-{
- /**
- * The logger for this class.
- */
- private static final Logger logger =
- Logger.getLogger(ProtocolProviderServiceZeroconfImpl.class);
-
- /**
- * We use this to lock access to initialization.
- */
- private final Object initializationLock = new Object();
-
- /**
- * The id of the account that this protocol provider represents.
- */
- private AccountID accountID = null;
-
- /**
- * Indicates whether or not the provider is initialized and ready for use.
- */
- private boolean isInitialized = false;
-
- /**
- * The logo corresponding to the zeroconf protocol.
- */
- private final ProtocolIconZeroconfImpl zeroconfIcon
- = new ProtocolIconZeroconfImpl();
-
- /**
- * The registration state that we are currently in. Note that in a real
- * world protocol implementation this field won't exist and the registration
- * state would be retrieved from the protocol stack.
- */
- private RegistrationState currentRegistrationState
- = RegistrationState.UNREGISTERED;
-
- /**
- * The BonjourService corresponding to this ProtocolProviderService
- */
-
- private BonjourService bonjourService;
-
- /**
- * The default constructor for the Zeroconf protocol provider.
- */
- public ProtocolProviderServiceZeroconfImpl()
- {
- if (logger.isTraceEnabled())
- logger.trace("Creating a zeroconf provider.");
- }
-
- /**
- * Returns the AccountID that uniquely identifies the account represented
- * by this instance of the ProtocolProviderService.
- *
- * @return the id of the account represented by this provider.
- */
- public AccountID getAccountID()
- {
- return accountID;
- }
-
- /**
- * Returns the Bonjour Service that handles the Bonjour protocol stack.
- *
- *@return the Bonjour Service linked with this Protocol Provider
- */
- public BonjourService getBonjourService()
- {
- return bonjourService;
- }
-
- /**
- * Initializes the service implementation, and puts it in a sate where it
- * could interoperate with other services. It is strongly recomended that
- * properties in this Map be mapped to property names as specified by
- * <tt>AccountProperties</tt>.
- *
- * @param userID the user id of the zeroconf account we're currently
- * initializing
- * @param accountID the identifier of the account that this protocol
- * provider represents.
- *
- * @see net.java.sip.communicator.service.protocol.AccountID
- */
- protected void initialize(String userID,
- AccountID accountID)
- {
- synchronized(initializationLock)
- {
- this.accountID = accountID;
-
-
- //initialize the presence operationset
- OperationSetPersistentPresenceZeroconfImpl persistentPresence =
- new OperationSetPersistentPresenceZeroconfImpl(this);
-
- addSupportedOperationSet(
- OperationSetPersistentPresence.class,
- persistentPresence);
- //register it once again for those that simply need presence and
- //won't be smart enough to check for a persistent presence
- //alternative
- addSupportedOperationSet(
- OperationSetPresence.class,
- persistentPresence);
-
- //initialize the IM operation set
- addSupportedOperationSet(
- OperationSetBasicInstantMessaging.class,
- new OperationSetBasicInstantMessagingZeroconfImpl(
- this,
- persistentPresence));
-
- //initialize the typing notifications operation set
- addSupportedOperationSet(
- OperationSetTypingNotifications.class,
- new OperationSetTypingNotificationsZeroconfImpl(this));
-
- isInitialized = true;
- }
- }
-
- /**
- * Returns the short name of the protocol that the implementation of this
- * provider is based upon (like SIP, Jabber, ICQ/AIM, or others for
- * example).
- *
- * @return a String containing the short name of the protocol this
- * service is implementing (most often that would be a name in
- * ProtocolNames).
- */
- public String getProtocolName()
- {
- return ProtocolNames.ZEROCONF;
- }
-
- /**
- * Returns the state of the registration of this protocol provider with
- * the corresponding registration service.
- *
- * @return ProviderRegistrationState
- */
- public RegistrationState getRegistrationState()
- {
- return currentRegistrationState;
- }
-
- /**
- * Starts the registration process.
- *
- * @param authority the security authority that will be used for
- * resolving any security challenges that may be returned during the
- * registration or at any moment while wer're registered.
- * @throws OperationFailedException with the corresponding code it the
- * registration fails for some reason (e.g. a networking error or an
- * implementation problem).
- */
- public void register(SecurityAuthority authority)
- throws OperationFailedException
- {
- //we don't need a password here since there's no server in
- //zeroconf.
-
- RegistrationState oldState = currentRegistrationState;
- currentRegistrationState = RegistrationState.REGISTERED;
-
-
- //ICI : creer le service Zeroconf !!
- if (logger.isInfoEnabled())
- logger.info("ZEROCONF: Starting the service");
- this.bonjourService = new BonjourService(5298, this);
-
- //bonjourService.changeStatus(ZeroconfStatusEnum.ONLINE);
-
- fireRegistrationStateChanged(
- oldState
- , currentRegistrationState
- , RegistrationStateChangeEvent.REASON_USER_REQUEST
- , null);
- }
-
- /**
- * Makes the service implementation close all open sockets and release
- * any resources that it might have taken and prepare for
- * shutdown/garbage collection.
- */
- public void shutdown()
- {
- if(!isInitialized)
- {
- return;
- }
- if (logger.isTraceEnabled())
- logger.trace("Killing the Zeroconf Protocol Provider.");
-
- if(isRegistered())
- {
- try
- {
- //do the unregistration
- unregister();
- }
- catch (OperationFailedException ex)
- {
- //we're shutting down so we need to silence the exception here
- logger.error(
- "Failed to properly unregister before shutting down. "
- + getAccountID()
- , ex);
- }
- }
-
- isInitialized = false;
- }
-
- /**
- * Ends the registration of this protocol provider with the current
- * registration service.
- *
- * @throws OperationFailedException with the corresponding code it the
- * registration fails for some reason (e.g. a networking error or an
- * implementation problem).
- */
- public void unregister()
- throws OperationFailedException
- {
- RegistrationState oldState = currentRegistrationState;
- currentRegistrationState = RegistrationState.UNREGISTERED;
-
- if(bonjourService != null)
- bonjourService.shutdown();
-
- fireRegistrationStateChanged(
- oldState
- , currentRegistrationState
- , RegistrationStateChangeEvent.REASON_USER_REQUEST
- , null);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see net.java.sip.communicator.service.protocol.ProtocolProviderService#
- * isSignallingTransportSecure()
- */
- public boolean isSignalingTransportSecure()
- {
- return false;
- }
-
- /**
- * Returns the "transport" protocol of this instance used to carry the
- * control channel for the current protocol service.
- *
- * @return The "transport" protocol of this instance: TCP.
- */
- public TransportProtocol getTransportProtocol()
- {
- return TransportProtocol.TCP;
- }
-
- /**
- * Returns the zeroconf protocol icon.
- * @return the zeroconf protocol icon
- */
- public ProtocolIcon getProtocolIcon()
- {
- return zeroconfIcon;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/ZeroconfAccountID.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/ZeroconfAccountID.java
deleted file mode 100644
index 64e22c7..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/ZeroconfAccountID.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * The Zeroconf implementation of a sip-communicator AccountID
- *
- * @author Christian Vincenot
- */
-public class ZeroconfAccountID
- extends AccountID
-{
- /* Firstname, lastname, mail address */
- private String first = null;
- private String last = null;
- private String mail = null;
-
- private boolean rememberContacts = false;
-
- /**
- * Creates a zeroconf account id from the specified id and account
- * properties.
- * @param userID id identifying this account
- * @param accountProperties any other properties necessary for the account.
- */
- ZeroconfAccountID(String userID, Map<String, String> accountProperties)
- {
- super(userID,
- accountProperties,
- ProtocolNames.ZEROCONF,
- "zeroconf.org");
-
- first = accountProperties.get("first");
- last = accountProperties.get("last");
- mail = accountProperties.get("mail");
-
- rememberContacts =
- new Boolean(accountProperties.get("rememberContacts"))
- .booleanValue();
- }
-
- /**
- * Returns a String representing the firstname of this user.
- * @return String representing the firstname of this user.
- */
- public String getFirst()
- {
- return first;
- }
-
- /**
- * Returns a String representing the lastname of this user.
- * @return String representing the lastname of this user.
- */
- public String getLast()
- {
- return last;
- }
-
- /**
- * Returns a String representing the mail address of this user.
- * @return String representing the mail address of this user.
- */
- public String getMail()
- {
- return mail;
- }
-
- /**
- * Returns a boolean indicating if we store the contacts we meet or not.
- * @return boolean indicating if we store the contacts we meet or not.
- */
- public boolean isRememberContacts()
- {
- return rememberContacts;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/ZeroconfActivator.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/ZeroconfActivator.java
deleted file mode 100644
index 2544bab..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/ZeroconfActivator.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * Loads the Zeroconf provider factory and registers its services in the OSGI
- * bundle context.
- *
- * @author Christian Vincenot
- * @author Maxime Catelin
- */
-public class ZeroconfActivator
- implements BundleActivator
-{
- private static final Logger logger
- = Logger.getLogger(ZeroconfActivator.class);
-
- /**
- * A reference to the registration of our Zeroconf protocol provider
- * factory.
- */
- private ServiceRegistration zeroconfPpFactoryServReg = null;
-
- /**
- * A reference to the Zeroconf protocol provider factory.
- */
- private static ProtocolProviderFactoryZeroconfImpl
- zeroconfProviderFactory = null;
-
- /**
- * The currently valid bundle context.
- */
- static BundleContext bundleContext = null;
-
-
- /**
- * Called when this bundle is started. In here we'll export the
- * zeroconf ProtocolProviderFactory implementation so that it could be
- * possible to register accounts with it in SIP Communicator.
- *
- * @param context The execution context of the bundle being started.
- * @throws Exception If this method throws an exception, this bundle is
- * marked as stopped and the Framework will remove this bundle's
- * listeners, unregister all services registered by this bundle, and
- * release all services used by this bundle.
- */
- public void start(BundleContext context)
- throws Exception
- {
-// logger.setLevelAll();
-
- bundleContext = context;
-
- Hashtable<String, String> hashtable = new Hashtable<String, String>();
- hashtable.put(ProtocolProviderFactory.PROTOCOL, "Zeroconf");
-
- zeroconfProviderFactory = new ProtocolProviderFactoryZeroconfImpl();
-
- //register the zeroconf provider factory.
- zeroconfPpFactoryServReg = context.registerService(
- ProtocolProviderFactory.class.getName(),
- zeroconfProviderFactory,
- hashtable);
-
- if (logger.isInfoEnabled())
- logger.info("Zeroconf protocol implementation [STARTED].");
- }
-
- /**
- * Returns a reference to the bundle context that we were started with.
- * @return a reference to the BundleContext instance that we were started
- * witn.
- */
- public static BundleContext getBundleContext()
- {
- return bundleContext;
- }
-
- /**
- * Retrurns a reference to the protocol provider factory that we have
- * registered.
- * @return a reference to the <tt>ProtocolProviderFactoryJabberImpl</tt>
- * instance that we have registered from this package.
- */
- public static ProtocolProviderFactoryZeroconfImpl getProtocolProviderFactory()
- {
- return zeroconfProviderFactory;
- }
-
-
- /**
- * Called when this bundle is stopped so the Framework can perform the
- * bundle-specific activities necessary to stop the bundle.
- *
- * @param context The execution context of the bundle being stopped.
- * @throws Exception If this method throws an exception, the bundle is
- * still marked as stopped, and the Framework will remove the bundle's
- * listeners, unregister all services registered by the bundle, and
- * release all services used by the bundle.
- */
- public void stop(BundleContext context)
- throws Exception
- {
- zeroconfProviderFactory.stop();
- zeroconfPpFactoryServReg.unregister();
-
- if (logger.isInfoEnabled())
- logger.info("Zeroconf protocol implementation [STOPPED].");
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/ZeroconfStatusEnum.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/ZeroconfStatusEnum.java
deleted file mode 100644
index 3fe2745..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/ZeroconfStatusEnum.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * An implementation of <tt>PresenceStatus</tt> that enumerates all states that
- * a Zeroconf contact can fall into.
- *
- * @author Christian Vincenot
- * @author Jonathan Martin
- */
-public class ZeroconfStatusEnum
- extends PresenceStatus
-{
-
- /**
- * Indicates an Offline status or status with 0 connectivity.
- */
- public static final ZeroconfStatusEnum OFFLINE
- = new ZeroconfStatusEnum(
- 0,
- "Offline",
- ProtocolIconZeroconfImpl.getImageInBytes(
- "service.protocol.zeroconf.OFFLINE_STATUS_ICON"));
-
- /**
- * The DND status. Indicates that the user has connectivity but prefers
- * not to be contacted.
- */
- public static final ZeroconfStatusEnum DO_NOT_DISTURB
- = new ZeroconfStatusEnum(
- 30,
- "Do Not Disturb",//, "Do Not Disturb",
- ProtocolIconZeroconfImpl.getImageInBytes(
- "service.protocol.zeroconf.DND_STATUS_ICON"));
-
- /**
- * The Invisible status. Indicates that the user has connectivity even
- * though it may appear otherwise to others, to whom she would appear to be
- * offline.
- */
- public static final ZeroconfStatusEnum INVISIBLE
- = new ZeroconfStatusEnum(
- 45,
- "Invisible",
- ProtocolIconZeroconfImpl.getImageInBytes(
- "service.protocol.zeroconf.INVISIBLE_STATUS_ICON"));
-
- /**
- * The Online status. Indicate that the user is able and willing to
- * communicate.
- */
- public static final ZeroconfStatusEnum ONLINE
- = new ZeroconfStatusEnum(
- 65,
- "Available",//, "Online"
- ProtocolIconZeroconfImpl.getImageInBytes(
- "service.protocol.zeroconf.ONLINE_STATUS_ICON"));
-
-
- /**
- * Initialize the list of supported status states.
- */
- private static List<PresenceStatus> supportedStatusSet = new LinkedList<PresenceStatus>();
- static
- {
- supportedStatusSet.add(OFFLINE);
- supportedStatusSet.add(DO_NOT_DISTURB);
-
- /* INVISIBLE STATUS could be supported by unregistering JmDNS and
- * accepting unknown contacts' messages */
- //supportedStatusSet.add(INVISIBLE);
-
- supportedStatusSet.add(ONLINE);
- }
-
- /**
- * Creates an instance of <tt>ZeroconfPresneceStatus</tt> with the
- * specified parameters.
- * @param status the connectivity level of the new presence status instance
- * @param statusName the name of the presence status.
- * @param statusIcon the icon associated with this status
- */
- private ZeroconfStatusEnum(int status,
- String statusName,
- byte[] statusIcon)
- {
- super(status, statusName, statusIcon);
- }
-
- /**
- * Returns an iterator over all status instances supproted by the zeroconf
- * provider.
- * @return an <tt>Iterator</tt> over all status instances supported by the
- * zeroconf provider.
- */
- static Iterator<PresenceStatus> supportedStatusSet()
- {
- return supportedStatusSet.iterator();
- }
-
- /**
- * @param status String representation of the status
- * @return ZeroconfStatusEnum corresponding the supplied String value
- */
- static ZeroconfStatusEnum statusOf(String status)
- {
- Iterator<PresenceStatus> statusIter = supportedStatusSet();
- while (statusIter.hasNext())
- {
- ZeroconfStatusEnum state = (ZeroconfStatusEnum)statusIter.next();
- if (state.statusName.equalsIgnoreCase(status))
- return state;
- }
- return null;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSCache.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSCache.java
deleted file mode 100644
index 0baaff4..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSCache.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright 2003-2005 Arthur van Hoff Rick Blair
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf.jmdns;
-
-import java.util.*;
-
-import net.java.sip.communicator.util.*;
-
-/**
- * A table of DNS entries. This is a hash table which
- * can handle multiple entries with the same name.
- * <p/>
- * Storing multiple entries with the same name is implemented using a
- * linked list of <code>CacheNode</code>'s.
- * <p/>
- * The current implementation of the API of DNSCache does expose the
- * cache nodes to clients. Clients must explicitly deal with the nodes
- * when iterating over entries in the cache. Here's how to iterate over
- * all entries in the cache:
- * <pre>
- * for (Iterator i=dnscache.iterator(); i.hasNext(); )
- * {
- * for ( DNSCache.CacheNode n = (DNSCache.CacheNode) i.next();
- * n != null;
- * n.next())
- * {
- * DNSEntry entry = n.getValue();
- * ...do something with entry...
- * }
- * }
- * </pre>
- * <p/>
- * And here's how to iterate over all entries having a given name:
- * <pre>
- * for ( DNSCache.CacheNode n = (DNSCache.CacheNode) dnscache.find(name);
- * n != null;
- * n.next())
- * {
- * DNSEntry entry = n.getValue();
- * ...do something with entry...
- * }
- * </pre>
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Werner Randelshofer, Rick Blair
- */
-class DNSCache
-{
- private static Logger logger = Logger.getLogger(DNSCache.class.toString());
- // Implementation note:
- // We might completely hide the existence of CacheNode's in a future version
- // of DNSCache. But this will require to implement two (inner) classes for
- // the iterators that will be returned by method <code>iterator()</code> and
- // method <code>find(name)</code>.
- // Since DNSCache is not a public class, it does not seem worth the effort
- // to clean its API up that much.
-
- // [PJYF Oct 15 2004] This should implements Collections
- // that would be amuch cleaner implementation
-
- /**
- * The number of DNSEntry's in the cache.
- */
- private int size;
-
- /**
- * The hashtable used internally to store the entries of the cache.
- * Keys are instances of String. The String contains an unqualified service
- * name.
- * Values are linked lists of CacheNode instances.
- */
- private HashMap<String, CacheNode> hashtable;
-
- /**
- * Cache nodes are used to implement storage of multiple DNSEntry's of the
- * same name in the cache.
- */
- public static class CacheNode
- {
- private DNSEntry value;
- private CacheNode next;
-
- public CacheNode(DNSEntry value)
- {
- this.value = value;
-// String SLevel = System.getProperty("jmdns.debug");
-// if (SLevel == null)
-// SLevel = "INFO";
-// logger.setLevel(Level.parse(SLevel));
- }
-
- public CacheNode next()
- {
- return next;
- }
-
- public DNSEntry getValue()
- {
- return value;
- }
- }
-
-
- /**
- * Create a table with a given initial size.
- * @param size initial size.
- */
- public DNSCache(final int size)
- {
- hashtable = new HashMap<String, CacheNode>(size);
-
-// String SLevel = System.getProperty("jmdns.debug");
-// if (SLevel == null) SLevel = "INFO";
-// logger.setLevel(Level.parse(SLevel));
- }
-
- /**
- * Clears the cache.
- */
- public synchronized void clear()
- {
- hashtable.clear();
- size = 0;
- }
-
- /**
- * Adds an entry to the table.
- * @param entry added to the table.
- */
- public synchronized void add(final DNSEntry entry)
- {
- //logger.log("DNSCache.add("+entry.getName()+")");
- CacheNode newValue = new CacheNode(entry);
- CacheNode node = hashtable.get(entry.getName());
- if (node == null)
- {
- hashtable.put(entry.getName(), newValue);
- }
- else
- {
- newValue.next = node.next;
- node.next = newValue;
- }
- size++;
- }
-
- /**
- * Remove a specific entry from the table.
- * @param entry removed from table.
- * @return Returns true if the entry was found.
- */
- public synchronized boolean remove(DNSEntry entry)
- {
- CacheNode node = hashtable.get(entry.getName());
- if (node != null)
- {
- if (node.value == entry)
- {
- if (node.next == null)
- {
- hashtable.remove(entry.getName());
- }
- else
- {
- hashtable.put(entry.getName(), node.next);
- }
- size--;
- return true;
- }
-
- CacheNode previous = node;
- node = node.next;
- while (node != null)
- {
- if (node.value == entry)
- {
- previous.next = node.next;
- size--;
- return true;
- }
- previous = node;
- node = node.next;
- }
- ;
- }
- return false;
- }
-
- /**
- * Get a matching DNS entry from the table (using equals).
- * @param entry to be found in table.
- * @return Returns the entry that was found.
- */
- public synchronized DNSEntry get(DNSEntry entry)
- {
- for (CacheNode node = find(entry.getName()); node != null; node = node.next)
- {
- if (node.value.equals(entry))
- {
- return node.value;
- }
- }
- return null;
- }
-
- /**
- * Get a matching DNS entry from the table.
- * @param name
- * @param type
- * @param clazz
- * @return Return the entry if found, null otherwise.
- */
- public synchronized DNSEntry get(String name, int type, int clazz)
- {
- for (CacheNode node = find(name); node != null; node = node.next)
- {
- if (node.value.type == type && node.value.clazz == clazz)
- {
- return node.value;
- }
- }
- return null;
- }
-
- /**
- * Iterates over all cache nodes.
- * The iterator returns instances of DNSCache.CacheNode.
- * Each instance returned is the first node of a linked list.
- * To retrieve all entries, one must iterate over this linked list. See
- * code snippets in the header of the class.
- * @return Returns iterator with instances of DNSCache.CacheNode.
- */
- public Iterator<DNSCache.CacheNode> iterator()
- {
- return Collections.unmodifiableCollection(hashtable.values()).iterator();
- }
-
- /**
- * Iterate only over items with matching name.
- * If an instance is returned, it is the first node of a linked list.
- * To retrieve all entries, one must iterate over this linked list.
- * @param name to be found.
- * @return Returns an instance of DNSCache.CacheNode or null.
- */
- public synchronized CacheNode find(String name)
- {
- return hashtable.get(name);
- }
-
- /**
- * List all entries for debugging.
- */
- public synchronized void print()
- {
- for (Iterator<CacheNode> i = iterator(); i.hasNext();)
- {
- for (CacheNode n = i.next(); n != null; n = n.next)
- {
- if (logger.isInfoEnabled())
- logger.info(n.value.toString());
- }
- }
- }
-
- @Override
- public synchronized String toString()
- {
- StringBuffer aLog = new StringBuffer();
- aLog.append("\t---- cache ----");
- for (Iterator<CacheNode> i = iterator(); i.hasNext();)
- {
- for (CacheNode n = i.next(); n != null; n = n.next)
- {
- aLog.append("\n\t\t" + n.value);
- }
- }
- return aLog.toString();
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSConstants.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSConstants.java
deleted file mode 100644
index 8792c8d..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSConstants.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright 2003-2005 Arthur van Hoff, Rick Blair
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf.jmdns;
-
-/**
- * DNS constants.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Jeff Sonstein,
- * Werner Randelshofer, Pierre Frisch, Rick Blair
- */
-public final class DNSConstants
-{
-
- // changed to final class - jeffs
- final static String MDNS_GROUP = "224.0.0.251";
- final static String MDNS_GROUP_IPV6 = "FF02::FB";
- final static int MDNS_PORT = 5353;
- final static int DNS_PORT = 53;
- // default one hour TTL
- final static int DNS_TTL = 60 * 60;
- // two hour TTL (draft-cheshire-dnsext-multicastdns.txt ch 13)
- // final static int DNS_TTL = 120 * 60;
-
- final static int MAX_MSG_TYPICAL = 1460;
- final static int MAX_MSG_ABSOLUTE = 8972;
-
- final static int FLAGS_QR_MASK = 0x8000; // Query response mask
- final static int FLAGS_QR_QUERY = 0x0000; // Query
- final static int FLAGS_QR_RESPONSE = 0x8000;// Response
-
- public final static int FLAGS_AA = 0x0400; // Authorative answer
- final static int FLAGS_TC = 0x0200; // Truncated
- final static int FLAGS_RD = 0x0100; // Recursion desired
- public final static int FLAGS_RA = 0x8000; // Recursion available
-
- final static int FLAGS_Z = 0x0040; // Zero
- final static int FLAGS_AD = 0x0020; // Authentic data
- final static int FLAGS_CD = 0x0010; // Checking disabled
-
- // Final Static Internet
- public final static int CLASS_IN = 1;
- // CSNET
- final static int CLASS_CS = 2;
- // CHAOS
- final static int CLASS_CH = 3;
- // Hesiod
- final static int CLASS_HS = 4;
- // Used in DNS UPDATE [RFC 2136]
- final static int CLASS_NONE = 254;
- // Not a DNS class, but a DNS query class, meaning "all classes"
- final static int CLASS_ANY = 255;
- // Multicast DNS uses the bottom 15 bits to identify the record class...
- final static int CLASS_MASK = 0x7FFF;
- // ... and the top bit indicates that all other cached records are now invalid
- public final static int CLASS_UNIQUE = 0x8000;
-
- final static int TYPE_IGNORE = 0; // This is a hack to stop further processing
- public final static int TYPE_A = 1; // Address
- final static int TYPE_NS = 2; // Name Server
- final static int TYPE_MD = 3; // Mail Destination
- final static int TYPE_MF = 4; // Mail Forwarder
- final static int TYPE_CNAME = 5; // Canonical Name
- final static int TYPE_SOA = 6; // Start of Authority
- final static int TYPE_MB = 7; // Mailbox
- final static int TYPE_MG = 8; // Mail Group
- final static int TYPE_MR = 9; // Mail Rename
- final static int TYPE_NULL = 10; // NULL RR
- final static int TYPE_WKS = 11; // Well-known-service
- final static int TYPE_PTR = 12; // Domain Name pofinal static inter
- final static int TYPE_HINFO = 13; // Host information
- final static int TYPE_MINFO = 14; // Mailbox information
- final static int TYPE_MX = 15; // Mail exchanger
- public final static int TYPE_TXT = 16;// Arbitrary text string
- final static int TYPE_RP = 17; // for Responsible Person [RFC1183]
- final static int TYPE_AFSDB = 18; // for AFS Data Base location [RFC1183]
- final static int TYPE_X25 = 19; // for X.25 PSDN address [RFC1183]
- final static int TYPE_ISDN = 20; // for ISDN address [RFC1183]
- final static int TYPE_RT = 21; // for Route Through [RFC1183]
- final static int TYPE_NSAP = 22; // for NSAP address, NSAP style A record [RFC1706]
- final static int TYPE_NSAP_PTR = 23;//
- final static int TYPE_SIG = 24; // for security signature [RFC2931]
- final static int TYPE_KEY = 25; // for security key [RFC2535]
- final static int TYPE_PX = 26; // X.400 mail mapping information [RFC2163]
- final static int TYPE_GPOS = 27; // Geographical Position [RFC1712]
- final static int TYPE_AAAA = 28; // IP6 Address [Thomson]
- final static int TYPE_LOC = 29; // Location Information [Vixie]
- final static int TYPE_NXT = 30; // Next Domain - OBSOLETE [RFC2535, RFC3755]
- final static int TYPE_EID = 31; // Endpoint Identifier [Patton]
- final static int TYPE_NIMLOC = 32; // Nimrod Locator [Patton]
- public final static int TYPE_SRV = 33;// Server Selection [RFC2782]
- final static int TYPE_ATMA = 34; // ATM Address [Dobrowski]
- final static int TYPE_NAPTR = 35; // Naming Authority Pointer [RFC2168, RFC2915]
- final static int TYPE_KX = 36; // Key Exchanger [RFC2230]
- final static int TYPE_CERT = 37; // CERT [RFC2538]
- final static int TYPE_A6 = 38; // A6 [RFC2874]
- final static int TYPE_DNAME = 39; // DNAME [RFC2672]
- final static int TYPE_SINK = 40; // SINK [Eastlake]
- final static int TYPE_OPT = 41; // OPT [RFC2671]
- final static int TYPE_APL = 42; // APL [RFC3123]
- final static int TYPE_DS = 43; // Delegation Signer [RFC3658]
- final static int TYPE_SSHFP = 44; // SSH Key Fingerprint [RFC-ietf-secsh-dns-05.txt]
- final static int TYPE_RRSIG = 46; // RRSIG [RFC3755]
- final static int TYPE_NSEC = 47; // NSEC [RFC3755]
- final static int TYPE_DNSKEY = 48; // DNSKEY [RFC3755]
- final static int TYPE_UINFO = 100; // [IANA-Reserved]
- final static int TYPE_UID = 101; // [IANA-Reserved]
- final static int TYPE_GID = 102; // [IANA-Reserved]
- final static int TYPE_UNSPEC = 103; // [IANA-Reserved]
- final static int TYPE_TKEY = 249; // Transaction Key [RFC2930]
- final static int TYPE_TSIG = 250; // Transaction Signature [RFC2845]
- final static int TYPE_IXFR = 251; // Incremental transfer [RFC1995]
- final static int TYPE_AXFR = 252; // Transfer of an entire zone [RFC1035]
- final static int TYPE_MAILA = 253; // Mailbox-related records (MB, MG or MR) [RFC1035]
- final static int TYPE_MAILB = 254; // Mail agent RRs (Obsolete - see MX) [RFC1035]
- final static int TYPE_ANY = 255; // Request for all records [RFC1035]
-
- //Time Intervals for various functions
-
- //milliseconds before send shared query
- final static int SHARED_QUERY_TIME = 20;
- //milliseconds between query loops.
- final static int QUERY_WAIT_INTERVAL = 225;
- //milliseconds between probe loops.
- final static int PROBE_WAIT_INTERVAL = 250;
- //minimal wait interval for response.
- final static int RESPONSE_MIN_WAIT_INTERVAL = 20;
- //maximal wait interval for response
- final static int RESPONSE_MAX_WAIT_INTERVAL = 115;
- //milliseconds to wait after conflict.
- final static int PROBE_CONFLICT_INTERVAL = 1000;
- //After x tries go 1 time a sec. on probes.
- final static int PROBE_THROTTLE_COUNT = 10;
- //We only increment the throttle count, if
- // the previous increment is inside this interval.
- final static int PROBE_THROTTLE_COUNT_INTERVAL = 5000;
- //milliseconds between Announce loops.
- final static int ANNOUNCE_WAIT_INTERVAL = 1000;
- //milliseconds between cache cleanups.
- final static int RECORD_REAPER_INTERVAL = 10000;
-
- final static int KNOWN_ANSWER_TTL = 120;
- // 50% of the TTL in milliseconds
- final static int ANNOUNCED_RENEWAL_TTL_INTERVAL = DNS_TTL * 500;
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSEntry.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSEntry.java
deleted file mode 100644
index 7132756..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSEntry.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright 2003-2005 Arthur van Hoff Rick Blair
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf.jmdns;
-
-import java.util.logging.*;
-
-/**
- * DNS entry with a name, type, and class. This is the base
- * class for questions and records.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Pierre Frisch, Rick Blair
- * @author Christian Vincenot
- */
-public class DNSEntry
-{
- private static Logger logger = Logger.getLogger(DNSEntry.class.toString());
- String key;
- String name;
- int type;
- int clazz;
- boolean unique;
-
- /**
- * Create an entry.
- */
- DNSEntry(String name, int type, int clazz)
- {
- this.key = name.toLowerCase();
- this.name = name;
- this.type = type;
- this.clazz = clazz & DNSConstants.CLASS_MASK;
- this.unique = (clazz & DNSConstants.CLASS_UNIQUE) != 0;
-
- String SLevel = System.getProperty("jmdns.debug");
- if (SLevel == null) SLevel = "INFO";
- logger.setLevel(Level.parse(SLevel));
- }
-
- /**
- * Check if two entries have exactly the same name, type, and class.
- */
- @Override
- public boolean equals(Object obj)
- {
- if (obj instanceof DNSEntry)
- {
- DNSEntry other = (DNSEntry) obj;
- return name.equals(other.name) &&
- type == other.type &&
- clazz == other.clazz;
- }
- return false;
- }
-
- public String getName()
- {
- return name;
- }
-
- public int getType()
- {
- return type;
- }
-
- public int getClazz()
- {
- return clazz;
- }
-
-
- public boolean isUnique()
- {
- return unique;
- }
-
- /**
- * Overriden, to return a value which is consistent with the value returned
- * by equals(Object).
- */
- @Override
- public int hashCode()
- {
- return name.hashCode() + type + clazz;
- }
-
- /**
- * Get a string given a clazz.
- */
- static String getClazz(int clazz)
- {
- switch (clazz & DNSConstants.CLASS_MASK)
- {
- case DNSConstants.CLASS_IN:
- return "in";
- case DNSConstants.CLASS_CS:
- return "cs";
- case DNSConstants.CLASS_CH:
- return "ch";
- case DNSConstants.CLASS_HS:
- return "hs";
- case DNSConstants.CLASS_NONE:
- return "none";
- case DNSConstants.CLASS_ANY:
- return "any";
- default:
- return "?";
- }
- }
-
- /**
- * Get a string given a type.
- */
- static String getType(int type)
- {
- switch (type)
- {
- case DNSConstants.TYPE_A:
- return "a";
- case DNSConstants.TYPE_AAAA:
- return "aaaa";
- case DNSConstants.TYPE_NS:
- return "ns";
- case DNSConstants.TYPE_MD:
- return "md";
- case DNSConstants.TYPE_MF:
- return "mf";
- case DNSConstants.TYPE_CNAME:
- return "cname";
- case DNSConstants.TYPE_SOA:
- return "soa";
- case DNSConstants.TYPE_MB:
- return "mb";
- case DNSConstants.TYPE_MG:
- return "mg";
- case DNSConstants.TYPE_MR:
- return "mr";
- case DNSConstants.TYPE_NULL:
- return "null";
- case DNSConstants.TYPE_WKS:
- return "wks";
- case DNSConstants.TYPE_PTR:
- return "ptr";
- case DNSConstants.TYPE_HINFO:
- return "hinfo";
- case DNSConstants.TYPE_MINFO:
- return "minfo";
- case DNSConstants.TYPE_MX:
- return "mx";
- case DNSConstants.TYPE_TXT:
- return "txt";
- case DNSConstants.TYPE_SRV:
- return "srv";
- case DNSConstants.TYPE_ANY:
- return "any";
- default:
- return "?";
- }
- }
-
- public String toString(String hdr, String other)
- {
- return hdr + "[" + getType(type) + "," +
- getClazz(clazz) + (unique ? "-unique," : ",") +
- name + ((other != null) ? "," +
- other + "]" : "]");
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSIncoming.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSIncoming.java
deleted file mode 100644
index 3dcedc4..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSIncoming.java
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright 2003-2005 Arthur van Hoff Rick Blair
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf.jmdns;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import java.util.logging.*;
-
-/**
- * Parse an incoming DNS message into its components.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Werner Randelshofer, Pierre Frisch, Daniel Bobbert
- */
-final class DNSIncoming
-{
- private static Logger logger = Logger.getLogger(DNSIncoming.class.toString());
- // Implementation note: This vector should be immutable.
- // If a client of DNSIncoming changes the contents of this vector,
- // we get undesired results. To fix this, we have to migrate to
- // the Collections API of Java 1.2. i.e we replace Vector by List.
- // final static Vector EMPTY = new Vector();
-
- private DatagramPacket packet;
- private int off;
- private int len;
- private byte data[];
-
- int id;
- private int flags;
- private int numQuestions;
- int numAnswers;
- private int numAuthorities;
- private int numAdditionals;
- private long receivedTime;
-
- List<DNSEntry> questions;
- List<DNSRecord> answers;
-
- /**
- * Parse a message from a datagram packet.
- */
- DNSIncoming(DatagramPacket packet) throws IOException
- {
- String SLevel = System.getProperty("jmdns.debug");
- if (SLevel == null) SLevel = "INFO";
- logger.setLevel(Level.parse(SLevel));
-
- this.packet = packet;
- this.data = packet.getData();
- this.len = packet.getLength();
- this.off = packet.getOffset();
- this.questions = new LinkedList<DNSEntry>();
- this.answers = new LinkedList<DNSRecord>();
- this.receivedTime = System.currentTimeMillis();
-
- try
- {
- id = readUnsignedShort();
- flags = readUnsignedShort();
- numQuestions = readUnsignedShort();
- numAnswers = readUnsignedShort();
- numAuthorities = readUnsignedShort();
- numAdditionals = readUnsignedShort();
-
- // parse questions
- if (numQuestions > 0)
- {
- questions =
- Collections.synchronizedList(
- new ArrayList<DNSEntry>(numQuestions));
- for (int i = 0; i < numQuestions; i++)
- {
- DNSQuestion question =
- new DNSQuestion(
- readName(),
- readUnsignedShort(),
- readUnsignedShort());
-
- questions.add(question);
- }
- }
-
- // parse answers
- int n = numAnswers + numAuthorities + numAdditionals;
- if (n > 0)
- {
- //System.out.println("JMDNS received "+n+" answers!");
- answers = Collections.synchronizedList(
- new ArrayList<DNSRecord>(n));
- for (int i = 0; i < n; i++)
- {
- String domain = readName();
- int type = readUnsignedShort();
- int clazz = readUnsignedShort();
- int ttl = readInt();
- int len = readUnsignedShort();
- int end = off + len;
- DNSRecord rec = null;
-
- switch (type)
- {
- case DNSConstants.TYPE_A: // IPv4
- case DNSConstants.TYPE_AAAA: // IPv6 FIXME [PJYF Oct 14 2004] This has not been tested
- rec = new DNSRecord.Address(
- domain, type, clazz, ttl, readBytes(off, len));
- break;
- case DNSConstants.TYPE_CNAME:
- case DNSConstants.TYPE_PTR:
- rec = new DNSRecord.Pointer(
- domain, type, clazz, ttl, readName());
- break;
- case DNSConstants.TYPE_TXT:
- rec = new DNSRecord.Text(
- domain, type, clazz, ttl, readBytes(off, len));
- break;
- case DNSConstants.TYPE_SRV:
- //System.out.println("JMDNS: One is a SRV field!!");
- rec = new DNSRecord.Service( domain,
- type,
- clazz,
- ttl,
- readUnsignedShort(),
- readUnsignedShort(),
- readUnsignedShort(),
- readName());
- break;
- case DNSConstants.TYPE_HINFO:
- // Maybe we should do something with those
- break;
- default :
- logger.finer("DNSIncoming() unknown type:" + type);
- break;
- }
-
- if (rec != null)
- {
- // Add a record, if we were able to create one.
- answers.add(rec);
- }
- else
- {
- // Addjust the numbers for the skipped record
- if (answers.size() < numAnswers)
- {
- numAnswers--;
- }
- else
- {
- if (answers.size() < numAnswers + numAuthorities)
- {
- numAuthorities--;
- }
- else
- {
- if (answers.size() < numAnswers +
- numAuthorities +
- numAdditionals)
- {
- numAdditionals--;
- }
- }
- }
- }
- off = end;
- }
- }
- }
- catch (IOException e)
- {
- logger.log(Level.WARNING,
- "DNSIncoming() dump " + print(true) + "\n exception ", e);
- throw e;
- }
- }
-
- /**
- * Check if the message is a query.
- */
- boolean isQuery()
- {
- return (flags & DNSConstants.FLAGS_QR_MASK) ==
- DNSConstants.FLAGS_QR_QUERY;
- }
-
- /**
- * Check if the message is truncated.
- */
- boolean isTruncated()
- {
- return (flags & DNSConstants.FLAGS_TC) != 0;
- }
-
- /**
- * Check if the message is a response.
- */
- boolean isResponse()
- {
- return (flags & DNSConstants.FLAGS_QR_MASK) ==
- DNSConstants.FLAGS_QR_RESPONSE;
- }
-
- private int get(int off) throws IOException
- {
- if ((off < 0) || (off >= len))
- {
- throw new IOException("parser error: offset=" + off);
- }
- return data[off] & 0xFF;
- }
-
- private int readUnsignedShort() throws IOException
- {
- return (get(off++) << 8) + get(off++);
- }
-
- private int readInt() throws IOException
- {
- return (readUnsignedShort() << 16) + readUnsignedShort();
- }
-
- private byte[] readBytes(int off, int len) throws IOException
- {
- byte bytes[] = new byte[len];
- System.arraycopy(data, off, bytes, 0, len);
- return bytes;
- }
-
- private void readUTF(StringBuffer buf, int off, int len) throws IOException
- {
- for (int end = off + len; off < end;)
- {
- int ch = get(off++);
- switch (ch >> 4)
- {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- // 0xxxxxxx
- break;
- case 12:
- case 13:
- // 110x xxxx 10xx xxxx
- ch = ((ch & 0x1F) << 6) | (get(off++) & 0x3F);
- break;
- case 14:
- // 1110 xxxx 10xx xxxx 10xx xxxx
- ch = ((ch & 0x0f) << 12) |
- ((get(off++) & 0x3F) << 6) |
- (get(off++) & 0x3F);
- break;
- default:
- // 10xx xxxx, 1111 xxxx
- ch = ((ch & 0x3F) << 4) | (get(off++) & 0x0f);
- break;
- }
- buf.append((char) ch);
- }
- }
-
- private String readName() throws IOException
- {
- StringBuffer buf = new StringBuffer();
- int off = this.off;
- int next = -1;
- int first = off;
-
- while (true)
- {
- int len = get(off++);
- if (len == 0)
- {
- break;
- }
- switch (len & 0xC0)
- {
- case 0x00:
- //buf.append("[" + off + "]");
- readUTF(buf, off, len);
- off += len;
- buf.append('.');
- break;
- case 0xC0:
- //buf.append("<" + (off - 1) + ">");
- if (next < 0)
- {
- next = off + 1;
- }
- off = ((len & 0x3F) << 8) | get(off++);
- if (off >= first)
- {
- throw new IOException(
- "bad domain name: possible circular name detected");
- }
- first = off;
- break;
- default:
- throw new IOException(
- "bad domain name: '" + buf + "' at " + off);
- }
- }
- this.off = (next >= 0) ? next : off;
- return buf.toString();
- }
-
- /**
- * Debugging.
- */
- String print(boolean dump)
- {
- StringBuffer buf = new StringBuffer();
- buf.append(toString() + "\n");
- for (Iterator<DNSEntry> iterator = questions.iterator();
- iterator.hasNext();)
- {
- buf.append(" ques:" + iterator.next() + "\n");
- }
- int count = 0;
- for (Iterator<DNSRecord> iterator = answers.iterator();
- iterator.hasNext();
- count++)
- {
- if (count < numAnswers)
- {
- buf.append(" answ:");
- }
- else
- {
- if (count < numAnswers + numAuthorities)
- {
- buf.append(" auth:");
- }
- else
- {
- buf.append(" addi:");
- }
- }
- buf.append(iterator.next() + "\n");
- }
- if (dump)
- {
- for (int off = 0, len = packet.getLength(); off < len; off += 32)
- {
- int n = Math.min(32, len - off);
- if (off < 10)
- {
- buf.append(' ');
- }
- if (off < 100)
- {
- buf.append(' ');
- }
- buf.append(off);
- buf.append(':');
- for (int i = 0; i < n; i++)
- {
- if ((i % 8) == 0)
- {
- buf.append(' ');
- }
- buf.append(Integer.toHexString((data[off + i] & 0xF0) >> 4));
- buf.append(Integer.toHexString((data[off + i] & 0x0F) >> 0));
- }
- buf.append("\n");
- buf.append(" ");
- for (int i = 0; i < n; i++)
- {
- if ((i % 8) == 0)
- {
- buf.append(' ');
- }
- buf.append(' ');
- int ch = data[off + i] & 0xFF;
- buf.append(((ch > ' ') && (ch < 127)) ? (char) ch : '.');
- }
- buf.append("\n");
-
- // limit message size
- if (off + 32 >= 256)
- {
- buf.append("....\n");
- break;
- }
- }
- }
- return buf.toString();
- }
-
- @Override
- public String toString()
- {
- StringBuffer buf = new StringBuffer();
- buf.append(isQuery() ? "dns[query," : "dns[response,");
- if (packet.getAddress() != null)
- {
- buf.append(packet.getAddress().getHostAddress());
- }
- buf.append(':');
- buf.append(packet.getPort());
- buf.append(",len=");
- buf.append(packet.getLength());
- buf.append(",id=0x");
- buf.append(Integer.toHexString(id));
- if (flags != 0)
- {
- buf.append(",flags=0x");
- buf.append(Integer.toHexString(flags));
- if ((flags & DNSConstants.FLAGS_QR_RESPONSE) != 0)
- {
- buf.append(":r");
- }
- if ((flags & DNSConstants.FLAGS_AA) != 0)
- {
- buf.append(":aa");
- }
- if ((flags & DNSConstants.FLAGS_TC) != 0)
- {
- buf.append(":tc");
- }
- }
- if (numQuestions > 0)
- {
- buf.append(",questions=");
- buf.append(numQuestions);
- }
- if (numAnswers > 0)
- {
- buf.append(",answers=");
- buf.append(numAnswers);
- }
- if (numAuthorities > 0)
- {
- buf.append(",authorities=");
- buf.append(numAuthorities);
- }
- if (numAdditionals > 0)
- {
- buf.append(",additionals=");
- buf.append(numAdditionals);
- }
- buf.append("]");
- return buf.toString();
- }
-
- /**
- * Appends answers to this Incoming.
- *
- * @throws IllegalArgumentException If not a query or if Truncated.
- */
- void append(DNSIncoming that)
- {
- if (this.isQuery() && this.isTruncated() && that.isQuery())
- {
- if (that.numQuestions > 0) {
- if (Collections.EMPTY_LIST.equals(this.questions))
- this.questions =
- Collections.synchronizedList(
- new ArrayList<DNSEntry>(that.numQuestions));
-
- this.questions.addAll(that.questions);
- this.numQuestions += that.numQuestions;
- }
-
- if (Collections.EMPTY_LIST.equals(answers))
- {
- answers = Collections.synchronizedList(
- new ArrayList<DNSRecord>());
- }
-
- if (that.numAnswers > 0)
- {
- this.answers.addAll(this.numAnswers,
- that.answers.subList(0, that.numAnswers));
- this.numAnswers += that.numAnswers;
- }
- if (that.numAuthorities > 0)
- {
- this.answers.addAll(this.numAnswers + this.numAuthorities,
- that.answers.subList(
- that.numAnswers,
- that.numAnswers + that.numAuthorities));
- this.numAuthorities += that.numAuthorities;
- }
- if (that.numAdditionals > 0)
- {
- this.answers.addAll(
- that.answers.subList(
- that.numAnswers + that.numAuthorities,
- that.numAnswers + that.numAuthorities + that.numAdditionals));
- this.numAdditionals += that.numAdditionals;
- }
- }
- else
- {
- throw new IllegalArgumentException();
- }
- }
-
- int elapseSinceArrival()
- {
- return (int) (System.currentTimeMillis() - receivedTime);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSListener.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSListener.java
deleted file mode 100644
index d317953..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSListener.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright 2003-2005 Arthur van Hoff Rick Blair
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf.jmdns;
-
-// REMIND: Listener should follow Java idiom for listener or have a different
-// name.
-
-/**
- * DNSListener.
- * Listener for record updates.
- *
- * @author Werner Randelshofer, Rick Blair
- * @version 1.0 May 22, 2004 Created.
- */
-public interface DNSListener
-{
- /**
- * Update a DNS record.
- * @param jmdns
- * @param now
- * @param record
- */
- public void updateRecord(JmDNS jmdns, long now, DNSRecord record);
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSOutgoing.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSOutgoing.java
deleted file mode 100644
index 4d099b8..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSOutgoing.java
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright 2003-2005 Arthur van Hoff Rick Blair
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf.jmdns;
-
-import java.io.*;
-import java.util.*;
-import java.util.logging.*;
-
-/**
- * An outgoing DNS message.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Rick Blair, Werner Randelshofer
- */
-final class DNSOutgoing
-{
- private static Logger logger =
- Logger.getLogger(DNSOutgoing.class.toString());
-
- int id;
- int flags;
- private boolean multicast;
- private int numQuestions;
- private int numAnswers;
- private int numAuthorities;
- private int numAdditionals;
- private Hashtable<String, Integer> names;
-
- byte data[];
- int off;
- int len;
-
- /**
- * Create an outgoing multicast query or response.
- */
- DNSOutgoing(int flags)
- {
- this(flags, true);
-
- }
-
- /**
- * Create an outgoing query or response.
- */
- DNSOutgoing(int flags, boolean multicast)
- {
- String SLevel = System.getProperty("jmdns.debug");
- if (SLevel == null) SLevel = "INFO";
- logger.setLevel(Level.parse(SLevel));
-
- this.flags = flags;
- this.multicast = multicast;
- names = new Hashtable<String, Integer>();
- data = new byte[DNSConstants.MAX_MSG_TYPICAL];
- off = 12;
- }
-
- /**
- * Add a question to the message.
- */
- void addQuestion(DNSQuestion rec) throws IOException
- {
- if (numAnswers > 0 || numAuthorities > 0 || numAdditionals > 0)
- {
- throw new IllegalStateException("Questions must be added before answers");
- }
- numQuestions++;
- writeQuestion(rec);
- }
-
- /**
- * Add an answer if it is not suppressed.
- */
- void addAnswer(DNSIncoming in, DNSRecord rec) throws IOException
- {
- if (numAuthorities > 0 || numAdditionals > 0)
- {
- throw new IllegalStateException(
- "Answers must be added before authorities and additionals");
- }
- if (!rec.suppressedBy(in))
- {
- addAnswer(rec, 0);
- }
- }
-
- /**
- * Add an additional answer to the record. Omit if there is no room.
- */
- void addAdditionalAnswer(DNSIncoming in, DNSRecord rec) throws IOException
- {
- if ((off < DNSConstants.MAX_MSG_TYPICAL - 200) && !rec.suppressedBy(in))
- {
- writeRecord(rec, 0);
- numAdditionals++;
- }
- }
-
- /**
- * Add an answer to the message.
- */
- void addAnswer(DNSRecord rec, long now) throws IOException
- {
- if (numAuthorities > 0 || numAdditionals > 0)
- {
- throw new IllegalStateException(
- "Questions must be added before answers");
- }
- if (rec != null)
- {
- if ((now == 0) || !rec.isExpired(now))
- {
- writeRecord(rec, now);
- numAnswers++;
- }
- }
- }
-
- private LinkedList<DNSRecord> authorativeAnswers = new LinkedList<DNSRecord>();
-
- /**
- * Add an authorative answer to the message.
- */
- void addAuthorativeAnswer(DNSRecord rec) throws IOException
- {
- if (numAdditionals > 0)
- {
- throw new IllegalStateException(
- "Authorative answers must be added before additional answers");
- }
- authorativeAnswers.add(rec);
- writeRecord(rec, 0);
- numAuthorities++;
-
- // VERIFY:
-
- }
-
- void writeByte(int value) throws IOException
- {
- if (off >= data.length)
- {
- throw new IOException("buffer full");
- }
- data[off++] = (byte) value;
- }
-
- void writeBytes(String str, int off, int len) throws IOException
- {
- for (int i = 0; i < len; i++)
- {
- writeByte(str.charAt(off + i));
- }
- }
-
- void writeBytes(byte data[]) throws IOException
- {
- if (data != null)
- {
- writeBytes(data, 0, data.length);
- }
- }
-
- void writeBytes(byte data[], int off, int len) throws IOException
- {
- for (int i = 0; i < len; i++)
- {
- writeByte(data[off + i]);
- }
- }
-
- void writeShort(int value) throws IOException
- {
- writeByte(value >> 8);
- writeByte(value);
- }
-
- void writeInt(int value) throws IOException
- {
- writeShort(value >> 16);
- writeShort(value);
- }
-
- void writeUTF(String str, int off, int len) throws IOException
- {
- // compute utf length
- int utflen = 0;
- for (int i = 0; i < len; i++)
- {
- int ch = str.charAt(off + i);
- if ((ch >= 0x0001) && (ch <= 0x007F))
- {
- utflen += 1;
- }
- else
- {
- if (ch > 0x07FF)
- {
- utflen += 3;
- }
- else
- {
- utflen += 2;
- }
- }
- }
- // write utf length
- writeByte(utflen);
- // write utf data
- for (int i = 0; i < len; i++)
- {
- int ch = str.charAt(off + i);
- if ((ch >= 0x0001) && (ch <= 0x007F))
- {
- writeByte(ch);
- }
- else
- {
- if (ch > 0x07FF)
- {
- writeByte(0xE0 | ((ch >> 12) & 0x0F));
- writeByte(0x80 | ((ch >> 6) & 0x3F));
- writeByte(0x80 | ((ch >> 0) & 0x3F));
- }
- else
- {
- writeByte(0xC0 | ((ch >> 6) & 0x1F));
- writeByte(0x80 | ((ch >> 0) & 0x3F));
- }
- }
- }
- }
-
- void writeName(String name) throws IOException
- {
- while (true)
- {
- int n = name.indexOf('.');
- if (n < 0)
- {
- n = name.length();
- }
- if (n <= 0)
- {
- writeByte(0);
- return;
- }
- Integer offset = names.get(name);
- if (offset != null)
- {
- int val = offset.intValue();
-
- if (val > off)
- {
- logger.log(Level.WARNING,
- "DNSOutgoing writeName failed val=" + val + " name=" + name);
- }
-
- writeByte((val >> 8) | 0xC0);
- writeByte(val);
- return;
- }
- names.put(name, off);
- writeUTF(name, 0, n);
- name = name.substring(n);
- if (name.startsWith("."))
- {
- name = name.substring(1);
- }
- }
- }
-
- void writeQuestion(DNSQuestion question) throws IOException
- {
- writeName(question.name);
- writeShort(question.type);
- writeShort(question.clazz);
- }
-
- void writeRecord(DNSRecord rec, long now) throws IOException
- {
- int save = off;
- try
- {
- writeName(rec.name);
- writeShort(rec.type);
- writeShort(rec.clazz |
- ((rec.unique && multicast) ? DNSConstants.CLASS_UNIQUE : 0));
- writeInt((now == 0) ? rec.ttl : rec.getRemainingTTL(now));
- writeShort(0);
- int start = off;
- rec.write(this);
- int len = off - start;
- data[start - 2] = (byte) (len >> 8);
- data[start - 1] = (byte) (len & 0xFF);
- }
- catch (IOException e)
- {
- off = save;
- throw e;
- }
- }
-
- /**
- * Finish the message before sending it off.
- */
- void finish() throws IOException
- {
- int save = off;
- off = 0;
-
- writeShort(multicast ? 0 : id);
- writeShort(flags);
- writeShort(numQuestions);
- writeShort(numAnswers);
- writeShort(numAuthorities);
- writeShort(numAdditionals);
- off = save;
- }
-
- boolean isQuery()
- {
- return (flags & DNSConstants.FLAGS_QR_MASK) ==
- DNSConstants.FLAGS_QR_QUERY;
- }
-
- public boolean isEmpty()
- {
- return numQuestions == 0 && numAuthorities == 0
- && numAdditionals == 0 && numAnswers == 0;
- }
-
-
- @Override
- public String toString()
- {
- StringBuffer buf = new StringBuffer();
- buf.append(isQuery() ? "dns[query," : "dns[response,");
- //buf.append(packet.getAddress().getHostAddress());
- buf.append(':');
- //buf.append(packet.getPort());
- //buf.append(",len=");
- //buf.append(packet.getLength());
- buf.append(",id=0x");
- buf.append(Integer.toHexString(id));
- if (flags != 0)
- {
- buf.append(",flags=0x");
- buf.append(Integer.toHexString(flags));
- if ((flags & DNSConstants.FLAGS_QR_RESPONSE) != 0)
- {
- buf.append(":r");
- }
- if ((flags & DNSConstants.FLAGS_AA) != 0)
- {
- buf.append(":aa");
- }
- if ((flags & DNSConstants.FLAGS_TC) != 0)
- {
- buf.append(":tc");
- }
- }
- if (numQuestions > 0)
- {
- buf.append(",questions=");
- buf.append(numQuestions);
- }
- if (numAnswers > 0)
- {
- buf.append(",answers=");
- buf.append(numAnswers);
- }
- if (numAuthorities > 0)
- {
- buf.append(",authorities=");
- buf.append(numAuthorities);
- }
- if (numAdditionals > 0)
- {
- buf.append(",additionals=");
- buf.append(numAdditionals);
- }
- buf.append(",\nnames=" + names);
- buf.append(",\nauthorativeAnswers=" + authorativeAnswers);
-
- buf.append("]");
- return buf.toString();
- }
-
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSQuestion.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSQuestion.java
deleted file mode 100644
index f6abaa7..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSQuestion.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright 2003-2005 Arthur van Hoff Rick Blair
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf.jmdns;
-
-import java.util.logging.*;
-
-/**
- * A DNS question.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff
- */
-public final class DNSQuestion
- extends DNSEntry
-{
- private static Logger logger =
- Logger.getLogger(DNSQuestion.class.toString());
-
- /**
- * Create a question.
- * @param name
- * @param type
- * @param clazz
- */
- public DNSQuestion(String name, int type, int clazz)
- {
- super(name, type, clazz);
-
- String SLevel = System.getProperty("jmdns.debug");
- if (SLevel == null) SLevel = "INFO";
- logger.setLevel(Level.parse(SLevel));
- }
-
- /**
- * Check if this question is answered by a given DNS record.
- */
- boolean answeredBy(DNSRecord rec)
- {
- return (clazz == rec.clazz) &&
- ((type == rec.type) ||
- (type == DNSConstants.TYPE_ANY)) &&
- name.equals(rec.name);
- }
-
- /**
- * For debugging only.
- */
- @Override
- public String toString()
- {
- return toString("question", null);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSRecord.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSRecord.java
deleted file mode 100644
index 673bbc4..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSRecord.java
+++ /dev/null
@@ -1,796 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright 2003-2005 Arthur van Hoff Rick Blair
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf.jmdns;
-
-import java.io.*;
-import java.net.*;
-import java.util.logging.*;
-
-/**
- * DNS record
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Rick Blair, Werner Randelshofer, Pierre Frisch
- */
-public abstract class DNSRecord extends DNSEntry
-{
- private static Logger logger =
- Logger.getLogger(DNSRecord.class.toString());
- int ttl;
- private long created;
-
- /**
- * Create a DNSRecord with a name, type, clazz, and ttl.
- */
- DNSRecord(String name, int type, int clazz, int ttl)
- {
- super(name, type, clazz);
- this.ttl = ttl;
- this.created = System.currentTimeMillis();
-
- String SLevel = System.getProperty("jmdns.debug");
- if (SLevel == null) SLevel = "INFO";
- logger.setLevel(Level.parse(SLevel));
- }
-
- /**
- * True if this record is the same as some other record.
- * @param other obj to be compared to.
- */
- @Override
- public boolean equals(Object other)
- {
- return (other instanceof DNSRecord) && sameAs((DNSRecord) other);
- }
-
- /**
- * True if this record is the same as some other record.
- */
- boolean sameAs(DNSRecord other)
- {
- return super.equals(other) && sameValue(other);
- }
-
- /**
- * True if this record has the same value as some other record.
- */
- abstract boolean sameValue(DNSRecord other);
-
- /**
- * True if this record has the same type as some other record.
- */
- boolean sameType(DNSRecord other)
- {
- return type == other.type;
- }
-
- /**
- * Handles a query represented by this record.
- *
- * @return Returns true if a conflict with one of the services registered
- * with JmDNS or with the hostname occured.
- */
- abstract boolean handleQuery(JmDNS dns, long expirationTime);
-
- /**
- * Handles a responserepresented by this record.
- *
- * @return Returns true if a conflict with one of the services registered
- * with JmDNS or with the hostname occured.
- */
- abstract boolean handleResponse(JmDNS dns);
-
- /**
- * Adds this as an answer to the provided outgoing datagram.
- */
- abstract DNSOutgoing addAnswer(JmDNS dns, DNSIncoming in, InetAddress addr,
- int port, DNSOutgoing out)
- throws IOException;
-
- /**
- * True if this record is suppressed by the answers in a message.
- */
- boolean suppressedBy(DNSIncoming msg)
- {
- try
- {
- for (int i = msg.numAnswers; i-- > 0;)
- {
- if (suppressedBy(msg.answers.get(i)))
- {
- return true;
- }
- }
- return false;
- }
- catch (ArrayIndexOutOfBoundsException e)
- {
- logger.log(Level.WARNING,
- "suppressedBy() message " + msg + " exception ", e);
- // msg.print(true);
- return false;
- }
- }
-
- /**
- * True if this record would be supressed by an answer.
- * This is the case if this record would not have a
- * significantly longer TTL.
- */
- boolean suppressedBy(DNSRecord other)
- {
- if (sameAs(other) && (other.ttl > ttl / 2))
- {
- return true;
- }
- return false;
- }
-
- /**
- * Get the expiration time of this record.
- */
- long getExpirationTime(int percent)
- {
- return created + (percent * ttl * 10L);
- }
-
- /**
- * Get the remaining TTL for this record.
- */
- int getRemainingTTL(long now)
- {
- return (int) Math.max(0, (getExpirationTime(100) - now) / 1000);
- }
-
- /**
- * Check if the record is expired.
- */
- boolean isExpired(long now)
- {
- return getExpirationTime(100) <= now;
- }
-
- /**
- * Check if the record is stale, ie it has outlived
- * more than half of its TTL.
- */
- boolean isStale(long now)
- {
- return getExpirationTime(50) <= now;
- }
-
- /**
- * Reset the TTL of a record. This avoids having to
- * update the entire record in the cache.
- */
- void resetTTL(DNSRecord other)
- {
- created = other.created;
- ttl = other.ttl;
- }
-
- /**
- * Write this record into an outgoing message.
- */
- abstract void write(DNSOutgoing out) throws IOException;
-
- /**
- * Address record.
- */
- static class Address extends DNSRecord
- {
- private static Logger logger =
- Logger.getLogger(Address.class.toString());
- InetAddress addr;
-
- Address(String name, int type, int clazz, int ttl, InetAddress addr)
- {
- super(name, type, clazz, ttl);
- this.addr = addr;
-
- String SLevel = System.getProperty("jmdns.debug");
- if (SLevel == null) SLevel = "INFO";
- logger.setLevel(Level.parse(SLevel));
- }
-
- Address(String name, int type, int clazz, int ttl, byte[] rawAddress)
- {
- super(name, type, clazz, ttl);
- try
- {
- this.addr = InetAddress.getByAddress(rawAddress);
- }
- catch (UnknownHostException exception)
- {
- logger.log(Level.WARNING, "Address() exception ", exception);
- }
- }
-
- @Override
- void write(DNSOutgoing out) throws IOException
- {
- if (addr != null)
- {
- byte[] buffer = addr.getAddress();
- if (DNSConstants.TYPE_A == type)
- {
- // If we have a type A records we should
- // answer with a IPv4 address
- if (addr instanceof Inet4Address)
- {
- // All is good
- }
- else
- {
- // Get the last four bytes
- byte[] tempbuffer = buffer;
- buffer = new byte[4];
- System.arraycopy(tempbuffer, 12, buffer, 0, 4);
- }
- }
- else
- {
- // If we have a type AAAA records we should
- // answer with a IPv6 address
- if (addr instanceof Inet4Address)
- {
- byte[] tempbuffer = buffer;
- buffer = new byte[16];
- for (int i = 0; i < 16; i++)
- {
- if (i < 11)
- {
- buffer[i] = tempbuffer[i - 12];
- }
- else
- {
- buffer[i] = 0;
- }
- }
- }
- }
- int length = buffer.length;
- out.writeBytes(buffer, 0, length);
- }
- }
-
- boolean same(DNSRecord other)
- {
- return ((sameName(other)) && ((sameValue(other))));
- }
-
- boolean sameName(DNSRecord other)
- {
- return name.equalsIgnoreCase(((Address) other).name);
- }
-
- @Override
- boolean sameValue(DNSRecord other)
- {
- return addr.equals(((Address) other).getAddress());
- }
-
- InetAddress getAddress()
- {
- return addr;
- }
-
- /**
- * Creates a byte array representation of this record.
- * This is needed for tie-break tests according to
- * draft-cheshire-dnsext-multicastdns-04.txt chapter 9.2.
- */
- private byte[] toByteArray()
- {
- try
- {
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- DataOutputStream dout = new DataOutputStream(bout);
- dout.write(name.getBytes("UTF8"));
- dout.writeShort(type);
- dout.writeShort(clazz);
- //dout.writeInt(len);
- byte[] buffer = addr.getAddress();
- for (int i = 0; i < buffer.length; i++)
- {
- dout.writeByte(buffer[i]);
- }
- dout.close();
- return bout.toByteArray();
- }
- catch (IOException e)
- {
- throw new InternalError();
- }
- }
-
- /**
- * Does a lexicographic comparison of the byte array representation
- * of this record and that record.
- * This is needed for tie-break tests according to
- * draft-cheshire-dnsext-multicastdns-04.txt chapter 9.2.
- */
- private int lexCompare(DNSRecord.Address that)
- {
- byte[] thisBytes = this.toByteArray();
- byte[] thatBytes = that.toByteArray();
- for ( int i = 0, n = Math.min(thisBytes.length, thatBytes.length);
- i < n;
- i++)
- {
- if (thisBytes[i] > thatBytes[i])
- {
- return 1;
- }
- else
- {
- if (thisBytes[i] < thatBytes[i])
- {
- return -1;
- }
- }
- }
- return thisBytes.length - thatBytes.length;
- }
-
- /**
- * Does the necessary actions, when this as a query.
- */
- @Override
- boolean handleQuery(JmDNS dns, long expirationTime)
- {
- DNSRecord.Address dnsAddress =
- dns.getLocalHost().getDNSAddressRecord(this);
- if (dnsAddress != null)
- {
- if (dnsAddress.sameType(this) &&
- dnsAddress.sameName(this) &&
- (!dnsAddress.sameValue(this)))
- {
- logger.finer(
- "handleQuery() Conflicting probe detected. dns state " +
- dns.getState() +
- " lex compare " + lexCompare(dnsAddress));
- // Tie-breaker test
- if (dns.getState().isProbing() && lexCompare(dnsAddress) >= 0)
- {
- // We lost the tie-break. We have to choose a different name.
- dns.getLocalHost().incrementHostName();
- dns.getCache().clear();
- for (ServiceInfo info : dns.services.values())
- info.revertState();
- }
- dns.revertState();
- return true;
- }
- }
- return false;
- }
-
- /**
- * Does the necessary actions, when this as a response.
- */
- @Override
- boolean handleResponse(JmDNS dns)
- {
- DNSRecord.Address dnsAddress =
- dns.getLocalHost().getDNSAddressRecord(this);
- if (dnsAddress != null)
- {
- if (dnsAddress.sameType(this) &&
- dnsAddress.sameName(this) &&
- (!dnsAddress.sameValue(this)))
- {
- logger.finer("handleResponse() Denial detected");
-
- if (dns.getState().isProbing())
- {
- dns.getLocalHost().incrementHostName();
- dns.getCache().clear();
- for (ServiceInfo info : dns.services.values())
- info.revertState();
- }
- dns.revertState();
- return true;
- }
- }
- return false;
- }
-
- @Override
- DNSOutgoing addAnswer(JmDNS dns,
- DNSIncoming in,
- InetAddress addr,
- int port,
- DNSOutgoing out)
- throws IOException
- {
- return out;
- }
-
- @Override
- public String toString()
- {
- return toString(" address '" +
- (addr != null ? addr.getHostAddress() : "null") + "'");
- }
-
- }
-
- /**
- * Pointer record.
- */
- static class Pointer extends DNSRecord
- {
- private static Logger logger =
- Logger.getLogger(Pointer.class.toString());
- String alias;
-
- Pointer(String name, int type, int clazz, int ttl, String alias)
- {
- super(name, type, clazz, ttl);
- this.alias = alias;
-
- String SLevel = System.getProperty("jmdns.debug");
- if (SLevel == null) SLevel = "INFO";
- logger.setLevel(Level.parse(SLevel));
- }
-
- @Override
- void write(DNSOutgoing out) throws IOException
- {
- out.writeName(alias);
- }
-
- @Override
- boolean sameValue(DNSRecord other)
- {
- return alias.equals(((Pointer) other).alias);
- }
-
- @Override
- boolean handleQuery(JmDNS dns, long expirationTime)
- {
- // Nothing to do (?)
- // I think there is no possibility
- // for conflicts for this record type?
- return false;
- }
-
- @Override
- boolean handleResponse(JmDNS dns)
- {
- // Nothing to do (?)
- // I think there is no possibility for conflicts for this record type?
- return false;
- }
-
- String getAlias()
- {
- return alias;
- }
-
- @Override
- DNSOutgoing addAnswer(JmDNS dns,
- DNSIncoming in,
- InetAddress addr,
- int port,
- DNSOutgoing out)
- throws IOException
- {
- return out;
- }
-
- @Override
- public String toString()
- {
- return toString(alias);
- }
- }
-
- static class Text extends DNSRecord
- {
- private static Logger logger =
- Logger.getLogger(Text.class.toString());
- byte text[];
-
- Text(String name, int type, int clazz, int ttl, byte text[])
- {
- super(name, type, clazz, ttl);
- this.text = text;
-
- String SLevel = System.getProperty("jmdns.debug");
- if (SLevel == null) SLevel = "INFO";
- logger.setLevel(Level.parse(SLevel));
- }
-
- @Override
- void write(DNSOutgoing out) throws IOException
- {
- out.writeBytes(text, 0, text.length);
- }
-
- @Override
- boolean sameValue(DNSRecord other)
- {
- Text txt = (Text) other;
- if (txt.text.length != text.length)
- {
- return false;
- }
- for (int i = text.length; i-- > 0;)
- {
- if (txt.text[i] != text[i])
- {
- return false;
- }
- }
- return true;
- }
-
- @Override
- boolean handleQuery(JmDNS dns, long expirationTime)
- {
- // Nothing to do (?)
- // I think there is no possibility for conflicts for this record type?
- return false;
- }
-
- @Override
- boolean handleResponse(JmDNS dns)
- {
- // Nothing to do (?)
- // Shouldn't we care if we get a conflict at this level?
- /*
- ServiceInfo info = (ServiceInfo) dns.services.get(name.toLowerCase());
- if (info != null)
- {
- if (! Arrays.equals(text,info.text))
- {
- info.revertState();
- return true;
- }
- }
- */
- return false;
- }
-
- @Override
- DNSOutgoing addAnswer(JmDNS dns,
- DNSIncoming in,
- InetAddress addr,
- int port,
- DNSOutgoing out)
- throws IOException
- {
- return out;
- }
-
- @Override
- public String toString()
- {
- return toString((text.length > 10) ?
- new String(text, 0, 7) + "..." :
- new String(text));
- }
- }
-
- /**
- * Service record.
- */
- static class Service extends DNSRecord
- {
- private static Logger logger =
- Logger.getLogger(Service.class.toString());
- int priority;
- int weight;
- int port;
- String server;
-
- Service(String name,
- int type,
- int clazz,
- int ttl,
- int priority,
- int weight,
- int port,
- String server)
- {
- super(name, type, clazz, ttl);
- this.priority = priority;
- this.weight = weight;
- this.port = port;
- this.server = server;
-
- String SLevel = System.getProperty("jmdns.debug");
- if (SLevel == null) SLevel = "INFO";
- logger.setLevel(Level.parse(SLevel));
- }
-
- @Override
- void write(DNSOutgoing out) throws IOException
- {
- out.writeShort(priority);
- out.writeShort(weight);
- out.writeShort(port);
- out.writeName(server);
- }
-
- private byte[] toByteArray()
- {
- try
- {
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- DataOutputStream dout = new DataOutputStream(bout);
- dout.write(name.getBytes("UTF8"));
- dout.writeShort(type);
- dout.writeShort(clazz);
- //dout.writeInt(len);
- dout.writeShort(priority);
- dout.writeShort(weight);
- dout.writeShort(port);
- dout.write(server.getBytes("UTF8"));
- dout.close();
- return bout.toByteArray();
- }
- catch (IOException e)
- {
- throw new InternalError();
- }
- }
-
- private int lexCompare(DNSRecord.Service that)
- {
- byte[] thisBytes = this.toByteArray();
- byte[] thatBytes = that.toByteArray();
- for (int i = 0, n = Math.min(thisBytes.length, thatBytes.length);
- i < n;
- i++)
- {
- if (thisBytes[i] > thatBytes[i])
- {
- return 1;
- }
- else
- {
- if (thisBytes[i] < thatBytes[i])
- {
- return -1;
- }
- }
- }
- return thisBytes.length - thatBytes.length;
- }
-
- @Override
- boolean sameValue(DNSRecord other)
- {
- Service s = (Service) other;
- return (priority == s.priority) &&
- (weight == s.weight) &&
- (port == s.port) &&
- server.equals(s.server);
- }
-
- @Override
- boolean handleQuery(JmDNS dns, long expirationTime)
- {
- ServiceInfo info = dns.services.get(name.toLowerCase());
- if (info != null &&
- (port != info.port ||
- !server.equalsIgnoreCase(dns.getLocalHost().getName())))
- {
- logger.finer("handleQuery() Conflicting probe detected");
-
- // Tie breaker test
- if (info.getState().isProbing() &&
- lexCompare(new DNSRecord.Service(
- info.getQualifiedName(),
- DNSConstants.TYPE_SRV,
- DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE,
- DNSConstants.DNS_TTL,
- info.priority,
- info.weight,
- info.port,
- dns.getLocalHost().getName())) >= 0)
- {
- // We lost the tie break
- String oldName = info.getQualifiedName().toLowerCase();
- info.setName(dns.incrementName(info.getName()));
- dns.services.remove(oldName);
- dns.services.put(info.getQualifiedName().toLowerCase(), info);
- logger.finer(
- "handleQuery() Lost tie break: new unique name chosen:" + info.getName());
-
- }
- info.revertState();
- return true;
-
- }
- return false;
- }
-
- @Override
- boolean handleResponse(JmDNS dns)
- {
- ServiceInfo info = dns.services.get(name.toLowerCase());
- if (info != null &&
- (port != info.port || !server.equalsIgnoreCase(dns.getLocalHost().getName())))
- {
- logger.finer("handleResponse() Denial detected");
-
- if (info.getState().isProbing())
- {
- String oldName = info.getQualifiedName().toLowerCase();
- info.setName(dns.incrementName(info.getName()));
- dns.services.remove(oldName);
- dns.services.put(info.getQualifiedName().toLowerCase(), info);
- logger.finer(
- "handleResponse() New unique name chose:" + info.getName());
-
- }
- info.revertState();
- return true;
- }
- return false;
- }
-
- @Override
- DNSOutgoing addAnswer(JmDNS dns,
- DNSIncoming in,
- InetAddress addr,
- int port,
- DNSOutgoing out)
- throws IOException
- {
- ServiceInfo info = dns.services.get(name.toLowerCase());
- if (info != null)
- {
- if (this.port == info.port != server.equals(dns.getLocalHost().getName()))
- {
- return dns.addAnswer(in, addr, port, out,
- new DNSRecord.Service(
- info.getQualifiedName(),
- DNSConstants.TYPE_SRV,
- DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE,
- DNSConstants.DNS_TTL,
- info.priority,
- info.weight,
- info.port,
- dns.getLocalHost().getName()));
- }
- }
- return out;
- }
-
- @Override
- public String toString()
- {
- return toString(server + ":" + port);
- }
- }
-
- public String toString(String other)
- {
- return toString("record", ttl + "/" +
- getRemainingTTL(System.currentTimeMillis())
-// + "," + other
- );
- }
-}
-
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSState.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSState.java
deleted file mode 100644
index 5016050..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/DNSState.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright 2003-2005 Arthur van Hoff Rick Blair
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf.jmdns;
-
-import java.util.*;
-import java.util.logging.*;
-
-/**
- * DNSState defines the possible states for services registered with JmDNS.
- *
- * @author Werner Randelshofer, Rick Blair
- * @version 1.0 May 23, 2004 Created.
- */
-public class DNSState
- implements Comparable<DNSState>
-{
- private static Logger logger =
- Logger.getLogger(DNSState.class.toString());
-
- private final String name;
-
- /**
- * Ordinal of next state to be created.
- */
- private static int nextOrdinal = 0;
- /**
- * Assign an ordinal to this state.
- */
- private final int ordinal = nextOrdinal++;
- /**
- * Logical sequence of states.
- * The sequence is consistent with the ordinal of a state.
- * This is used for advancing through states.
- */
- private final static ArrayList<DNSState> sequence
- = new ArrayList<DNSState>();
-
- private DNSState(String name)
- {
- this.name = name;
- sequence.add(this);
-
- String SLevel = System.getProperty("jmdns.debug");
- if (SLevel == null) SLevel = "INFO";
- logger.setLevel(Level.parse(SLevel));
- }
-
- @Override
- public final String toString()
- {
- return name;
- }
-
- public static final DNSState PROBING_1 = new DNSState("probing 1");
- public static final DNSState PROBING_2 = new DNSState("probing 2");
- public static final DNSState PROBING_3 = new DNSState("probing 3");
- public static final DNSState ANNOUNCING_1 = new DNSState("announcing 1");
- public static final DNSState ANNOUNCING_2 = new DNSState("announcing 2");
- public static final DNSState ANNOUNCED = new DNSState("announced");
- public static final DNSState CANCELED = new DNSState("canceled");
-
- /**
- * Returns the next advanced state.
- * In general, this advances one step in the following sequence: PROBING_1,
- * PROBING_2, PROBING_3, ANNOUNCING_1, ANNOUNCING_2, ANNOUNCED.
- * Does not advance for ANNOUNCED and CANCELED state.
- * @return Returns the next advanced state.
- */
- public final DNSState advance()
- {
- return (isProbing() || isAnnouncing()) ?
- sequence.get(ordinal + 1) :
- this;
- }
-
- /**
- * Returns to the next reverted state.
- * All states except CANCELED revert to PROBING_1.
- * Status CANCELED does not revert.
- * @return Returns to the next reverted state.
- */
- public final DNSState revert()
- {
- return (this == CANCELED) ? this : PROBING_1;
- }
-
- /**
- * Returns true, if this is a probing state.
- * @return Returns true, if this is a probing state.
- */
- public boolean isProbing()
- {
- return compareTo(PROBING_1) >= 0 && compareTo(PROBING_3) <= 0;
- }
-
- /**
- * Returns true, if this is an announcing state.
- * @return Returns true, if this is an announcing state.
- */
- public boolean isAnnouncing()
- {
- return compareTo(ANNOUNCING_1) >= 0 && compareTo(ANNOUNCING_2) <= 0;
- }
-
- /**
- * Returns true, if this is an announced state.
- * @return Returns true, if this is an announced state.
- */
- public boolean isAnnounced()
- {
- return compareTo(ANNOUNCED) == 0;
- }
-
- /**
- * Compares two states.
- * The states compare as follows:
- * PROBING_1 &lt; PROBING_2 &lt; PROBING_3 &lt; ANNOUNCING_1 &lt;
- * ANNOUNCING_2 &lt; RESPONDING &lt; ANNOUNCED &lt; CANCELED.
- */
- public int compareTo(DNSState state)
- {
- return ordinal - state.ordinal;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/HostInfo.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/HostInfo.java
deleted file mode 100644
index 644afc9..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/HostInfo.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright 2003-2005 Arthur van Hoff Rick Blair
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf.jmdns;
-
-import java.net.*;
-import java.util.logging.*;
-
-
-/**
- * HostInfo information on the local host to be able to cope with change of addresses.
- *
- * @version %I%, %G%
- * @author Pierre Frisch, Werner Randelshofer
- */
-class HostInfo
-{
- private static Logger logger = Logger.getLogger(HostInfo.class.toString());
- protected String name;
- protected InetAddress address;
- protected NetworkInterface interfaze;
- /**
- * This is used to create a unique name for the host name.
- */
- private int hostNameCount;
-
- public HostInfo(InetAddress address, String name)
- {
- super();
-
- String SLevel = System.getProperty("jmdns.debug");
- if (SLevel == null) SLevel = "INFO";
- logger.setLevel(Level.parse(SLevel));
-
- this.address = address;
- this.name = name;
- if (address != null)
- {
- try
- {
- interfaze = NetworkInterface.getByInetAddress(address);
- }
- catch (Exception exception)
- {
- // FIXME Shouldn't we take an action here?
- logger.log(Level.WARNING,
- "LocalHostInfo() exception ", exception);
- }
- }
- }
-
- public String getName()
- {
- return name;
- }
-
- public InetAddress getAddress()
- {
- return address;
- }
-
- public NetworkInterface getInterface()
- {
- return interfaze;
- }
-
- synchronized String incrementHostName()
- {
- hostNameCount++;
- int plocal = name.indexOf(".local.");
- int punder = name.lastIndexOf("-");
- name = name.substring(0, (punder == -1 ? plocal : punder)) + "-" +
- hostNameCount + ".local.";
- return name;
- }
-
- boolean shouldIgnorePacket(DatagramPacket packet)
- {
- boolean result = false;
- if (getAddress() != null)
- {
- InetAddress from = packet.getAddress();
- if (from != null)
- {
- if (from.isLinkLocalAddress() &&
- (!getAddress().isLinkLocalAddress()))
- {
- // Ignore linklocal packets on regular interfaces, unless this is
- // also a linklocal interface. This is to avoid duplicates. This is
- // a terrible hack caused by the lack of an API to get the address
- // of the interface on which the packet was received.
- result = true;
- }
- if (from.isLoopbackAddress() &&
- (!getAddress().isLoopbackAddress()))
- {
- // Ignore loopback packets on a regular interface unless this is
- // also a loopback interface.
- result = true;
- }
- }
- }
- return result;
- }
-
- DNSRecord.Address getDNSAddressRecord(DNSRecord.Address address)
- {
- return (DNSConstants.TYPE_AAAA == address.type ?
- getDNS6AddressRecord() :
- getDNS4AddressRecord());
- }
-
- DNSRecord.Address getDNS4AddressRecord()
- {
- if ((getAddress() != null) &&
- ((getAddress() instanceof Inet4Address) ||
- ((getAddress() instanceof Inet6Address) &&
- (((Inet6Address) getAddress()).isIPv4CompatibleAddress()))))
- {
- return new DNSRecord.Address(getName(),
- DNSConstants.TYPE_A,
- DNSConstants.CLASS_IN,
- DNSConstants.DNS_TTL, getAddress());
- }
- return null;
- }
-
- DNSRecord.Address getDNS6AddressRecord()
- {
- if ((getAddress() != null) && (getAddress() instanceof Inet6Address))
- {
- return new DNSRecord.Address(
- getName(),
- DNSConstants.TYPE_AAAA,
- DNSConstants.CLASS_IN,
- DNSConstants.DNS_TTL,
- getAddress());
- }
- return null;
- }
-
- @Override
- public String toString()
- {
- StringBuffer buf = new StringBuffer();
- buf.append("local host info[");
- buf.append(getName() != null ? getName() : "no name");
- buf.append(", ");
- buf.append(getInterface() != null ?
- getInterface().getDisplayName() :
- "???");
- buf.append(":");
- buf.append(getAddress() != null ?
- getAddress().getHostAddress() :
- "no address");
- buf.append("]");
- return buf.toString();
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/JmDNS.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/JmDNS.java
deleted file mode 100644
index 96420ba..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/JmDNS.java
+++ /dev/null
@@ -1,3048 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright 2003-2005 Arthur van Hoff Rick Blair
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf.jmdns;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-import net.java.sip.communicator.util.*;
-
-// REMIND: multiple IP addresses
-
-/**
- * mDNS implementation in Java.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Rick Blair, Jeff Sonstein,
- * Werner Randelshofer, Pierre Frisch, Scott Lewis
- * @author Christian Vincenot
- */
-public class JmDNS
-{
- private static final Logger logger
- = Logger.getLogger(JmDNS.class);
-
- /**
- * The version of JmDNS.
- */
- public static String VERSION = "2.0";
-
- /**
- * This is the multicast group, we are listening to for
- * multicast DNS messages.
- */
- private InetAddress group;
- /**
- * This is our multicast socket.
- */
- private MulticastSocket socket;
-
- /**
- * Used to fix live lock problem on unregester.
- */
-
- protected boolean closed = false;
-
- /**
- * Holds instances of JmDNS.DNSListener.
- * Must by a synchronized collection, because it is updated from
- * concurrent threads.
- */
- private List<DNSListener> listeners;
- /**
- * Holds instances of ServiceListener's.
- * Keys are Strings holding a fully qualified service type.
- * Values are LinkedList's of ServiceListener's.
- */
- private Map<String, List<ServiceListener>> serviceListeners;
- /**
- * Holds instances of ServiceTypeListener's.
- */
- private List<ServiceTypeListener> typeListeners;
-
-
- /**
- * Cache for DNSEntry's.
- */
- private DNSCache cache;
-
- /**
- * This hashtable holds the services that have been registered.
- * Keys are instances of String which hold an all lower-case version of the
- * fully qualified service name.
- * Values are instances of ServiceInfo.
- */
- Map<String, ServiceInfo> services;
-
- /**
- * This hashtable holds the service types that have been registered or
- * that have been received in an incoming datagram.
- * Keys are instances of String which hold an all lower-case version of the
- * fully qualified service type.
- * Values hold the fully qualified service type.
- */
- Map<String, String> serviceTypes;
-
- /**
- * Handle on the local host
- */
- HostInfo localHost;
-
- private Thread incomingListener = null;
-
- /**
- * Throttle count.
- * This is used to count the overall number of probes sent by JmDNS.
- * When the last throttle increment happened .
- */
- private int throttle;
- /**
- * Last throttle increment.
- */
- private long lastThrottleIncrement;
-
- /**
- * The timer is used to dispatch all outgoing messages of JmDNS.
- * It is also used to dispatch maintenance tasks for the DNS cache.
- */
- private Timer timer;
-
- /**
- * The source for random values.
- * This is used to introduce random delays in responses. This reduces the
- * potential for collisions on the network.
- */
- private final static Random random = new Random();
-
- /**
- * This lock is used to coordinate processing of incoming and outgoing
- * messages. This is needed, because the Rendezvous Conformance Test
- * does not forgive race conditions.
- */
- private Object ioLock = new Object();
-
- /**
- * If an incoming package which needs an answer is truncated, we store it
- * here. We add more incoming DNSRecords to it, until the JmDNS.Responder
- * timer picks it up.
- * Remind: This does not work well with multiple planned answers for packages
- * that came in from different clients.
- */
- private DNSIncoming plannedAnswer;
-
- // State machine
- /**
- * The state of JmDNS.
- * <p/>
- * For proper handling of concurrency, this variable must be
- * changed only using methods advanceState(), revertState() and cancel().
- */
- private DNSState state = DNSState.PROBING_1;
-
- /**
- * Timer task associated to the host name.
- * This is used to prevent from having multiple tasks associated to the host
- * name at the same time.
- */
- TimerTask task;
-
- /**
- * This hashtable is used to maintain a list of service types being collected
- * by this JmDNS instance.
- * The key of the hashtable is a service type name, the value is an instance
- * of JmDNS.ServiceCollector.
- *
- * @see #list
- */
- private HashMap<String, ServiceCollector> serviceCollectors = new HashMap<String, ServiceCollector>();
-
- /**
- * Create an instance of JmDNS.
- * @throws java.io.IOException
- */
- public JmDNS()
- throws IOException
- {
- //String SLevel = System.getProperty("jmdns.debug");
-
- if (logger.isDebugEnabled())
- logger.debug("JmDNS instance created");
- try
- {
- InetAddress addr = InetAddress.getLocalHost();
- // [PJYF Oct 14 2004] Why do we disallow the loopback address?
- init(addr.isLoopbackAddress() ? null : addr, addr.getHostName());
- }
- catch (IOException exc)
- {
- logger.error("Failed to get a reference to localhost", exc);
- init(null, "computer");
- }
- }
-
- /**
- * Create an instance of JmDNS and bind it to a
- * specific network interface given its IP-address.
- * @param addr
- * @throws java.io.IOException
- */
- public JmDNS(InetAddress addr)
- throws IOException
- {
- try
- {
- init(addr, addr.getHostName());
- }
- catch (IOException e)
- {
- init(null, "computer");
- }
- }
-
- /**
- * Initialize everything.
- *
- * @param address The interface to which JmDNS binds to.
- * @param name The host name of the interface.
- */
- private void init(InetAddress address, String name) throws IOException
- {
- // A host name with "." is illegal.
- // so strip off everything and append .local.
- int idx = name.indexOf(".");
- if (idx > 0)
- {
- name = name.substring(0, idx);
- }
- name += ".local.";
- // localHost to IP address binding
- localHost = new HostInfo(address, name);
-
- cache = new DNSCache(100);
-
- listeners = Collections.synchronizedList(new ArrayList<DNSListener>());
- serviceListeners = new HashMap<String, List<ServiceListener>>();
- typeListeners = new ArrayList<ServiceTypeListener>();
-
- services = new Hashtable<String, ServiceInfo>(20);
- serviceTypes = new Hashtable<String, String>(20);
-
- // REMIND: If I could pass in a name for the Timer thread,
- // I would pass 'JmDNS.Timer'.
- timer = new Timer();
- new RecordReaper().start();
-
- incomingListener = new Thread(
- new SocketListener(), "JmDNS.SocketListener");
- incomingListener.setDaemon(true);
- // Bind to multicast socket
- openMulticastSocket(localHost);
- start(services.values());
- }
-
- private void start(Collection<ServiceInfo> serviceInfos)
- {
- state = DNSState.PROBING_1;
- incomingListener.start();
- new Prober().start();
- for (ServiceInfo serviceInfo : serviceInfos)
- {
- try
- {
- registerService(new ServiceInfo(serviceInfo));
- }
- catch (Exception exception)
- {
- logger.warn("start() Registration exception ", exception);
- }
- }
- }
-
- private void openMulticastSocket(HostInfo hostInfo) throws IOException
- {
- if (group == null)
- {
- group = InetAddress.getByName(DNSConstants.MDNS_GROUP);
- }
- if (socket != null)
- {
- this.closeMulticastSocket();
- }
- socket = new MulticastSocket(DNSConstants.MDNS_PORT);
- if ((hostInfo != null) && (localHost.getInterface() != null))
- {
- socket.setNetworkInterface(hostInfo.getInterface());
- }
- socket.setTimeToLive(255);
- socket.joinGroup(group);
- }
-
- private void closeMulticastSocket()
- {
- if (logger.isDebugEnabled())
- logger.debug("closeMulticastSocket()");
- if (socket != null)
- {
- // close socket
- try
- {
- socket.leaveGroup(group);
- socket.close();
- if (incomingListener != null)
- {
- incomingListener.join();
- }
- }
- catch (Exception exception)
- {
- logger.warn("closeMulticastSocket() Close socket exception ",
- exception);
- }
- socket = null;
- }
- }
-
- // State machine
- /**
- * Sets the state and notifies all objects that wait on JmDNS.
- */
- synchronized void advanceState()
- {
- state = state.advance();
- notifyAll();
- }
-
- /**
- * Sets the state and notifies all objects that wait on JmDNS.
- */
- synchronized void revertState()
- {
- state = state.revert();
- notifyAll();
- }
-
- /**
- * Sets the state and notifies all objects that wait on JmDNS.
- */
- synchronized void cancel()
- {
- state = DNSState.CANCELED;
- notifyAll();
- }
-
- /**
- * Returns the current state of this info.
- */
- DNSState getState()
- {
- return state;
- }
-
-
- /**
- * Return the DNSCache associated with the cache variable
- */
- DNSCache getCache()
- {
- return cache;
- }
-
- /**
- * Return the HostName associated with this JmDNS instance.
- * Note: May not be the same as what started. The host name is subject to
- * negotiation.
- * @return Return the HostName associated with this JmDNS instance.
- */
- public String getHostName()
- {
- return localHost.getName();
- }
-
- public HostInfo getLocalHost()
- {
- return localHost;
- }
-
- /**
- * Return the address of the interface to which this instance of JmDNS is
- * bound.
- * @return Return the address of the interface to which this instance
- * of JmDNS is bound.
- * @throws java.io.IOException
- */
- public InetAddress getInterface()
- throws IOException
- {
- return socket.getInterface();
- }
-
- /**
- * Get service information. If the information is not cached, the method
- * will block until updated information is received.
- * <p/>
- * Usage note: Do not call this method from the AWT event dispatcher thread.
- * You will make the user interface unresponsive.
- *
- * @param type fully qualified service type,
- * such as <code>_http._tcp.local.</code> .
- * @param name unqualified service name, such as <code>foobar</code> .
- * @return null if the service information cannot be obtained
- */
- public ServiceInfo getServiceInfo(String type, String name)
- {
- return getServiceInfo(type, name, 3 * 1000);
- }
-
- /**
- * Get service information. If the information is not cached, the method
- * will block for the given timeout until updated information is received.
- * <p/>
- * Usage note: If you call this method from the AWT event dispatcher thread,
- * use a small timeout, or you will make the user interface unresponsive.
- *
- * @param type full qualified service type,
- * such as <code>_http._tcp.local.</code> .
- * @param name unqualified service name, such as <code>foobar</code> .
- * @param timeout timeout in milliseconds
- * @return null if the service information cannot be obtained
- */
- public ServiceInfo getServiceInfo(String type, String name, int timeout)
- {
- ServiceInfo info = new ServiceInfo(type, name);
- new ServiceInfoResolver(info).start();
-
- try
- {
- long end = System.currentTimeMillis() + timeout;
- long delay;
- synchronized (info)
- {
- while (!info.hasData() &&
- (delay = end - System.currentTimeMillis()) > 0)
- {
- info.wait(delay);
- }
- }
- }
- catch (InterruptedException e)
- {
- // empty
- }
-
- return (info.hasData()) ? info : null;
- }
-
- /**
- * Request service information. The information about the service is
- * requested and the ServiceListener.resolveService method is called as soon
- * as it is available.
- * <p/>
- * Usage note: Do not call this method from the AWT event dispatcher thread.
- * You will make the user interface unresponsive.
- *
- * @param type full qualified service type,
- * such as <code>_http._tcp.local.</code> .
- * @param name unqualified service name, such as <code>foobar</code> .
- */
- public void requestServiceInfo(String type, String name)
- {
- requestServiceInfo(type, name, 3 * 1000);
- }
-
- /**
- * Request service information. The information about the service
- * is requested and the ServiceListener.resolveService method is
- * called as soon as it is available.
- *
- * @param type full qualified service type,
- * such as <code>_http._tcp.local.</code> .
- * @param name unqualified service name, such as <code>foobar</code> .
- * @param timeout timeout in milliseconds
- */
- public void requestServiceInfo(String type, String name, int timeout)
- {
- registerServiceType(type);
- ServiceInfo info = new ServiceInfo(type, name);
- new ServiceInfoResolver(info).start();
-
- try
- {
- long end = System.currentTimeMillis() + timeout;
- long delay;
- synchronized (info)
- {
- while (!info.hasData() &&
- (delay = end - System.currentTimeMillis()) > 0)
- {
- info.wait(delay);
- }
- }
- }
- catch (InterruptedException e)
- {
- // empty
- }
- }
-
- void handleServiceResolved(ServiceInfo info)
- {
- List<ServiceListener> list = serviceListeners.get(info.type.toLowerCase());
- if (list != null)
- {
- ServiceEvent event =
- new ServiceEvent(this, info.type, info.getName(), info);
- // Iterate on a copy in case listeners will modify it
- List<ServiceListener> listCopy
- = new ArrayList<ServiceListener> (list);
- for (ServiceListener serviceListener : listCopy)
- serviceListener.serviceResolved(event);
- }
- }
-
- /**
- * Listen for service types.
- *
- * @param listener listener for service types
- * @throws java.io.IOException
- */
- public void addServiceTypeListener(ServiceTypeListener listener)
- throws IOException
- {
- synchronized (this)
- {
- typeListeners.remove(listener);
- typeListeners.add(listener);
- }
-
- // report cached service types
- for (String serviceType : serviceTypes.values())
- {
- listener.serviceTypeAdded(
- new ServiceEvent(this, serviceType, null, null));
- }
-
- new TypeResolver().start();
- }
-
- /**
- * Remove listener for service types.
- *
- * @param listener listener for service types
- */
- public void removeServiceTypeListener(ServiceTypeListener listener)
- {
- synchronized (this)
- {
- typeListeners.remove(listener);
- }
- }
-
- /**
- * Listen for services of a given type. The type has to be a fully
- * qualified type name such as <code>_http._tcp.local.</code>.
- *
- * @param type full qualified service type,
- * such as <code>_http._tcp.local.</code>.
- * @param listener listener for service updates
- */
- public void addServiceListener(String type, ServiceListener listener)
- {
- String lotype = type.toLowerCase();
- removeServiceListener(lotype, listener);
- List<ServiceListener> list = null;
- synchronized (this)
- {
- list = serviceListeners.get(lotype);
- if (list == null)
- {
- list = Collections.synchronizedList(new LinkedList<ServiceListener>());
- serviceListeners.put(lotype, list);
- }
- list.add(listener);
- }
-
- // report cached service types
- for (Iterator<DNSCache.CacheNode> i = cache.iterator(); i.hasNext();)
- {
- for (DNSCache.CacheNode n = i.next(); n != null; n = n.next())
- {
- DNSRecord rec = (DNSRecord) n.getValue();
- if (rec.type == DNSConstants.TYPE_SRV)
- {
- if (rec.name.endsWith(type))
- {
- listener.serviceAdded(
- new ServiceEvent(
- this,
- type,
- toUnqualifiedName(type, rec.name),
- null));
- }
- }
- }
- }
- new ServiceResolver(type).start();
- }
-
- /**
- * Remove listener for services of a given type.
- *
- * @param type of listener to be removed
- * @param listener listener for service updates
- */
- public void removeServiceListener(String type, ServiceListener listener)
- {
- type = type.toLowerCase();
- List<ServiceListener> list = serviceListeners.get(type);
- if (list != null)
- {
- synchronized (this)
- {
- list.remove(listener);
- if (list.size() == 0)
- {
- serviceListeners.remove(type);
- }
- }
- }
- }
-
- /**
- * Register a service. The service is registered
- * for access by other jmdns clients.
- * The name of the service may be changed to make it unique.
- * @param info of service
- * @throws java.io.IOException
- */
- public void registerService(ServiceInfo info) throws IOException
- {
- registerServiceType(info.type);
-
- // bind the service to this address
- info.server = localHost.getName();
- info.addr = localHost.getAddress();
-
- synchronized (this)
- {
- makeServiceNameUnique(info);
- services.put(info.getQualifiedName().toLowerCase(), info);
- }
-
- new /*Service*/Prober().start();
- try
- {
- synchronized (info)
- {
- while (info.getState().compareTo(DNSState.ANNOUNCED) < 0)
- {
- info.wait();
- }
- }
- }
- catch (InterruptedException e)
- {
- logger.error(e.getMessage(), e);
- }
- if (logger.isDebugEnabled())
- logger.debug("registerService() JmDNS registered service as " + info);
- }
-
- /**
- * Unregister a service. The service should have been registered.
- * @param info of service
- */
- public void unregisterService(ServiceInfo info)
- {
- synchronized (this)
- {
- services.remove(info.getQualifiedName().toLowerCase());
- }
- info.cancel();
-
- // Note: We use this lock object to synchronize on it.
- // Synchronizing on another object (e.g. the ServiceInfo) does
- // not make sense, because the sole purpose of the lock is to
- // wait until the canceler has finished. If we synchronized on
- // the ServiceInfo or on the Canceler, we would block all
- // accesses to synchronized methods on that object. This is not
- // what we want!
- Object lock = new Object();
- new Canceler(info, lock).start();
-
- // Remind: We get a deadlock here, if the Canceler does not run!
- try
- {
- synchronized (lock)
- {
- lock.wait();
- }
- }
- catch (InterruptedException e)
- {
- // empty
- }
- }
-
- /**
- * Unregister all services.
- */
- public void unregisterAllServices()
- {
- if (logger.isDebugEnabled())
- logger.debug("unregisterAllServices()");
- if (services.size() == 0)
- {
- return;
- }
-
- Collection<ServiceInfo> list;
- synchronized (this)
- {
- list = new LinkedList<ServiceInfo>(services.values());
- services.clear();
- }
- for (Iterator<ServiceInfo> iterator = list.iterator(); iterator.hasNext();)
- {
- iterator.next().cancel();
- }
-
-
- Object lock = new Object();
- new Canceler(list, lock).start();
- // Remind: We get a livelock here, if the Canceler does not run!
- try
- {
- synchronized (lock)
- {
- if (!closed)
- {
- lock.wait();
- }
- }
- }
- catch (InterruptedException e)
- {
- // empty
- }
- }
-
- /**
- * Register a service type. If this service type was not already known,
- * all service listeners will be notified of the new service type.
- * Service types are automatically registered as they are discovered.
- * @param type of service
- */
- public void registerServiceType(String type)
- {
- String name = type.toLowerCase();
- if (serviceTypes.get(name) == null)
- {
- if ((type.indexOf("._mdns._udp.") < 0) &&
- !type.endsWith(".in-addr.arpa."))
- {
- Collection<ServiceTypeListener> list;
- synchronized (this)
- {
- serviceTypes.put(name, type);
- list = new LinkedList<ServiceTypeListener>(typeListeners);
- }
- for (ServiceTypeListener listener : list)
- listener
- .serviceTypeAdded(
- new ServiceEvent(this, type, null, null));
- }
- }
- }
-
- /**
- * Generate a possibly unique name for a service using the information we
- * have in the cache.
- *
- * @return returns true, if the name of the service info had to be changed.
- */
- private boolean makeServiceNameUnique(ServiceInfo info)
- {
- String originalQualifiedName = info.getQualifiedName();
- long now = System.currentTimeMillis();
-
- boolean collision;
- do
- {
- collision = false;
-
- // Check for collision in cache
- for (DNSCache.CacheNode j = cache.find(
- info.getQualifiedName().toLowerCase());
- j != null;
- j = j.next())
- {
- DNSRecord a = (DNSRecord) j.getValue();
- if ((a.type == DNSConstants.TYPE_SRV) && !a.isExpired(now))
- {
- DNSRecord.Service s = (DNSRecord.Service) a;
- if (s.port != info.port || !s.server.equals(localHost.getName()))
- {
- if (logger.isDebugEnabled())
- logger.debug("makeServiceNameUnique() " +
- "JmDNS.makeServiceNameUnique srv collision:" +
- a + " s.server=" + s.server + " " +
- localHost.getName() + " equals:" +
- (s.server.equals(localHost.getName())));
- info.setName(incrementName(info.getName()));
- collision = true;
- break;
- }
- }
- }
-
- // Check for collision with other service infos published by JmDNS
- Object selfService =
- services.get(info.getQualifiedName().toLowerCase());
- if (selfService != null && selfService != info)
- {
- info.setName(incrementName(info.getName()));
- collision = true;
- }
- }
- while (collision);
-
- return !(originalQualifiedName.equals(info.getQualifiedName()));
- }
-
- String incrementName(String name)
- {
- try
- {
- int l = name.lastIndexOf('(');
- int r = name.lastIndexOf(')');
- if ((l >= 0) && (l < r))
- {
- name = name.substring(0, l) + "(" +
- (Integer.parseInt(name.substring(l + 1, r)) + 1) + ")";
- }
- else
- {
- name += " (2)";
- }
- }
- catch (NumberFormatException e)
- {
- name += " (2)";
- }
- return name;
- }
-
- /**
- * Add a listener for a question. The listener will receive updates
- * of answers to the question as they arrive, or from the cache if they
- * are already available.
- * @param listener to be added
- * @param question - which the listener is responsible for.
- */
- public void addListener(DNSListener listener, DNSQuestion question)
- {
- long now = System.currentTimeMillis();
-
- // add the new listener
- synchronized (this)
- {
- listeners.add(listener);
- }
-
- // report existing matched records
- if (question != null)
- {
- for (DNSCache.CacheNode i = cache.find(question.name);
- i != null;
- i = i.next())
- {
- DNSRecord c = (DNSRecord) i.getValue();
- if (question.answeredBy(c) && !c.isExpired(now))
- {
- listener.updateRecord(this, now, c);
- }
- }
- }
- }
-
- /**
- * Remove a listener from all outstanding questions.
- * The listener will no longer receive any updates.
- */
- void removeListener(DNSListener listener)
- {
- synchronized (this)
- {
- listeners.remove(listener);
- }
- }
-
-
- // Remind: Method updateRecord should receive a better name.
- /**
- * Notify all listeners that a record was updated.
- */
- void updateRecord(long now, DNSRecord rec)
- {
- // We do not want to block the entire DNS
- // while we are updating the record for each listener (service info)
- List<DNSListener> listenerList = null;
- synchronized (this)
- {
- listenerList = new ArrayList<DNSListener>(listeners);
- }
-
- //System.out.println("OUT OF MUTEX!!!!!");
-
- for (DNSListener listener : listenerList)
- listener.updateRecord(this, now, rec);
-
- if (rec.type == DNSConstants.TYPE_PTR ||
- rec.type == DNSConstants.TYPE_SRV)
- {
- List<ServiceListener> serviceListenerList = null;
- synchronized (this)
- {
- serviceListenerList = serviceListeners.get(rec.name.toLowerCase());
- // Iterate on a copy in case listeners will modify it
- if (serviceListenerList != null)
- {
- serviceListenerList = new ArrayList<ServiceListener>(serviceListenerList);
- }
- }
- if (serviceListenerList != null)
- {
- boolean expired = rec.isExpired(now);
- String type = rec.getName();
- String name = ((DNSRecord.Pointer) rec).getAlias();
- // DNSRecord old = (DNSRecord)services.get(name.toLowerCase());
- if (!expired)
- {
- // new record
- ServiceEvent event =
- new ServiceEvent(
- this,
- type,
- toUnqualifiedName(type, name),
- null);
- for (Iterator<ServiceListener> iterator = serviceListenerList.iterator();
- iterator.hasNext();)
- {
- iterator.next().serviceAdded(event);
- }
- }
- else
- {
- // expire record
- ServiceEvent event =
- new ServiceEvent(
- this,
- type,
- toUnqualifiedName(type, name),
- null);
- for (Iterator<ServiceListener> iterator = serviceListenerList.iterator();
- iterator.hasNext();)
- {
- iterator.next().serviceRemoved(event);
- }
- }
- }
- }
- }
-
- /**
- * Handle an incoming response. Cache answers, and pass them on to
- * the appropriate questions.
- */
- private void handleResponse(DNSIncoming msg)
- throws IOException
- {
- long now = System.currentTimeMillis();
-
- boolean hostConflictDetected = false;
- boolean serviceConflictDetected = false;
-
- if (logger.isTraceEnabled())
- logger.trace("JMDNS/handleResponse received " +
- msg.answers.size()+ " messages");
- for (DNSRecord rec : msg.answers)
- {
- if (logger.isTraceEnabled())
- logger.trace("PRINT: "+ rec);
- //cache.add(rec);
- }
-
- for (DNSRecord rec : msg.answers)
- {
- boolean isInformative = false;
- boolean expired = rec.isExpired(now);
-
- if (logger.isTraceEnabled())
- logger.trace("JMDNS received : " + rec + " expired: "+expired);
-
- // update the cache
- DNSRecord c = (DNSRecord) cache.get(rec);
- if (c != null)
- {
- if (logger.isTraceEnabled())
- logger.trace("JMDNS has found "+rec+" in cache");
- if (expired)
- {
- isInformative = true;
- cache.remove(c);
- }
- else
- {
- /* Special case for SIP Communicator.
- * We want to be informed if a cache entry is modified
- */
-// if ((c.isUnique()
-// && c.getType() == DNSConstants.TYPE_TXT
-// && ((c.getClazz() & DNSConstants.CLASS_IN) != 0)))
-// isInformative = true;
-// c.resetTTL(rec);
-// rec = c;
- if (logger.isTraceEnabled())
- logger.trace(
- new Boolean(c.isUnique()).toString() +
- c.getType()+c.getClazz() + "/" +
- DNSConstants.TYPE_TXT + " "+DNSConstants.CLASS_IN);
-
- if ((rec.isUnique()
- && ((rec.getType() & DNSConstants.TYPE_TXT) != 0)
- && ((rec.getClazz() & DNSConstants.CLASS_IN) != 0)))
- {
- if (logger.isTraceEnabled())
- logger.trace("UPDATING CACHE !! ");
- isInformative = true;
- cache.remove(c);
- cache.add(rec);
- }
- else
- {
- c.resetTTL(rec);
- rec = c;
- }
- }
- }
- else
- {
- if (!expired)
- {
- isInformative = true;
- if (logger.isTraceEnabled())
- logger.trace("Adding "+rec+" to the cache");
- cache.add(rec);
- }
- }
- switch (rec.type)
- {
- case DNSConstants.TYPE_PTR:
- // handle _mdns._udp records
- if (rec.getName().indexOf("._mdns._udp.") >= 0)
- {
- if (!expired &&
- rec.name.startsWith("_services._mdns._udp."))
- {
- isInformative = true;
- registerServiceType(((DNSRecord.Pointer)rec).alias);
- }
- continue;
- }
- registerServiceType(rec.name);
- break;
- }
-
-
- if ((rec.getType() == DNSConstants.TYPE_A) ||
- (rec.getType() == DNSConstants.TYPE_AAAA))
- {
- hostConflictDetected |= rec.handleResponse(this);
- }
- else
- {
- serviceConflictDetected |= rec.handleResponse(this);
- }
-
- // notify the listeners
- if (isInformative)
- {
- updateRecord(now, rec);
- }
-
-
- }
-
- if (hostConflictDetected || serviceConflictDetected)
- {
- new Prober().start();
- }
- }
-
- /**
- * Handle an incoming query. See if we can answer any part of it
- * given our service infos.
- */
- private void handleQuery(DNSIncoming in, InetAddress addr, int port)
- throws IOException
- {
- // Track known answers
- boolean hostConflictDetected = false;
- boolean serviceConflictDetected = false;
- long expirationTime = System.currentTimeMillis() +
- DNSConstants.KNOWN_ANSWER_TTL;
- for (DNSRecord answer : in.answers)
- {
- if ((answer.getType() == DNSConstants.TYPE_A) ||
- (answer.getType() == DNSConstants.TYPE_AAAA))
- {
- hostConflictDetected |=
- answer.handleQuery(this, expirationTime);
- }
- else
- {
- serviceConflictDetected |=
- answer.handleQuery(this, expirationTime);
- }
- }
-
- if (plannedAnswer != null)
- {
- plannedAnswer.append(in);
- }
- else
- {
- if (in.isTruncated())
- {
- plannedAnswer = in;
- }
-
- new Responder(in, addr, port).start();
- }
-
- if (hostConflictDetected || serviceConflictDetected)
- {
- new Prober().start();
- }
- }
-
- /**
- * Add an answer to a question. Deal with the case when the
- * outgoing packet overflows
- */
- DNSOutgoing addAnswer(DNSIncoming in,
- InetAddress addr,
- int port,
- DNSOutgoing out,
- DNSRecord rec)
- throws IOException
- {
- if (out == null)
- {
- out = new DNSOutgoing(
- DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA);
- }
- try
- {
- out.addAnswer(in, rec);
- }
- catch (IOException e)
- {
- out.flags |= DNSConstants.FLAGS_TC;
- out.id = in.id;
- out.finish();
- send(out);
-
- out = new DNSOutgoing(
- DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA);
- out.addAnswer(in, rec);
- }
- return out;
- }
-
-
- /**
- * Send an outgoing multicast DNS message.
- */
- private void send(DNSOutgoing out) throws IOException
- {
- out.finish();
- if (!out.isEmpty())
- {
- DatagramPacket packet =
- new DatagramPacket(
- out.data, out.off, group, DNSConstants.MDNS_PORT);
-
- try
- {
- DNSIncoming msg = new DNSIncoming(packet);
- if (logger.isTraceEnabled())
- logger.trace("send() JmDNS out:" + msg.print(true));
- }
- catch (IOException exc)
- {
- logger.error(
- "send(DNSOutgoing) - JmDNS can not parse what it sends!!!",
- exc);
- }
- socket.send(packet);
- }
- }
-
- /**
- * Listen for multicast packets.
- */
- class SocketListener implements Runnable
- {
- public void run()
- {
- try
- {
- byte buf[] = new byte[DNSConstants.MAX_MSG_ABSOLUTE];
- DatagramPacket packet = new DatagramPacket(buf, buf.length);
- while (state != DNSState.CANCELED)
- {
- packet.setLength(buf.length);
- socket.receive(packet);
- if (state == DNSState.CANCELED)
- {
- break;
- }
- try
- {
- if (localHost.shouldIgnorePacket(packet))
- {
- continue;
- }
-
- DNSIncoming msg = new DNSIncoming(packet);
- if (logger.isTraceEnabled())
- logger.trace("SocketListener.run() JmDNS in:" +
- msg.print(true));
-
- synchronized (ioLock)
- {
- if (msg.isQuery())
- {
- if (packet.getPort() != DNSConstants.MDNS_PORT)
- {
- handleQuery(msg,
- packet.getAddress(),
- packet.getPort());
- }
- handleQuery(msg, group, DNSConstants.MDNS_PORT);
- }
- else
- {
- handleResponse(msg);
- }
- }
- }
- catch (IOException e)
- {
- logger.warn( "run() exception ", e);
- }
- }
- }
- catch (IOException e)
- {
- if (state != DNSState.CANCELED)
- {
- logger.warn( "run() exception ", e);
- recover();
- }
- }
- }
- }
-
-
- /**
- * Periodicaly removes expired entries from the cache.
- */
- private class RecordReaper extends TimerTask
- {
- public void start()
- {
- timer.schedule( this,
- DNSConstants.RECORD_REAPER_INTERVAL,
- DNSConstants.RECORD_REAPER_INTERVAL);
- }
-
- @Override
- public void run()
- {
- synchronized (JmDNS.this)
- {
- if (state == DNSState.CANCELED)
- {
- return;
- }
- if (logger.isTraceEnabled())
- logger.trace("run() JmDNS reaping cache");
-
- // Remove expired answers from the cache
- // -------------------------------------
- // To prevent race conditions, we defensively copy all cache
- // entries into a list.
- List<DNSEntry> list = new ArrayList<DNSEntry>();
- synchronized (cache)
- {
- for (Iterator<DNSCache.CacheNode> i = cache.iterator();
- i.hasNext();)
- {
- for (DNSCache.CacheNode n = i.next();
- n != null;
- n = n.next())
- {
- list.add(n.getValue());
- }
- }
- }
- // Now, we remove them.
- long now = System.currentTimeMillis();
- for (Iterator<DNSEntry> i = list.iterator(); i.hasNext();)
- {
- DNSRecord c = (DNSRecord)i.next();
- if (c.isExpired(now))
- {
- updateRecord(now, c);
- cache.remove(c);
- }
- }
- }
- }
- }
-
-
- /**
- * The Prober sends three consecutive probes for all service infos
- * that needs probing as well as for the host name.
- * The state of each service info of the host name is advanced,
- * when a probe has been sent for it.
- * When the prober has run three times, it launches an Announcer.
- * <p/>
- * If a conflict during probes occurs, the affected service
- * infos (and affected host name) are taken away from the prober.
- * This eventually causes the prober tho cancel itself.
- */
- private class Prober extends TimerTask
- {
- /**
- * The state of the prober.
- */
- DNSState taskState = DNSState.PROBING_1;
-
- public Prober()
- {
- // Associate the host name to this, if it needs probing
- if (state == DNSState.PROBING_1)
- {
- task = this;
- }
- // Associate services to this, if they need probing
- synchronized (JmDNS.this)
- {
- for (Iterator<ServiceInfo> iterator = services.values().iterator();
- iterator.hasNext();)
- {
- ServiceInfo info = iterator.next();
- if (info.getState() == DNSState.PROBING_1)
- {
- info.task = this;
- }
- }
- }
- }
-
-
- public void start()
- {
- long now = System.currentTimeMillis();
- if (now - lastThrottleIncrement <
- DNSConstants.PROBE_THROTTLE_COUNT_INTERVAL)
- {
- throttle++;
- }
- else
- {
- throttle = 1;
- }
- lastThrottleIncrement = now;
-
- if (state == DNSState.ANNOUNCED &&
- throttle < DNSConstants.PROBE_THROTTLE_COUNT)
- {
- timer.schedule(this,
- random.nextInt(1 + DNSConstants.PROBE_WAIT_INTERVAL),
- DNSConstants.PROBE_WAIT_INTERVAL);
- }
- else
- {
- timer.schedule(this,
- DNSConstants.PROBE_CONFLICT_INTERVAL,
- DNSConstants.PROBE_CONFLICT_INTERVAL);
- }
- }
-
- @Override
- public boolean cancel()
- {
- // Remove association from host name to this
- if (task == this)
- {
- task = null;
- }
-
- // Remove associations from services to this
- synchronized (JmDNS.this)
- {
- for (Iterator<ServiceInfo> i = services.values().iterator();
- i.hasNext();)
- {
- ServiceInfo info = i.next();
- if (info.task == this)
- {
- info.task = null;
- }
- }
- }
-
- return super.cancel();
- }
-
- @Override
- public void run()
- {
- synchronized (ioLock)
- {
- DNSOutgoing out = null;
- try
- {
- // send probes for JmDNS itself
- if (state == taskState && task == this)
- {
- if (out == null)
- {
- out = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY);
- }
- out.addQuestion(
- new DNSQuestion(
- localHost.getName(),
- DNSConstants.TYPE_ANY,
- DNSConstants.CLASS_IN));
- DNSRecord answer = localHost.getDNS4AddressRecord();
- if (answer != null)
- {
- out.addAuthorativeAnswer(answer);
- }
- answer = localHost.getDNS6AddressRecord();
- if (answer != null)
- {
- out.addAuthorativeAnswer(answer);
- }
- advanceState();
- }
- // send probes for services
- // Defensively copy the services into a local list,
- // to prevent race conditions with methods registerService
- // and unregisterService.
- List<ServiceInfo> list;
- synchronized (JmDNS.this)
- {
- list = new LinkedList<ServiceInfo>(services.values());
- }
- for (Iterator<ServiceInfo> i = list.iterator(); i.hasNext();)
- {
- ServiceInfo info = i.next();
-
- synchronized (info)
- {
- if (info.getState() == taskState &&
- info.task == this)
- {
- info.advanceState();
- if (logger.isDebugEnabled())
- logger.debug("run() JmDNS probing " +
- info.getQualifiedName() + " state " +
- info.getState());
-
- if (out == null)
- {
- out = new DNSOutgoing(
- DNSConstants.FLAGS_QR_QUERY);
- out.addQuestion(
- new DNSQuestion(
- info.getQualifiedName(),
- DNSConstants.TYPE_ANY,
- DNSConstants.CLASS_IN));
- }
- out.addAuthorativeAnswer(
- new DNSRecord.Service(
- info.getQualifiedName(),
- DNSConstants.TYPE_SRV,
- DNSConstants.CLASS_IN,
- DNSConstants.DNS_TTL,
- info.priority,
- info.weight,
- info.port,
- localHost.getName()));
- }
- }
- }
- if (out != null)
- {
- if (logger.isDebugEnabled())
- logger.debug("run() JmDNS probing #" + taskState);
- send(out);
- }
- else
- {
- // If we have nothing to send, another timer taskState
- // ahead of us has done the job for us. We can cancel.
- cancel();
- return;
- }
- }
- catch (Throwable e)
- {
- logger.warn( "run() exception ", e);
- recover();
- }
-
- taskState = taskState.advance();
- if (!taskState.isProbing())
- {
- cancel();
-
- new Announcer().start();
- }
- }
- }
-
- }
-
- /**
- * The Announcer sends an accumulated query of all announces, and advances
- * the state of all serviceInfos, for which it has sent an announce.
- * The Announcer also sends announcements and advances the state of JmDNS
- * itself.
- * <p/>
- * When the announcer has run two times, it finishes.
- */
- private class Announcer extends TimerTask
- {
- /**
- * The state of the announcer.
- */
- DNSState taskState = DNSState.ANNOUNCING_1;
-
- public Announcer()
- {
- // Associate host to this, if it needs announcing
- if (state == DNSState.ANNOUNCING_1)
- {
- task = this;
- }
- // Associate services to this, if they need announcing
- synchronized (JmDNS.this)
- {
- for (Iterator<ServiceInfo> s = services.values().iterator(); s.hasNext();)
- {
- ServiceInfo info = s.next();
- if (info.getState() == DNSState.ANNOUNCING_1)
- {
- info.task = this;
- }
- }
- }
- }
-
- public void start()
- {
- timer.schedule(this,
- DNSConstants.ANNOUNCE_WAIT_INTERVAL,
- DNSConstants.ANNOUNCE_WAIT_INTERVAL);
- }
-
- @Override
- public boolean cancel()
- {
- // Remove association from host to this
- if (task == this)
- {
- task = null;
- }
-
- // Remove associations from services to this
- synchronized (JmDNS.this)
- {
- for (Iterator<ServiceInfo> i = services.values().iterator();
- i.hasNext();)
- {
- ServiceInfo info = i.next();
- if (info.task == this)
- {
- info.task = null;
- }
- }
- }
-
- return super.cancel();
- }
-
- @Override
- public void run()
- {
- DNSOutgoing out = null;
- try
- {
- // send probes for JmDNS itself
- if (state == taskState)
- {
- if (out == null)
- {
- out = new DNSOutgoing(
- DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA);
- }
- DNSRecord answer = localHost.getDNS4AddressRecord();
- if (answer != null)
- {
- out.addAnswer(answer, 0);
- }
- answer = localHost.getDNS6AddressRecord();
- if (answer != null)
- {
- out.addAnswer(answer, 0);
- }
- advanceState();
- }
- // send announces for services
- // Defensively copy the services into a local list,
- // to prevent race conditions with methods registerService
- // and unregisterService.
- List<ServiceInfo> list;
- synchronized (JmDNS.this)
- {
- list = new ArrayList<ServiceInfo>(services.values());
- }
- for (Iterator<ServiceInfo> i = list.iterator(); i.hasNext();)
- {
- ServiceInfo info = i.next();
- synchronized (info)
- {
- if (info.getState() == taskState && info.task == this)
- {
- info.advanceState();
- if (logger.isDebugEnabled())
- logger.debug("run() JmDNS announcing " +
- info.getQualifiedName() +
- " state " + info.getState());
-
- if (out == null)
- {
- out = new DNSOutgoing(
- DNSConstants.FLAGS_QR_RESPONSE |
- DNSConstants.FLAGS_AA);
- }
- out.addAnswer(
- new DNSRecord.Pointer(
- info.type,
- DNSConstants.TYPE_PTR,
- DNSConstants.CLASS_IN,
- DNSConstants.DNS_TTL,
- info.getQualifiedName()), 0);
- out.addAnswer(
- new DNSRecord.Service(
- info.getQualifiedName(),
- DNSConstants.TYPE_SRV,
- DNSConstants.CLASS_IN,
- DNSConstants.DNS_TTL,
- info.priority,
- info.weight,
- info.port,
- localHost.getName()), 0);
- out.addAnswer(
- new DNSRecord.Text(
- info.getQualifiedName(),
- DNSConstants.TYPE_TXT,
- DNSConstants.CLASS_IN,
- DNSConstants.DNS_TTL,
- info.text), 0);
- }
- }
- }
- if (out != null)
- {
- if (logger.isDebugEnabled())
- logger.debug("run() JmDNS announcing #" + taskState);
- send(out);
- }
- else
- {
- // If we have nothing to send, another timer taskState ahead
- // of us has done the job for us. We can cancel.
- cancel();
- }
- }
- catch (Throwable e)
- {
- logger.warn( "run() exception ", e);
- recover();
- }
-
- taskState = taskState.advance();
- if (!taskState.isAnnouncing())
- {
- cancel();
-
- new Renewer().start();
- }
- }
- }
-
- /**
- * The Renewer is there to send renewal announcment
- * when the record expire for ours infos.
- */
- private class Renewer extends TimerTask
- {
- /**
- * The state of the announcer.
- */
- DNSState taskState = DNSState.ANNOUNCED;
-
- public Renewer()
- {
- // Associate host to this, if it needs renewal
- if (state == DNSState.ANNOUNCED)
- {
- task = this;
- }
- // Associate services to this, if they need renewal
- synchronized (JmDNS.this)
- {
- for (Iterator<ServiceInfo> s = services.values().iterator(); s.hasNext();)
- {
- ServiceInfo info = s.next();
- if (info.getState() == DNSState.ANNOUNCED)
- {
- info.task = this;
- }
- }
- }
- }
-
- public void start()
- {
- timer.schedule(this,
- DNSConstants.ANNOUNCED_RENEWAL_TTL_INTERVAL,
- DNSConstants.ANNOUNCED_RENEWAL_TTL_INTERVAL);
- }
-
- @Override
- public boolean cancel()
- {
- // Remove association from host to this
- if (task == this)
- {
- task = null;
- }
-
- // Remove associations from services to this
- synchronized (JmDNS.this)
- {
- for (Iterator<ServiceInfo> i = services.values().iterator();
- i.hasNext();)
- {
- ServiceInfo info = i.next();
- if (info.task == this)
- {
- info.task = null;
- }
- }
- }
-
- return super.cancel();
- }
-
- @Override
- public void run()
- {
- DNSOutgoing out = null;
- try
- {
- // send probes for JmDNS itself
- if (state == taskState)
- {
- if (out == null)
- {
- out = new DNSOutgoing(
- DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA);
- }
- DNSRecord answer = localHost.getDNS4AddressRecord();
- if (answer != null)
- {
- out.addAnswer(answer, 0);
- }
- answer = localHost.getDNS6AddressRecord();
- if (answer != null)
- {
- out.addAnswer(answer, 0);
- }
- advanceState();
- }
- // send announces for services
- // Defensively copy the services into a local list,
- // to prevent race conditions with methods registerService
- // and unregisterService.
- List<ServiceInfo> list;
- synchronized (JmDNS.this)
- {
- list = new ArrayList<ServiceInfo>(services.values());
- }
- for (Iterator<ServiceInfo> i = list.iterator(); i.hasNext();)
- {
- ServiceInfo info = i.next();
- synchronized (info)
- {
- if (info.getState() == taskState && info.task == this)
- {
- info.advanceState();
- if (logger.isDebugEnabled())
- logger.debug("run() JmDNS announced " +
- info.getQualifiedName() + " state " + info.getState());
-
- if (out == null)
- {
- out = new DNSOutgoing(
- DNSConstants.FLAGS_QR_RESPONSE |
- DNSConstants.FLAGS_AA);
- }
- out.addAnswer(
- new DNSRecord.Pointer(
- info.type,
- DNSConstants.TYPE_PTR,
- DNSConstants.CLASS_IN,
- DNSConstants.DNS_TTL,
- info.getQualifiedName()), 0);
- out.addAnswer(
- new DNSRecord.Service(
- info.getQualifiedName(),
- DNSConstants.TYPE_SRV,
- DNSConstants.CLASS_IN,
- DNSConstants.DNS_TTL,
- info.priority,
- info.weight,
- info.port,
- localHost.getName()), 0);
- out.addAnswer(
- new DNSRecord.Text(
- info.getQualifiedName(),
- DNSConstants.TYPE_TXT,
- DNSConstants.CLASS_IN,
- DNSConstants.DNS_TTL,
- info.text), 0);
- }
- }
- }
- if (out != null)
- {
- if (logger.isDebugEnabled())
- logger.debug("run() JmDNS announced");
- send(out);
- }
- else
- {
- // If we have nothing to send, another timer taskState ahead
- // of us has done the job for us. We can cancel.
- cancel();
- }
- }
- catch (Throwable e)
- {
- logger.warn( "run() exception ", e);
- recover();
- }
-
- taskState = taskState.advance();
- if (!taskState.isAnnounced())
- {
- cancel();
-
- }
- }
- }
-
- /**
- * The Responder sends a single answer for the specified service infos
- * and for the host name.
- */
- private class Responder extends TimerTask
- {
- private DNSIncoming in;
- private InetAddress addr;
- private int port;
-
- public Responder(DNSIncoming in, InetAddress addr, int port)
- {
- this.in = in;
- this.addr = addr;
- this.port = port;
- }
-
- public void start()
- {
- // According to draft-cheshire-dnsext-multicastdns.txt
- // chapter "8 Responding":
- // We respond immediately if we know for sure, that we are
- // the only one who can respond to the query.
- // In all other cases, we respond within 20-120 ms.
- //
- // According to draft-cheshire-dnsext-multicastdns.txt
- // chapter "7.2 Multi-Packet Known Answer Suppression":
- // We respond after 20-120 ms if the query is truncated.
-
- boolean iAmTheOnlyOne = true;
- for (DNSEntry entry : in.questions)
- {
- if (entry instanceof DNSQuestion)
- {
- DNSQuestion q = (DNSQuestion) entry;
- if (logger.isTraceEnabled())
- logger.trace("start() question=" + q);
- iAmTheOnlyOne &= (q.type == DNSConstants.TYPE_SRV
- || q.type == DNSConstants.TYPE_TXT
- || q.type == DNSConstants.TYPE_A
- || q.type == DNSConstants.TYPE_AAAA
- || localHost.getName().equalsIgnoreCase(q.name)
- || services.containsKey(q.name.toLowerCase()));
- if (!iAmTheOnlyOne)
- {
- break;
- }
- }
- }
- int delay = (iAmTheOnlyOne && !in.isTruncated()) ?
- 0 :
- DNSConstants.RESPONSE_MIN_WAIT_INTERVAL +
- random.nextInt(
- DNSConstants.RESPONSE_MAX_WAIT_INTERVAL -
- DNSConstants.RESPONSE_MIN_WAIT_INTERVAL + 1) -
- in.elapseSinceArrival();
- if (delay < 0)
- {
- delay = 0;
- }
- if (logger.isTraceEnabled())
- logger.trace("start() Responder chosen delay=" + delay);
- timer.schedule(this, delay);
- }
-
- @Override
- public void run()
- {
- synchronized (ioLock)
- {
- if (plannedAnswer == in)
- {
- plannedAnswer = null;
- }
-
- // We use these sets to prevent duplicate records
- // FIXME - This should be moved into DNSOutgoing
- HashSet<DNSQuestion> questions = new HashSet<DNSQuestion>();
- HashSet<DNSRecord> answers = new HashSet<DNSRecord>();
-
-
- if (state == DNSState.ANNOUNCED)
- {
- try
- {
- boolean isUnicast = (port != DNSConstants.MDNS_PORT);
-
-
- // Answer questions
- for (Iterator<DNSEntry> iterator = in.questions.iterator();
- iterator.hasNext();)
- {
- DNSEntry entry = iterator.next();
- if (entry instanceof DNSQuestion)
- {
- DNSQuestion q = (DNSQuestion) entry;
-
- // for unicast responses the question
- // must be included
- if (isUnicast)
- {
- //out.addQuestion(q);
- questions.add(q);
- }
-
- int type = q.type;
- if (type == DNSConstants.TYPE_ANY ||
- type == DNSConstants.TYPE_SRV)
- { // I ama not sure of why there is a special
- // case here [PJYF Oct 15 2004]
- if (localHost.getName().
- equalsIgnoreCase(q.getName()))
- {
- // type = DNSConstants.TYPE_A;
- DNSRecord answer =
- localHost.getDNS4AddressRecord();
- if (answer != null)
- {
- answers.add(answer);
- }
- answer = localHost.getDNS6AddressRecord();
- if (answer != null)
- {
- answers.add(answer);
- }
- type = DNSConstants.TYPE_IGNORE;
- }
- else
- {
- if (serviceTypes.containsKey(
- q.getName().toLowerCase()))
- {
- type = DNSConstants.TYPE_PTR;
- }
- }
- }
-
- switch (type)
- {
- case DNSConstants.TYPE_A:
- {
- // Answer a query for a domain name
- //out = addAnswer( in, addr, port, out, host );
- DNSRecord answer =
- localHost.getDNS4AddressRecord();
- if (answer != null)
- {
- answers.add(answer);
- }
- break;
- }
- case DNSConstants.TYPE_AAAA:
- {
- // Answer a query for a domain name
- DNSRecord answer =
- localHost.getDNS6AddressRecord();
- if (answer != null)
- {
- answers.add(answer);
- }
- break;
- }
- case DNSConstants.TYPE_PTR:
- {
- // Answer a query for services of a given type
-
- // find matching services
- for (Iterator<ServiceInfo> serviceIterator =
- services.values().iterator();
- serviceIterator.hasNext();)
- {
- ServiceInfo info = serviceIterator.next();
- if (info.getState() == DNSState.ANNOUNCED)
- {
- if (q.name.equalsIgnoreCase(info.type))
- {
- DNSRecord answer =
- localHost.getDNS4AddressRecord();
- if (answer != null)
- {
- answers.add(answer);
- }
- answer =
- localHost.getDNS6AddressRecord();
- if (answer != null)
- {
- answers.add(answer);
- }
- answers.add(
- new DNSRecord.Pointer(
- info.type,
- DNSConstants.TYPE_PTR,
- DNSConstants.CLASS_IN,
- DNSConstants.DNS_TTL,
- info.getQualifiedName()));
- answers.add(
- new DNSRecord.Service(
- info.getQualifiedName(),
- DNSConstants.TYPE_SRV,
- DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE,
- DNSConstants.DNS_TTL,
- info.priority,
- info.weight,
- info.port,
- localHost.getName()));
- answers.add(
- new DNSRecord.Text(
- info.getQualifiedName(),
- DNSConstants.TYPE_TXT,
- DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE,
- DNSConstants.DNS_TTL,
- info.text));
- }
- }
- }
- if (q.name.equalsIgnoreCase("_services._mdns._udp.local."))
- {
- for (Iterator<String> serviceTypeIterator = serviceTypes.values().iterator();
- serviceTypeIterator.hasNext();)
- {
- answers.add(
- new DNSRecord.Pointer(
- "_services._mdns._udp.local.",
- DNSConstants.TYPE_PTR,
- DNSConstants.CLASS_IN,
- DNSConstants.DNS_TTL,
- serviceTypeIterator.next()));
- }
- }
- break;
- }
- case DNSConstants.TYPE_SRV:
- case DNSConstants.TYPE_ANY:
- case DNSConstants.TYPE_TXT:
- {
- ServiceInfo info = services.get(q.name.toLowerCase());
- if (info != null &&
- info.getState() == DNSState.ANNOUNCED)
- {
- DNSRecord answer =
- localHost.getDNS4AddressRecord();
- if (answer != null)
- {
- answers.add(answer);
- }
- answer =
- localHost.getDNS6AddressRecord();
- if (answer != null)
- {
- answers.add(answer);
- }
- answers.add(
- new DNSRecord.Pointer(
- info.type,
- DNSConstants.TYPE_PTR,
- DNSConstants.CLASS_IN,
- DNSConstants.DNS_TTL,
- info.getQualifiedName()));
- answers.add(
- new DNSRecord.Service(
- info.getQualifiedName(),
- DNSConstants.TYPE_SRV,
- DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE,
- DNSConstants.DNS_TTL,
- info.priority,
- info.weight,
- info.port,
- localHost.getName()));
- answers.add(
- new DNSRecord.Text(
- info.getQualifiedName(),
- DNSConstants.TYPE_TXT,
- DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE,
- DNSConstants.DNS_TTL,
- info.text));
- }
- break;
- }
- default :
- {
- //System.out.println("JmDNSResponder.unhandled query:"+q);
- break;
- }
- }
- }
- }
-
-
- // remove known answers, if the ttl is at least half of
- // the correct value. (See Draft Cheshire chapter 7.1.).
- for (DNSRecord knownAnswer : in.answers)
- {
- if (knownAnswer.ttl > DNSConstants.DNS_TTL / 2 &&
- answers.remove(knownAnswer))
- {
- if (logger.isDebugEnabled())
- logger.debug(
- "JmDNS Responder Known Answer Removed");
- }
- }
-
-
- // responde if we have answers
- if (answers.size() != 0)
- {
- if (logger.isDebugEnabled())
- logger.debug("run() JmDNS responding");
- DNSOutgoing out = null;
- if (isUnicast)
- {
- out = new DNSOutgoing(
- DNSConstants.FLAGS_QR_RESPONSE
- | DNSConstants.FLAGS_AA,
- false);
- }
-
- for (Iterator<DNSQuestion> i = questions.iterator();
- i.hasNext();)
- {
- out.addQuestion(i.next());
- }
- for (Iterator<DNSRecord> i = answers.iterator();
- i.hasNext();)
- {
- out = addAnswer(in, addr, port, out, i.next());
- }
- send(out);
- }
- this.cancel();
- }
- catch (Throwable e)
- {
- logger.warn( "run() exception ", e);
- close();
- }
- }
- }
- }
- }
-
- /**
- * Helper class to resolve service types.
- * <p/>
- * The TypeResolver queries three times consecutively for service types, and then
- * removes itself from the timer.
- * <p/>
- * The TypeResolver will run only if JmDNS is in state ANNOUNCED.
- */
- private class TypeResolver extends TimerTask
- {
- public void start()
- {
- timer.schedule(this,
- DNSConstants.QUERY_WAIT_INTERVAL,
- DNSConstants.QUERY_WAIT_INTERVAL);
- }
-
- /**
- * Counts the number of queries that were sent.
- */
- int count = 0;
-
- @Override
- public void run()
- {
- try
- {
- if (state == DNSState.ANNOUNCED)
- {
- if (count++ < 3)
- {
- if (logger.isDebugEnabled())
- logger.debug("run() JmDNS querying type");
- DNSOutgoing out =
- new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY);
- out.addQuestion(
- new DNSQuestion(
- "_services._mdns._udp.local.",
- DNSConstants.TYPE_PTR,
- DNSConstants.CLASS_IN));
- for (String serviceType : serviceTypes.values())
- {
- out.addAnswer(
- new DNSRecord.Pointer(
- "_services._mdns._udp.local.",
- DNSConstants.TYPE_PTR,
- DNSConstants.CLASS_IN,
- DNSConstants.DNS_TTL,
- serviceType), 0);
- }
- send(out);
- }
- else
- {
- // After three queries, we can quit.
- this.cancel();
- }
- }
- else
- {
- if (state == DNSState.CANCELED)
- {
- this.cancel();
- }
- }
- }
- catch (Throwable e)
- {
- logger.warn( "run() exception ", e);
- recover();
- }
- }
- }
-
- /**
- * The ServiceResolver queries three times consecutively for services of
- * a given type, and then removes itself from the timer.
- * <p/>
- * The ServiceResolver will run only if JmDNS is in state ANNOUNCED.
- * REMIND: Prevent having multiple service resolvers for the same type in the
- * timer queue.
- */
- private class ServiceResolver extends TimerTask
- {
- /**
- * Counts the number of queries being sent.
- */
- int count = 0;
- private String type;
-
- public ServiceResolver(String type)
- {
- this.type = type;
- }
-
- public void start()
- {
- timer.schedule(this,
- DNSConstants.QUERY_WAIT_INTERVAL,
- DNSConstants.QUERY_WAIT_INTERVAL);
- }
-
- @Override
- public void run()
- {
- try
- {
- if (state == DNSState.ANNOUNCED)
- {
- if (count++ < 3)
- {
- if (logger.isDebugEnabled())
- logger.debug("run() JmDNS querying service");
- long now = System.currentTimeMillis();
- DNSOutgoing out =
- new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY);
- out.addQuestion(
- new DNSQuestion(
- type,
- DNSConstants.TYPE_PTR,
- DNSConstants.CLASS_IN));
- for (Iterator<ServiceInfo> s = services.values().iterator(); s.hasNext();)
- {
- final ServiceInfo info = s.next();
- try
- {
- out.addAnswer(
- new DNSRecord.Pointer(
- info.type,
- DNSConstants.TYPE_PTR,
- DNSConstants.CLASS_IN,
- DNSConstants.DNS_TTL,
- info.getQualifiedName()), now);
- }
- catch (IOException ee)
- {
- break;
- }
- }
- send(out);
- }
- else
- {
- // After three queries, we can quit.
- this.cancel();
- }
- }
- else
- {
- if (state == DNSState.CANCELED)
- {
- this.cancel();
- }
- }
- }
- catch (Throwable e)
- {
- logger.warn( "run() exception ", e);
- recover();
- }
- }
- }
-
- /**
- * The ServiceInfoResolver queries up to three times consecutively for
- * a service info, and then removes itself from the timer.
- * <p/>
- * The ServiceInfoResolver will run only if JmDNS is in state ANNOUNCED.
- * REMIND: Prevent having multiple service resolvers for the same info in the
- * timer queue.
- */
- private class ServiceInfoResolver extends TimerTask
- {
- /**
- * Counts the number of queries being sent.
- */
- int count = 0;
- private ServiceInfo info;
-
- public ServiceInfoResolver(ServiceInfo info)
- {
- this.info = info;
- info.dns = JmDNS.this;
- addListener(info,
- new DNSQuestion(
- info.getQualifiedName(),
- DNSConstants.TYPE_ANY,
- DNSConstants.CLASS_IN));
- }
-
- public void start()
- {
- timer.schedule(this,
- DNSConstants.QUERY_WAIT_INTERVAL,
- DNSConstants.QUERY_WAIT_INTERVAL);
- }
-
- @Override
- public void run()
- {
- try
- {
- if (state == DNSState.ANNOUNCED)
- {
- if (count++ < 3 && !info.hasData())
- {
- long now = System.currentTimeMillis();
- DNSOutgoing out =
- new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY);
- out.addQuestion(
- new DNSQuestion(
- info.getQualifiedName(),
- DNSConstants.TYPE_SRV,
- DNSConstants.CLASS_IN));
- out.addQuestion(
- new DNSQuestion(
- info.getQualifiedName(),
- DNSConstants.TYPE_TXT,
- DNSConstants.CLASS_IN));
- if (info.server != null)
- {
- out.addQuestion(
- new DNSQuestion(
- info.server,
- DNSConstants.TYPE_A,
- DNSConstants.CLASS_IN));
- }
- out.addAnswer((DNSRecord) cache.get(
- info.getQualifiedName(),
- DNSConstants.TYPE_SRV,
- DNSConstants.CLASS_IN), now);
- out.addAnswer((DNSRecord) cache.get(
- info.getQualifiedName(),
- DNSConstants.TYPE_TXT,
- DNSConstants.CLASS_IN), now);
- if (info.server != null)
- {
- out.addAnswer((DNSRecord) cache.get(
- info.server,
- DNSConstants.TYPE_A,
- DNSConstants.CLASS_IN), now);
- }
- send(out);
- }
- else
- {
- // After three queries, we can quit.
- this.cancel();
- removeListener(info);
- }
- }
- else
- {
- if (state == DNSState.CANCELED)
- {
- this.cancel();
- removeListener(info);
- }
- }
- }
- catch (Throwable e)
- {
- logger.warn( "run() exception ", e);
- recover();
- }
- }
- }
-
- /**
- * The Canceler sends two announces with TTL=0 for the specified services.
- */
- /* TODO: Clarify whether 2 or 3 announces should be sent. The header says 2,
- * run() uses the (misleading) ++count < 3 (while all other tasks use count++ < 3)
- * and the comment in the else block in run() says: "After three successful..."
- */
- public class Canceler extends TimerTask
- {
- /**
- * Counts the number of announces being sent.
- */
- int count = 0;
- /**
- * The services that need cancelling.
- * Note: We have to use a local variable here, because the services
- * that are canceled, are removed immediately from variable JmDNS.services.
- */
- private ServiceInfo[] infos;
- /**
- * We call notifyAll() on the lock object, when we have canceled the
- * service infos.
- * This is used by method JmDNS.unregisterService() and
- * JmDNS.unregisterAllServices, to ensure that the JmDNS
- * socket stays open until the Canceler has canceled all services.
- * <p/>
- * Note: We need this lock, because ServiceInfos do the transition from
- * state ANNOUNCED to state CANCELED before we get here. We could get
- * rid of this lock, if we added a state named CANCELLING to DNSState.
- */
- private Object lock;
- int ttl = 0;
-
- public Canceler(ServiceInfo info, Object lock)
- {
- this.infos = new ServiceInfo[]{info};
- this.lock = lock;
- addListener(info,
- new DNSQuestion(
- info.getQualifiedName(),
- DNSConstants.TYPE_ANY,
- DNSConstants.CLASS_IN));
- }
-
- public Canceler(ServiceInfo[] infos, Object lock)
- {
- this.infos = infos;
- this.lock = lock;
- }
-
- public Canceler(Collection<ServiceInfo> infos, Object lock)
- {
- this.infos = infos.toArray(new ServiceInfo[infos.size()]);
- this.lock = lock;
- }
-
- public void start()
- {
- timer.schedule(this, 0, DNSConstants.ANNOUNCE_WAIT_INTERVAL);
- }
-
- @Override
- public void run()
- {
- try
- {
- if (++count < 3)
- {
- if (logger.isDebugEnabled())
- logger.debug("run() JmDNS canceling service");
- // announce the service
- //long now = System.currentTimeMillis();
- DNSOutgoing out =
- new DNSOutgoing(
- DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA);
- for (int i = 0; i < infos.length; i++)
- {
- ServiceInfo info = infos[i];
- out.addAnswer(
- new DNSRecord.Pointer(
- info.type,
- DNSConstants.TYPE_PTR,
- DNSConstants.CLASS_IN,
- ttl,
- info.getQualifiedName()), 0);
- out.addAnswer(
- new DNSRecord.Service(
- info.getQualifiedName(),
- DNSConstants.TYPE_SRV,
- DNSConstants.CLASS_IN,
- ttl,
- info.priority,
- info.weight,
- info.port,
- localHost.getName()), 0);
- out.addAnswer(
- new DNSRecord.Text(
- info.getQualifiedName(),
- DNSConstants.TYPE_TXT,
- DNSConstants.CLASS_IN,
- ttl,
- info.text), 0);
- DNSRecord answer = localHost.getDNS4AddressRecord();
- if (answer != null)
- {
- out.addAnswer(answer, 0);
- }
- answer = localHost.getDNS6AddressRecord();
- if (answer != null)
- {
- out.addAnswer(answer, 0);
- }
- }
- send(out);
- }
- else
- {
- // After three successful announcements, we are finished.
- synchronized (lock)
- {
- closed=true;
- lock.notifyAll();
- }
- this.cancel();
- }
- }
- catch (Throwable e)
- {
- logger.warn( "run() exception ", e);
- recover();
- }
- }
- }
-
- /**
- * Recover jmdns when there is an error.
- */
- protected void recover()
- {
- if (logger.isDebugEnabled())
- logger.debug("recover()");
- // We have an IO error so lets try to recover if anything happens lets close it.
- // This should cover the case of the IP address changing under our feet
- if (DNSState.CANCELED != state)
- {
- synchronized (this)
- { // Synchronize only if we are not already in process to prevent dead locks
- //
- if (logger.isDebugEnabled())
- logger.debug("recover() Cleanning up");
- // Stop JmDNS
- state = DNSState.CANCELED; // This protects against recursive calls
-
- // We need to keep a copy for reregistration
- Collection<ServiceInfo> oldServiceInfos = new ArrayList<ServiceInfo>(services.values());
-
- // Cancel all services
- unregisterAllServices();
- disposeServiceCollectors();
- //
- // close multicast socket
- closeMulticastSocket();
- //
- cache.clear();
- if (logger.isDebugEnabled())
- logger.debug("recover() All is clean");
- //
- // All is clear now start the services
- //
- try
- {
- openMulticastSocket(localHost);
- start(oldServiceInfos);
- }
- catch (Exception exception)
- {
- logger.warn(
- "recover() Start services exception ", exception);
- }
- logger.warn( "recover() We are back!");
- }
- }
- }
-
- /**
- * Close down jmdns. Release all resources and unregister all services.
- */
- public void close()
- {
- if (state != DNSState.CANCELED)
- {
- synchronized (this)
- { // Synchronize only if we are not already in process to prevent dead locks
- // Stop JmDNS
- state = DNSState.CANCELED; // This protects against recursive calls
-
- unregisterAllServices();
- disposeServiceCollectors();
-
- // close socket
- closeMulticastSocket();
-
- // Stop the timer
- timer.cancel();
- }
- }
- }
-
- /**
- * List cache entries, for debugging only.
- */
- void print()
- {
- if (logger.isInfoEnabled())
- logger.info("---- cache ----\n");
- cache.print();
- if (logger.isInfoEnabled())
- logger.info("\n");
- }
-
- /**
- * List Services and serviceTypes.
- * Debugging Only
- */
-
- public void printServices()
- {
- if (logger.isInfoEnabled())
- logger.info(toString());
- }
-
- @Override
- public String toString()
- {
- StringBuffer aLog = new StringBuffer();
- aLog.append("\t---- Services -----");
- if (services != null)
- {
- for (Map.Entry<String, ServiceInfo> entry : services.entrySet())
- {
- aLog.append("\n\t\tService: " + entry.getKey() + ": "
- + entry.getValue());
- }
- }
- aLog.append("\n");
- aLog.append("\t---- Types ----");
- if (serviceTypes != null)
- {
- for (Map.Entry<String, String> entry : serviceTypes.entrySet())
- {
- aLog.append("\n\t\tType: " + entry.getKey() + ": "
- + entry.getValue());
- }
- }
- aLog.append("\n");
- aLog.append(cache.toString());
- aLog.append("\n");
- aLog.append("\t---- Service Collectors ----");
- if (serviceCollectors != null)
- {
- synchronized (serviceCollectors)
- {
- for (Map.Entry<String, ServiceCollector> entry
- : serviceCollectors.entrySet())
- {
- aLog.append("\n\t\tService Collector: " + entry.getKey()
- + ": " + entry.getValue());
- }
- serviceCollectors.clear();
- }
- }
- return aLog.toString();
- }
-
- /**
- * Returns a list of service infos of the specified type.
- *
- * @param type Service type name, such as <code>_http._tcp.local.</code>.
- * @return An array of service instance names.
- */
- public ServiceInfo[] list(String type)
- {
- // Implementation note: The first time a list for a given type is
- // requested, a ServiceCollector is created which collects service
- // infos. This greatly speeds up the performance of subsequent calls
- // to this method. The caveats are, that 1) the first call to this method
- // for a given type is slow, and 2) we spawn a ServiceCollector
- // instance for each service type which increases network traffic a
- // little.
-
- ServiceCollector collector;
-
- boolean newCollectorCreated;
- synchronized (serviceCollectors)
- {
- collector = serviceCollectors.get(type);
- if (collector == null)
- {
- collector = new ServiceCollector(type);
- serviceCollectors.put(type, collector);
- addServiceListener(type, collector);
- newCollectorCreated = true;
- }
- else
- {
- newCollectorCreated = false;
- }
- }
-
- // After creating a new ServiceCollector, we collect service infos for
- // 200 milliseconds. This should be enough time, to get some service
- // infos from the network.
- if (newCollectorCreated)
- {
- try
- {
- Thread.sleep(200);
- }
- catch (InterruptedException e)
- {
- }
- }
-
- return collector.list();
- }
-
- /**
- * This method disposes all ServiceCollector instances which have been
- * created by calls to method <code>list(type)</code>.
- *
- * @see #list
- */
- private void disposeServiceCollectors()
- {
- if (logger.isDebugEnabled())
- logger.debug("disposeServiceCollectors()");
- synchronized (serviceCollectors)
- {
- for (Iterator<ServiceCollector> i = serviceCollectors.values().iterator(); i.hasNext();)
- {
- ServiceCollector collector = i.next();
- removeServiceListener(collector.type, collector);
- }
- serviceCollectors.clear();
- }
- }
-
- /**
- * Instances of ServiceCollector are used internally to speed up the
- * performance of method <code>list(type)</code>.
- *
- * @see #list
- */
- private static class ServiceCollector implements ServiceListener
- {
-
- /**
- * A set of collected service instance names.
- */
- private Map<String, ServiceInfo> infos = Collections.synchronizedMap(new HashMap<String, ServiceInfo>());
-
- public String type;
-
- public ServiceCollector(String type)
- {
- this.type = type;
- }
-
- /**
- * A service has been added.
- */
- public void serviceAdded(ServiceEvent event)
- {
- synchronized (infos)
- {
- event.getDNS().requestServiceInfo(
- event.getType(), event.getName(), 0);
- }
- }
-
- /**
- * A service has been removed.
- */
- public void serviceRemoved(ServiceEvent event)
- {
- synchronized (infos)
- {
- infos.remove(event.getName());
- }
- }
-
- /**
- * A service hase been resolved. Its details are now available in the
- * ServiceInfo record.
- */
- public void serviceResolved(ServiceEvent event)
- {
- synchronized (infos)
- {
- infos.put(event.getName(), event.getInfo());
- }
- }
-
- /**
- * Returns an array of all service infos which have been collected by this
- * ServiceCollector.
- * @return
- */
- public ServiceInfo[] list()
- {
- synchronized (infos)
- {
- return infos.values().
- toArray(new ServiceInfo[infos.size()]);
- }
- }
-
- @Override
- public String toString()
- {
- StringBuffer aLog = new StringBuffer();
- synchronized (infos)
- {
- for (Map.Entry<String, ServiceInfo> entry : infos.entrySet())
- {
- aLog.append("\n\t\tService: " + entry.getKey() + ": "
- + entry.getValue());
- }
- }
- return aLog.toString();
- }
- };
-
- private static String toUnqualifiedName(String type, String qualifiedName)
- {
- if (qualifiedName.endsWith(type))
- {
- return qualifiedName.substring(0,
- qualifiedName.length() - type.length() - 1);
- }
- else
- {
- return qualifiedName;
- }
- }
-
- /**
- * SC-Bonjour Implementation : Method used to update the corresponding DNS
- * entry in the cache of JmDNS with the new information in this ServiceInfo.
- * A call to getLocalService must first be issued to get the
- * ServiceInfo object to be modified.
- * THIS METHOD MUST BE USED INSTEAD OF ANY DIRECT ACCESS TO JMDNS' CACHE!!
- * This is used in the implementation of Zeroconf in SIP Communicator
- * to be able to change fields declared by the local contact (status, etc).
- * @param info Updated service data to be used to replace the old
- * stuff contained in JmDNS' cache
- * @param old info bytes
- */
- public void updateInfos(ServiceInfo info, byte[] old)
- {
-
- DNSOutgoing out, out2;
- synchronized (JmDNS.this)
- {
- //list = new ArrayList(services.values());
- services.put(info.getQualifiedName().toLowerCase(), info);
- }
-
- synchronized (info)
- {
- if (logger.isDebugEnabled())
- logger.debug("updateInfos() JmDNS updating " +
- info.getQualifiedName() + " state " +
- info.getState());
-
- out = new DNSOutgoing(
- /*DNSConstants.FLAGS_QR_RESPONSE*/
- DNSConstants.FLAGS_RA | DNSConstants.FLAGS_AA);
- out2 = new DNSOutgoing(
- /*DNSConstants.FLAGS_QR_RESPONSE*/
- DNSConstants.FLAGS_RA | DNSConstants.FLAGS_AA);
-
-
- try
- {
- //out.addAnswer(new DNSRecord.Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.getQualifiedName()), 0);
- //out.addAnswer(new DNSRecord.Service(info.getQualifiedName(), DNSConstants.TYPE_A, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, localHost.getName()), 0);
- //out.addAnswer(new DNSRecord.Service(info.getQualifiedName(), DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, localHost.getName()), 0);
-// out.addAnswer(
-// new DNSRecord.Text(
-// info.getQualifiedName(),
-// DNSConstants.TYPE_TXT,
-// DNSConstants.CLASS_IN ,
-// DNSConstants.DNS_TTL,
-// info.text), 0);
- out.addAnswer(
- new DNSRecord.Text(
- info.getQualifiedName(),
- DNSConstants.TYPE_TXT,
- DNSConstants.CLASS_IN ,
- 0,
- old), 0);
- out.addAnswer(
- new DNSRecord.Text(
- info.getQualifiedName(),
- DNSConstants.TYPE_TXT,
- DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE,
- DNSConstants.DNS_TTL,
- info.text), 0);
-
- out2.addAnswer(
- new DNSRecord.Text(
- info.getQualifiedName(),
- DNSConstants.TYPE_TXT,
- DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE,
- DNSConstants.DNS_TTL,
- info.text), 0);
-
- if (logger.isDebugEnabled())
- logger.debug("updateInfos() JmDNS updated infos for "+info);
-
- send(out);
- Thread.sleep(1000);
- send(out2);
- Thread.sleep(2000);
- send(out2);
- }
- catch( Exception e)
- {
- logger.warn( "", e);
- }
- }
- }
-
-
- /**
- * SC-Bonjour Implementation: Method to retrieve the DNS Entry corresponding to a service
- * that has been declared and return it as a ServiceInfo structure.
- * It is used in the implementation of Bonjour in SIP Communicator to retrieve the information
- * concerning the service declared by the local contact. THIS METHOD MUST BE USED INSTEAD OF ANY
- * LOCAL COPY SAVED BEFORE SERVICE REGISTRATION!!
- * @return information corresponding to the specified service
- * @param FQN String representing the Fully Qualified name of the service we want info about
- */
- public ServiceInfo getLocalService(String FQN)
- {
- return services.get(FQN);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/ServiceEvent.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/ServiceEvent.java
deleted file mode 100644
index ff922d1..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/ServiceEvent.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright 2003-2005 Arthur van Hoff Rick Blair
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf.jmdns;
-
-import java.util.*;
-import java.util.logging.*;
-
-/**
- * ServiceEvent.
- *
- * @author Werner Randelshofer, Rick Blair
- * @version %I%, %G%
- */
-public class ServiceEvent
- extends EventObject
-{
- private static Logger logger =
- Logger.getLogger(ServiceEvent.class.toString());
- /**
- * The type name of the service.
- */
- private String type;
- /**
- * The instance name of the service. Or null, if the event was
- * fired to a service type listener.
- */
- private String name;
- /**
- * The service info record, or null if the service could be be resolved.
- * This is also null, if the event was fired to a service type listener.
- */
- private ServiceInfo info;
-
- /**
- * Creates a new instance.
- *
- * @param source the JmDNS instance which originated the event.
- * @param type the type name of the service.
- * @param name the instance name of the service.
- * @param info the service info record, or null if the
- * service could be be resolved.
- */
- public ServiceEvent(JmDNS source, String type, String name, ServiceInfo info)
- {
- super(source);
- this.type = type;
- this.name = name;
- this.info = info;
-
- String SLevel = System.getProperty("jmdns.debug");
- if (SLevel == null) SLevel = "INFO";
- logger.setLevel(Level.parse(SLevel));
- }
-
- /**
- * Returns the JmDNS instance which originated the event.
- * @return Returns the JmDNS instance which originated the event.
- */
- public JmDNS getDNS()
- {
- return (JmDNS) getSource();
- }
-
- /**
- * Returns the fully qualified type of the service.
- * @return Returns the fully qualified type of the service.
- */
- public String getType()
- {
- return type;
- }
-
- /**
- * Returns the instance name of the service.
- * Always returns null, if the event is sent to a service type listener.
- * @return Returns the instance name of the service.
- */
- public String getName()
- {
- return name;
- }
-
- /**
- * Returns the service info record, or null if the service could not be
- * resolved.
- * Always returns null, if the event is sent to a service type listener.
- * @return Returns the service info record.
- */
- public ServiceInfo getInfo()
- {
- return info;
- }
-
- @Override
- public String toString()
- {
- StringBuffer buf = new StringBuffer();
- buf.append("<" + getClass().getName() + "> ");
- buf.append(super.toString());
- buf.append(" name ");
- buf.append(getName());
- buf.append(" type ");
- buf.append(getType());
- buf.append(" info ");
- buf.append(getInfo());
- return buf.toString();
- }
-
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/ServiceInfo.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/ServiceInfo.java
deleted file mode 100644
index b7f7f2d..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/ServiceInfo.java
+++ /dev/null
@@ -1,785 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright 2003-2005 Arthur van Hoff Rick Blair
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf.jmdns;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import java.util.logging.*;
-
-/**
- * JmDNS service information.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer
- * @author Christian Vincenot
- */
-public class ServiceInfo implements DNSListener
-{
- private static Logger logger =
- Logger.getLogger(ServiceInfo.class.toString());
- public final static byte[] NO_VALUE = new byte[0];
- JmDNS dns;
-
- // State machine
- /**
- * The state of this service info.
- * This is used only for services announced by JmDNS.
- * <p/>
- * For proper handling of concurrency, this variable must be
- * changed only using methods advanceState(), revertState() and cancel().
- */
- private DNSState state = DNSState.PROBING_1;
-
- /**
- * Task associated to this service info.
- * Possible tasks are JmDNS.Prober, JmDNS.Announcer, JmDNS.Responder,
- * JmDNS.Canceler.
- */
- TimerTask task;
-
- String type;
- private String name;
- String server;
- int port;
- int weight;
- int priority;
- byte text[];
- private Map<String, Object> props;
- InetAddress addr;
-
-
- /**
- * Construct a service description for registrating with JmDNS.
- *
- * @param type fully qualified service type name,
- * such as <code>_http._tcp.local.</code>.
- * @param name unqualified service instance name,
- * such as <code>foobar</code>
- * @param port the local port on which the service runs
- * @param text string describing the service
- */
- public ServiceInfo(String type, String name, int port, String text)
- {
- this(type, name, port, 0, 0, text);
- }
-
- /**
- * Construct a service description for registrating with JmDNS.
- *
- * @param type fully qualified service type name,
- * such as <code>_http._tcp.local.</code>.
- * @param name unqualified service instance name,
- * such as <code>foobar</code>
- * @param port the local port on which the service runs
- * @param weight weight of the service
- * @param priority priority of the service
- * @param text string describing the service
- */
- public ServiceInfo(String type, String name,
- int port, int weight,
- int priority, String text)
- {
- this(type, name, port, weight, priority, (byte[]) null);
- try
- {
- ByteArrayOutputStream out = new ByteArrayOutputStream(text.length());
- writeUTF(out, text);
- this.text = out.toByteArray();
- }
- catch (IOException e)
- {
- throw new RuntimeException("unexpected exception: " + e);
- }
- }
-
- /**
- * Construct a service description for registrating with JmDNS. The properties hashtable must
- * map property names to either Strings or byte arrays describing the property values.
- *
- * @param type fully qualified service type name, such as <code>_http._tcp.local.</code>.
- * @param name unqualified service instance name, such as <code>foobar</code>
- * @param port the local port on which the service runs
- * @param weight weight of the service
- * @param priority priority of the service
- * @param props properties describing the service
- */
- public ServiceInfo(String type, String name,
- int port, int weight,
- int priority, Map<String, Object> props)
- {
- this(type, name, port, weight, priority, new byte[0]);
- if (props != null)
- {
- try
- {
- ByteArrayOutputStream out = new ByteArrayOutputStream(256);
- for (Map.Entry<String, Object> prop : props.entrySet())
- {
- String key = prop.getKey();
- Object val = prop.getValue();
- ByteArrayOutputStream out2 = new ByteArrayOutputStream(100);
- writeUTF(out2, key);
- if (val instanceof String)
- {
- out2.write('=');
- writeUTF(out2, (String) val);
- }
- else
- {
- if (val instanceof byte[])
- {
- out2.write('=');
- byte[] bval = (byte[]) val;
- out2.write(bval, 0, bval.length);
- }
- else
- {
- if (val != NO_VALUE)
- {
- throw new IllegalArgumentException(
- "invalid property value: " + val);
- }
- }
- }
- byte data[] = out2.toByteArray();
- out.write(data.length);
- out.write(data, 0, data.length);
- }
- this.text = out.toByteArray();
- }
- catch (IOException e)
- {
- throw new RuntimeException("unexpected exception: " + e);
- }
- }
- }
-
- /**
- * Construct a service description for registrating with JmDNS.
- *
- * @param type fully qualified service type name,
- * such as <code>_http._tcp.local.</code>.
- * @param name unqualified service instance name,
- * such as <code>foobar</code>
- * @param port the local port on which the service runs
- * @param weight weight of the service
- * @param priority priority of the service
- * @param text bytes describing the service
- */
- public ServiceInfo(String type, String name,
- int port, int weight,
- int priority, byte text[])
- {
- this.type = type;
- this.name = name;
- this.port = port;
- this.weight = weight;
- this.priority = priority;
- this.text = text;
-
- String SLevel = System.getProperty("jmdns.debug");
- if (SLevel == null) SLevel = "INFO";
- logger.setLevel(Level.parse(SLevel));
- }
-
- /**
- * Construct a service record during service discovery.
- */
- ServiceInfo(String type, String name)
- {
- if (!type.endsWith("."))
- {
- throw new IllegalArgumentException(
- "type must be fully qualified DNS name ending in '.': " + type);
- }
-
- this.type = type;
- this.name = name;
- }
-
- /**
- * During recovery we need to duplicate service info to reregister them
- */
- ServiceInfo(ServiceInfo info)
- {
- if (info != null)
- {
- this.type = info.type;
- this.name = info.name;
- this.port = info.port;
- this.weight = info.weight;
- this.priority = info.priority;
- this.text = info.text;
- }
- }
-
- /**
- * Fully qualified service type name,
- * such as <code>_http._tcp.local.</code> .
- * @return Returns fully qualified service type name.
- */
- public String getType()
- {
- return type;
- }
-
- /**
- * Unqualified service instance name,
- * such as <code>foobar</code> .
- * @return Returns unqualified service instance name.
- */
- public String getName()
- {
- return name;
- }
-
- /**
- * Sets the service instance name.
- *
- * @param name unqualified service instance name,
- * such as <code>foobar</code>
- */
- void setName(String name)
- {
- this.name = name;
- }
-
- /**
- * Fully qualified service name,
- * such as <code>foobar._http._tcp.local.</code> .
- * @return Returns fully qualified service name.
- */
- public String getQualifiedName()
- {
- return name + "." + type;
- }
-
- /**
- * Get the name of the server.
- * @return Returns name of the server.
- */
- public String getServer()
- {
- return server;
- }
-
- /**
- * Get the host address of the service (ie X.X.X.X).
- * @return Returns host address of the service.
- */
- public String getHostAddress()
- {
- return (addr != null ? addr.getHostAddress() : "");
- }
-
- public InetAddress getAddress()
- {
- return addr;
- }
-
- /**
- * Get the InetAddress of the service.
- * @return Returns the InetAddress of the service.
- */
- public InetAddress getInetAddress()
- {
- return addr;
- }
-
- /**
- * Get the port for the service.
- * @return Returns port for the service.
- */
- public int getPort()
- {
- return port;
- }
-
- /**
- * Get the priority of the service.
- * @return Returns the priority of the service.
- */
- public int getPriority()
- {
- return priority;
- }
-
- /**
- * Get the weight of the service.
- * @return Returns the weight of the service.
- */
- public int getWeight()
- {
- return weight;
- }
-
- /**
- * Get the text for the serivce as raw bytes.
- * @return Returns the text for the serivce as raw bytes.
- */
- public byte[] getTextBytes()
- {
- return text;
- }
-
- /**
- * Get the text for the service. This will interpret the text bytes
- * as a UTF8 encoded string. Will return null if the bytes are not
- * a valid UTF8 encoded string.
- * @return Returns the text for the service.
- */
- public String getTextString()
- {
- if ((text == null) ||
- (text.length == 0) ||
- ((text.length == 1) && (text[0] == 0)))
- {
- return null;
- }
- return readUTF(text, 0, text.length);
- }
-
- /**
- * Get the URL for this service. An http URL is created by
- * combining the address, port, and path properties.
- * @return Returns the URL for this service.
- */
- public String getURL()
- {
- return getURL("http");
- }
-
- /**
- * Get the URL for this service. An URL is created by
- * combining the protocol, address, port, and path properties.
- * @param protocol
- * @return Returns URL for this service.
- */
- public String getURL(String protocol)
- {
- String url = protocol + "://" + getHostAddress() + ":" + getPort();
- String path = getPropertyString("path");
- if (path != null)
- {
- if (path.indexOf("://") >= 0)
- {
- url = path;
- }
- else
- {
- url += path.startsWith("/") ? path : "/" + path;
- }
- }
- return url;
- }
-
- /**
- * Get a property of the service. This involves decoding the
- * text bytes into a property list. Returns null if the property
- * is not found or the text data could not be decoded correctly.
- * @param name
- * @return Returns property of the service as bytes.
- */
- public synchronized byte[] getPropertyBytes(String name)
- {
- return (byte[]) getProperties().get(name);
- }
-
- /**
- * Get a property of the service. This involves decoding the
- * text bytes into a property list. Returns null if the property
- * is not found, the text data could not be decoded correctly, or
- * the resulting bytes are not a valid UTF8 string.
- * @param name
- * @return Returns property of the service as string.
- */
- public synchronized String getPropertyString(String name)
- {
- byte data[] = (byte[]) getProperties().get(name);
-
- if (data == null)
- {
- return null;
- }
- if (data == NO_VALUE)
- {
- return "true";
- }
- String res = readUTF(data, 0, data.length);
-
- return res;
- }
-
- /**
- * Iterator<String> of the property names.
- * @return Iterator<String> of the property names.
- */
- public Iterator<String> getPropertyNames()
- {
- Map<String, Object> properties = getProperties();
- Iterable<String> propertyNames
- = (properties != null) ? properties.keySet() : new Vector<String>();
- return propertyNames.iterator();
- }
-
- /**
- * Write a UTF string with a length to a stream.
- */
- void writeUTF(OutputStream out, String str) throws IOException
- {
- for (int i = 0, len = str.length(); i < len; i++)
- {
- int c = str.charAt(i);
- if ((c >= 0x0001) && (c <= 0x007F))
- {
- out.write(c);
- }
- else
- {
- if (c > 0x07FF)
- {
- out.write(0xE0 | ((c >> 12) & 0x0F));
- out.write(0x80 | ((c >> 6) & 0x3F));
- out.write(0x80 | ((c >> 0) & 0x3F));
- }
- else
- {
- out.write(0xC0 | ((c >> 6) & 0x1F));
- out.write(0x80 | ((c >> 0) & 0x3F));
- }
- }
- }
- }
-
- /**
- * Read data bytes as a UTF stream.
- */
- String readUTF(byte data[], int off, int len)
- {
- StringBuffer buf = new StringBuffer();
- for (int end = off + len; off < end;)
- {
- int ch = data[off++] & 0xFF;
- switch (ch >> 4)
- {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- // 0xxxxxxx
- break;
- case 12:
- case 13:
- if (off >= len)
- {
- return null;
- }
- // 110x xxxx 10xx xxxx
- ch = ((ch & 0x1F) << 6) | (data[off++] & 0x3F);
- break;
- case 14:
- if (off + 2 >= len)
- {
- return null;
- }
- // 1110 xxxx 10xx xxxx 10xx xxxx
- ch = ((ch & 0x0f) << 12) |
- ((data[off++] & 0x3F) << 6) |
- (data[off++] & 0x3F);
- break;
- default:
- if (off + 1 >= len)
- {
- return null;
- }
- // 10xx xxxx, 1111 xxxx
- ch = ((ch & 0x3F) << 4) | (data[off++] & 0x0f);
- break;
- }
- buf.append((char) ch);
- }
- return buf.toString();
- }
-
- synchronized Map<String, Object> getProperties()
- {
- if ((props == null) && (text != null))
- {
- Map<String, Object> props = new Hashtable<String, Object>();
- int off = 0;
- while (off < text.length)
- {
- // length of the next key value pair
- int len = text[off++] & 0xFF;
- if ((len == 0) || (off + len > text.length))
- {
- props.clear();
- break;
- }
- // look for the '='
- int i = 0;
- for (; (i < len) && (text[off + i] != '='); i++)
- {
- ;
- }
-
- // get the property name
- String name = readUTF(text, off, i);
- if (name == null)
- {
- props.clear();
- break;
- }
- if (i == len)
- {
- props.put(name, NO_VALUE);
- }
- else
- {
- byte value[] = new byte[len - ++i];
- System.arraycopy(text, off + i, value, 0, len - i);
- props.put(name, value);
- off += len;
- }
- }
- this.props = props;
- }
- return props;
- }
-
-
- /**
- * JmDNS callback to update a DNS record.
- * @param rec
- */
- public void updateRecord(JmDNS jmdns, long now, DNSRecord rec)
- {
- if ((rec != null) && !rec.isExpired(now))
- {
- switch (rec.type)
- {
- case DNSConstants.TYPE_A: // IPv4
- case DNSConstants.TYPE_AAAA: // IPv6 FIXME [PJYF Oct 14 2004] This has not been tested
- if (rec.name.equals(server))
- {
- addr = ((DNSRecord.Address) rec).getAddress();
-
- }
- break;
- case DNSConstants.TYPE_SRV:
- if (rec.name.equals(getQualifiedName()))
- {
- DNSRecord.Service srv = (DNSRecord.Service) rec;
- server = srv.server;
- port = srv.port;
- weight = srv.weight;
- priority = srv.priority;
- addr = null;
- // changed to use getCache() instead - jeffs
- // updateRecord(jmdns, now, (DNSRecord)jmdns.cache.get(server, TYPE_A, CLASS_IN));
- updateRecord(jmdns,
- now,
- (DNSRecord) jmdns.getCache().get(
- server,
- DNSConstants.TYPE_A,
- DNSConstants.CLASS_IN));
- }
- break;
- case DNSConstants.TYPE_TXT:
- if (rec.name.equals(getQualifiedName()))
- {
- DNSRecord.Text txt = (DNSRecord.Text) rec;
- text = txt.text;
- }
- break;
- }
- // Future Design Pattern
- // This is done, to notify the wait loop in method
- // JmDNS.getServiceInfo(type, name, timeout);
- if (hasData() && dns != null)
- {
- dns.handleServiceResolved(this);
- dns = null;
- }
- synchronized (this)
- {
- notifyAll();
- }
- }
- }
-
- /**
- * Returns true if the service info is filled with data.
- */
- boolean hasData()
- {
- return server != null && addr != null && text != null;
- }
-
-
- // State machine
- /**
- * Sets the state and notifies all objects that wait on the ServiceInfo.
- */
- synchronized void advanceState()
- {
- state = state.advance();
- notifyAll();
- }
-
- /**
- * Sets the state and notifies all objects that wait on the ServiceInfo.
- */
- synchronized void revertState()
- {
- state = state.revert();
- notifyAll();
- }
-
- /**
- * Sets the state and notifies all objects that wait on the ServiceInfo.
- */
- synchronized void cancel()
- {
- state = DNSState.CANCELED;
- notifyAll();
- }
-
- /**
- * Returns the current state of this info.
- */
- DNSState getState()
- {
- return state;
- }
-
-
- @Override
- public int hashCode()
- {
- return getQualifiedName().hashCode();
- }
-
- @Override
- public boolean equals(Object obj)
- {
- return (obj instanceof ServiceInfo) &&
- getQualifiedName().equals(((ServiceInfo) obj).getQualifiedName());
- }
-
- public String getNiceTextString()
- {
- StringBuffer buf = new StringBuffer();
- for (int i = 0, len = text.length; i < len; i++)
- {
- if (i >= 20)
- {
- buf.append("...");
- break;
- }
- int ch = text[i] & 0xFF;
- if ((ch < ' ') || (ch > 127))
- {
- buf.append("\\0");
- buf.append(Integer.toString(ch, 8));
- }
- else
- {
- buf.append((char) ch);
- }
- }
- return buf.toString();
- }
-
- @Override
- public String toString()
- {
- StringBuffer buf = new StringBuffer();
- buf.append("service[");
- buf.append(getQualifiedName());
- buf.append(',');
- buf.append(getAddress());
- buf.append(':');
- buf.append(port);
- buf.append(',');
- buf.append(getNiceTextString());
- buf.append(']');
- return buf.toString();
- }
-
- /**
- * SC-Bonjour Implementation: Method used to set the properties of an existing ServiceInfo.
- * This is used in the implementation of Bonjour in SIP Communicator to be able to replace
- * old properties of the service we've declared to announce the local user with new properties
- * (for example in case of a status change).
- * @param props Hashtable containing all the new properties to set
- */
- public void setProps(Map<String, Object> props)
- {
- if (props != null)
- {
- try
- {
- ByteArrayOutputStream out = new ByteArrayOutputStream(256);
- for (Map.Entry<String, Object> prop : props.entrySet())
- {
- String key = prop.getKey();
- Object val = prop.getValue();
-
- ByteArrayOutputStream out2 = new ByteArrayOutputStream(100);
- writeUTF(out2, key);
- if (val instanceof String)
- {
- out2.write('=');
- writeUTF(out2, (String) val);
- }
- else
- {
- if (val instanceof byte[])
- {
- out2.write('=');
- byte[] bval = (byte[]) val;
- out2.write(bval, 0, bval.length);
- }
- else
- {
- if (val != NO_VALUE)
- {
- throw new IllegalArgumentException(
- "invalid property value: " + val);
- }
- }
- }
- byte data[] = out2.toByteArray();
- out.write(data.length);
- out.write(data, 0, data.length);
- }
- this.text = out.toByteArray();
- }
- catch (IOException e)
- {
- throw new RuntimeException("unexpected exception: " + e);
- }
- }
- }
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/ServiceListener.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/ServiceListener.java
deleted file mode 100644
index 1c34adf..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/ServiceListener.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright 2003-2005 Arthur van Hoff Rick Blair
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf.jmdns;
-
-import java.util.*;
-
-/**
- * Listener for service updates.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Werner Randelshofer
- */
-public interface ServiceListener extends EventListener
-{
- /**
- * A service has been added.
- *
- * @param event The ServiceEvent providing the name and fully qualified type
- * of the service.
- */
-
- void serviceAdded(ServiceEvent event);
-
- /**
- * A service has been removed.
- *
- * @param event The ServiceEvent providing the name and fully qualified type
- * of the service.
- */
- void serviceRemoved(ServiceEvent event);
-
- /**
- * A service has been resolved. Its details are now available in the
- * ServiceInfo record.
- *
- * @param event The ServiceEvent providing the name, the fully qualified
- * type of the service, and the service info record,
- * or null if the service could not be resolved.
- */
-
- void serviceResolved(ServiceEvent event);
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/ServiceTypeListener.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/ServiceTypeListener.java
deleted file mode 100644
index 84e5c59..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/jmdns/ServiceTypeListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright 2003-2005 Arthur van Hoff Rick Blair
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.protocol.zeroconf.jmdns;
-
-import java.util.*;
-
-/**
- * Listener for service types.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Werner Randelshofer
- */
-public interface ServiceTypeListener extends EventListener
-{
- /**
- * A new service type was discovered.
- *
- * @param event The service event providing the fully qualified type of
- * the service.
- */
- void serviceTypeAdded(ServiceEvent event);
-}
diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/zeroconf.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/zeroconf/zeroconf.provider.manifest.mf
deleted file mode 100644
index 24daba0..0000000
--- a/src/net/java/sip/communicator/impl/protocol/zeroconf/zeroconf.provider.manifest.mf
+++ /dev/null
@@ -1,12 +0,0 @@
-Bundle-Activator: net.java.sip.communicator.impl.protocol.zeroconf.ZeroconfActivator
-Bundle-Name: Zeroconf Protocol Provider
-Bundle-Description: A bundle providing support for the Zeroconf protocol.
-Bundle-Vendor: jitsi.org
-Bundle-Version: 0.0.1
-Bundle-SymbolicName: net.java.sip.communicator.protocol.zeroconf
-Import-Package: org.osgi.framework,
- org.jitsi.service.configuration,
- org.jitsi.service.resources, net.java.sip.communicator.service.resources,
- net.java.sip.communicator.util,
- net.java.sip.communicator.service.protocol,
- net.java.sip.communicator.service.protocol.event
diff --git a/src/net/java/sip/communicator/impl/replacement/directimage/ReplacementServiceDirectImageImpl.java b/src/net/java/sip/communicator/impl/replacement/directimage/ReplacementServiceDirectImageImpl.java
index 48bb362..3bdaaa4 100644
--- a/src/net/java/sip/communicator/impl/replacement/directimage/ReplacementServiceDirectImageImpl.java
+++ b/src/net/java/sip/communicator/impl/replacement/directimage/ReplacementServiceDirectImageImpl.java
@@ -45,7 +45,7 @@ public class ReplacementServiceDirectImageImpl
* The regex used to match the link in the message.
*/
public static final String URL_PATTERN =
- "https?\\:\\/\\/(www\\.)*.*\\.(?:jpg|png|gif)";
+ "https?\\:\\/\\/.*\\.(?:jpg|png|gif)";
/**
* Configuration label shown in the config form.
diff --git a/src/net/java/sip/communicator/impl/resources/ResourceManagementActivator.java b/src/net/java/sip/communicator/impl/resources/ResourceManagementActivator.java
index 6c76906..1e7e7e4 100644
--- a/src/net/java/sip/communicator/impl/resources/ResourceManagementActivator.java
+++ b/src/net/java/sip/communicator/impl/resources/ResourceManagementActivator.java
@@ -19,6 +19,7 @@ package net.java.sip.communicator.impl.resources;
import net.java.sip.communicator.util.*;
+import org.jitsi.service.configuration.*;
import org.jitsi.service.resources.*;
import org.osgi.framework.*;
@@ -31,6 +32,7 @@ public class ResourceManagementActivator
extends SimpleServiceActivator<ResourceManagementServiceImpl>
{
static BundleContext bundleContext;
+ private static ConfigurationService configService;
/**
* Creates new instance of <tt>ResourceManagementActivator</tt>
@@ -68,4 +70,22 @@ public class ResourceManagementActivator
{
return new ResourceManagementServiceImpl();
}
+
+ /**
+ * Returns the <tt>ConfigurationService</tt> obtained from the bundle
+ * context.
+ * @return the <tt>ConfigurationService</tt> obtained from the bundle
+ * context
+ */
+ public static ConfigurationService getConfigService()
+ {
+ if(configService == null)
+ {
+ configService
+ = ServiceUtils.getService(
+ bundleContext,
+ ConfigurationService.class);
+ }
+ return configService;
+ }
}
diff --git a/src/net/java/sip/communicator/impl/resources/ResourceManagementServiceImpl.java b/src/net/java/sip/communicator/impl/resources/ResourceManagementServiceImpl.java
index d116fea..1cc2dcf 100644
--- a/src/net/java/sip/communicator/impl/resources/ResourceManagementServiceImpl.java
+++ b/src/net/java/sip/communicator/impl/resources/ResourceManagementServiceImpl.java
@@ -344,4 +344,24 @@ public class ResourceManagementServiceImpl
{
return SkinJarBuilder.createBundleFromZip(zipFile, getImagePack());
}
+
+ /**
+ * Gets the specified setting from the config service if present, otherwise
+ * from the embedded resources (resources/config/defaults.properties).
+ *
+ * @param key The setting to lookup.
+ * @return The setting for the key or {@code null} if not found.
+ */
+ @Override
+ public String getSettingsString(String key)
+ {
+ Object configValue = ResourceManagementActivator
+ .getConfigService().getProperty(key);
+ if (configValue == null)
+ {
+ configValue = super.getSettingsString(key);
+ }
+
+ return configValue == null ? null : configValue.toString();
+ }
}
diff --git a/src/net/java/sip/communicator/impl/sysactivity/DBusNetworkManager.java b/src/net/java/sip/communicator/impl/sysactivity/DBusNetworkManager.java
index 4c148df..c75e941 100644
--- a/src/net/java/sip/communicator/impl/sysactivity/DBusNetworkManager.java
+++ b/src/net/java/sip/communicator/impl/sysactivity/DBusNetworkManager.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,133 +15,133 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.sysactivity;
-
-import org.freedesktop.dbus.*;
-import org.freedesktop.dbus.exceptions.*;
-
-/**
- * NetworkManager D-Bus Interface
- *
- * @author Damian Minkov
- * @author Ingo Bauersachs
- */
-@DBusInterfaceName("org.freedesktop.NetworkManager")
-public interface DBusNetworkManager
- extends DBusInterface
-{
- /*
- * Types of NetworkManager states for versions < 0.9
- */
- public static final int NM_STATE_UNKNOWN = 0;
- public static final int NM_STATE_ASLEEP = 1;
- public static final int NM_STATE_CONNECTING = 2;
- public static final int NM_STATE_CONNECTED = 3;
- public static final int NM_STATE_DISCONNECTED = 4;
-
- /*
- * Types of NetworkManager states for versions >= 0.9
- */
- public static final int NM9_STATE_UNKNOWN = 0;
- public static final int NM9_STATE_ASLEEP = 10;
- public static final int NM9_STATE_DISCONNECTED = 20;
- public static final int NM9_STATE_DISCONNECTING = 30;
- public static final int NM9_STATE_CONNECTING = 40;
- public static final int NM9_STATE_CONNECTED_LOCAL = 50;
- public static final int NM9_STATE_CONNECTED_SITE = 60;
- public static final int NM9_STATE_CONNECTED_GLOBAL = 70;
-
- /**
- * State change signal.
- */
- public class StateChange extends DBusSignal
- {
- /**
- * The name of the signal.
- */
- public final String name;
-
- /**
- * The current status it holds.
- */
- public final UInt32 status;
-
- /**
- * Creates status change.
- * @param path the path
- * @param status the status
- * @throws DBusException
- */
- public StateChange(String path, UInt32 status)
- throws DBusException
- {
- super(path, status);
- name = path;
- this.status = status;
- }
-
- /**
- * The current status.
- * @return the current status
- */
- public int getStatus()
- {
- return status.intValue();
- }
-
- /**
- * Returns status description
- * @return the status description
- */
- public String getStatusName()
- {
- switch(status.intValue())
- {
- case NM_STATE_ASLEEP : return "Asleep";
- case NM_STATE_CONNECTING : return "Connecting";
- case NM_STATE_CONNECTED : return "Connected";
- case NM_STATE_DISCONNECTED : return "Disconnected";
- default : return "Unknown";
- }
- }
- }
-
- /**
- * State changed signal.
- */
- public static class StateChanged extends StateChange
- {
- /**
- * Creates status changed.
- * @param path the path
- * @param status the status
- * @throws DBusException
- */
- public StateChanged(String path, UInt32 status)
- throws DBusException
- {
- super(path, status);
- }
-
- /**
- * Returns status description
- * @return the status name
- */
- @Override
- public String getStatusName()
- {
- switch(status.intValue())
- {
- case NM9_STATE_UNKNOWN: return "Unknown";
- case NM9_STATE_ASLEEP: return "Asleep";
- case NM9_STATE_DISCONNECTED: return "Disconnected";
- case NM9_STATE_DISCONNECTING: return "Disconnecting";
- case NM9_STATE_CONNECTING: return "Connecting";
- case NM9_STATE_CONNECTED_LOCAL: return "LocalConnectivity";
- case NM9_STATE_CONNECTED_SITE: return "SiteConnectivity";
- case NM9_STATE_CONNECTED_GLOBAL: return "GlobalConnectivity";
- default : return "Unknown";
- }
- }
- }
-}
+package net.java.sip.communicator.impl.sysactivity;
+
+import org.freedesktop.dbus.*;
+import org.freedesktop.dbus.exceptions.*;
+
+/**
+ * NetworkManager D-Bus Interface
+ *
+ * @author Damian Minkov
+ * @author Ingo Bauersachs
+ */
+@DBusInterfaceName("org.freedesktop.NetworkManager")
+public interface DBusNetworkManager
+ extends DBusInterface
+{
+ /*
+ * Types of NetworkManager states for versions < 0.9
+ */
+ public static final int NM_STATE_UNKNOWN = 0;
+ public static final int NM_STATE_ASLEEP = 1;
+ public static final int NM_STATE_CONNECTING = 2;
+ public static final int NM_STATE_CONNECTED = 3;
+ public static final int NM_STATE_DISCONNECTED = 4;
+
+ /*
+ * Types of NetworkManager states for versions >= 0.9
+ */
+ public static final int NM9_STATE_UNKNOWN = 0;
+ public static final int NM9_STATE_ASLEEP = 10;
+ public static final int NM9_STATE_DISCONNECTED = 20;
+ public static final int NM9_STATE_DISCONNECTING = 30;
+ public static final int NM9_STATE_CONNECTING = 40;
+ public static final int NM9_STATE_CONNECTED_LOCAL = 50;
+ public static final int NM9_STATE_CONNECTED_SITE = 60;
+ public static final int NM9_STATE_CONNECTED_GLOBAL = 70;
+
+ /**
+ * State change signal.
+ */
+ public class StateChange extends DBusSignal
+ {
+ /**
+ * The name of the signal.
+ */
+ public final String name;
+
+ /**
+ * The current status it holds.
+ */
+ public final UInt32 status;
+
+ /**
+ * Creates status change.
+ * @param path the path
+ * @param status the status
+ * @throws DBusException
+ */
+ public StateChange(String path, UInt32 status)
+ throws DBusException
+ {
+ super(path, status);
+ name = path;
+ this.status = status;
+ }
+
+ /**
+ * The current status.
+ * @return the current status
+ */
+ public int getStatus()
+ {
+ return status.intValue();
+ }
+
+ /**
+ * Returns status description
+ * @return the status description
+ */
+ public String getStatusName()
+ {
+ switch(status.intValue())
+ {
+ case NM_STATE_ASLEEP : return "Asleep";
+ case NM_STATE_CONNECTING : return "Connecting";
+ case NM_STATE_CONNECTED : return "Connected";
+ case NM_STATE_DISCONNECTED : return "Disconnected";
+ default : return "Unknown";
+ }
+ }
+ }
+
+ /**
+ * State changed signal.
+ */
+ public static class StateChanged extends StateChange
+ {
+ /**
+ * Creates status changed.
+ * @param path the path
+ * @param status the status
+ * @throws DBusException
+ */
+ public StateChanged(String path, UInt32 status)
+ throws DBusException
+ {
+ super(path, status);
+ }
+
+ /**
+ * Returns status description
+ * @return the status name
+ */
+ @Override
+ public String getStatusName()
+ {
+ switch(status.intValue())
+ {
+ case NM9_STATE_UNKNOWN: return "Unknown";
+ case NM9_STATE_ASLEEP: return "Asleep";
+ case NM9_STATE_DISCONNECTED: return "Disconnected";
+ case NM9_STATE_DISCONNECTING: return "Disconnecting";
+ case NM9_STATE_CONNECTING: return "Connecting";
+ case NM9_STATE_CONNECTED_LOCAL: return "LocalConnectivity";
+ case NM9_STATE_CONNECTED_SITE: return "SiteConnectivity";
+ case NM9_STATE_CONNECTED_GLOBAL: return "GlobalConnectivity";
+ default : return "Unknown";
+ }
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/sysactivity/NetworkManagerListenerImpl.java b/src/net/java/sip/communicator/impl/sysactivity/NetworkManagerListenerImpl.java
index 952645a..94f8748 100644
--- a/src/net/java/sip/communicator/impl/sysactivity/NetworkManagerListenerImpl.java
+++ b/src/net/java/sip/communicator/impl/sysactivity/NetworkManagerListenerImpl.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,164 +15,164 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.sysactivity;
-
-import net.java.sip.communicator.service.sysactivity.event.*;
-import net.java.sip.communicator.util.*;
-
-import org.freedesktop.*;
-import org.freedesktop.dbus.*;
-import org.freedesktop.dbus.exceptions.*;
-
-/**
- * Responsible for subscribe and dispatch signals from NetworkManager.
- * Uses dbus to connect.
- *
- * @author Damian Minkov
- */
-@SuppressWarnings("rawtypes")
-public class NetworkManagerListenerImpl
- implements DBusSigHandler,
- SystemActivityManager
-{
- /**
- * The logger.
- */
- private Logger logger = Logger.getLogger(
- NetworkManagerListenerImpl.class.getName());
-
- /**
- * Dbus connection we use.
- */
- private DBusConnection dbusConn;
-
- /**
- * Make only one instance.
- */
- public NetworkManagerListenerImpl()
- {
- try
- {
- dbusConn = DBusConnection.getConnection(DBusConnection.SYSTEM);
- }
- catch(DBusException e)
- {
- logger.error("Cannot obtain dbus connection", e);
- }
- }
-
- /**
- * Starts
- */
- @SuppressWarnings("unchecked")
- public void start()
- {
- // on error connecting to dbus do nothing
- if(dbusConn == null)
- return;
-
- try
- {
- dbusConn.addSigHandler(DBus.NameOwnerChanged.class, this);
- dbusConn.addSigHandler(DBusNetworkManager.StateChange.class, this);
- dbusConn.addSigHandler(DBusNetworkManager.StateChanged.class, this);
- }
- catch(DBusException e)
- {
- logger.error("Error adding dbus signal handlers", e);
- }
- }
-
- /**
- * Stops.
- */
- @SuppressWarnings("unchecked")
- public void stop()
- {
- // on error connecting to dbus do nothing
- if(dbusConn == null)
- return;
-
- try
- {
- dbusConn.removeSigHandler(DBus.NameOwnerChanged.class, this);
- dbusConn.removeSigHandler(
- DBusNetworkManager.StateChange.class, this);
- dbusConn.removeSigHandler(
- DBusNetworkManager.StateChanged.class, this);
- }
- catch(DBusException e)
- {
- logger.error("Error removing dbus signal handlers", e);
- }
- }
-
- /**
- * Receives signals and dispatch them.
- * @param dBusSignal signal to handle.
- */
- public void handle(DBusSignal dBusSignal)
- {
- if(dBusSignal instanceof DBus.NameOwnerChanged)
- {
- DBus.NameOwnerChanged nameOwnerChanged =
- (DBus.NameOwnerChanged)dBusSignal;
-
- if(nameOwnerChanged.name.equals("org.freedesktop.NetworkManager"))
- {
- boolean b1 = nameOwnerChanged.old_owner != null
- && nameOwnerChanged.old_owner.length() > 0;
- boolean b2 = nameOwnerChanged.new_owner != null
- && nameOwnerChanged.new_owner.length() > 0;
-
- if(b1 && !b2)
- {
- SystemActivityEvent evt = new SystemActivityEvent(
- SysActivityActivator.getSystemActivityService(),
- SystemActivityEvent.EVENT_NETWORK_CHANGE);
- SysActivityActivator.getSystemActivityService()
- .fireSystemActivityEvent(evt);
- }
- }
- }
- else if(dBusSignal instanceof DBusNetworkManager.StateChange)
- {
- DBusNetworkManager.StateChange stateChange =
- (DBusNetworkManager.StateChange)dBusSignal;
-
- SystemActivityEvent evt = null;
- switch(stateChange.getStatus())
- {
- case DBusNetworkManager.NM_STATE_CONNECTED:
- case DBusNetworkManager.NM_STATE_DISCONNECTED:
- case DBusNetworkManager.NM9_STATE_DISCONNECTED:
- case DBusNetworkManager.NM9_STATE_CONNECTED_LOCAL:
- case DBusNetworkManager.NM9_STATE_CONNECTED_SITE:
- case DBusNetworkManager.NM9_STATE_CONNECTED_GLOBAL:
- evt = new SystemActivityEvent(
- SysActivityActivator.getSystemActivityService(),
- SystemActivityEvent.EVENT_NETWORK_CHANGE);
- break;
- case DBusNetworkManager.NM_STATE_ASLEEP:
- case DBusNetworkManager.NM9_STATE_ASLEEP:
- evt = new SystemActivityEvent(
- SysActivityActivator.getSystemActivityService(),
- SystemActivityEvent.EVENT_SLEEP);
- break;
- }
-
- if(evt != null)
- SysActivityActivator.getSystemActivityService()
- .fireSystemActivityEvent(evt);
- }
- }
-
- /**
- * Whether we are connected to the network manager through dbus.
- * @return whether we are connected to the network manager.
- */
- public boolean isConnected()
- {
- return dbusConn != null;
- }
-}
+package net.java.sip.communicator.impl.sysactivity;
+
+import net.java.sip.communicator.service.sysactivity.event.*;
+import net.java.sip.communicator.util.*;
+
+import org.freedesktop.*;
+import org.freedesktop.dbus.*;
+import org.freedesktop.dbus.exceptions.*;
+
+/**
+ * Responsible for subscribe and dispatch signals from NetworkManager.
+ * Uses dbus to connect.
+ *
+ * @author Damian Minkov
+ */
+@SuppressWarnings("rawtypes")
+public class NetworkManagerListenerImpl
+ implements DBusSigHandler,
+ SystemActivityManager
+{
+ /**
+ * The logger.
+ */
+ private Logger logger = Logger.getLogger(
+ NetworkManagerListenerImpl.class.getName());
+
+ /**
+ * Dbus connection we use.
+ */
+ private DBusConnection dbusConn;
+
+ /**
+ * Make only one instance.
+ */
+ public NetworkManagerListenerImpl()
+ {
+ try
+ {
+ dbusConn = DBusConnection.getConnection(DBusConnection.SYSTEM);
+ }
+ catch(DBusException e)
+ {
+ logger.error("Cannot obtain dbus connection", e);
+ }
+ }
+
+ /**
+ * Starts
+ */
+ @SuppressWarnings("unchecked")
+ public void start()
+ {
+ // on error connecting to dbus do nothing
+ if(dbusConn == null)
+ return;
+
+ try
+ {
+ dbusConn.addSigHandler(DBus.NameOwnerChanged.class, this);
+ dbusConn.addSigHandler(DBusNetworkManager.StateChange.class, this);
+ dbusConn.addSigHandler(DBusNetworkManager.StateChanged.class, this);
+ }
+ catch(DBusException e)
+ {
+ logger.error("Error adding dbus signal handlers", e);
+ }
+ }
+
+ /**
+ * Stops.
+ */
+ @SuppressWarnings("unchecked")
+ public void stop()
+ {
+ // on error connecting to dbus do nothing
+ if(dbusConn == null)
+ return;
+
+ try
+ {
+ dbusConn.removeSigHandler(DBus.NameOwnerChanged.class, this);
+ dbusConn.removeSigHandler(
+ DBusNetworkManager.StateChange.class, this);
+ dbusConn.removeSigHandler(
+ DBusNetworkManager.StateChanged.class, this);
+ }
+ catch(DBusException e)
+ {
+ logger.error("Error removing dbus signal handlers", e);
+ }
+ }
+
+ /**
+ * Receives signals and dispatch them.
+ * @param dBusSignal signal to handle.
+ */
+ public void handle(DBusSignal dBusSignal)
+ {
+ if(dBusSignal instanceof DBus.NameOwnerChanged)
+ {
+ DBus.NameOwnerChanged nameOwnerChanged =
+ (DBus.NameOwnerChanged)dBusSignal;
+
+ if(nameOwnerChanged.name.equals("org.freedesktop.NetworkManager"))
+ {
+ boolean b1 = nameOwnerChanged.old_owner != null
+ && nameOwnerChanged.old_owner.length() > 0;
+ boolean b2 = nameOwnerChanged.new_owner != null
+ && nameOwnerChanged.new_owner.length() > 0;
+
+ if(b1 && !b2)
+ {
+ SystemActivityEvent evt = new SystemActivityEvent(
+ SysActivityActivator.getSystemActivityService(),
+ SystemActivityEvent.EVENT_NETWORK_CHANGE);
+ SysActivityActivator.getSystemActivityService()
+ .fireSystemActivityEvent(evt);
+ }
+ }
+ }
+ else if(dBusSignal instanceof DBusNetworkManager.StateChange)
+ {
+ DBusNetworkManager.StateChange stateChange =
+ (DBusNetworkManager.StateChange)dBusSignal;
+
+ SystemActivityEvent evt = null;
+ switch(stateChange.getStatus())
+ {
+ case DBusNetworkManager.NM_STATE_CONNECTED:
+ case DBusNetworkManager.NM_STATE_DISCONNECTED:
+ case DBusNetworkManager.NM9_STATE_DISCONNECTED:
+ case DBusNetworkManager.NM9_STATE_CONNECTED_LOCAL:
+ case DBusNetworkManager.NM9_STATE_CONNECTED_SITE:
+ case DBusNetworkManager.NM9_STATE_CONNECTED_GLOBAL:
+ evt = new SystemActivityEvent(
+ SysActivityActivator.getSystemActivityService(),
+ SystemActivityEvent.EVENT_NETWORK_CHANGE);
+ break;
+ case DBusNetworkManager.NM_STATE_ASLEEP:
+ case DBusNetworkManager.NM9_STATE_ASLEEP:
+ evt = new SystemActivityEvent(
+ SysActivityActivator.getSystemActivityService(),
+ SystemActivityEvent.EVENT_SLEEP);
+ break;
+ }
+
+ if(evt != null)
+ SysActivityActivator.getSystemActivityService()
+ .fireSystemActivityEvent(evt);
+ }
+ }
+
+ /**
+ * Whether we are connected to the network manager through dbus.
+ * @return whether we are connected to the network manager.
+ */
+ public boolean isConnected()
+ {
+ return dbusConn != null;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/sysactivity/SysActivityActivator.java b/src/net/java/sip/communicator/impl/sysactivity/SysActivityActivator.java
index 6a46e18..96cea29 100644
--- a/src/net/java/sip/communicator/impl/sysactivity/SysActivityActivator.java
+++ b/src/net/java/sip/communicator/impl/sysactivity/SysActivityActivator.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,101 +15,101 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.sysactivity;
-
-import net.java.sip.communicator.service.sysactivity.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * Listens for system activity changes like sleep, network change, inactivity
- * and informs all its listeners.
- *
- * @author Damian Minkov
- */
-public class SysActivityActivator
- implements BundleActivator
-{
- /**
- * The <tt>Logger</tt> used by this <tt>SysActivityActivator</tt> for
- * logging output.
- */
- private final Logger logger = Logger.getLogger(SysActivityActivator.class);
-
- /**
- * The OSGi <tt>BundleContext</tt>.
- */
- private static BundleContext bundleContext = null;
-
- /**
- * The system activity service impl.
- */
- private static SystemActivityNotificationsServiceImpl
- sysActivitiesServiceImpl;
-
- /**
- * Called when this bundle is started so the Framework can perform the
- * bundle-specific activities necessary to start this bundle.
- *
- * @param bundleContext The execution context of the bundle being started.
- * @throws Exception If this method throws an exception, this bundle is
- * marked as stopped and the Framework will remove this bundle's listeners,
- * unregister all services registered by this bundle, and release all
- * services used by this bundle.
- */
- public void start(BundleContext bundleContext)
- throws Exception
- {
- SysActivityActivator.bundleContext = bundleContext;
-
- if (logger.isDebugEnabled())
- logger.debug("Started.");
-
- sysActivitiesServiceImpl = new SystemActivityNotificationsServiceImpl();
- sysActivitiesServiceImpl.start();
-
- bundleContext.registerService(
- SystemActivityNotificationsService.class.getName(),
- sysActivitiesServiceImpl,
- null);
- }
-
- /**
- * Returns a reference to the bundle context that we were started with.
- * @return a reference to the BundleContext instance that we were started
- * with.
- */
- public static SystemActivityNotificationsServiceImpl
- getSystemActivityService()
- {
- return sysActivitiesServiceImpl;
- }
-
- /**
- * Called when this bundle is stopped so the Framework can perform the
- * bundle-specific activities necessary to stop the bundle.
- *
- * @param bundleContext The execution context of the bundle being stopped.
- * @throws Exception If this method throws an exception, the bundle is still
- * marked as stopped, and the Framework will remove the bundle's listeners,
- * unregister all services registered by the bundle, and release all
- * services used by the bundle.
- */
- public void stop(BundleContext bundleContext)
- throws Exception
- {
- if (sysActivitiesServiceImpl != null)
- sysActivitiesServiceImpl.stop();
- }
-
- /**
- * Returns a reference to the bundle context that we were started with.
- * @return a reference to the BundleContext instance that we were started
- * with.
- */
- public static BundleContext getBundleContext()
- {
- return bundleContext;
- }
-}
+package net.java.sip.communicator.impl.sysactivity;
+
+import net.java.sip.communicator.service.sysactivity.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * Listens for system activity changes like sleep, network change, inactivity
+ * and informs all its listeners.
+ *
+ * @author Damian Minkov
+ */
+public class SysActivityActivator
+ implements BundleActivator
+{
+ /**
+ * The <tt>Logger</tt> used by this <tt>SysActivityActivator</tt> for
+ * logging output.
+ */
+ private final Logger logger = Logger.getLogger(SysActivityActivator.class);
+
+ /**
+ * The OSGi <tt>BundleContext</tt>.
+ */
+ private static BundleContext bundleContext = null;
+
+ /**
+ * The system activity service impl.
+ */
+ private static SystemActivityNotificationsServiceImpl
+ sysActivitiesServiceImpl;
+
+ /**
+ * Called when this bundle is started so the Framework can perform the
+ * bundle-specific activities necessary to start this bundle.
+ *
+ * @param bundleContext The execution context of the bundle being started.
+ * @throws Exception If this method throws an exception, this bundle is
+ * marked as stopped and the Framework will remove this bundle's listeners,
+ * unregister all services registered by this bundle, and release all
+ * services used by this bundle.
+ */
+ public void start(BundleContext bundleContext)
+ throws Exception
+ {
+ SysActivityActivator.bundleContext = bundleContext;
+
+ if (logger.isDebugEnabled())
+ logger.debug("Started.");
+
+ sysActivitiesServiceImpl = new SystemActivityNotificationsServiceImpl();
+ sysActivitiesServiceImpl.start();
+
+ bundleContext.registerService(
+ SystemActivityNotificationsService.class.getName(),
+ sysActivitiesServiceImpl,
+ null);
+ }
+
+ /**
+ * Returns a reference to the bundle context that we were started with.
+ * @return a reference to the BundleContext instance that we were started
+ * with.
+ */
+ public static SystemActivityNotificationsServiceImpl
+ getSystemActivityService()
+ {
+ return sysActivitiesServiceImpl;
+ }
+
+ /**
+ * Called when this bundle is stopped so the Framework can perform the
+ * bundle-specific activities necessary to stop the bundle.
+ *
+ * @param bundleContext The execution context of the bundle being stopped.
+ * @throws Exception If this method throws an exception, the bundle is still
+ * marked as stopped, and the Framework will remove the bundle's listeners,
+ * unregister all services registered by the bundle, and release all
+ * services used by the bundle.
+ */
+ public void stop(BundleContext bundleContext)
+ throws Exception
+ {
+ if (sysActivitiesServiceImpl != null)
+ sysActivitiesServiceImpl.stop();
+ }
+
+ /**
+ * Returns a reference to the bundle context that we were started with.
+ * @return a reference to the BundleContext instance that we were started
+ * with.
+ */
+ public static BundleContext getBundleContext()
+ {
+ return bundleContext;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotifications.java b/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotifications.java
index a6ff936..e2fb17a 100644
--- a/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotifications.java
+++ b/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotifications.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,235 +15,237 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.sysactivity;
-
-import net.java.sip.communicator.util.*;
-
-/**
- * @author Damian Minkov
- */
-public class SystemActivityNotifications
-{
- /**
- * The <tt>Logger</tt> used by the <tt>SystemActivityNotifications</tt>
- * class to log debugging information.
- */
- private static final Logger logger
- = Logger.getLogger(SystemActivityNotifications.class);
-
- /**
- * Computer display has stand by.
- */
- public static final int NOTIFY_DISPLAY_SLEEP = 2;
-
- /**
- * Computer display wakes up after stand by.
- */
- public static final int NOTIFY_DISPLAY_WAKE = 3;
-
- /**
- * A change in dns configuration has occurred.
- */
- public static final int NOTIFY_DNS_CHANGE = 10;
-
- /**
- * All processes have been informed about ending session, now notify for
- * the actual end session.
- */
- public static final int NOTIFY_ENDSESSION = 12;
-
- /**
- * A change in network configuration has occurred.
- */
- public static final int NOTIFY_NETWORK_CHANGE = 9;
-
- /**
- * Notifies for start of process of ending desktop session,
- * logoff or shutdown.
- */
- public static final int NOTIFY_QUERY_ENDSESSION = 11;
-
- /**
- * Screen has been locked.
- */
- public static final int NOTIFY_SCREEN_LOCKED = 7;
-
- /**
- * Screen has been unlocked.
- */
- public static final int NOTIFY_SCREEN_UNLOCKED = 8;
-
- /**
- * Screensaver has been started.
- */
- public static final int NOTIFY_SCREENSAVER_START = 4;
-
- /**
- * Screensaver has been stopped.
- */
- public static final int NOTIFY_SCREENSAVER_STOP = 6;
-
- /**
- * Screensaver will stop.
- */
- public static final int NOTIFY_SCREENSAVER_WILL_STOP = 5;
-
- /**
- * Notify that computers is going to sleep.
- */
- public static final int NOTIFY_SLEEP = 0;
-
- /**
- * Notify that computer is wakeing up after stand by.
- */
- public static final int NOTIFY_WAKE = 1;
-
- /**
- * The native instance.
- */
- private static long ptr;
-
- /**
- * Init native library.
- */
- static
- {
- try
- {
- // Don't load native library on Android to prevent the exception
- if(!org.jitsi.util.OSUtils.IS_ANDROID)
- {
- System.loadLibrary("sysactivitynotifications");
-
- ptr = allocAndInit();
- if (ptr == -1)
- ptr = 0;
- }
- }
- catch (Throwable t)
- {
- if (t instanceof ThreadDeath)
- throw (ThreadDeath) t;
- else
- logger.warn("Failed to initialize native counterpart", t);
- }
- }
-
- /**
- * Allocate native resources and gets a pointer.
- *
- * @return
- */
- private static native long allocAndInit();
-
- /**
- * Returns the when was last input in milliseconds. The time when there was
- * any activity on the computer.
- *
- * @return the last input in milliseconds
- */
- public static native long getLastInput();
-
- /**
- * Whether native library is loaded.
- *
- * @return whether native library is loaded.
- */
- public static boolean isLoaded()
- {
- return (ptr != 0);
- }
-
- /**
- * Release native resources.
- *
- * @param ptr
- */
- private static native void release(long ptr);
-
- /**
- * Sets notifier delegate.
- *
- * @param ptr
- * @param delegate
- */
- public static native void setDelegate(
- long ptr,
- NotificationsDelegate delegate);
-
- /**
- * Sets delegate.
- *
- * @param delegate
- */
- public static void setDelegate(NotificationsDelegate delegate)
- {
- if (ptr != 0)
- setDelegate(ptr, delegate);
- }
-
- /**
- * Start.
- */
- public static void start()
- {
- if (ptr != 0)
- start(ptr);
- }
-
- /**
- * Start processing.
- *
- * @param ptr
- */
- private static native void start(long ptr);
-
- /**
- * Stop.
- */
- public static void stop()
- {
- if (ptr != 0)
- {
- stop(ptr);
- release(ptr);
- ptr = 0;
- }
- }
-
- /**
- * Stop processing.
- *
- * @param ptr
- */
- private static native void stop(long ptr);
-
- /**
- * Delegate class to be notified about changes.
- */
- public interface NotificationsDelegate
- {
- /**
- * Callback method when receiving notifications.
- *
- * @param type
- */
- public void notify(int type);
-
- /**
- * Callback method when receiving special network notifications.
- *
- * @param family family of network change (ipv6, ipv4)
- * @param luidIndex unique index of interface
- * @param name name of the interface
- * @param type of the interface
- * @param connected whether interface is connected or not.
- */
- public void notifyNetworkChange(
- int family,
- long luidIndex,
- String name,
- long type,
- boolean connected);
- }
-}
+package net.java.sip.communicator.impl.sysactivity;
+
+import net.java.sip.communicator.util.Logger;
+import org.jitsi.util.*;
+
+/**
+ * @author Damian Minkov
+ */
+public class SystemActivityNotifications
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>SystemActivityNotifications</tt>
+ * class to log debugging information.
+ */
+ private static final Logger logger
+ = Logger.getLogger(SystemActivityNotifications.class);
+
+ /**
+ * Computer display has stand by.
+ */
+ public static final int NOTIFY_DISPLAY_SLEEP = 2;
+
+ /**
+ * Computer display wakes up after stand by.
+ */
+ public static final int NOTIFY_DISPLAY_WAKE = 3;
+
+ /**
+ * A change in dns configuration has occurred.
+ */
+ public static final int NOTIFY_DNS_CHANGE = 10;
+
+ /**
+ * All processes have been informed about ending session, now notify for
+ * the actual end session.
+ */
+ public static final int NOTIFY_ENDSESSION = 12;
+
+ /**
+ * A change in network configuration has occurred.
+ */
+ public static final int NOTIFY_NETWORK_CHANGE = 9;
+
+ /**
+ * Notifies for start of process of ending desktop session,
+ * logoff or shutdown.
+ */
+ public static final int NOTIFY_QUERY_ENDSESSION = 11;
+
+ /**
+ * Screen has been locked.
+ */
+ public static final int NOTIFY_SCREEN_LOCKED = 7;
+
+ /**
+ * Screen has been unlocked.
+ */
+ public static final int NOTIFY_SCREEN_UNLOCKED = 8;
+
+ /**
+ * Screensaver has been started.
+ */
+ public static final int NOTIFY_SCREENSAVER_START = 4;
+
+ /**
+ * Screensaver has been stopped.
+ */
+ public static final int NOTIFY_SCREENSAVER_STOP = 6;
+
+ /**
+ * Screensaver will stop.
+ */
+ public static final int NOTIFY_SCREENSAVER_WILL_STOP = 5;
+
+ /**
+ * Notify that computers is going to sleep.
+ */
+ public static final int NOTIFY_SLEEP = 0;
+
+ /**
+ * Notify that computer is wakeing up after stand by.
+ */
+ public static final int NOTIFY_WAKE = 1;
+
+ /**
+ * The native instance.
+ */
+ private static long ptr;
+
+ /**
+ * Init native library.
+ */
+ static
+ {
+ try
+ {
+ // Don't load native library on Android to prevent the exception
+ if(!org.jitsi.util.OSUtils.IS_ANDROID)
+ {
+ JNIUtils.loadLibrary("sysactivitynotifications",
+ SystemActivityNotifications.class);
+
+ ptr = allocAndInit();
+ if (ptr == -1)
+ ptr = 0;
+ }
+ }
+ catch (Throwable t)
+ {
+ if (t instanceof ThreadDeath)
+ throw (ThreadDeath) t;
+ else
+ logger.warn("Failed to initialize native counterpart", t);
+ }
+ }
+
+ /**
+ * Allocate native resources and gets a pointer.
+ *
+ * @return
+ */
+ private static native long allocAndInit();
+
+ /**
+ * Returns the when was last input in milliseconds. The time when there was
+ * any activity on the computer.
+ *
+ * @return the last input in milliseconds
+ */
+ public static native long getLastInput();
+
+ /**
+ * Whether native library is loaded.
+ *
+ * @return whether native library is loaded.
+ */
+ public static boolean isLoaded()
+ {
+ return (ptr != 0);
+ }
+
+ /**
+ * Release native resources.
+ *
+ * @param ptr
+ */
+ private static native void release(long ptr);
+
+ /**
+ * Sets notifier delegate.
+ *
+ * @param ptr
+ * @param delegate
+ */
+ public static native void setDelegate(
+ long ptr,
+ NotificationsDelegate delegate);
+
+ /**
+ * Sets delegate.
+ *
+ * @param delegate
+ */
+ public static void setDelegate(NotificationsDelegate delegate)
+ {
+ if (ptr != 0)
+ setDelegate(ptr, delegate);
+ }
+
+ /**
+ * Start.
+ */
+ public static void start()
+ {
+ if (ptr != 0)
+ start(ptr);
+ }
+
+ /**
+ * Start processing.
+ *
+ * @param ptr
+ */
+ private static native void start(long ptr);
+
+ /**
+ * Stop.
+ */
+ public static void stop()
+ {
+ if (ptr != 0)
+ {
+ stop(ptr);
+ release(ptr);
+ ptr = 0;
+ }
+ }
+
+ /**
+ * Stop processing.
+ *
+ * @param ptr
+ */
+ private static native void stop(long ptr);
+
+ /**
+ * Delegate class to be notified about changes.
+ */
+ public interface NotificationsDelegate
+ {
+ /**
+ * Callback method when receiving notifications.
+ *
+ * @param type
+ */
+ public void notify(int type);
+
+ /**
+ * Callback method when receiving special network notifications.
+ *
+ * @param family family of network change (ipv6, ipv4)
+ * @param luidIndex unique index of interface
+ * @param name name of the interface
+ * @param type of the interface
+ * @param connected whether interface is connected or not.
+ */
+ public void notifyNetworkChange(
+ int family,
+ long luidIndex,
+ String name,
+ long type,
+ boolean connected);
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotificationsServiceImpl.java b/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotificationsServiceImpl.java
index c25504f..c58805b 100644
--- a/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotificationsServiceImpl.java
+++ b/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotificationsServiceImpl.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,639 +15,639 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.sysactivity;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.sysactivity.*;
-import net.java.sip.communicator.service.sysactivity.event.*;
-import net.java.sip.communicator.util.Logger;
-
-import org.jitsi.util.*;
-
-/**
- * Service implementation listens for computer changes as sleeping, network
- * change, inactivity.
- *
- * @author Damian Minkov
- */
-public class SystemActivityNotificationsServiceImpl
- implements SystemActivityNotifications.NotificationsDelegate,
- SystemActivityNotificationsService,
- Runnable
-{
- /**
- * The <tt>Logger</tt> used by this
- * <tt>SystemActivityNotificationsServiceImpl</tt> for logging output.
- */
- private final Logger logger
- = Logger.getLogger(SystemActivityNotificationsServiceImpl.class);
-
- /**
- * The thread dispatcher of network change events.
- */
- private final SystemActivityEventDispatcher eventDispatcher
- = new SystemActivityEventDispatcher();
-
- /**
- * A list of listeners registered for idle events.
- */
- private final Map<SystemActivityChangeListener,Long> idleChangeListeners
- = new HashMap<SystemActivityChangeListener, Long>();
-
- /**
- * Listeners which are fired for idle state and which will be fired
- * with idle end when needed.
- */
- private final List<SystemActivityChangeListener> listenersInIdleState
- = new ArrayList<SystemActivityChangeListener>();
-
- /**
- * The interval between checks when not idle.
- */
- private static final int CHECK_FOR_IDLE_DEFAULT = 30 * 1000;
-
- /**
- * The interval between checks when idle. The interval is shorter
- * so we can react almost immediately when we are active again.
- */
- private static final int CHECK_FOR_IDLE_WHEN_IDLE = 1000;
-
- /**
- * The time in milliseconds between two checks for system idle.
- */
- private static int idleStateCheckDelay = CHECK_FOR_IDLE_DEFAULT;
-
- /**
- * Whether current service is started or stopped.
- */
- private boolean running = false;
-
- /**
- * The time when we received latest network change event.
- */
- private long lastNetworkChange = -1;
-
- /**
- * Sometimes (on windows) we got several network change events
- * this is the time after which latest event we will skip next events.
- */
- private static final long NETWORK_EVENT_SILENT_TIME = 10*1000;
-
- /**
- * Whether network is currently connected.
- */
- private Boolean networkIsConnected = null;
-
- /**
- * The linux impl class name.
- */
- private static final String SYSTEM_ACTIVITY_MANAGER_LINUX_CLASS
- = "net.java.sip.communicator.impl.sysactivity.NetworkManagerListenerImpl";
-
- /**
- * The android impl class name.
- */
- private static final String SYSTEM_ACTIVITY_MANAGER_ANDROID_CLASS
- = "net.java.sip.communicator.impl.sysactivity.ConnectivityManagerListenerImpl";
-
- /**
- * The currently instantiated and working manager.
- */
- private SystemActivityManager currentRunningManager = null;
-
- /**
- * Init and start notifications.
- */
- public void start()
- {
- running = true;
-
- // set the delegate and start notification in new thread
- // make sure we don't block startup process
- Thread notifystartThread
- = new Thread(
- new Runnable()
- {
- public void run()
- {
- SystemActivityNotifications.setDelegate(
- SystemActivityNotificationsServiceImpl.this);
- SystemActivityNotifications.start();
- }
- },
- "SystemActivityNotificationsServiceImpl");
- notifystartThread.setDaemon(true);
- notifystartThread.start();
-
- if(isSupported(SystemActivityEvent.EVENT_SYSTEM_IDLE))
- {
- // a thread periodically checks system idle state and if it pass the
- // idle time for a particular listener, will inform it.
- Thread idleNotifyThread = new Thread(
- this,
- "SystemActivityNotificationsServiceImpl.IdleNotifyThread");
- idleNotifyThread.setDaemon(true);
- idleNotifyThread.start();
- }
-
- if (getCurrentRunningManager() != null)
- getCurrentRunningManager().start();
- }
-
- /**
- * Stop notifications.
- */
- public void stop()
- {
- SystemActivityNotifications.stop();
-
- if (getCurrentRunningManager() != null)
- getCurrentRunningManager().stop();
-
- eventDispatcher.stop();
-
- running = false;
-
- synchronized(this)
- {
- this.notifyAll();
- }
- }
-
- /**
- * Registers a listener that would be notified of changes that have occurred
- * in the underlying system.
- *
- * @param listener the listener that we'd like to register for changes in
- * the underlying system.
- */
- public void addSystemActivityChangeListener(
- SystemActivityChangeListener listener)
- {
- eventDispatcher.addSystemActivityChangeListener(listener);
- }
-
- /**
- * Remove the specified listener so that it won't receive further
- * notifications of changes that occur in the underlying system
- *
- * @param listener the listener to remove.
- */
- public void removeSystemActivityChangeListener(
- SystemActivityChangeListener listener)
- {
- eventDispatcher.removeSystemActivityChangeListener(listener);
- }
-
- /**
- * Registers a listener that would be notified for idle of the system
- * for <tt>idleTime</tt>.
- *
- * @param idleTime the time in milliseconds after which we will consider
- * system to be idle. This doesn't count when system seems idle as
- * monitor is off or screensaver is on, or desktop is locked.
- * @param listener the listener that we'd like to register for changes in
- * the underlying system.
- */
- public void addIdleSystemChangeListener(
- long idleTime,
- SystemActivityChangeListener listener)
- {
- synchronized (idleChangeListeners)
- {
- if (idleTime > 0
- && !idleChangeListeners.containsKey(listener))
- idleChangeListeners.put(listener, idleTime);
- }
- }
-
- /**
- * Remove the specified listener so that it won't receive further
- * notifications for idle system.
- *
- * @param listener the listener to remove.
- */
- public void removeIdleSystemChangeListener(
- SystemActivityChangeListener listener)
- {
- synchronized (idleChangeListeners)
- {
- idleChangeListeners.remove(listener);
- }
- }
-
- /**
- * The time since last user input. The time the system has been idle.
- * @return time the system has been idle.
- */
- public long getTimeSinceLastInput()
- {
- if(SystemActivityNotifications.isLoaded())
- return SystemActivityNotifications.getLastInput();
- else
- return -1;
- }
-
- /**
- * Callback method when receiving notifications.
- *
- * @param type type of the notification.
- */
- public void notify(int type)
- {
- SystemActivityEvent evt = null;
- switch(type)
- {
- case SystemActivityNotifications.NOTIFY_SLEEP :
- evt = new SystemActivityEvent(this,
- SystemActivityEvent.EVENT_SLEEP);
- break;
- case SystemActivityNotifications.NOTIFY_WAKE :
- evt = new SystemActivityEvent(this,
- SystemActivityEvent.EVENT_WAKE);
- break;
- case SystemActivityNotifications.NOTIFY_DISPLAY_SLEEP :
- evt = new SystemActivityEvent(this,
- SystemActivityEvent.EVENT_DISPLAY_SLEEP);
- break;
- case SystemActivityNotifications.NOTIFY_DISPLAY_WAKE :
- evt = new SystemActivityEvent(this,
- SystemActivityEvent.EVENT_DISPLAY_WAKE);
- break;
- case SystemActivityNotifications.NOTIFY_SCREENSAVER_START :
- evt = new SystemActivityEvent(this,
- SystemActivityEvent.EVENT_SCREENSAVER_START);
- break;
- case SystemActivityNotifications.NOTIFY_SCREENSAVER_WILL_STOP :
- evt = new SystemActivityEvent(this,
- SystemActivityEvent.EVENT_SCREENSAVER_WILL_STOP);
- break;
- case SystemActivityNotifications.NOTIFY_SCREENSAVER_STOP :
- evt = new SystemActivityEvent(this,
- SystemActivityEvent.EVENT_SCREENSAVER_STOP);
- break;
- case SystemActivityNotifications.NOTIFY_SCREEN_LOCKED :
- evt = new SystemActivityEvent(this,
- SystemActivityEvent.EVENT_SCREEN_LOCKED);
- break;
- case SystemActivityNotifications.NOTIFY_SCREEN_UNLOCKED :
- evt = new SystemActivityEvent(this,
- SystemActivityEvent.EVENT_SCREEN_UNLOCKED);
- break;
- case SystemActivityNotifications.NOTIFY_NETWORK_CHANGE :
- {
- evt = new SystemActivityEvent(this,
- SystemActivityEvent.EVENT_NETWORK_CHANGE);
- break;
- }
- case SystemActivityNotifications.NOTIFY_DNS_CHANGE :
- {
- evt = new SystemActivityEvent(this,
- SystemActivityEvent.EVENT_DNS_CHANGE);
- break;
- }
- case SystemActivityNotifications.NOTIFY_QUERY_ENDSESSION :
- {
- // both events QUERY_ENDSESSION and ENDSESSION
- // depend on the result one after another
- // we don't put them in new thread in order to give control
- // in the bundles using this events.
- evt = new SystemActivityEvent(this,
- SystemActivityEvent.EVENT_QUERY_ENDSESSION);
- eventDispatcher.fireSystemActivityEventCurrentThread(evt);
-
- return;
- }
- case SystemActivityNotifications.NOTIFY_ENDSESSION :
- {
- // both events QUERY_ENDSESSION and ENDSESSION
- // depend on the result one after another
- // we don't put them in new thread in order to give control
- // in the bundles using this events.
- evt = new SystemActivityEvent(this,
- SystemActivityEvent.EVENT_ENDSESSION);
- eventDispatcher.fireSystemActivityEventCurrentThread(evt);
-
- return;
- }
- }
-
- if (evt != null)
- fireSystemActivityEvent(evt);
- }
-
- /**
- * Callback method when receiving special network notifications.
- *
- * @param family family of network change (ipv6, ipv4)
- * AF_UNSPEC = 0 (The address family is unspecified.)
- * AF_INET = 2 (The Internet Protocol version 4 (IPv4) address family)
- * AF_INET6 = 23 (The Internet Protocol version 6 (IPv6) address family)
- * @param luidIndex unique index of interface
- * @param name name of the interface
- * @param type of the interface
- * Possible values for the interface type are listed in the Ipifcons.h file.
- * common values:
- * IF_TYPE_OTHER = 1 (Some other type of network interface.)
- * IF_TYPE_ETHERNET_CSMACD = 6 (An Ethernet network interface.)
- * IF_TYPE_ISO88025_TOKENRING = 9 (A token ring network interface.)
- * IF_TYPE_PPP = 23 (A PPP network interface.)
- * IF_TYPE_SOFTWARE_LOOPBACK = 24 (A software loopback network interface.)
- * IF_TYPE_IEEE80211 = 71 (An IEEE 802.11 wireless network interface.)
- * IF_TYPE_TUNNEL = 131 (A tunnel type encapsulation network interface.)
- * IF_TYPE_IEEE1394 = 144 (An IEEE 1394 (Firewire) high performance
- * serial bus network interface.)
- * @param connected whether interface is connected or not.
- */
- public void notifyNetworkChange(
- int family,
- long luidIndex,
- String name,
- long type,
- boolean connected)
- {
- long current = System.currentTimeMillis();
- if(current - lastNetworkChange <= NETWORK_EVENT_SILENT_TIME
- && (networkIsConnected != null && networkIsConnected.equals(connected)))
- {
- networkIsConnected = connected;
- return;
- }
-
- lastNetworkChange = current;
- networkIsConnected = connected;
-
- SystemActivityEvent evt = new SystemActivityEvent(this,
- SystemActivityEvent.EVENT_NETWORK_CHANGE);
- fireSystemActivityEvent(evt);
- }
-
- /**
- * The thread run method that handles idle notifies.
- *
- * @see Thread#run()
- */
- public void run()
- {
- while(running)
- {
- try
- {
- long idleTime = 0;
- if(idleChangeListeners.size() > 0)
- {
- // check
- idleTime = SystemActivityNotifications.getLastInput();
-
- if((idleTime < idleStateCheckDelay)
- && (listenersInIdleState.size() > 0))
- {
- for(SystemActivityChangeListener l
- : listenersInIdleState)
- {
- fireSystemIdleEndEvent(l);
- }
- listenersInIdleState.clear();
- }
-
- for(Map.Entry<SystemActivityChangeListener, Long> entry
- : idleChangeListeners.entrySet())
- {
- SystemActivityChangeListener listener =
- entry.getKey();
-
- if(!listenersInIdleState.contains(listener)
- && (entry.getValue() <= idleTime))
- {
- fireSystemIdleEvent(listener);
-
- listenersInIdleState.add(listener);
- }
- }
- }
-
- // if the minimum check for idle is X minutes
- // we will wait before checking (X - Y + 1sec)
- // where Y is the last idle time returned by OS
- if(listenersInIdleState.size() > 0)
- {
- idleStateCheckDelay = CHECK_FOR_IDLE_WHEN_IDLE;
- }
- else if(idleTime != 0)
- {
- long minIdleSetting = CHECK_FOR_IDLE_DEFAULT;
-
- if(!idleChangeListeners.isEmpty())
- minIdleSetting =
- Collections.min(idleChangeListeners.values());
-
- int newSetting = (int)(minIdleSetting - idleTime) + 1000;
-
- if(newSetting > 0)
- idleStateCheckDelay = newSetting;
- else
- idleStateCheckDelay = CHECK_FOR_IDLE_DEFAULT;
- }
- else
- {
- idleStateCheckDelay = CHECK_FOR_IDLE_DEFAULT;
- }
-
- // wait for the specified time
- synchronized(this)
- {
- this.wait(idleStateCheckDelay);
- }
- }
- catch(UnsatisfiedLinkError t)
- {
- logger.error("Missing native impl", t);
- return;
- }
- catch(Throwable t)
- {
- logger.error("Error checking for idle", t);
- }
- }
- }
-
- /**
- * Delivers the specified event to all registered listeners.
- *
- * @param evt the <tt>SystemActivityEvent</tt> that we'd like delivered to
- * all registered message listeners.
- */
- protected void fireSystemActivityEvent(SystemActivityEvent evt)
- {
- int eventID = evt.getEventID();
-
- // Add network activity info to track wake up problems.
- if (logger.isInfoEnabled()
- && ((eventID == SystemActivityEvent.EVENT_NETWORK_CHANGE)
- || (eventID == SystemActivityEvent.EVENT_DNS_CHANGE)))
- {
- logger.info("Received system activity event: " + evt);
- }
-
- if (eventID == SystemActivityEvent.EVENT_NETWORK_CHANGE)
- {
- // Give time to Java to dispatch same event and populate its network
- // interfaces.
- eventDispatcher.fireSystemActivityEvent(evt, 500);
- }
- else
- eventDispatcher.fireSystemActivityEvent(evt);
- }
-
- /**
- * Delivers the specified event to all registered listeners.
- *
- * @param listener listener to inform
- */
- protected void fireSystemIdleEvent(SystemActivityChangeListener listener)
- {
- SystemActivityEvent evt
- = new SystemActivityEvent(
- this,
- SystemActivityEvent.EVENT_SYSTEM_IDLE);
-
- if (logger.isDebugEnabled())
- logger.debug("Dispatching SystemActivityEvent evt=" + evt);
-
- try
- {
- listener.activityChanged(evt);
- }
- catch (Throwable t)
- {
- if (t instanceof ThreadDeath)
- throw (ThreadDeath) t;
- else
- logger.error("Error delivering event", t);
- }
- }
-
- /**
- * Delivers the specified event to listener.
- *
- * @param listener listener to inform
- */
- protected void fireSystemIdleEndEvent(
- SystemActivityChangeListener listener)
- {
- SystemActivityEvent evt
- = new SystemActivityEvent(
- this,
- SystemActivityEvent.EVENT_SYSTEM_IDLE_END);
-
- if (logger.isDebugEnabled())
- logger.debug("Dispatching SystemActivityEvent evt=" + evt);
-
- try
- {
- listener.activityChanged(evt);
- }
- catch (Throwable t)
- {
- if (t instanceof ThreadDeath)
- throw (ThreadDeath) t;
- else
- logger.error("Error delivering event", t);
- }
- }
-
- /**
- * Can check whether an event id is supported on
- * current operation system.
- * Simple return what is implemented in native, and checks
- * are made when possible, for example linux cannot connect
- * to NM through dbus.
- * @param eventID the event to check.
- * @return whether the supplied event id is supported.
- */
- public boolean isSupported(int eventID)
- {
- if(OSUtils.IS_WINDOWS)
- {
- switch(eventID)
- {
- case SystemActivityEvent.EVENT_SLEEP:
- case SystemActivityEvent.EVENT_WAKE:
- case SystemActivityEvent.EVENT_NETWORK_CHANGE:
- case SystemActivityEvent.EVENT_SYSTEM_IDLE:
- case SystemActivityEvent.EVENT_SYSTEM_IDLE_END:
- return SystemActivityNotifications.isLoaded();
- default:
- return false;
- }
- }
- else if(OSUtils.IS_MAC)
- {
- return SystemActivityNotifications.isLoaded();
- }
- else if(OSUtils.IS_LINUX)
- {
- switch(eventID)
- {
- case SystemActivityEvent.EVENT_SLEEP:
- case SystemActivityEvent.EVENT_NETWORK_CHANGE:
- {
- SystemActivityManager currentRunningManager
- = getCurrentRunningManager();
-
- return
- (currentRunningManager == null)
- ? false
- : currentRunningManager.isConnected();
- }
- case SystemActivityEvent.EVENT_SYSTEM_IDLE:
- case SystemActivityEvent.EVENT_SYSTEM_IDLE_END:
- return SystemActivityNotifications.isLoaded();
- default:
- return false;
- }
- }
- else if(OSUtils.IS_ANDROID)
- {
- return (eventID == SystemActivityEvent.EVENT_NETWORK_CHANGE);
- }
- else
- {
- return false;
- }
- }
-
- /**
- * Returns or instantiate the manager.
- * @return
- */
- private SystemActivityManager getCurrentRunningManager()
- {
- if(currentRunningManager == null)
- {
- try
- {
- String className = null;
- if(OSUtils.IS_LINUX)
- {
- className = SYSTEM_ACTIVITY_MANAGER_LINUX_CLASS;
- }
- else if(OSUtils.IS_ANDROID)
- {
- className = SYSTEM_ACTIVITY_MANAGER_ANDROID_CLASS;
- }
-
- if(className != null)
- currentRunningManager = (SystemActivityManager)
- Class.forName(className).newInstance();
- }
- catch(Throwable t)
- {
- logger.error("Error creating manager", t);
- }
- }
-
- return currentRunningManager;
- }
-}
+package net.java.sip.communicator.impl.sysactivity;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.sysactivity.*;
+import net.java.sip.communicator.service.sysactivity.event.*;
+import net.java.sip.communicator.util.Logger;
+
+import org.jitsi.util.*;
+
+/**
+ * Service implementation listens for computer changes as sleeping, network
+ * change, inactivity.
+ *
+ * @author Damian Minkov
+ */
+public class SystemActivityNotificationsServiceImpl
+ implements SystemActivityNotifications.NotificationsDelegate,
+ SystemActivityNotificationsService,
+ Runnable
+{
+ /**
+ * The <tt>Logger</tt> used by this
+ * <tt>SystemActivityNotificationsServiceImpl</tt> for logging output.
+ */
+ private final Logger logger
+ = Logger.getLogger(SystemActivityNotificationsServiceImpl.class);
+
+ /**
+ * The thread dispatcher of network change events.
+ */
+ private final SystemActivityEventDispatcher eventDispatcher
+ = new SystemActivityEventDispatcher();
+
+ /**
+ * A list of listeners registered for idle events.
+ */
+ private final Map<SystemActivityChangeListener,Long> idleChangeListeners
+ = new HashMap<SystemActivityChangeListener, Long>();
+
+ /**
+ * Listeners which are fired for idle state and which will be fired
+ * with idle end when needed.
+ */
+ private final List<SystemActivityChangeListener> listenersInIdleState
+ = new ArrayList<SystemActivityChangeListener>();
+
+ /**
+ * The interval between checks when not idle.
+ */
+ private static final int CHECK_FOR_IDLE_DEFAULT = 30 * 1000;
+
+ /**
+ * The interval between checks when idle. The interval is shorter
+ * so we can react almost immediately when we are active again.
+ */
+ private static final int CHECK_FOR_IDLE_WHEN_IDLE = 1000;
+
+ /**
+ * The time in milliseconds between two checks for system idle.
+ */
+ private static int idleStateCheckDelay = CHECK_FOR_IDLE_DEFAULT;
+
+ /**
+ * Whether current service is started or stopped.
+ */
+ private boolean running = false;
+
+ /**
+ * The time when we received latest network change event.
+ */
+ private long lastNetworkChange = -1;
+
+ /**
+ * Sometimes (on windows) we got several network change events
+ * this is the time after which latest event we will skip next events.
+ */
+ private static final long NETWORK_EVENT_SILENT_TIME = 10*1000;
+
+ /**
+ * Whether network is currently connected.
+ */
+ private Boolean networkIsConnected = null;
+
+ /**
+ * The linux impl class name.
+ */
+ private static final String SYSTEM_ACTIVITY_MANAGER_LINUX_CLASS
+ = "net.java.sip.communicator.impl.sysactivity.NetworkManagerListenerImpl";
+
+ /**
+ * The android impl class name.
+ */
+ private static final String SYSTEM_ACTIVITY_MANAGER_ANDROID_CLASS
+ = "net.java.sip.communicator.impl.sysactivity.ConnectivityManagerListenerImpl";
+
+ /**
+ * The currently instantiated and working manager.
+ */
+ private SystemActivityManager currentRunningManager = null;
+
+ /**
+ * Init and start notifications.
+ */
+ public void start()
+ {
+ running = true;
+
+ // set the delegate and start notification in new thread
+ // make sure we don't block startup process
+ Thread notifystartThread
+ = new Thread(
+ new Runnable()
+ {
+ public void run()
+ {
+ SystemActivityNotifications.setDelegate(
+ SystemActivityNotificationsServiceImpl.this);
+ SystemActivityNotifications.start();
+ }
+ },
+ "SystemActivityNotificationsServiceImpl");
+ notifystartThread.setDaemon(true);
+ notifystartThread.start();
+
+ if(isSupported(SystemActivityEvent.EVENT_SYSTEM_IDLE))
+ {
+ // a thread periodically checks system idle state and if it pass the
+ // idle time for a particular listener, will inform it.
+ Thread idleNotifyThread = new Thread(
+ this,
+ "SystemActivityNotificationsServiceImpl.IdleNotifyThread");
+ idleNotifyThread.setDaemon(true);
+ idleNotifyThread.start();
+ }
+
+ if (getCurrentRunningManager() != null)
+ getCurrentRunningManager().start();
+ }
+
+ /**
+ * Stop notifications.
+ */
+ public void stop()
+ {
+ SystemActivityNotifications.stop();
+
+ if (getCurrentRunningManager() != null)
+ getCurrentRunningManager().stop();
+
+ eventDispatcher.stop();
+
+ running = false;
+
+ synchronized(this)
+ {
+ this.notifyAll();
+ }
+ }
+
+ /**
+ * Registers a listener that would be notified of changes that have occurred
+ * in the underlying system.
+ *
+ * @param listener the listener that we'd like to register for changes in
+ * the underlying system.
+ */
+ public void addSystemActivityChangeListener(
+ SystemActivityChangeListener listener)
+ {
+ eventDispatcher.addSystemActivityChangeListener(listener);
+ }
+
+ /**
+ * Remove the specified listener so that it won't receive further
+ * notifications of changes that occur in the underlying system
+ *
+ * @param listener the listener to remove.
+ */
+ public void removeSystemActivityChangeListener(
+ SystemActivityChangeListener listener)
+ {
+ eventDispatcher.removeSystemActivityChangeListener(listener);
+ }
+
+ /**
+ * Registers a listener that would be notified for idle of the system
+ * for <tt>idleTime</tt>.
+ *
+ * @param idleTime the time in milliseconds after which we will consider
+ * system to be idle. This doesn't count when system seems idle as
+ * monitor is off or screensaver is on, or desktop is locked.
+ * @param listener the listener that we'd like to register for changes in
+ * the underlying system.
+ */
+ public void addIdleSystemChangeListener(
+ long idleTime,
+ SystemActivityChangeListener listener)
+ {
+ synchronized (idleChangeListeners)
+ {
+ if (idleTime > 0
+ && !idleChangeListeners.containsKey(listener))
+ idleChangeListeners.put(listener, idleTime);
+ }
+ }
+
+ /**
+ * Remove the specified listener so that it won't receive further
+ * notifications for idle system.
+ *
+ * @param listener the listener to remove.
+ */
+ public void removeIdleSystemChangeListener(
+ SystemActivityChangeListener listener)
+ {
+ synchronized (idleChangeListeners)
+ {
+ idleChangeListeners.remove(listener);
+ }
+ }
+
+ /**
+ * The time since last user input. The time the system has been idle.
+ * @return time the system has been idle.
+ */
+ public long getTimeSinceLastInput()
+ {
+ if(SystemActivityNotifications.isLoaded())
+ return SystemActivityNotifications.getLastInput();
+ else
+ return -1;
+ }
+
+ /**
+ * Callback method when receiving notifications.
+ *
+ * @param type type of the notification.
+ */
+ public void notify(int type)
+ {
+ SystemActivityEvent evt = null;
+ switch(type)
+ {
+ case SystemActivityNotifications.NOTIFY_SLEEP :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_SLEEP);
+ break;
+ case SystemActivityNotifications.NOTIFY_WAKE :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_WAKE);
+ break;
+ case SystemActivityNotifications.NOTIFY_DISPLAY_SLEEP :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_DISPLAY_SLEEP);
+ break;
+ case SystemActivityNotifications.NOTIFY_DISPLAY_WAKE :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_DISPLAY_WAKE);
+ break;
+ case SystemActivityNotifications.NOTIFY_SCREENSAVER_START :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_SCREENSAVER_START);
+ break;
+ case SystemActivityNotifications.NOTIFY_SCREENSAVER_WILL_STOP :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_SCREENSAVER_WILL_STOP);
+ break;
+ case SystemActivityNotifications.NOTIFY_SCREENSAVER_STOP :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_SCREENSAVER_STOP);
+ break;
+ case SystemActivityNotifications.NOTIFY_SCREEN_LOCKED :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_SCREEN_LOCKED);
+ break;
+ case SystemActivityNotifications.NOTIFY_SCREEN_UNLOCKED :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_SCREEN_UNLOCKED);
+ break;
+ case SystemActivityNotifications.NOTIFY_NETWORK_CHANGE :
+ {
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_NETWORK_CHANGE);
+ break;
+ }
+ case SystemActivityNotifications.NOTIFY_DNS_CHANGE :
+ {
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_DNS_CHANGE);
+ break;
+ }
+ case SystemActivityNotifications.NOTIFY_QUERY_ENDSESSION :
+ {
+ // both events QUERY_ENDSESSION and ENDSESSION
+ // depend on the result one after another
+ // we don't put them in new thread in order to give control
+ // in the bundles using this events.
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_QUERY_ENDSESSION);
+ eventDispatcher.fireSystemActivityEventCurrentThread(evt);
+
+ return;
+ }
+ case SystemActivityNotifications.NOTIFY_ENDSESSION :
+ {
+ // both events QUERY_ENDSESSION and ENDSESSION
+ // depend on the result one after another
+ // we don't put them in new thread in order to give control
+ // in the bundles using this events.
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_ENDSESSION);
+ eventDispatcher.fireSystemActivityEventCurrentThread(evt);
+
+ return;
+ }
+ }
+
+ if (evt != null)
+ fireSystemActivityEvent(evt);
+ }
+
+ /**
+ * Callback method when receiving special network notifications.
+ *
+ * @param family family of network change (ipv6, ipv4)
+ * AF_UNSPEC = 0 (The address family is unspecified.)
+ * AF_INET = 2 (The Internet Protocol version 4 (IPv4) address family)
+ * AF_INET6 = 23 (The Internet Protocol version 6 (IPv6) address family)
+ * @param luidIndex unique index of interface
+ * @param name name of the interface
+ * @param type of the interface
+ * Possible values for the interface type are listed in the Ipifcons.h file.
+ * common values:
+ * IF_TYPE_OTHER = 1 (Some other type of network interface.)
+ * IF_TYPE_ETHERNET_CSMACD = 6 (An Ethernet network interface.)
+ * IF_TYPE_ISO88025_TOKENRING = 9 (A token ring network interface.)
+ * IF_TYPE_PPP = 23 (A PPP network interface.)
+ * IF_TYPE_SOFTWARE_LOOPBACK = 24 (A software loopback network interface.)
+ * IF_TYPE_IEEE80211 = 71 (An IEEE 802.11 wireless network interface.)
+ * IF_TYPE_TUNNEL = 131 (A tunnel type encapsulation network interface.)
+ * IF_TYPE_IEEE1394 = 144 (An IEEE 1394 (Firewire) high performance
+ * serial bus network interface.)
+ * @param connected whether interface is connected or not.
+ */
+ public void notifyNetworkChange(
+ int family,
+ long luidIndex,
+ String name,
+ long type,
+ boolean connected)
+ {
+ long current = System.currentTimeMillis();
+ if(current - lastNetworkChange <= NETWORK_EVENT_SILENT_TIME
+ && (networkIsConnected != null && networkIsConnected.equals(connected)))
+ {
+ networkIsConnected = connected;
+ return;
+ }
+
+ lastNetworkChange = current;
+ networkIsConnected = connected;
+
+ SystemActivityEvent evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_NETWORK_CHANGE);
+ fireSystemActivityEvent(evt);
+ }
+
+ /**
+ * The thread run method that handles idle notifies.
+ *
+ * @see Thread#run()
+ */
+ public void run()
+ {
+ while(running)
+ {
+ try
+ {
+ long idleTime = 0;
+ if(idleChangeListeners.size() > 0)
+ {
+ // check
+ idleTime = SystemActivityNotifications.getLastInput();
+
+ if((idleTime < idleStateCheckDelay)
+ && (listenersInIdleState.size() > 0))
+ {
+ for(SystemActivityChangeListener l
+ : listenersInIdleState)
+ {
+ fireSystemIdleEndEvent(l);
+ }
+ listenersInIdleState.clear();
+ }
+
+ for(Map.Entry<SystemActivityChangeListener, Long> entry
+ : idleChangeListeners.entrySet())
+ {
+ SystemActivityChangeListener listener =
+ entry.getKey();
+
+ if(!listenersInIdleState.contains(listener)
+ && (entry.getValue() <= idleTime))
+ {
+ fireSystemIdleEvent(listener);
+
+ listenersInIdleState.add(listener);
+ }
+ }
+ }
+
+ // if the minimum check for idle is X minutes
+ // we will wait before checking (X - Y + 1sec)
+ // where Y is the last idle time returned by OS
+ if(listenersInIdleState.size() > 0)
+ {
+ idleStateCheckDelay = CHECK_FOR_IDLE_WHEN_IDLE;
+ }
+ else if(idleTime != 0)
+ {
+ long minIdleSetting = CHECK_FOR_IDLE_DEFAULT;
+
+ if(!idleChangeListeners.isEmpty())
+ minIdleSetting =
+ Collections.min(idleChangeListeners.values());
+
+ int newSetting = (int)(minIdleSetting - idleTime) + 1000;
+
+ if(newSetting > 0)
+ idleStateCheckDelay = newSetting;
+ else
+ idleStateCheckDelay = CHECK_FOR_IDLE_DEFAULT;
+ }
+ else
+ {
+ idleStateCheckDelay = CHECK_FOR_IDLE_DEFAULT;
+ }
+
+ // wait for the specified time
+ synchronized(this)
+ {
+ this.wait(idleStateCheckDelay);
+ }
+ }
+ catch(UnsatisfiedLinkError t)
+ {
+ logger.error("Missing native impl", t);
+ return;
+ }
+ catch(Throwable t)
+ {
+ logger.error("Error checking for idle", t);
+ }
+ }
+ }
+
+ /**
+ * Delivers the specified event to all registered listeners.
+ *
+ * @param evt the <tt>SystemActivityEvent</tt> that we'd like delivered to
+ * all registered message listeners.
+ */
+ protected void fireSystemActivityEvent(SystemActivityEvent evt)
+ {
+ int eventID = evt.getEventID();
+
+ // Add network activity info to track wake up problems.
+ if (logger.isInfoEnabled()
+ && ((eventID == SystemActivityEvent.EVENT_NETWORK_CHANGE)
+ || (eventID == SystemActivityEvent.EVENT_DNS_CHANGE)))
+ {
+ logger.info("Received system activity event: " + evt);
+ }
+
+ if (eventID == SystemActivityEvent.EVENT_NETWORK_CHANGE)
+ {
+ // Give time to Java to dispatch same event and populate its network
+ // interfaces.
+ eventDispatcher.fireSystemActivityEvent(evt, 500);
+ }
+ else
+ eventDispatcher.fireSystemActivityEvent(evt);
+ }
+
+ /**
+ * Delivers the specified event to all registered listeners.
+ *
+ * @param listener listener to inform
+ */
+ protected void fireSystemIdleEvent(SystemActivityChangeListener listener)
+ {
+ SystemActivityEvent evt
+ = new SystemActivityEvent(
+ this,
+ SystemActivityEvent.EVENT_SYSTEM_IDLE);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Dispatching SystemActivityEvent evt=" + evt);
+
+ try
+ {
+ listener.activityChanged(evt);
+ }
+ catch (Throwable t)
+ {
+ if (t instanceof ThreadDeath)
+ throw (ThreadDeath) t;
+ else
+ logger.error("Error delivering event", t);
+ }
+ }
+
+ /**
+ * Delivers the specified event to listener.
+ *
+ * @param listener listener to inform
+ */
+ protected void fireSystemIdleEndEvent(
+ SystemActivityChangeListener listener)
+ {
+ SystemActivityEvent evt
+ = new SystemActivityEvent(
+ this,
+ SystemActivityEvent.EVENT_SYSTEM_IDLE_END);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Dispatching SystemActivityEvent evt=" + evt);
+
+ try
+ {
+ listener.activityChanged(evt);
+ }
+ catch (Throwable t)
+ {
+ if (t instanceof ThreadDeath)
+ throw (ThreadDeath) t;
+ else
+ logger.error("Error delivering event", t);
+ }
+ }
+
+ /**
+ * Can check whether an event id is supported on
+ * current operation system.
+ * Simple return what is implemented in native, and checks
+ * are made when possible, for example linux cannot connect
+ * to NM through dbus.
+ * @param eventID the event to check.
+ * @return whether the supplied event id is supported.
+ */
+ public boolean isSupported(int eventID)
+ {
+ if(OSUtils.IS_WINDOWS)
+ {
+ switch(eventID)
+ {
+ case SystemActivityEvent.EVENT_SLEEP:
+ case SystemActivityEvent.EVENT_WAKE:
+ case SystemActivityEvent.EVENT_NETWORK_CHANGE:
+ case SystemActivityEvent.EVENT_SYSTEM_IDLE:
+ case SystemActivityEvent.EVENT_SYSTEM_IDLE_END:
+ return SystemActivityNotifications.isLoaded();
+ default:
+ return false;
+ }
+ }
+ else if(OSUtils.IS_MAC)
+ {
+ return SystemActivityNotifications.isLoaded();
+ }
+ else if(OSUtils.IS_LINUX)
+ {
+ switch(eventID)
+ {
+ case SystemActivityEvent.EVENT_SLEEP:
+ case SystemActivityEvent.EVENT_NETWORK_CHANGE:
+ {
+ SystemActivityManager currentRunningManager
+ = getCurrentRunningManager();
+
+ return
+ (currentRunningManager == null)
+ ? false
+ : currentRunningManager.isConnected();
+ }
+ case SystemActivityEvent.EVENT_SYSTEM_IDLE:
+ case SystemActivityEvent.EVENT_SYSTEM_IDLE_END:
+ return SystemActivityNotifications.isLoaded();
+ default:
+ return false;
+ }
+ }
+ else if(OSUtils.IS_ANDROID)
+ {
+ return (eventID == SystemActivityEvent.EVENT_NETWORK_CHANGE);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Returns or instantiate the manager.
+ * @return
+ */
+ private SystemActivityManager getCurrentRunningManager()
+ {
+ if(currentRunningManager == null)
+ {
+ try
+ {
+ String className = null;
+ if(OSUtils.IS_LINUX)
+ {
+ className = SYSTEM_ACTIVITY_MANAGER_LINUX_CLASS;
+ }
+ else if(OSUtils.IS_ANDROID)
+ {
+ className = SYSTEM_ACTIVITY_MANAGER_ANDROID_CLASS;
+ }
+
+ if(className != null)
+ currentRunningManager = (SystemActivityManager)
+ Class.forName(className).newInstance();
+ }
+ catch(Throwable t)
+ {
+ logger.error("Error creating manager", t);
+ }
+ }
+
+ return currentRunningManager;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/version/VersionImpl.java b/src/net/java/sip/communicator/impl/version/VersionImpl.java
index 8bed4ec..74e199c 100644
--- a/src/net/java/sip/communicator/impl/version/VersionImpl.java
+++ b/src/net/java/sip/communicator/impl/version/VersionImpl.java
@@ -42,7 +42,7 @@ public class VersionImpl
* number changes when a relatively extensive set of new features and
* possibly rearchitecturing have been applied to the Jitsi.
*/
- public static final int VERSION_MINOR = 9;
+ public static final int VERSION_MINOR = 11;
/**
* Indicates whether this version represents a prerelease (i.e. a
diff --git a/src/net/java/sip/communicator/launcher/SIPCommunicator.java b/src/net/java/sip/communicator/launcher/SIPCommunicator.java
index 0fccc20..fee1e40 100644
--- a/src/net/java/sip/communicator/launcher/SIPCommunicator.java
+++ b/src/net/java/sip/communicator/launcher/SIPCommunicator.java
@@ -118,7 +118,7 @@ public class SIPCommunicator
{
System.setProperty(
"sun.net.spi.nameservice.provider.1",
- "dns,dnsjava");
+ "dns,jitsi");
}
if (version.startsWith("1.5") || vmVendor.startsWith("Gnu") ||
diff --git a/src/net/java/sip/communicator/plugin/accountinfo/AccountInfoActivator.java b/src/net/java/sip/communicator/plugin/accountinfo/AccountInfoActivator.java
index f2181cd..06b595e 100644
--- a/src/net/java/sip/communicator/plugin/accountinfo/AccountInfoActivator.java
+++ b/src/net/java/sip/communicator/plugin/accountinfo/AccountInfoActivator.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,163 +15,163 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.accountinfo;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.globaldisplaydetails.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.configuration.*;
-import org.osgi.framework.*;
-
-/**
- * Starts the account info bundle.
- *
- * @author Adam Glodstein
- * @author Marin Dzhigarov
- */
-public class AccountInfoActivator
- implements BundleActivator
-{
- private static final Logger logger =
- Logger.getLogger(AccountInfoActivator.class);
-
- /**
- * Property to disable account info in tools menu.
- */
- private static final String ACCOUNT_INFO_TOOLS_MENU_DISABLED_PROP =
- "net.java.sip.communicator.plugin.accountinfo" +
- ".ACCOUNT_INFO_TOOLS_MENU_DISABLED_PROP";
-
- /**
- * Property to disable account info in account config.
- */
- private static final String ACCOUNT_INFO_ACC_CONFIG_DISABLED_PROP =
- "net.java.sip.communicator.plugin.accountinfo" +
- ".ACCOUNT_INFO_ACC_CONFIG_DISABLED_PROP";
-
- /**
- * The OSGi bundle context.
- */
- public static BundleContext bundleContext;
-
- private static GlobalDisplayDetailsService globalDisplayDetailsService;
-
- public void start(BundleContext bc) throws Exception
- {
- AccountInfoActivator.bundleContext = bc;
-
- ConfigurationService config = ServiceUtils.getService(
- bundleContext, ConfigurationService.class);
-
- if(!config.getBoolean(ACCOUNT_INFO_TOOLS_MENU_DISABLED_PROP, false))
- {
- Hashtable<String, String> containerFilter
- = new Hashtable<String, String>();
- containerFilter.put(
- Container.CONTAINER_ID,
- Container.CONTAINER_TOOLS_MENU.getID());
-
- bundleContext.registerService(
- PluginComponentFactory.class.getName(),
- new PluginComponentFactory(Container.CONTAINER_TOOLS_MENU)
- {
- @Override
- protected PluginComponent getPluginInstance()
- {
- return new AccountInfoMenuItemComponent(
- getContainer(), this);
- }
- },
- containerFilter);
- }
-
- if(!config.getBoolean(ACCOUNT_INFO_ACC_CONFIG_DISABLED_PROP, false))
- {
- Hashtable<String, String> containerFilter
- = new Hashtable<String, String>();
- containerFilter.put(
- Container.CONTAINER_ID,
- Container.CONTAINER_ACCOUNT_RIGHT_BUTTON_MENU.getID());
-
- bundleContext.registerService(
- PluginComponentFactory.class.getName(),
- new PluginComponentFactory(
- Container.CONTAINER_ACCOUNT_RIGHT_BUTTON_MENU)
- {
- @Override
- protected PluginComponent getPluginInstance()
- {
- return new AccountInfoMenuItemComponent(
- getContainer(), this);
- }
- },
- containerFilter);
- }
- }
-
- public void stop(BundleContext bc) throws Exception {}
-
- /**
- * Returns all <tt>ProtocolProviderFactory</tt>s obtained from the bundle
- * context.
- *
- * @return all <tt>ProtocolProviderFactory</tt>s obtained from the bundle
- * context
- */
- public static Map<Object, ProtocolProviderFactory>
- getProtocolProviderFactories()
- {
- Map<Object, ProtocolProviderFactory> providerFactoriesMap =
- new Hashtable<Object, ProtocolProviderFactory>();
-
- ServiceReference[] serRefs = null;
- try
- {
- // get all registered provider factories
- serRefs =
- bundleContext.getServiceReferences(
- ProtocolProviderFactory.class.getName(), null);
-
- }
- catch (InvalidSyntaxException e)
- {
- logger.error("LoginManager : " + e);
- }
-
- for (int i = 0; i < serRefs.length; i++)
- {
-
- ProtocolProviderFactory providerFactory =
- (ProtocolProviderFactory) bundleContext.getService(serRefs[i]);
-
- providerFactoriesMap
- .put(serRefs[i].getProperty(ProtocolProviderFactory.PROTOCOL),
- providerFactory);
- }
-
- return providerFactoriesMap;
- }
-
- /**
- * Returns the <tt>GlobalDisplayDetailsService</tt> obtained from the bundle
- * context.
- *
- * @return the <tt>GlobalDisplayDetailsService</tt> obtained from the bundle
- * context
- */
- public static GlobalDisplayDetailsService getGlobalDisplayDetailsService()
- {
- if (globalDisplayDetailsService == null)
- {
- globalDisplayDetailsService
- = ServiceUtils.getService(
- bundleContext,
- GlobalDisplayDetailsService.class);
- }
- return globalDisplayDetailsService;
- }
-}
+package net.java.sip.communicator.plugin.accountinfo;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.globaldisplaydetails.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.configuration.*;
+import org.osgi.framework.*;
+
+/**
+ * Starts the account info bundle.
+ *
+ * @author Adam Glodstein
+ * @author Marin Dzhigarov
+ */
+public class AccountInfoActivator
+ implements BundleActivator
+{
+ private static final Logger logger =
+ Logger.getLogger(AccountInfoActivator.class);
+
+ /**
+ * Property to disable account info in tools menu.
+ */
+ private static final String ACCOUNT_INFO_TOOLS_MENU_DISABLED_PROP =
+ "net.java.sip.communicator.plugin.accountinfo" +
+ ".ACCOUNT_INFO_TOOLS_MENU_DISABLED_PROP";
+
+ /**
+ * Property to disable account info in account config.
+ */
+ private static final String ACCOUNT_INFO_ACC_CONFIG_DISABLED_PROP =
+ "net.java.sip.communicator.plugin.accountinfo" +
+ ".ACCOUNT_INFO_ACC_CONFIG_DISABLED_PROP";
+
+ /**
+ * The OSGi bundle context.
+ */
+ public static BundleContext bundleContext;
+
+ private static GlobalDisplayDetailsService globalDisplayDetailsService;
+
+ public void start(BundleContext bc) throws Exception
+ {
+ AccountInfoActivator.bundleContext = bc;
+
+ ConfigurationService config = ServiceUtils.getService(
+ bundleContext, ConfigurationService.class);
+
+ if(!config.getBoolean(ACCOUNT_INFO_TOOLS_MENU_DISABLED_PROP, false))
+ {
+ Hashtable<String, String> containerFilter
+ = new Hashtable<String, String>();
+ containerFilter.put(
+ Container.CONTAINER_ID,
+ Container.CONTAINER_TOOLS_MENU.getID());
+
+ bundleContext.registerService(
+ PluginComponentFactory.class.getName(),
+ new PluginComponentFactory(Container.CONTAINER_TOOLS_MENU)
+ {
+ @Override
+ protected PluginComponent getPluginInstance()
+ {
+ return new AccountInfoMenuItemComponent(
+ getContainer(), this);
+ }
+ },
+ containerFilter);
+ }
+
+ if(!config.getBoolean(ACCOUNT_INFO_ACC_CONFIG_DISABLED_PROP, false))
+ {
+ Hashtable<String, String> containerFilter
+ = new Hashtable<String, String>();
+ containerFilter.put(
+ Container.CONTAINER_ID,
+ Container.CONTAINER_ACCOUNT_RIGHT_BUTTON_MENU.getID());
+
+ bundleContext.registerService(
+ PluginComponentFactory.class.getName(),
+ new PluginComponentFactory(
+ Container.CONTAINER_ACCOUNT_RIGHT_BUTTON_MENU)
+ {
+ @Override
+ protected PluginComponent getPluginInstance()
+ {
+ return new AccountInfoMenuItemComponent(
+ getContainer(), this);
+ }
+ },
+ containerFilter);
+ }
+ }
+
+ public void stop(BundleContext bc) throws Exception {}
+
+ /**
+ * Returns all <tt>ProtocolProviderFactory</tt>s obtained from the bundle
+ * context.
+ *
+ * @return all <tt>ProtocolProviderFactory</tt>s obtained from the bundle
+ * context
+ */
+ public static Map<Object, ProtocolProviderFactory>
+ getProtocolProviderFactories()
+ {
+ Map<Object, ProtocolProviderFactory> providerFactoriesMap =
+ new Hashtable<Object, ProtocolProviderFactory>();
+
+ ServiceReference[] serRefs = null;
+ try
+ {
+ // get all registered provider factories
+ serRefs =
+ bundleContext.getServiceReferences(
+ ProtocolProviderFactory.class.getName(), null);
+
+ }
+ catch (InvalidSyntaxException e)
+ {
+ logger.error("LoginManager : " + e);
+ }
+
+ for (int i = 0; i < serRefs.length; i++)
+ {
+
+ ProtocolProviderFactory providerFactory =
+ (ProtocolProviderFactory) bundleContext.getService(serRefs[i]);
+
+ providerFactoriesMap
+ .put(serRefs[i].getProperty(ProtocolProviderFactory.PROTOCOL),
+ providerFactory);
+ }
+
+ return providerFactoriesMap;
+ }
+
+ /**
+ * Returns the <tt>GlobalDisplayDetailsService</tt> obtained from the bundle
+ * context.
+ *
+ * @return the <tt>GlobalDisplayDetailsService</tt> obtained from the bundle
+ * context
+ */
+ public static GlobalDisplayDetailsService getGlobalDisplayDetailsService()
+ {
+ if (globalDisplayDetailsService == null)
+ {
+ globalDisplayDetailsService
+ = ServiceUtils.getService(
+ bundleContext,
+ GlobalDisplayDetailsService.class);
+ }
+ return globalDisplayDetailsService;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/accountinfo/AccountInfoPanel.java b/src/net/java/sip/communicator/plugin/accountinfo/AccountInfoPanel.java
index 075aa33..92f0b9a 100644
--- a/src/net/java/sip/communicator/plugin/accountinfo/AccountInfoPanel.java
+++ b/src/net/java/sip/communicator/plugin/accountinfo/AccountInfoPanel.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,349 +15,349 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.accountinfo;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.util.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.plugin.accountinfo.AccountInfoMenuItemComponent.*;
-
-import org.osgi.framework.*;
-
-/**
- * A GUI plug-in for Jitsi that will allow users to set cross
- * protocol account information.
- *
- * @author Adam Goldstein
- * @author Marin Dzhigarov
- */
-public class AccountInfoPanel
- extends TransparentPanel
- implements ServiceListener,
- RegistrationStateChangeListener
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * The panel that contains the currently active <tt>AccountDetailsPanel</tt>
- */
- private final JPanel centerPanel =
- new TransparentPanel(new BorderLayout(10, 10));
-
- /**
- * The currently active <tt>AccountDetailsPanel</tt>
- */
- private AccountDetailsPanel currentDetailsPanel;
-
- /**
- * Combo box that is used for switching between accounts.
- */
- private final JComboBox accountsComboBox;
-
- /**
- * Instances of the <tt>AccountDetailsPanel</tt> are created for every
- * registered <tt>AccountID</tt>. All such pairs are stored in
- * this map.
- */
- private final Map<AccountID, AccountDetailsPanel>
- accountsTable =
- new HashMap<AccountID, AccountDetailsPanel>();
-
- /**
- * The parent dialog.
- */
- private AccountInfoDialog dialog;
-
- /**
- * Creates an instance of <tt>AccountInfoPanel</tt> that contains combo box
- * component with active user accounts and <tt>AccountDetailsPanel</tt> to
- * display and edit account information.
- */
- public AccountInfoPanel(AccountInfoDialog dialog)
- {
- this.dialog = dialog;
-
- setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
-
- accountsComboBox = new JComboBox();
- accountsComboBox.setOpaque(false);
- accountsComboBox.addItemListener(new ItemListener()
- {
- @Override
- public void itemStateChanged(ItemEvent e)
- {
- if (e.getStateChange() == ItemEvent.SELECTED)
- {
- AccountDetailsPanel panel =
- (AccountDetailsPanel) e.getItem();
- panel.setOpaque(false);
- centerPanel.removeAll();
- centerPanel.add(panel, BorderLayout.CENTER);
- centerPanel.revalidate();
- centerPanel.repaint();
- currentDetailsPanel = panel;
- }
- }
- });
-
- init();
-
- centerPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
-
- ComboBoxRenderer renderer = new ComboBoxRenderer();
- accountsComboBox.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
- accountsComboBox.setRenderer(renderer);
-
- JLabel comboLabel = new JLabel(
- Resources.getString(
- "plugin.accountinfo.SELECT_ACCOUNT"));
- comboLabel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
-
- JPanel comboBoxPanel = new TransparentPanel();
- comboBoxPanel.setLayout(new BoxLayout(comboBoxPanel, BoxLayout.X_AXIS));
- comboBoxPanel.setBorder(
- BorderFactory.createEmptyBorder(10, 10, 10, 10));
-
- comboBoxPanel.add(comboLabel);
- comboBoxPanel.add(accountsComboBox);
-
- add(comboBoxPanel);
- add(centerPanel);
- }
-
- /**
- * Initialize.
- */
- private void init()
- {
- AccountInfoActivator.bundleContext.addServiceListener(this);
-
- for (ProtocolProviderFactory providerFactory : AccountInfoActivator
- .getProtocolProviderFactories().values())
- {
- ArrayList<AccountID> accountsList =
- providerFactory.getRegisteredAccounts();
-
- ServiceReference serRef;
- ProtocolProviderService protocolProvider;
-
- for (AccountID accountID : accountsList)
- {
- serRef = providerFactory.getProviderForAccount(accountID);
-
- protocolProvider = (ProtocolProviderService)AccountInfoActivator
- .bundleContext.getService(serRef);
-
- currentDetailsPanel = new AccountDetailsPanel(
- dialog,
- protocolProvider);
-
- accountsTable.put(
- protocolProvider.getAccountID(), currentDetailsPanel);
-
- accountsComboBox.addItem(currentDetailsPanel);
-
- protocolProvider.addRegistrationStateChangeListener(this);
- }
- }
- }
-
- /**
- * Clears all listeners.
- */
- public void dispose()
- {
- AccountInfoActivator.bundleContext.removeServiceListener(this);
-
- for(AccountDetailsPanel pan : accountsTable.values())
- {
- pan.getProtocolProvider()
- .removeRegistrationStateChangeListener(this);
- }
- }
-
- /**
- * A custom renderer to display properly <tt>AccountDetailsPanel</tt>
- * in a combo box.
- */
- private class ComboBoxRenderer extends DefaultListCellRenderer
- {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- @Override
- public Component getListCellRendererComponent(
- JList list, Object value, int index,
- boolean isSelected, boolean hasFocus)
- {
- JLabel renderer
- = (JLabel) super.getListCellRendererComponent(
- list, value, index, isSelected, hasFocus);
-
- if (value != null)
- {
- AccountDetailsPanel panel = (AccountDetailsPanel) value;
-
- renderer.setText(
- panel.protocolProvider.getAccountID().getUserID());
- ImageIcon protocolIcon =
- new ImageIcon(panel.protocolProvider.getProtocolIcon().
- getIcon((ProtocolIcon.ICON_SIZE_16x16)));
- renderer.setIcon(protocolIcon);
- }
-
- return renderer;
- }
- }
-
- public void registrationStateChanged(final RegistrationStateChangeEvent evt)
- {
- if(!SwingUtilities.isEventDispatchThread())
- {
- SwingUtilities.invokeLater(new Runnable()
- {
- public void run()
- {
- registrationStateChanged(evt);
- }
- });
- return;
- }
-
- ProtocolProviderService protocolProvider = evt.getProvider();
-
- if (evt.getNewState() == RegistrationState.REGISTERED)
- {
- if (accountsTable.containsKey(protocolProvider.getAccountID()))
- {
- AccountDetailsPanel detailsPanel
- = accountsTable.get(protocolProvider.getAccountID());
- detailsPanel.loadDetails();
- }
- else
- {
- AccountDetailsPanel panel =
- new AccountDetailsPanel(dialog, protocolProvider);
- accountsTable.put(protocolProvider.getAccountID(), panel);
- accountsComboBox.addItem(panel);
- }
- }
- else if (evt.getNewState() == RegistrationState.UNREGISTERING)
- {
- AccountDetailsPanel panel
- = accountsTable.get(protocolProvider.getAccountID());
- if (panel != null)
- {
- accountsTable.remove(protocolProvider.getAccountID());
- accountsComboBox.removeItem(panel);
- if (currentDetailsPanel == panel)
- {
- currentDetailsPanel = null;
- centerPanel.removeAll();
- centerPanel.revalidate();
- centerPanel.repaint();
- }
- }
- }
- }
-
- /**
- * Handles registration and unregistration of
- * <tt>ProtocolProviderService</tt>
- *
- * @param event
- */
- @Override
- public void serviceChanged(final ServiceEvent event)
- {
- if(!SwingUtilities.isEventDispatchThread())
- {
- SwingUtilities.invokeLater(new Runnable()
- {
- public void run()
- {
- serviceChanged(event);
- }
- });
- return;
- }
-
- // Get the service from the event.
- Object service
- = AccountInfoActivator.bundleContext.getService(
- event.getServiceReference());
-
- // We are not interested in any services
- // other than ProtocolProviderService
- if (!(service instanceof ProtocolProviderService))
- return;
-
- ProtocolProviderService protocolProvider =
- (ProtocolProviderService) service;
-
- // If a new protocol provider is registered we to add new
- // AccountDetailsPanel to the combo box containing active accounts.
- if (event.getType() == ServiceEvent.REGISTERED)
- {
- if (accountsTable.get(protocolProvider.getAccountID()) == null)
- {
- AccountDetailsPanel panel =
- new AccountDetailsPanel(dialog, protocolProvider);
- accountsTable.put(protocolProvider.getAccountID(), panel);
- accountsComboBox.addItem(panel);
- protocolProvider.addRegistrationStateChangeListener(this);
- }
- }
- // If the protocol provider is being unregistered we have to remove
- // a AccountDetailsPanel from the combo box containing active accounts.
- else if (event.getType() == ServiceEvent.UNREGISTERING)
- {
- AccountDetailsPanel panel
- = accountsTable.get(protocolProvider.getAccountID());
- if (panel != null)
- {
- accountsTable.remove(protocolProvider.getAccountID());
- accountsComboBox.removeItem(panel);
- if (currentDetailsPanel == panel)
- {
- currentDetailsPanel = null;
- centerPanel.removeAll();
- centerPanel.revalidate();
- centerPanel.repaint();
- }
- }
- }
- }
-
- /**
- * Returns the combo box that switches between account detail panels.
- *
- * @return The combo box that switches between account detail panels.
- */
- public JComboBox getAccountsComboBox()
- {
- return accountsComboBox;
- }
-
- /**
- * Returns mapping between registered AccountIDs and their respective
- * AccountDetailsPanel that contains all the details for the account.
- *
- * @return mapping between registered AccountIDs and AccountDetailsPanel.
- */
- public Map<AccountID, AccountDetailsPanel> getAccountsTable()
- {
- return accountsTable;
- }
-}
+package net.java.sip.communicator.plugin.accountinfo;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.plugin.accountinfo.AccountInfoMenuItemComponent.*;
+
+import org.osgi.framework.*;
+
+/**
+ * A GUI plug-in for Jitsi that will allow users to set cross
+ * protocol account information.
+ *
+ * @author Adam Goldstein
+ * @author Marin Dzhigarov
+ */
+public class AccountInfoPanel
+ extends TransparentPanel
+ implements ServiceListener,
+ RegistrationStateChangeListener
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * The panel that contains the currently active <tt>AccountDetailsPanel</tt>
+ */
+ private final JPanel centerPanel =
+ new TransparentPanel(new BorderLayout(10, 10));
+
+ /**
+ * The currently active <tt>AccountDetailsPanel</tt>
+ */
+ private AccountDetailsPanel currentDetailsPanel;
+
+ /**
+ * Combo box that is used for switching between accounts.
+ */
+ private final JComboBox accountsComboBox;
+
+ /**
+ * Instances of the <tt>AccountDetailsPanel</tt> are created for every
+ * registered <tt>AccountID</tt>. All such pairs are stored in
+ * this map.
+ */
+ private final Map<AccountID, AccountDetailsPanel>
+ accountsTable =
+ new HashMap<AccountID, AccountDetailsPanel>();
+
+ /**
+ * The parent dialog.
+ */
+ private AccountInfoDialog dialog;
+
+ /**
+ * Creates an instance of <tt>AccountInfoPanel</tt> that contains combo box
+ * component with active user accounts and <tt>AccountDetailsPanel</tt> to
+ * display and edit account information.
+ */
+ public AccountInfoPanel(AccountInfoDialog dialog)
+ {
+ this.dialog = dialog;
+
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+
+ accountsComboBox = new JComboBox();
+ accountsComboBox.setOpaque(false);
+ accountsComboBox.addItemListener(new ItemListener()
+ {
+ @Override
+ public void itemStateChanged(ItemEvent e)
+ {
+ if (e.getStateChange() == ItemEvent.SELECTED)
+ {
+ AccountDetailsPanel panel =
+ (AccountDetailsPanel) e.getItem();
+ panel.setOpaque(false);
+ centerPanel.removeAll();
+ centerPanel.add(panel, BorderLayout.CENTER);
+ centerPanel.revalidate();
+ centerPanel.repaint();
+ currentDetailsPanel = panel;
+ }
+ }
+ });
+
+ init();
+
+ centerPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+
+ ComboBoxRenderer renderer = new ComboBoxRenderer();
+ accountsComboBox.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
+ accountsComboBox.setRenderer(renderer);
+
+ JLabel comboLabel = new JLabel(
+ Resources.getString(
+ "plugin.accountinfo.SELECT_ACCOUNT"));
+ comboLabel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
+
+ JPanel comboBoxPanel = new TransparentPanel();
+ comboBoxPanel.setLayout(new BoxLayout(comboBoxPanel, BoxLayout.X_AXIS));
+ comboBoxPanel.setBorder(
+ BorderFactory.createEmptyBorder(10, 10, 10, 10));
+
+ comboBoxPanel.add(comboLabel);
+ comboBoxPanel.add(accountsComboBox);
+
+ add(comboBoxPanel);
+ add(centerPanel);
+ }
+
+ /**
+ * Initialize.
+ */
+ private void init()
+ {
+ AccountInfoActivator.bundleContext.addServiceListener(this);
+
+ for (ProtocolProviderFactory providerFactory : AccountInfoActivator
+ .getProtocolProviderFactories().values())
+ {
+ ArrayList<AccountID> accountsList =
+ providerFactory.getRegisteredAccounts();
+
+ ServiceReference serRef;
+ ProtocolProviderService protocolProvider;
+
+ for (AccountID accountID : accountsList)
+ {
+ serRef = providerFactory.getProviderForAccount(accountID);
+
+ protocolProvider = (ProtocolProviderService)AccountInfoActivator
+ .bundleContext.getService(serRef);
+
+ currentDetailsPanel = new AccountDetailsPanel(
+ dialog,
+ protocolProvider);
+
+ accountsTable.put(
+ protocolProvider.getAccountID(), currentDetailsPanel);
+
+ accountsComboBox.addItem(currentDetailsPanel);
+
+ protocolProvider.addRegistrationStateChangeListener(this);
+ }
+ }
+ }
+
+ /**
+ * Clears all listeners.
+ */
+ public void dispose()
+ {
+ AccountInfoActivator.bundleContext.removeServiceListener(this);
+
+ for(AccountDetailsPanel pan : accountsTable.values())
+ {
+ pan.getProtocolProvider()
+ .removeRegistrationStateChangeListener(this);
+ }
+ }
+
+ /**
+ * A custom renderer to display properly <tt>AccountDetailsPanel</tt>
+ * in a combo box.
+ */
+ private class ComboBoxRenderer extends DefaultListCellRenderer
+ {
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ @Override
+ public Component getListCellRendererComponent(
+ JList list, Object value, int index,
+ boolean isSelected, boolean hasFocus)
+ {
+ JLabel renderer
+ = (JLabel) super.getListCellRendererComponent(
+ list, value, index, isSelected, hasFocus);
+
+ if (value != null)
+ {
+ AccountDetailsPanel panel = (AccountDetailsPanel) value;
+
+ renderer.setText(
+ panel.protocolProvider.getAccountID().getUserID());
+ ImageIcon protocolIcon =
+ new ImageIcon(panel.protocolProvider.getProtocolIcon().
+ getIcon((ProtocolIcon.ICON_SIZE_16x16)));
+ renderer.setIcon(protocolIcon);
+ }
+
+ return renderer;
+ }
+ }
+
+ public void registrationStateChanged(final RegistrationStateChangeEvent evt)
+ {
+ if(!SwingUtilities.isEventDispatchThread())
+ {
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ registrationStateChanged(evt);
+ }
+ });
+ return;
+ }
+
+ ProtocolProviderService protocolProvider = evt.getProvider();
+
+ if (evt.getNewState() == RegistrationState.REGISTERED)
+ {
+ if (accountsTable.containsKey(protocolProvider.getAccountID()))
+ {
+ AccountDetailsPanel detailsPanel
+ = accountsTable.get(protocolProvider.getAccountID());
+ detailsPanel.loadDetails();
+ }
+ else
+ {
+ AccountDetailsPanel panel =
+ new AccountDetailsPanel(dialog, protocolProvider);
+ accountsTable.put(protocolProvider.getAccountID(), panel);
+ accountsComboBox.addItem(panel);
+ }
+ }
+ else if (evt.getNewState() == RegistrationState.UNREGISTERING)
+ {
+ AccountDetailsPanel panel
+ = accountsTable.get(protocolProvider.getAccountID());
+ if (panel != null)
+ {
+ accountsTable.remove(protocolProvider.getAccountID());
+ accountsComboBox.removeItem(panel);
+ if (currentDetailsPanel == panel)
+ {
+ currentDetailsPanel = null;
+ centerPanel.removeAll();
+ centerPanel.revalidate();
+ centerPanel.repaint();
+ }
+ }
+ }
+ }
+
+ /**
+ * Handles registration and unregistration of
+ * <tt>ProtocolProviderService</tt>
+ *
+ * @param event
+ */
+ @Override
+ public void serviceChanged(final ServiceEvent event)
+ {
+ if(!SwingUtilities.isEventDispatchThread())
+ {
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ serviceChanged(event);
+ }
+ });
+ return;
+ }
+
+ // Get the service from the event.
+ Object service
+ = AccountInfoActivator.bundleContext.getService(
+ event.getServiceReference());
+
+ // We are not interested in any services
+ // other than ProtocolProviderService
+ if (!(service instanceof ProtocolProviderService))
+ return;
+
+ ProtocolProviderService protocolProvider =
+ (ProtocolProviderService) service;
+
+ // If a new protocol provider is registered we to add new
+ // AccountDetailsPanel to the combo box containing active accounts.
+ if (event.getType() == ServiceEvent.REGISTERED)
+ {
+ if (accountsTable.get(protocolProvider.getAccountID()) == null)
+ {
+ AccountDetailsPanel panel =
+ new AccountDetailsPanel(dialog, protocolProvider);
+ accountsTable.put(protocolProvider.getAccountID(), panel);
+ accountsComboBox.addItem(panel);
+ protocolProvider.addRegistrationStateChangeListener(this);
+ }
+ }
+ // If the protocol provider is being unregistered we have to remove
+ // a AccountDetailsPanel from the combo box containing active accounts.
+ else if (event.getType() == ServiceEvent.UNREGISTERING)
+ {
+ AccountDetailsPanel panel
+ = accountsTable.get(protocolProvider.getAccountID());
+ if (panel != null)
+ {
+ accountsTable.remove(protocolProvider.getAccountID());
+ accountsComboBox.removeItem(panel);
+ if (currentDetailsPanel == panel)
+ {
+ currentDetailsPanel = null;
+ centerPanel.removeAll();
+ centerPanel.revalidate();
+ centerPanel.repaint();
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the combo box that switches between account detail panels.
+ *
+ * @return The combo box that switches between account detail panels.
+ */
+ public JComboBox getAccountsComboBox()
+ {
+ return accountsComboBox;
+ }
+
+ /**
+ * Returns mapping between registered AccountIDs and their respective
+ * AccountDetailsPanel that contains all the details for the account.
+ *
+ * @return mapping between registered AccountIDs and AccountDetailsPanel.
+ */
+ public Map<AccountID, AccountDetailsPanel> getAccountsTable()
+ {
+ return accountsTable;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/accountinfo/Resources.java b/src/net/java/sip/communicator/plugin/accountinfo/Resources.java
index 4557782..7c5987a 100644
--- a/src/net/java/sip/communicator/plugin/accountinfo/Resources.java
+++ b/src/net/java/sip/communicator/plugin/accountinfo/Resources.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,65 +15,65 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.accountinfo;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.service.resources.*;
-
-import org.jitsi.service.resources.*;
-
-/**
- * The <tt>Resources</tt> class manages the access to the internationalization
- * properties files and the image resources used in this plugin.
- *
- * @author Yana Stamcheva
- */
-public class Resources
-{
- private static ResourceManagementService resourcesService;
-
- /**
- * Returns an internationalized string corresponding to the given key.
- * @param key The key of the string.
- * @return An internationalized string corresponding to the given key.
- */
- public static String getString(String key)
- {
- return getResources().getI18NString(key);
- }
-
- /**
- * Loads an image from a given image identifier.
- * @param imageID The identifier of the image.
- * @return The image for the given identifier.
- */
- public static ImageIcon getImage(String imageID)
- {
- return getResources().getImage(imageID);
- }
-
- /**
- * Loads an image from a given image identifier.
- * @param imageID The identifier of the image.
- * @return The image for the given identifier.
- */
- public static byte[] getImageInBytes(String imageID)
- {
- return getResources().getImageInBytes(imageID);
- }
-
- /**
- * Returns the <tt>ResourceManagementService</tt>.
- *
- * @return the <tt>ResourceManagementService</tt>.
- */
- public static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- resourcesService =
- ResourceManagementServiceUtils
- .getService(AccountInfoActivator.bundleContext);
- return resourcesService;
- }
-}
+package net.java.sip.communicator.plugin.accountinfo;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.service.resources.*;
+
+import org.jitsi.service.resources.*;
+
+/**
+ * The <tt>Resources</tt> class manages the access to the internationalization
+ * properties files and the image resources used in this plugin.
+ *
+ * @author Yana Stamcheva
+ */
+public class Resources
+{
+ private static ResourceManagementService resourcesService;
+
+ /**
+ * Returns an internationalized string corresponding to the given key.
+ * @param key The key of the string.
+ * @return An internationalized string corresponding to the given key.
+ */
+ public static String getString(String key)
+ {
+ return getResources().getI18NString(key);
+ }
+
+ /**
+ * Loads an image from a given image identifier.
+ * @param imageID The identifier of the image.
+ * @return The image for the given identifier.
+ */
+ public static ImageIcon getImage(String imageID)
+ {
+ return getResources().getImage(imageID);
+ }
+
+ /**
+ * Loads an image from a given image identifier.
+ * @param imageID The identifier of the image.
+ * @return The image for the given identifier.
+ */
+ public static byte[] getImageInBytes(String imageID)
+ {
+ return getResources().getImageInBytes(imageID);
+ }
+
+ /**
+ * Returns the <tt>ResourceManagementService</tt>.
+ *
+ * @return the <tt>ResourceManagementService</tt>.
+ */
+ public static ResourceManagementService getResources()
+ {
+ if (resourcesService == null)
+ resourcesService =
+ ResourceManagementServiceUtils
+ .getService(AccountInfoActivator.bundleContext);
+ return resourcesService;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/addrbook/AdvancedConfigForm.java b/src/net/java/sip/communicator/plugin/addrbook/AdvancedConfigForm.java
index 402f549..85ccd76 100644
--- a/src/net/java/sip/communicator/plugin/addrbook/AdvancedConfigForm.java
+++ b/src/net/java/sip/communicator/plugin/addrbook/AdvancedConfigForm.java
@@ -25,6 +25,7 @@ import javax.swing.*;
import net.java.sip.communicator.plugin.addrbook.macosx.*;
import net.java.sip.communicator.plugin.addrbook.msoutlook.*;
import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.service.calendar.CalendarService;
import org.jitsi.util.*;
@@ -67,13 +68,16 @@ public class AdvancedConfigForm
if (OSUtils.IS_MAC)
propertiesPanel.add(createEnableCheckBox(
AddrBookActivator.PNAME_ENABLE_MACOSX_ADDRESS_BOOK_SEARCH,
- "plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK"));
+ "plugin.addrbook.ENABLE_MACOSX_ADDRESSBOOK", true));
if (OSUtils.IS_WINDOWS)
{
propertiesPanel.add(createEnableCheckBox(
AddrBookActivator.PNAME_ENABLE_MICROSOFT_OUTLOOK_SEARCH,
- "plugin.addrbook.ENABLE_MICROSOFT_OUTLOOK"));
+ "plugin.addrbook.ENABLE_MICROSOFT_OUTLOOK", true));
+ propertiesPanel.add(createEnableCheckBox(
+ CalendarService.PNAME_FREE_BUSY_STATUS_DISABLED,
+ "plugin.addrbook.ENABLE_OUTLOOK_CALENDAR", false));
if(AddrBookActivator.getConfigService().getBoolean(
AddrBookActivator.PNAME_ENABLE_DEFAULT_IM_APPLICATION_CHANGE,
true))
@@ -95,13 +99,14 @@ public class AdvancedConfigForm
* @return the created enable check box
*/
private Component createEnableCheckBox(final String configPropName,
- String labelNameKey)
+ String labelNameKey,
+ boolean defaultValue)
{
final JCheckBox checkBox = new SIPCommCheckBox(AddrBookActivator
.getResources().getI18NString(
labelNameKey),
AddrBookActivator.getConfigService().getBoolean(configPropName,
- true));
+ defaultValue));
checkBox.setAlignmentX(Component.LEFT_ALIGNMENT);
checkBox.addActionListener(new ActionListener()
@@ -113,9 +118,15 @@ public class AdvancedConfigForm
new Boolean(checkBox.isSelected()).toString());
if (checkBox.isSelected())
+ {
AddrBookActivator.startService();
+ AddrBookActivator.startCalendarService();
+ }
else
+ {
AddrBookActivator.stopService();
+ AddrBookActivator.stopCalendarService();
+ }
}
});
return checkBox;
diff --git a/src/net/java/sip/communicator/plugin/addrbook/PtrCallback.java b/src/net/java/sip/communicator/plugin/addrbook/PtrCallback.java
index a06c778..674f261 100644
--- a/src/net/java/sip/communicator/plugin/addrbook/PtrCallback.java
+++ b/src/net/java/sip/communicator/plugin/addrbook/PtrCallback.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,23 +15,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.addrbook;
-
-/**
- * Defines the interface for a callback function which is called by the native
- * counterpart of the support for the OS-specific Address Book with a pointer as
- * its argument.
- *
- * @author Lyubomir Marinov
- */
-public interface PtrCallback
-{
- /**
- * Notifies this <tt>PtrCallback</tt> about a specific pointer.
- *
- * @param ptr the pointer to notify this <tt>PtrCallback</tt> about
- * @return <tt>true</tt> if this <tt>PtrCallback</tt> is to continue being
- * called; otherwise, <tt>false</tt>
- */
- boolean callback(long ptr);
-}
+package net.java.sip.communicator.plugin.addrbook;
+
+/**
+ * Defines the interface for a callback function which is called by the native
+ * counterpart of the support for the OS-specific Address Book with a pointer as
+ * its argument.
+ *
+ * @author Lyubomir Marinov
+ */
+public interface PtrCallback
+{
+ /**
+ * Notifies this <tt>PtrCallback</tt> about a specific pointer.
+ *
+ * @param ptr the pointer to notify this <tt>PtrCallback</tt> about
+ * @return <tt>true</tt> if this <tt>PtrCallback</tt> is to continue being
+ * called; otherwise, <tt>false</tt>
+ */
+ boolean callback(long ptr);
+}
diff --git a/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactQuery.java b/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactQuery.java
index 0658d59..81a4aad 100644
--- a/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactQuery.java
+++ b/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactQuery.java
@@ -419,7 +419,7 @@ public class MacOSXAddrBookContactQuery
c = Category.InstantMessaging;
break;
case kABMSNInstantProperty:
- sc = SubCategory.MSN;
+ sc = SubCategory.Skype;
c = Category.InstantMessaging;
break;
case kABYahooInstantProperty:
@@ -1240,12 +1240,6 @@ public class MacOSXAddrBookContactQuery
case kABPhoneProperty:
supportedOpSets.add(OperationSetBasicTelephony.class);
break;
- case kABYahooInstantProperty:
- supportedOpSets.add(OperationSetBasicInstantMessaging.class);
- preferredProtocols.put(
- OperationSetBasicInstantMessaging.class,
- ProtocolNames.YAHOO);
- break;
default:
break;
}
@@ -1339,7 +1333,7 @@ public class MacOSXAddrBookContactQuery
return kABAIMInstantProperty;
else if(subCategories.contains(SubCategory.ICQ))
return kABICQInstantProperty;
- else if(subCategories.contains(SubCategory.MSN))
+ else if(subCategories.contains(SubCategory.Skype))
return kABMSNInstantProperty;
else if(subCategories.contains(SubCategory.Jabber))
return kABJabberInstantProperty;
diff --git a/src/net/java/sip/communicator/plugin/addrbook/msoutlook/DefaultMailClientMessageDialog.java b/src/net/java/sip/communicator/plugin/addrbook/msoutlook/DefaultMailClientMessageDialog.java
index 84d9525..afec158 100644
--- a/src/net/java/sip/communicator/plugin/addrbook/msoutlook/DefaultMailClientMessageDialog.java
+++ b/src/net/java/sip/communicator/plugin/addrbook/msoutlook/DefaultMailClientMessageDialog.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,94 +15,94 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.addrbook.msoutlook;
-
-import java.awt.event.*;
-
-import javax.swing.*;
-
-import org.jitsi.service.resources.*;
-
-import net.java.sip.communicator.plugin.addrbook.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
-
-/**
- * A dialog with warning message that Outlook is not the default mail client
- * shown when the contact source is started.
- *
- * @author Hristo Terezov
- */
-public class DefaultMailClientMessageDialog
- extends MessageDialog
-{
-
- /**
- * Serial ID.
- */
- private static final long serialVersionUID = -6321186451307613417L;
-
- /**
- * The <tt>ResourceManagementService</tt>
- */
- private static ResourceManagementService resources
- = AddrBookActivator.getResources();
-
- /**
- * Make Outlook default mail client check box.
- */
- private JCheckBox defaultMailClientCheckBox = new SIPCommCheckBox(
- resources
- .getI18NString("plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT"));
-
- public static int DONT_ASK_SELECTED_MASK = 1;
-
- public static int DEFAULT_MAIL_CLIENT_SELECTED_MASK = 2;
-
- /**
- * Creates an instance of <tt>DefaultMailClientMessageDialog</tt>.
- */
- public DefaultMailClientMessageDialog()
- {
- super(null,
- AddrBookActivator.getResources().getI18NString(
- "plugin.addrbook.OUTLOOK_IS_NOT_DEFAULT_MAIL_CLIENT_TITLE"),
- resources.getI18NString(
- "plugin.addrbook.OUTLOOK_IS_NOT_DEFAULT_MAIL_CLIENT",
- new String[]{
- resources.getSettingsString(
- "service.gui.APPLICATION_NAME")}), false);
- checkBoxPanel.setLayout(new BoxLayout(checkBoxPanel, BoxLayout.Y_AXIS));
- checkBoxPanel.add(defaultMailClientCheckBox);
- }
-
-
- /**
- * Handles the <tt>ActionEvent</tt>. Depending on the user choice sets
- * the return code to the appropriate value.
- *
- * @param e the <tt>ActionEvent</tt> that notified us
- */
- public void actionPerformed(ActionEvent e)
- {
- JButton button = (JButton)e.getSource();
-
- if(!button.equals(okButton))
- return;
-
- this.returnCode = 0;
-
- if (doNotAskAgain.isSelected())
- {
- this.returnCode = this.returnCode | DONT_ASK_SELECTED_MASK;
- }
-
- if (defaultMailClientCheckBox.isSelected())
- {
- this.returnCode
- = this.returnCode | DEFAULT_MAIL_CLIENT_SELECTED_MASK;
- }
-
- this.dispose();
- }
-
-}
+package net.java.sip.communicator.plugin.addrbook.msoutlook;
+
+import java.awt.event.*;
+
+import javax.swing.*;
+
+import org.jitsi.service.resources.*;
+
+import net.java.sip.communicator.plugin.addrbook.*;
+import net.java.sip.communicator.plugin.desktoputil.*;
+
+/**
+ * A dialog with warning message that Outlook is not the default mail client
+ * shown when the contact source is started.
+ *
+ * @author Hristo Terezov
+ */
+public class DefaultMailClientMessageDialog
+ extends MessageDialog
+{
+
+ /**
+ * Serial ID.
+ */
+ private static final long serialVersionUID = -6321186451307613417L;
+
+ /**
+ * The <tt>ResourceManagementService</tt>
+ */
+ private static ResourceManagementService resources
+ = AddrBookActivator.getResources();
+
+ /**
+ * Make Outlook default mail client check box.
+ */
+ private JCheckBox defaultMailClientCheckBox = new SIPCommCheckBox(
+ resources
+ .getI18NString("plugin.addrbook.MAKE_OUTLOOK_DEFAULT_MAIL_CLIENT"));
+
+ public static int DONT_ASK_SELECTED_MASK = 1;
+
+ public static int DEFAULT_MAIL_CLIENT_SELECTED_MASK = 2;
+
+ /**
+ * Creates an instance of <tt>DefaultMailClientMessageDialog</tt>.
+ */
+ public DefaultMailClientMessageDialog()
+ {
+ super(null,
+ AddrBookActivator.getResources().getI18NString(
+ "plugin.addrbook.OUTLOOK_IS_NOT_DEFAULT_MAIL_CLIENT_TITLE"),
+ resources.getI18NString(
+ "plugin.addrbook.OUTLOOK_IS_NOT_DEFAULT_MAIL_CLIENT",
+ new String[]{
+ resources.getSettingsString(
+ "service.gui.APPLICATION_NAME")}), false);
+ checkBoxPanel.setLayout(new BoxLayout(checkBoxPanel, BoxLayout.Y_AXIS));
+ checkBoxPanel.add(defaultMailClientCheckBox);
+ }
+
+
+ /**
+ * Handles the <tt>ActionEvent</tt>. Depending on the user choice sets
+ * the return code to the appropriate value.
+ *
+ * @param e the <tt>ActionEvent</tt> that notified us
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ JButton button = (JButton)e.getSource();
+
+ if(!button.equals(okButton))
+ return;
+
+ this.returnCode = 0;
+
+ if (doNotAskAgain.isSelected())
+ {
+ this.returnCode = this.returnCode | DONT_ASK_SELECTED_MASK;
+ }
+
+ if (defaultMailClientCheckBox.isSelected())
+ {
+ this.returnCode
+ = this.returnCode | DEFAULT_MAIL_CLIENT_SELECTED_MASK;
+ }
+
+ this.dispose();
+ }
+
+}
diff --git a/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookMAPIHResultException.java b/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookMAPIHResultException.java
index ff4a614..f27b77d 100644
--- a/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookMAPIHResultException.java
+++ b/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookMAPIHResultException.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,110 +15,110 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.addrbook.msoutlook;
-
-/**
- * Represents a specific Microsoft Outlook MAPI <tt>HRESULT</tt> as an
- * <tt>Exception</tt>.
- *
- * @author Lyubomir Marinov
- */
-public class MsOutlookMAPIHResultException
- extends Exception
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * The <tt>HRESULT</tt> which is represented by this <tt>Exception</tt>.
- */
- private final long hResult;
-
- /**
- * Initializes a new <tt>MsOutlookMAPIHResultException</tt> instance which
- * is to represent a specific <tt>HRESULT</tt>.
- *
- * @param hResult the <tt>HRESULT</tt> to be represented by the new instance
- */
- public MsOutlookMAPIHResultException(long hResult)
- {
- this(hResult, toString(hResult));
- }
-
- /**
- * Initializes a new <tt>MsOutlookMAPIHResultException</tt> instance which
- * is to represent a specific <tt>HRESULT</tt> and to provide a specific
- * <tt>String</tt> message.
- *
- * @param hResult the <tt>HRESULT</tt> to be represented by the new instance
- * @param message the <tt>String</tt> message to be provided by the new
- * instance
- */
- public MsOutlookMAPIHResultException(long hResult, String message)
- {
- super(message);
-
- this.hResult = hResult;
- }
-
- /**
- * Initializes a new <tt>MsOutlookMAPIHResultException</tt> instance with a
- * specific <tt>String</tt> message.
- *
- * @param message the <tt>String</tt> message to be provided by the new
- * instance
- */
- public MsOutlookMAPIHResultException(String message)
- {
- this(0, message);
- }
-
- /**
- * Gets the <tt>HRESULT</tt> which is represented by this
- * <tt>Exception</tt>.
- *
- * @return the <tt>HRESULT</tt> which is represented by this
- * <tt>Exception</tt>
- */
- public long getHResult()
- {
- return hResult;
- }
-
- /**
- * Converts a specific <tt>HRESULT</tt> to a touch more readable
- * <tt>String</tt> in accord with the rule of constructing MAPI
- * <tt>HRESULT</tt> values.
- *
- * @param hResult the <tt>HRESULT</tt> to convert
- * @return a <tt>String</tt> which represents the specified <tt>hResult</tt>
- * in a touch more readable form
- */
- private static String toString(long hResult)
- {
- if (hResult == 0)
- return "S_OK";
- else
- {
- StringBuilder s = new StringBuilder("MAPI_");
-
- s.append(((hResult & 0x80000000L) == 0) ? 'W' : 'E');
- s.append("_0x");
- s.append(Long.toHexString(hResult & 0xFFFL));
- s.append(" (" + Long.toHexString(hResult) + ")");
- return s.toString();
- }
- }
-
- /**
- * Returns the string representation for the current hResult code.
- *
- * @return The string representation for the current hResult code.
- */
- public String getHresultString()
- {
- return MsOutlookMAPIHResultException.toString(this.getHResult());
- }
-}
+package net.java.sip.communicator.plugin.addrbook.msoutlook;
+
+/**
+ * Represents a specific Microsoft Outlook MAPI <tt>HRESULT</tt> as an
+ * <tt>Exception</tt>.
+ *
+ * @author Lyubomir Marinov
+ */
+public class MsOutlookMAPIHResultException
+ extends Exception
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * The <tt>HRESULT</tt> which is represented by this <tt>Exception</tt>.
+ */
+ private final long hResult;
+
+ /**
+ * Initializes a new <tt>MsOutlookMAPIHResultException</tt> instance which
+ * is to represent a specific <tt>HRESULT</tt>.
+ *
+ * @param hResult the <tt>HRESULT</tt> to be represented by the new instance
+ */
+ public MsOutlookMAPIHResultException(long hResult)
+ {
+ this(hResult, toString(hResult));
+ }
+
+ /**
+ * Initializes a new <tt>MsOutlookMAPIHResultException</tt> instance which
+ * is to represent a specific <tt>HRESULT</tt> and to provide a specific
+ * <tt>String</tt> message.
+ *
+ * @param hResult the <tt>HRESULT</tt> to be represented by the new instance
+ * @param message the <tt>String</tt> message to be provided by the new
+ * instance
+ */
+ public MsOutlookMAPIHResultException(long hResult, String message)
+ {
+ super(message);
+
+ this.hResult = hResult;
+ }
+
+ /**
+ * Initializes a new <tt>MsOutlookMAPIHResultException</tt> instance with a
+ * specific <tt>String</tt> message.
+ *
+ * @param message the <tt>String</tt> message to be provided by the new
+ * instance
+ */
+ public MsOutlookMAPIHResultException(String message)
+ {
+ this(0, message);
+ }
+
+ /**
+ * Gets the <tt>HRESULT</tt> which is represented by this
+ * <tt>Exception</tt>.
+ *
+ * @return the <tt>HRESULT</tt> which is represented by this
+ * <tt>Exception</tt>
+ */
+ public long getHResult()
+ {
+ return hResult;
+ }
+
+ /**
+ * Converts a specific <tt>HRESULT</tt> to a touch more readable
+ * <tt>String</tt> in accord with the rule of constructing MAPI
+ * <tt>HRESULT</tt> values.
+ *
+ * @param hResult the <tt>HRESULT</tt> to convert
+ * @return a <tt>String</tt> which represents the specified <tt>hResult</tt>
+ * in a touch more readable form
+ */
+ private static String toString(long hResult)
+ {
+ if (hResult == 0)
+ return "S_OK";
+ else
+ {
+ StringBuilder s = new StringBuilder("MAPI_");
+
+ s.append(((hResult & 0x80000000L) == 0) ? 'W' : 'E');
+ s.append("_0x");
+ s.append(Long.toHexString(hResult & 0xFFFL));
+ s.append(" (" + Long.toHexString(hResult) + ")");
+ return s.toString();
+ }
+ }
+
+ /**
+ * Returns the string representation for the current hResult code.
+ *
+ * @return The string representation for the current hResult code.
+ */
+ public String getHresultString()
+ {
+ return MsOutlookMAPIHResultException.toString(this.getHResult());
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/aimaccregwizz/aimaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/aimaccregwizz/aimaccregwizz.manifest.mf
index 274310a..b5d678f 100644
--- a/src/net/java/sip/communicator/plugin/aimaccregwizz/aimaccregwizz.manifest.mf
+++ b/src/net/java/sip/communicator/plugin/aimaccregwizz/aimaccregwizz.manifest.mf
@@ -12,7 +12,6 @@ Import-Package: org.osgi.framework,
net.java.sip.communicator.service.gui,
net.java.sip.communicator.service.gui.event,
net.java.sip.communicator.service.protocol,
- net.java.sip.communicator.service.protocol.aimconstants,
net.java.sip.communicator.service.protocol.event,
net.java.sip.communicator.service.protocol.icqconstants,
org.jitsi.service.resources, net.java.sip.communicator.service.resources,
diff --git a/src/net/java/sip/communicator/plugin/branding/AboutWindow.java b/src/net/java/sip/communicator/plugin/branding/AboutWindow.java
index 086d891..1f75f1d 100644
--- a/src/net/java/sip/communicator/plugin/branding/AboutWindow.java
+++ b/src/net/java/sip/communicator/plugin/branding/AboutWindow.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,473 +15,440 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.branding;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.io.*;
-
-import javax.imageio.*;
-import javax.swing.*;
-import javax.swing.event.*;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.plugin.desktoputil.plaf.*;
-import net.java.sip.communicator.service.browserlauncher.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.util.Logger;
-import net.java.sip.communicator.util.skin.*;
-
-import org.jitsi.service.resources.*;
-import org.jitsi.util.*;
-import org.osgi.framework.*;
-
-/**
- * The <tt>AboutWindow</tt> is containing information about the application
- * name, version, license etc..
- *
- * @author Yana Stamcheva
- * @author Adam Netocny
- * @author Lyubomir Marinov
- */
-public class AboutWindow
- extends JDialog
- implements HyperlinkListener,
- ActionListener,
- ExportedWindow,
- Skinnable
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * The global/shared <code>AboutWindow</code> currently showing.
- */
- private static AboutWindow aboutWindow;
-
- /**
- * Class id key used in UIDefaults for the version label.
- */
- private static final String uiClassID =
- AboutWindow.class.getName() + "$VersionTextFieldUI";
-
- /**
- * Adds the ui class to UIDefaults.
- */
- static
- {
- UIManager.getDefaults().put(uiClassID,
- SIPCommTextFieldUI.class.getName());
- }
-
- private final JTextField versionLabel;
-
- /**
- * Shows a <code>AboutWindow</code> creating it first if necessary. The
- * shown instance is shared in order to prevent displaying multiple
- * instances of one and the same <code>AboutWindow</code>.
- */
- public static void showAboutWindow()
- {
- if (aboutWindow == null)
- {
- aboutWindow = new AboutWindow(null);
-
- /*
- * When the global/shared AboutWindow closes, don't keep a reference
- * to it and let it be garbage-collected.
- */
- aboutWindow.addWindowListener(new WindowAdapter()
- {
- @Override
- public void windowClosed(WindowEvent e)
- {
- if (aboutWindow == e.getWindow())
- aboutWindow = null;
- }
- });
- }
- aboutWindow.setVisible(true);
- }
-
- private static final int DEFAULT_TEXT_INDENT
- = BrandingActivator.getResources()
- .getSettingsInt("plugin.branding.ABOUT_TEXT_INDENT");
-
- /**
- * Creates an <tt>AboutWindow</tt> by specifying the parent frame owner.
- * @param owner the parent owner
- */
- public AboutWindow(Frame owner)
- {
- super(owner);
-
- ResourceManagementService resources = BrandingActivator.getResources();
-
- String applicationName
- = resources.getSettingsString("service.gui.APPLICATION_NAME");
-
- this.setTitle(
- resources.getI18NString("plugin.branding.ABOUT_WINDOW_TITLE",
- new String[]{applicationName}));
-
- setModal(false);
- setDefaultCloseOperation(DISPOSE_ON_CLOSE);
- setResizable(false);
-
- JPanel mainPanel = new WindowBackground();
- mainPanel.setLayout(new BorderLayout());
-
- JPanel textPanel = new JPanel();
- textPanel.setPreferredSize(new Dimension(470, 280));
- textPanel.setLayout(new BoxLayout(textPanel, BoxLayout.Y_AXIS));
- textPanel.setBorder(BorderFactory
- .createEmptyBorder(15, 15, 15, 15));
- textPanel.setOpaque(false);
-
- JLabel titleLabel = null;
- if (isApplicationNameShown())
- {
- titleLabel = new JLabel(applicationName);
- titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, 28));
- titleLabel.setForeground(Constants.TITLE_COLOR);
- titleLabel.setAlignmentX(Component.RIGHT_ALIGNMENT);
- }
-
- // Force the use of the custom text field UI in order to fix an
- // incorrect rendering on Ubuntu.
- versionLabel
- = new JTextField(" "
- + System.getProperty("sip-communicator.version"))
- {
- /**
- * Returns the name of the L&F class that renders this component.
- *
- * @return the string "TreeUI"
- * @see JComponent#getUIClassID
- * @see UIDefaults#getUI
- */
- @Override
- public String getUIClassID()
- {
- return uiClassID;
- }
- };
-
- versionLabel.setBorder(null);
- versionLabel.setOpaque(false);
- versionLabel.setEditable(false);
- versionLabel.setFont(versionLabel.getFont().deriveFont(Font.BOLD, 18));
- versionLabel.setForeground(Constants.TITLE_COLOR);
- versionLabel.setAlignmentX(Component.RIGHT_ALIGNMENT);
- versionLabel.setHorizontalAlignment(JTextField.RIGHT);
-
- int logoAreaFontSize
- = resources.getSettingsInt("plugin.branding.ABOUT_LOGO_FONT_SIZE");
-
- // FIXME: the message exceeds the window length
- JTextArea logoArea =
- new JTextArea(resources.getI18NString(
- "plugin.branding.LOGO_MESSAGE"));
- logoArea.setFont(
- logoArea.getFont().deriveFont(Font.BOLD, logoAreaFontSize));
- logoArea.setForeground(Constants.TITLE_COLOR);
- logoArea.setOpaque(false);
- logoArea.setLineWrap(true);
- logoArea.setWrapStyleWord(true);
- logoArea.setEditable(false);
- logoArea.setPreferredSize(new Dimension(100, 20));
- logoArea.setAlignmentX(Component.RIGHT_ALIGNMENT);
- logoArea.setBorder(BorderFactory
- .createEmptyBorder(30, DEFAULT_TEXT_INDENT, 0, 0));
-
- StyledHTMLEditorPane rightsArea = new StyledHTMLEditorPane();
- rightsArea.setContentType("text/html");
-
- rightsArea.appendToEnd(resources.getI18NString(
- "plugin.branding.COPYRIGHT",
- new String[]
- { Constants.TEXT_COLOR }));
-
- rightsArea.setPreferredSize(new Dimension(50, 20));
- rightsArea
- .setBorder(BorderFactory
- .createEmptyBorder(0, DEFAULT_TEXT_INDENT, 0, 0));
- rightsArea.setOpaque(false);
- rightsArea.setEditable(false);
- rightsArea.setAlignmentX(Component.RIGHT_ALIGNMENT);
- rightsArea.addHyperlinkListener(this);
-
- StyledHTMLEditorPane licenseArea = new StyledHTMLEditorPane();
- licenseArea.setContentType("text/html");
- licenseArea.appendToEnd(resources.
- getI18NString("plugin.branding.LICENSE",
- new String[]{Constants.TEXT_COLOR}));
-
- licenseArea.setPreferredSize(new Dimension(50, 20));
- licenseArea.setBorder(
- BorderFactory.createEmptyBorder(
- resources.getSettingsInt("plugin.branding.ABOUT_PARAGRAPH_GAP"),
- DEFAULT_TEXT_INDENT,
- 0, 0));
- licenseArea.setOpaque(false);
- licenseArea.setEditable(false);
- licenseArea.setAlignmentX(Component.RIGHT_ALIGNMENT);
- licenseArea.addHyperlinkListener(this);
-
- if (titleLabel != null)
- textPanel.add(titleLabel);
-
- textPanel.add(versionLabel);
- textPanel.add(logoArea);
- textPanel.add(rightsArea);
- textPanel.add(licenseArea);
-
- JButton okButton
- = new JButton(resources.getI18NString("service.gui.OK"));
-
- this.getRootPane().setDefaultButton(okButton);
-
- okButton.setMnemonic(resources.getI18nMnemonic("service.gui.OK"));
- okButton.addActionListener(this);
-
- JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
- buttonPanel.add(okButton);
- buttonPanel.setOpaque(false);
-
- mainPanel.add(textPanel, BorderLayout.CENTER);
- mainPanel.add(buttonPanel, BorderLayout.SOUTH);
-
- this.getContentPane().add(mainPanel);
-
- this.pack();
-
- setLocationRelativeTo(getParent());
-
- this.getRootPane().getActionMap().put("close", new CloseAction());
-
- InputMap imap = this.getRootPane().getInputMap(
- JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
-
- imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "close");
-
- if(OSUtils.IS_MAC)
- {
- imap.put(
- KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.META_DOWN_MASK),
- "close");
- imap.put(
- KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_DOWN_MASK),
- "close");
- }
-
- WindowUtils.addWindow(this);
- }
-
- /**
- * Reloads text field UI.
- */
- public void loadSkin()
- {
- if(versionLabel.getUI() instanceof Skinnable)
- ((Skinnable)versionLabel.getUI()).loadSkin();
- }
-
- /**
- * Constructs the window background in order to have a background image.
- */
- private static class WindowBackground
- extends JPanel
- implements Skinnable
- {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- private static final Logger logger
- = Logger.getLogger(WindowBackground.class);
-
- private Image bgImage = null;
-
- public WindowBackground()
- {
- loadSkin();
- }
-
- /**
- * Reloads resources for this component.
- */
- public void loadSkin()
- {
- try
- {
- bgImage = ImageIO.read(BrandingActivator.getResources().
- getImageURL("plugin.branding.ABOUT_WINDOW_BACKGROUND"));
-
- this.setPreferredSize(new Dimension(bgImage.getWidth(this),
- bgImage.getHeight(this)));
- }
- catch (IOException e)
- {
- logger.error("Error cannot obtain background image", e);
- bgImage = null;
- }
- }
-
- @Override
- protected void paintComponent(Graphics g)
- {
- super.paintComponent(g);
-
- g = g.create();
- try
- {
- AntialiasingManager.activateAntialiasing(g);
-
- int bgImageWidth = bgImage.getWidth(null);
- int bgImageHeight = bgImage.getHeight(null);
- boolean bgImageHasBeenDrawn = false;
-
- if ((bgImageWidth != -1) && (bgImageHeight != -1))
- {
- int width = getWidth();
- int height = getHeight();
-
- if ((bgImageWidth < width) || (bgImageHeight < height))
- {
- g.drawImage(bgImage, 0, 0, width, height, null);
- bgImageHasBeenDrawn = true;
- }
- }
-
- if (!bgImageHasBeenDrawn)
- g.drawImage(bgImage, 0, 0, null);
- }
- finally
- {
- g.dispose();
- }
- }
- }
-
- /**
- * Opens a browser when the link has been activated (clicked).
- * @param e the <tt>HyperlinkEvent</tt> that notified us
- */
- public void hyperlinkUpdate(HyperlinkEvent e)
- {
- if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED)
- {
- String href = e.getDescription();
- ServiceReference serviceReference = BrandingActivator
- .getBundleContext().getServiceReference(
- BrowserLauncherService.class.getName());
-
- if (serviceReference != null)
- {
- BrowserLauncherService browserLauncherService
- = (BrowserLauncherService) BrandingActivator
- .getBundleContext().getService(serviceReference);
-
- browserLauncherService.openURL(href);
- }
- }
- }
-
- /**
- * Indicates that the ok button has been pressed. Closes the window.
- * @param e the <tt>ActionEvent</tt> that notified us
- */
- public void actionPerformed(ActionEvent e)
- {
- setVisible(false);
- dispose();
- }
-
- /**
- * Implements the <tt>ExportedWindow.getIdentifier()</tt> method.
- * @return the identifier of this exported window
- */
- public WindowID getIdentifier()
- {
- return ExportedWindow.ABOUT_WINDOW;
- }
-
- /**
- * This dialog could not be minimized.
- */
- public void minimize()
- {
- }
-
- /**
- * This dialog could not be maximized.
- */
- public void maximize()
- {
- }
-
- /**
- * Implements the <tt>ExportedWindow.bringToFront()</tt> method. Brings
- * this window to front.
- */
- public void bringToFront()
- {
- this.toFront();
- }
-
- /**
- * The source of the window
- * @return the source of the window
- */
- public Object getSource()
- {
- return this;
- }
-
- /**
- * Implementation of {@link ExportedWindow#setParams(Object[])}.
- */
- public void setParams(Object[] windowParams) {}
-
- /**
- * The action invoked when user presses Escape key.
- */
- private class CloseAction extends UIAction
- {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- public void actionPerformed(ActionEvent e)
- {
- setVisible(false);
- dispose();
- }
- }
-
- /**
- * Indicates if the application name should be shown.
- *
- * @return <tt>true</tt> if the application name should be shown,
- * <tt>false</tt> - otherwise
- */
- private boolean isApplicationNameShown()
- {
- String showApplicationNameProp
- = BrandingActivator.getResources().getSettingsString(
- "plugin.branding.IS_APPLICATION_NAME_SHOWN");
-
- if (showApplicationNameProp != null
- && showApplicationNameProp.length() > 0)
- {
- return Boolean.parseBoolean(showApplicationNameProp);
- }
-
- return true;
- }
-}
+package net.java.sip.communicator.plugin.branding;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import javax.imageio.*;
+import javax.swing.*;
+import javax.swing.event.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.plugin.desktoputil.plaf.*;
+import net.java.sip.communicator.service.browserlauncher.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.util.Logger;
+import net.java.sip.communicator.util.skin.*;
+
+import org.jitsi.service.resources.*;
+import org.jitsi.util.*;
+import org.osgi.framework.*;
+
+/**
+ * The <tt>AboutWindow</tt> is containing information about the application
+ * name, version, license etc..
+ *
+ * @author Yana Stamcheva
+ * @author Adam Netocny
+ * @author Lyubomir Marinov
+ */
+public class AboutWindow
+ extends JDialog
+ implements HyperlinkListener,
+ ActionListener,
+ ExportedWindow,
+ Skinnable
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ private static AboutWindow aboutWindow;
+
+ /**
+ * Class id key used in UIDefaults for the version label.
+ */
+ private static final String uiClassID =
+ AboutWindow.class.getName() + "$VersionTextFieldUI";
+
+ /**
+ * Adds the ui class to UIDefaults.
+ */
+ static
+ {
+ UIManager.getDefaults().put(uiClassID,
+ SIPCommTextFieldUI.class.getName());
+ }
+
+ private final JTextField versionLabel;
+
+ /**
+ * Shows a <code>AboutWindow</code> creating it first if necessary. The
+ * shown instance is shared in order to prevent displaying multiple
+ * instances of one and the same <code>AboutWindow</code>.
+ */
+ public static void showAboutWindow()
+ {
+ if (aboutWindow == null)
+ {
+ aboutWindow = new AboutWindow(null);
+
+ /*
+ * When the global/shared AboutWindow closes, don't keep a reference
+ * to it and let it be garbage-collected.
+ */
+ aboutWindow.addWindowListener(new WindowAdapter()
+ {
+ @Override
+ public void windowClosed(WindowEvent e)
+ {
+ if (aboutWindow == e.getWindow())
+ aboutWindow = null;
+ }
+ });
+ }
+ aboutWindow.setVisible(true);
+ }
+
+ private static final int DEFAULT_TEXT_INDENT
+ = BrandingActivator.getResources()
+ .getSettingsInt("plugin.branding.ABOUT_TEXT_INDENT");
+
+ /**
+ * Creates an <tt>AboutWindow</tt> by specifying the parent frame owner.
+ * @param owner the parent owner
+ */
+ public AboutWindow(Frame owner)
+ {
+ super(owner);
+
+ ResourceManagementService resources = BrandingActivator.getResources();
+
+ String applicationName =
+ resources.getSettingsString("service.gui.APPLICATION_NAME");
+ String website =
+ resources.getSettingsString("service.gui.APPLICATION_WEB_SITE");
+
+ this.setTitle(
+ resources.getI18NString("plugin.branding.ABOUT_WINDOW_TITLE",
+ new String[]{applicationName}));
+
+ setModal(false);
+ setDefaultCloseOperation(DISPOSE_ON_CLOSE);
+ setResizable(false);
+
+ JPanel mainPanel = new WindowBackground();
+ mainPanel.setLayout(new BorderLayout());
+
+ JPanel textPanel = new JPanel();
+ textPanel.setPreferredSize(new Dimension(470, 280));
+ textPanel.setLayout(new BoxLayout(textPanel, BoxLayout.Y_AXIS));
+ textPanel.setBorder(BorderFactory
+ .createEmptyBorder(15, 15, 15, 15));
+ textPanel.setOpaque(false);
+
+ JLabel titleLabel = new JLabel(applicationName);
+ titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, 28));
+ titleLabel.setForeground(Constants.TITLE_COLOR);
+ titleLabel.setAlignmentX(Component.RIGHT_ALIGNMENT);
+
+ // Force the use of the custom text field UI in order to fix an
+ // incorrect rendering on Ubuntu.
+ versionLabel
+ = new JTextField(" "
+ + System.getProperty("sip-communicator.version"))
+ {
+ /**
+ * Returns the name of the L&F class that renders this component.
+ *
+ * @return the string "TreeUI"
+ * @see JComponent#getUIClassID
+ * @see UIDefaults#getUI
+ */
+ @Override
+ public String getUIClassID()
+ {
+ return uiClassID;
+ }
+ };
+
+ versionLabel.setBorder(null);
+ versionLabel.setOpaque(false);
+ versionLabel.setEditable(false);
+ versionLabel.setFont(versionLabel.getFont().deriveFont(Font.BOLD, 18));
+ versionLabel.setForeground(Constants.TITLE_COLOR);
+ versionLabel.setAlignmentX(Component.RIGHT_ALIGNMENT);
+ versionLabel.setHorizontalAlignment(JTextField.RIGHT);
+
+ int logoAreaFontSize
+ = resources.getSettingsInt("plugin.branding.ABOUT_LOGO_FONT_SIZE");
+
+ JTextArea logoArea =
+ new JTextArea(resources.getI18NString(
+ "plugin.branding.LOGO_MESSAGE"));
+ logoArea.setFont(
+ logoArea.getFont().deriveFont(Font.BOLD, logoAreaFontSize));
+ logoArea.setForeground(Constants.TITLE_COLOR);
+ logoArea.setOpaque(false);
+ logoArea.setLineWrap(true);
+ logoArea.setWrapStyleWord(true);
+ logoArea.setEditable(false);
+ logoArea.setAlignmentX(Component.RIGHT_ALIGNMENT);
+ logoArea.setBorder(BorderFactory
+ .createEmptyBorder(30, DEFAULT_TEXT_INDENT, 0, 0));
+
+ StyledHTMLEditorPane rightsArea = new StyledHTMLEditorPane();
+ rightsArea.setContentType("text/html");
+
+ String host = website;
+ try
+ {
+ host = new URL(website).getHost();
+ }
+ catch (Exception ex)
+ {}
+
+ rightsArea.appendToEnd(resources.getI18NString(
+ "plugin.branding.COPYRIGHT_LICENSE",
+ new String[]
+ {
+ Constants.TEXT_COLOR,
+ Integer.toString(Calendar.getInstance().get(Calendar.YEAR)),
+ website,
+ host,
+ applicationName,
+ "http://www.apache.org/licenses/LICENSE-2.0",
+ "Apache License 2.0"
+ }));
+
+ rightsArea.setBorder(BorderFactory
+ .createEmptyBorder(0, DEFAULT_TEXT_INDENT, 0, 0));
+ rightsArea.setOpaque(false);
+ rightsArea.setEditable(false);
+ rightsArea.setAlignmentX(Component.RIGHT_ALIGNMENT);
+ rightsArea.addHyperlinkListener(this);
+
+ textPanel.add(titleLabel);
+ textPanel.add(versionLabel);
+ textPanel.add(logoArea);
+ textPanel.add(rightsArea);
+
+ JButton okButton
+ = new JButton(resources.getI18NString("service.gui.OK"));
+
+ this.getRootPane().setDefaultButton(okButton);
+
+ okButton.setMnemonic(resources.getI18nMnemonic("service.gui.OK"));
+ okButton.addActionListener(this);
+
+ JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+ buttonPanel.add(okButton);
+ buttonPanel.setOpaque(false);
+
+ mainPanel.add(textPanel, BorderLayout.CENTER);
+ mainPanel.add(buttonPanel, BorderLayout.SOUTH);
+
+ this.getContentPane().add(mainPanel);
+
+ this.pack();
+
+ setLocationRelativeTo(getParent());
+
+ this.getRootPane().getActionMap().put("close", new CloseAction());
+
+ InputMap imap = this.getRootPane().getInputMap(
+ JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+
+ imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "close");
+
+ if(OSUtils.IS_MAC)
+ {
+ imap.put(
+ KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.META_DOWN_MASK),
+ "close");
+ imap.put(
+ KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_DOWN_MASK),
+ "close");
+ }
+
+ WindowUtils.addWindow(this);
+ }
+
+ /**
+ * Reloads text field UI.
+ */
+ public void loadSkin()
+ {
+ if(versionLabel.getUI() instanceof Skinnable)
+ ((Skinnable)versionLabel.getUI()).loadSkin();
+ }
+
+ /**
+ * Constructs the window background in order to have a background image.
+ */
+ private static class WindowBackground
+ extends JPanel
+ implements Skinnable
+ {
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ private static final Logger logger
+ = Logger.getLogger(WindowBackground.class);
+
+ private Image bgImage = null;
+
+ public WindowBackground()
+ {
+ loadSkin();
+ }
+
+ /**
+ * Reloads resources for this component.
+ */
+ public void loadSkin()
+ {
+ try
+ {
+ bgImage = ImageIO.read(BrandingActivator.getResources().
+ getImageURL("plugin.branding.ABOUT_WINDOW_BACKGROUND"));
+
+ this.setPreferredSize(new Dimension(bgImage.getWidth(this),
+ bgImage.getHeight(this)));
+ }
+ catch (IOException e)
+ {
+ logger.error("Error cannot obtain background image", e);
+ bgImage = null;
+ }
+ }
+
+ @Override
+ protected void paintComponent(Graphics g)
+ {
+ super.paintComponent(g);
+
+ g = g.create();
+ try
+ {
+ AntialiasingManager.activateAntialiasing(g);
+
+ int bgImageWidth = bgImage.getWidth(null);
+ int bgImageHeight = bgImage.getHeight(null);
+ boolean bgImageHasBeenDrawn = false;
+
+ if ((bgImageWidth != -1) && (bgImageHeight != -1))
+ {
+ int width = getWidth();
+ int height = getHeight();
+
+ if ((bgImageWidth < width) || (bgImageHeight < height))
+ {
+ g.drawImage(bgImage, 0, 0, width, height, null);
+ bgImageHasBeenDrawn = true;
+ }
+ }
+
+ if (!bgImageHasBeenDrawn)
+ g.drawImage(bgImage, 0, 0, null);
+ }
+ finally
+ {
+ g.dispose();
+ }
+ }
+ }
+
+ /**
+ * Opens a browser when the link has been activated (clicked).
+ * @param e the <tt>HyperlinkEvent</tt> that notified us
+ */
+ public void hyperlinkUpdate(HyperlinkEvent e)
+ {
+ if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED)
+ {
+ ServiceReference<BrowserLauncherService> serviceReference =
+ BrandingActivator.getBundleContext().getServiceReference(
+ BrowserLauncherService.class);
+
+ if (serviceReference != null)
+ {
+ BrowserLauncherService browserLauncherService
+ = BrandingActivator
+ .getBundleContext().getService(serviceReference);
+
+ browserLauncherService.openURL(e.getDescription());
+ }
+ }
+ }
+
+ /**
+ * Indicates that the ok button has been pressed. Closes the window.
+ * @param e the <tt>ActionEvent</tt> that notified us
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ setVisible(false);
+ dispose();
+ }
+
+ /**
+ * Implements the <tt>ExportedWindow.getIdentifier()</tt> method.
+ * @return the identifier of this exported window
+ */
+ public WindowID getIdentifier()
+ {
+ return ExportedWindow.ABOUT_WINDOW;
+ }
+
+ /**
+ * This dialog could not be minimized.
+ */
+ public void minimize()
+ {
+ }
+
+ /**
+ * This dialog could not be maximized.
+ */
+ public void maximize()
+ {
+ }
+
+ /**
+ * Implements the <tt>ExportedWindow.bringToFront()</tt> method. Brings
+ * this window to front.
+ */
+ public void bringToFront()
+ {
+ this.toFront();
+ }
+
+ /**
+ * The source of the window
+ * @return the source of the window
+ */
+ public Object getSource()
+ {
+ return this;
+ }
+
+ /**
+ * Implementation of {@link ExportedWindow#setParams(Object[])}.
+ */
+ public void setParams(Object[] windowParams) {}
+
+ /**
+ * The action invoked when user presses Escape key.
+ */
+ private class CloseAction extends UIAction
+ {
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ public void actionPerformed(ActionEvent e)
+ {
+ setVisible(false);
+ dispose();
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/branding/AboutWindowPluginComponent.java b/src/net/java/sip/communicator/plugin/branding/AboutWindowPluginComponent.java
index 333781d..eb2d61a 100644
--- a/src/net/java/sip/communicator/plugin/branding/AboutWindowPluginComponent.java
+++ b/src/net/java/sip/communicator/plugin/branding/AboutWindowPluginComponent.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,89 +15,89 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.branding;
-
-import java.awt.event.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.service.gui.*;
-
-/**
- * Implements an About menu item for the Help menu of the application in the
- * form of a <tt>PluginComponent</tt>.
- *
- * @author Lyubomir Marinov
- */
-public class AboutWindowPluginComponent
- extends AbstractPluginComponent
-{
-
- /**
- * Invokes the default action associated with Help > About regardless of the
- * specifics of its visual representation.
- */
- public static void actionPerformed()
- {
- AboutWindow.showAboutWindow();
- }
-
- private JMenuItem aboutMenuItem;
-
- /**
- * Constructor.
- *
- * @param container parent container
- */
- public AboutWindowPluginComponent(Container container,
- PluginComponentFactory parentFactory)
- {
- super(container, parentFactory);
- }
-
- public Object getComponent()
- {
- if (aboutMenuItem == null)
- {
- aboutMenuItem = new JMenuItem(getName());
- aboutMenuItem
- .setMnemonic(
- BrandingActivator
- .getResources()
- .getI18nMnemonic(
- "plugin.branding.ABOUT_MENU_ENTRY"));
-
- aboutMenuItem.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- AboutWindowPluginComponent.actionPerformed();
- }
- });
- }
- return aboutMenuItem;
- }
-
- public String getName()
- {
- return
- BrandingActivator
- .getResources()
- .getI18NString("plugin.branding.ABOUT_MENU_ENTRY");
- }
-
- /**
- * Implements {@link PluginComponent#getPositionIndex()}. Returns
- * <tt>Integer#MAX_VALUE</tt> in order to indicate that the About menu item
- * in the Help menu is conventionally displayed at the very bottom.
- *
- * @return <tt>Integer#MAX_VALUE</tt> in order to indicate that the About
- * menu item in the Help menu is conventionally displayed at the very bottom
- * @see AbstractPluginComponent#getPositionIndex()
- */
- @Override
- public int getPositionIndex()
- {
- return Integer.MAX_VALUE;
- }
-}
+package net.java.sip.communicator.plugin.branding;
+
+import java.awt.event.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.service.gui.*;
+
+/**
+ * Implements an About menu item for the Help menu of the application in the
+ * form of a <tt>PluginComponent</tt>.
+ *
+ * @author Lyubomir Marinov
+ */
+public class AboutWindowPluginComponent
+ extends AbstractPluginComponent
+{
+
+ /**
+ * Invokes the default action associated with Help > About regardless of the
+ * specifics of its visual representation.
+ */
+ public static void actionPerformed()
+ {
+ AboutWindow.showAboutWindow();
+ }
+
+ private JMenuItem aboutMenuItem;
+
+ /**
+ * Constructor.
+ *
+ * @param container parent container
+ */
+ public AboutWindowPluginComponent(Container container,
+ PluginComponentFactory parentFactory)
+ {
+ super(container, parentFactory);
+ }
+
+ public Object getComponent()
+ {
+ if (aboutMenuItem == null)
+ {
+ aboutMenuItem = new JMenuItem(getName());
+ aboutMenuItem
+ .setMnemonic(
+ BrandingActivator
+ .getResources()
+ .getI18nMnemonic(
+ "plugin.branding.ABOUT_MENU_ENTRY"));
+
+ aboutMenuItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ AboutWindowPluginComponent.actionPerformed();
+ }
+ });
+ }
+ return aboutMenuItem;
+ }
+
+ public String getName()
+ {
+ return
+ BrandingActivator
+ .getResources()
+ .getI18NString("plugin.branding.ABOUT_MENU_ENTRY");
+ }
+
+ /**
+ * Implements {@link PluginComponent#getPositionIndex()}. Returns
+ * <tt>Integer#MAX_VALUE</tt> in order to indicate that the About menu item
+ * in the Help menu is conventionally displayed at the very bottom.
+ *
+ * @return <tt>Integer#MAX_VALUE</tt> in order to indicate that the About
+ * menu item in the Help menu is conventionally displayed at the very bottom
+ * @see AbstractPluginComponent#getPositionIndex()
+ */
+ @Override
+ public int getPositionIndex()
+ {
+ return Integer.MAX_VALUE;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/branding/BrandingActivator.java b/src/net/java/sip/communicator/plugin/branding/BrandingActivator.java
index 6d8bdfd..f6de958 100644
--- a/src/net/java/sip/communicator/plugin/branding/BrandingActivator.java
+++ b/src/net/java/sip/communicator/plugin/branding/BrandingActivator.java
@@ -33,91 +33,12 @@ import org.osgi.framework.*;
*/
public class BrandingActivator
extends AbstractServiceDependentActivator
- implements BundleListener
{
private final Logger logger = Logger.getLogger(BrandingActivator.class);
-
- /**
- * The name of the boolean property which indicates whether the splash
- * screen (i.e. <code>WelcomeWindow</code>) is to be shown or to not be
- * utilized for the sake of better memory consumption and faster startup.
- */
- private static final String PNAME_SHOW_SPLASH_SCREEN
- = "net.java.sip.communicator.plugin.branding.SHOW_SPLASH_SCREEN";
-
private static BundleContext bundleContext;
-
private static ResourceManagementService resourcesService;
/**
- * The welcome window.
- */
- private WelcomeWindow welcomeWindow;
-
- @Override
- public void start(BundleContext bc) throws Exception
- {
- super.start(bc);
-
- ConfigurationService config = getConfigurationService();
- boolean showSplashScreen
- = (config == null)
- ? true /*
- * Having no ConfigurationService reference is not good
- * for the application so we are better off with the
- * splash screen to actually see which bundles get loaded
- * and maybe be able to debug the problem.
- */
- : config.getBoolean(PNAME_SHOW_SPLASH_SCREEN, false);
-
- /*
- * WelcomeWindow is huge because it has a large image spread all over it
- * so, given it's only necessary before the UIService gets activated, we
- * certainly don't want to keep it around (e.g. as an instance field or
- * as a final variable used inside a BundleListener which never gets
- * removed).
- */
- if (showSplashScreen)
- {
- welcomeWindow = new WelcomeWindow();
- welcomeWindow.pack();
- welcomeWindow.setVisible(true);
- }
- else
- welcomeWindow = null;
-
- if (getResources().getSettingsString(
- "service.gui.APPLICATION_NAME").equals("SIP Communicator"))
- new JitsiWarningWindow(null).setVisible(true);
-
- bundleContext.addBundleListener(this);
- }
-
- /**
- * Bundle has been started if welcome window is available and visible
- * update it to show the bundle activity.
- * @param evt
- */
- public synchronized void bundleChanged(BundleEvent evt)
- {
- if (welcomeWindow != null
- && welcomeWindow.isShowing()
- && (evt.getType() == BundleEvent.STARTED))
- {
- /*
- * The IBM JRE on GNU/Linux reports the Bundle-Name as null while
- * the SUN JRE reports it as non-null. Just prevent the throwing of
- * a NullPointerException because displaying the Bundle-Name isn't
- * vital anyway.
- */
- Object bundleName = evt.getBundle().getHeaders().get("Bundle-Name");
-
- welcomeWindow.setBundle(
- (bundleName == null) ? null : bundleName.toString());
- }
- }
-
- /**
* Setting context to the activator, as soon as we have one.
*
* @param context the context to set.
@@ -145,31 +66,12 @@ public class BrandingActivator
@Override
public void start(Object dependentService)
{
- // UI-Service started.
-
- /*
- * Don't let bundleContext retain a reference to this
- * listener because it'll retain a reference to
- * welcomeWindow. Besides, we're no longer interested in
- * handling events so it doesn't make sense to even retain
- * this listener.
- */
- bundleContext.removeBundleListener(this);
-
// register the about dialog menu entry
registerMenuEntry((UIService)dependentService);
-
- if (welcomeWindow != null)
- {
- synchronized(this)
- {
- welcomeWindow.close();
- welcomeWindow = null;
- }
- }
}
- public void stop(BundleContext arg0) throws Exception
+ @Override
+ public void stop(BundleContext context) throws Exception
{
}
@@ -189,7 +91,6 @@ public class BrandingActivator
private boolean registerMenuEntryMacOSX(UIService uiService)
{
- Exception exception = null;
try
{
Class<?> clazz =
@@ -199,28 +100,16 @@ public class BrandingActivator
Object result = method.invoke(null, (Object[]) null);
if (result instanceof Boolean)
+ {
return ((Boolean) result).booleanValue();
+ }
}
- catch (ClassNotFoundException ex)
- {
- exception = ex;
- }
- catch (IllegalAccessException ex)
- {
- exception = ex;
- }
- catch (InvocationTargetException ex)
- {
- exception = ex;
- }
- catch (NoSuchMethodException ex)
+ catch (Exception ex)
{
- exception = ex;
+ logger.error("Failed to register Mac OS X-specific About handling.",
+ ex);
}
- if (exception != null)
- logger.error(
- "Failed to register Mac OS X-specific About handling.",
- exception);
+
return false;
}
@@ -276,17 +165,6 @@ public class BrandingActivator
return bundleContext;
}
- private static ConfigurationService getConfigurationService()
- {
- ServiceReference serRef
- = bundleContext
- .getServiceReference(ConfigurationService.class.getName());
- return
- (serRef == null)
- ? null
- : (ConfigurationService) bundleContext.getService(serRef);
- }
-
/**
* Returns the <tt>ResourceManagementService</tt>.
*
diff --git a/src/net/java/sip/communicator/plugin/branding/Constants.java b/src/net/java/sip/communicator/plugin/branding/Constants.java
index 9d15df4..b098e4d 100644
--- a/src/net/java/sip/communicator/plugin/branding/Constants.java
+++ b/src/net/java/sip/communicator/plugin/branding/Constants.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,65 +15,65 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.branding;
-
-import java.awt.*;
-import java.io.*;
-
-import javax.swing.text.html.*;
-
-/**
- * All look and feel related constants are stored here.
- *
- * @author Yana Stamcheva
- */
-public class Constants
-{
- /*
- * ======================================================================
- * -------------------- FONTS AND COLOR CONSTANTS ------------------------
- * ======================================================================
- */
-
- /**
- * Dark blue color used in the about window and the splash screen.
- */
- public static final Color TITLE_COLOR
- = new Color(BrandingActivator.getResources()
- .getColor("service.gui.SPLASH_SCREEN_TITLE_COLOR"));
-
- /**
- * Text color used in the about window and the splash screen.
- */
- public static final String TEXT_COLOR
- = BrandingActivator.getResources()
- .getColorString("service.gui.SPLASH_SCREEN_TEXT_COLOR");
-
-
- /*
- * ======================================================================
- * --------------------------- FONT CONSTANTS ---------------------------
- * ======================================================================
- */
-
- /**
- * Temporary method to load the css style used in the chat window.
- *
- * @param style
- */
- public static void loadSimpleStyle(StyleSheet style)
- {
- InputStream is = BrandingActivator.getResources().
- getSettingsInputStream("service.gui.HTML_TEXT_STYLE");
-
- Reader r = new BufferedReader(new InputStreamReader(is));
- try
- {
- style.loadRules(r, null);
- r.close();
- }
- catch (IOException e)
- {
- }
- }
-}
+package net.java.sip.communicator.plugin.branding;
+
+import java.awt.*;
+import java.io.*;
+
+import javax.swing.text.html.*;
+
+/**
+ * All look and feel related constants are stored here.
+ *
+ * @author Yana Stamcheva
+ */
+public class Constants
+{
+ /*
+ * ======================================================================
+ * -------------------- FONTS AND COLOR CONSTANTS ------------------------
+ * ======================================================================
+ */
+
+ /**
+ * Dark blue color used in the about window and the splash screen.
+ */
+ public static final Color TITLE_COLOR
+ = new Color(BrandingActivator.getResources()
+ .getColor("service.gui.SPLASH_SCREEN_TITLE_COLOR"));
+
+ /**
+ * Text color used in the about window and the splash screen.
+ */
+ public static final String TEXT_COLOR
+ = BrandingActivator.getResources()
+ .getColorString("service.gui.SPLASH_SCREEN_TEXT_COLOR");
+
+
+ /*
+ * ======================================================================
+ * --------------------------- FONT CONSTANTS ---------------------------
+ * ======================================================================
+ */
+
+ /**
+ * Temporary method to load the css style used in the chat window.
+ *
+ * @param style
+ */
+ public static void loadSimpleStyle(StyleSheet style)
+ {
+ InputStream is = BrandingActivator.getResources().
+ getSettingsInputStream("service.gui.HTML_TEXT_STYLE");
+
+ Reader r = new BufferedReader(new InputStreamReader(is));
+ try
+ {
+ style.loadRules(r, null);
+ r.close();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/branding/JitsiWarningWindow.java b/src/net/java/sip/communicator/plugin/branding/JitsiWarningWindow.java
deleted file mode 100644
index 0ca6a89..0000000
--- a/src/net/java/sip/communicator/plugin/branding/JitsiWarningWindow.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.branding;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.service.browserlauncher.*;
-
-import org.jitsi.service.resources.*;
-import org.jitsi.util.*;
-import org.osgi.framework.*;
-
-/**
- * The <tt>JitsiWarningWindow</tt>.
- *
- * @author Yana Stamcheva
- */
-public class JitsiWarningWindow
- extends SIPCommDialog
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * Creates an <tt>JitsiWarningWindow</tt> by specifying the parent frame
- * owner.
- * @param owner the parent owner
- */
- public JitsiWarningWindow(Frame owner)
- {
- super(owner, false);
-
- ResourceManagementService resources = BrandingActivator.getResources();
-
- this.setTitle(
- resources.getI18NString("service.gui.UPDATE")
- + " " + resources.getSettingsString(
- "service.gui.APPLICATION_NAME"));
-
- setModal(false);
- setDefaultCloseOperation(DISPOSE_ON_CLOSE);
-
- StyledHTMLEditorPane textArea = new StyledHTMLEditorPane();
- textArea.setContentType("text/html");
- textArea.setText(resources.getI18NString("service.gui.JITSI_WARNING"));
- textArea.setOpaque(false);
- textArea.setEditable(false);
-
- JLabel titleLabel = new JLabel(
- resources.getI18NString("service.gui.JITSI_WARNING_TITLE"));
- titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, 14f));
- titleLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
- titleLabel.setMaximumSize(new Dimension(400, 50));
-
- JPanel textPanel = new TransparentPanel();
- textPanel.setLayout(new BoxLayout(textPanel, BoxLayout.Y_AXIS));
-
- textPanel.add(titleLabel);
- textPanel.add(Box.createRigidArea(new Dimension(20, 20)));
- textPanel.add(textArea);
-
- JButton downloadButton = new JButton(
- resources.getI18NString("service.gui.DOWNLOAD_NOW"));
- JButton remindButton = new JButton(
- resources.getI18NString("service.gui.REMIND_ME_LATER"));
-
- this.getRootPane().setDefaultButton(downloadButton);
-
- downloadButton.setMnemonic(
- resources.getI18nMnemonic("service.gui.DOWNLOAD_NOW"));
- downloadButton.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- openURL(getDownloadLink());
- dispose();
- }
- });
- remindButton.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- dispose();
- }
- });
-
- JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
- buttonPanel.add(remindButton);
- buttonPanel.add(downloadButton);
- buttonPanel.setOpaque(false);
-
- JPanel mainPanel = new TransparentPanel(new BorderLayout(10, 10));
- mainPanel.add(new JLabel(resources.getImage(
- "service.gui.SIP_COMMUNICATOR_LOGO_128x128")), BorderLayout.WEST);
- mainPanel.add(textPanel, BorderLayout.CENTER);
- mainPanel.add(buttonPanel, BorderLayout.SOUTH);
- mainPanel.setPreferredSize(new Dimension(500, 200));
- mainPanel.setBorder(
- BorderFactory.createEmptyBorder(20, 20, 20, 20));
-
- getContentPane().add(mainPanel);
-
- this.pack();
- this.setResizable(false);
-
- setLocationRelativeTo(getParent());
-
- this.getRootPane().getActionMap().put("close", new CloseAction());
-
- InputMap imap = this.getRootPane().getInputMap(
- JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
-
- imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "close");
-
- if(OSUtils.IS_MAC)
- {
- imap.put(
- KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.META_DOWN_MASK),
- "close");
- imap.put(
- KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_DOWN_MASK),
- "close");
- }
- }
-
- /**
- * The action invoked when user presses Escape key.
- */
- private class CloseAction extends UIAction
- {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- public void actionPerformed(ActionEvent e)
- {
- setVisible(false);
- dispose();
- }
- }
-
- /**
- * Opens the given url in a new browser window.
- * @param url the url to open
- */
- private void openURL(String url)
- {
- ServiceReference serviceReference = BrandingActivator
- .getBundleContext().getServiceReference(
- BrowserLauncherService.class.getName());
-
- if (serviceReference != null)
- {
- BrowserLauncherService browserLauncherService
- = (BrowserLauncherService) BrandingActivator
- .getBundleContext().getService(
- serviceReference);
-
- browserLauncherService.openURL(url);
- }
- }
-
- /**
- * Indicates if the application name should be shown.
- *
- * @return <tt>true</tt> if the application name should be shown,
- * <tt>false</tt> - otherwise
- */
- private String getDownloadLink()
- {
- if (OSUtils.IS_WINDOWS)
- return "http://download.jitsi.org/jitsi/windows/";
- else if (OSUtils.IS_MAC)
- return "http://download.jitsi.org/jitsi/macosx/";
-
- return "http://download.jitsi.org";
- }
-
- @Override
- protected void close(boolean escaped) {}
-}
diff --git a/src/net/java/sip/communicator/plugin/branding/MacOSXAboutRegistration.java b/src/net/java/sip/communicator/plugin/branding/MacOSXAboutRegistration.java
index 22ce126..0648e4b 100644
--- a/src/net/java/sip/communicator/plugin/branding/MacOSXAboutRegistration.java
+++ b/src/net/java/sip/communicator/plugin/branding/MacOSXAboutRegistration.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,34 +15,34 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.branding;
-
-import com.apple.eawt.*;
-
-/**
- * @author Lubomir Marinov
- */
-public final class MacOSXAboutRegistration
-{
- /**
- * Show the about dialog on Mac OS X.
- *
- * @return true if the Mac OS X application is not null
- */
- public static boolean run()
- {
- Application application = Application.getApplication();
- if (application != null)
- {
- application.setAboutHandler(new AboutHandler()
- {
- public void handleAbout(AppEvent.AboutEvent aboutEvent)
- {
- AboutWindowPluginComponent.actionPerformed();
- }
- });
- return true;
- }
- return false;
- }
-}
+package net.java.sip.communicator.plugin.branding;
+
+import com.apple.eawt.*;
+
+/**
+ * @author Lubomir Marinov
+ */
+public final class MacOSXAboutRegistration
+{
+ /**
+ * Show the about dialog on Mac OS X.
+ *
+ * @return true if the Mac OS X application is not null
+ */
+ public static boolean run()
+ {
+ Application application = Application.getApplication();
+ if (application != null)
+ {
+ application.setAboutHandler(new AboutHandler()
+ {
+ public void handleAbout(AppEvent.AboutEvent aboutEvent)
+ {
+ AboutWindowPluginComponent.actionPerformed();
+ }
+ });
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/branding/StyledHTMLEditorPane.java b/src/net/java/sip/communicator/plugin/branding/StyledHTMLEditorPane.java
index 7eb02bc..d67050e 100644
--- a/src/net/java/sip/communicator/plugin/branding/StyledHTMLEditorPane.java
+++ b/src/net/java/sip/communicator/plugin/branding/StyledHTMLEditorPane.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,64 +15,64 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.branding;
-
-import java.io.*;
-
-import javax.swing.*;
-import javax.swing.text.*;
-import javax.swing.text.html.*;
-
-import net.java.sip.communicator.util.*;
-
-public class StyledHTMLEditorPane
- extends JEditorPane
-{
- private final Logger logger = Logger.getLogger(StyledHTMLEditorPane.class);
-
- private final HTMLDocument document;
-
- public StyledHTMLEditorPane()
- {
- this.setContentType("text/html");
-
- this.document
- = (HTMLDocument) this.getDocument();
-
- this.setDocument(document);
-
- Constants.loadSimpleStyle(document.getStyleSheet());
- }
-
- public void appendToEnd(String text)
- {
- Element root = document.getDefaultRootElement();
- try
- {
- document.insertAfterEnd(root
- .getElement(root.getElementCount() - 1), text);
- }
- catch (BadLocationException e)
- {
- logger.error("Insert in the HTMLDocument failed.", e);
- }
- catch (IOException e)
- {
- logger.error("Insert in the HTMLDocument failed.", e);
- }
- }
-
- public void insertAfterStart(String text)
- {
- Element root = this.document.getDefaultRootElement();
-
- try {
- this.document.insertBeforeStart(root
- .getElement(0), text);
- } catch (BadLocationException e) {
- logger.error("Insert in the HTMLDocument failed.", e);
- } catch (IOException e) {
- logger.error("Insert in the HTMLDocument failed.", e);
- }
- }
-}
+package net.java.sip.communicator.plugin.branding;
+
+import java.io.*;
+
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.text.html.*;
+
+import net.java.sip.communicator.util.*;
+
+public class StyledHTMLEditorPane
+ extends JEditorPane
+{
+ private final Logger logger = Logger.getLogger(StyledHTMLEditorPane.class);
+
+ private final HTMLDocument document;
+
+ public StyledHTMLEditorPane()
+ {
+ this.setContentType("text/html");
+
+ this.document
+ = (HTMLDocument) this.getDocument();
+
+ this.setDocument(document);
+
+ Constants.loadSimpleStyle(document.getStyleSheet());
+ }
+
+ public void appendToEnd(String text)
+ {
+ Element root = document.getDefaultRootElement();
+ try
+ {
+ document.insertAfterEnd(root
+ .getElement(root.getElementCount() - 1), text);
+ }
+ catch (BadLocationException e)
+ {
+ logger.error("Insert in the HTMLDocument failed.", e);
+ }
+ catch (IOException e)
+ {
+ logger.error("Insert in the HTMLDocument failed.", e);
+ }
+ }
+
+ public void insertAfterStart(String text)
+ {
+ Element root = this.document.getDefaultRootElement();
+
+ try {
+ this.document.insertBeforeStart(root
+ .getElement(0), text);
+ } catch (BadLocationException e) {
+ logger.error("Insert in the HTMLDocument failed.", e);
+ } catch (IOException e) {
+ logger.error("Insert in the HTMLDocument failed.", e);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/branding/WelcomeWindow.java b/src/net/java/sip/communicator/plugin/branding/WelcomeWindow.java
deleted file mode 100644
index 7cc78b8..0000000
--- a/src/net/java/sip/communicator/plugin/branding/WelcomeWindow.java
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.branding;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.image.*;
-import java.io.*;
-
-import javax.imageio.*;
-import javax.swing.*;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-
-import org.jitsi.service.resources.*;
-
-/**
- * The <tt>WelcomeWindow</tt> is actually the splash screen shown while the
- * application is loading. It displays the status of the loading process and
- * some general information about the version, licenses and contact details.
- *
- * @author Yana Stamcheva
- */
-public class WelcomeWindow extends JDialog
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- private static final String APPLICATION_NAME
- = BrandingActivator.getResources()
- .getSettingsString("service.gui.APPLICATION_NAME");
-
- private static final int DEFAULT_TEXT_INDENT
- = BrandingActivator.getResources()
- .getSettingsInt("plugin.branding.SPLASH_SCREEN_TEXT_INDENT");
-
- private static final int PREFERRED_HEIGHT = 330;
-
- private static final int PREFERRED_WIDTH = 570;
-
- private final JLabel bundleLabel = new JLabel();
-
- /**
- * Constructor.
- */
- public WelcomeWindow()
- {
- JLabel titleLabel = new JLabel(APPLICATION_NAME);
-
- JLabel versionLabel = new JLabel(" "
- + System.getProperty("sip-communicator.version"));
-
- JTextArea logoArea = new JTextArea(
- BrandingActivator.getResources()
- .getI18NString("plugin.branding.LOGO_MESSAGE"));
-
- StyledHTMLEditorPane rightsArea = new StyledHTMLEditorPane();
-
- StyledHTMLEditorPane licenseArea = new StyledHTMLEditorPane();
-
- JPanel textPanel = new JPanel();
-
- Container mainPanel = new WindowBackground();
-
- this.setTitle(APPLICATION_NAME);
-
- this.setModal(false);
- this.setUndecorated(true);
-
- mainPanel.setLayout(new BorderLayout());
-
- textPanel.setPreferredSize(new Dimension(470, 280));
- textPanel.setLayout(new BoxLayout(textPanel, BoxLayout.Y_AXIS));
- textPanel
- .setBorder(BorderFactory.createEmptyBorder(15, 15, 0, 15));
- textPanel.setOpaque(false);
-
- this.initTitleLabel(titleLabel);
-
- this.initVersionLabel(versionLabel);
-
- this.initLogoArea(logoArea);
-
- this.initRightsArea(rightsArea);
-
- this.initLicenseArea(licenseArea);
-
- Component loadingPanel = initLoadingPanel();
-
- textPanel.add(titleLabel);
- textPanel.add(versionLabel);
- textPanel.add(logoArea);
- textPanel.add(rightsArea);
- textPanel.add(licenseArea);
-
- mainPanel.add(textPanel, BorderLayout.CENTER);
- mainPanel.add(loadingPanel, BorderLayout.SOUTH);
-
- this.getContentPane().add(mainPanel);
-
- this.setResizable(false);
-
- mainPanel.setPreferredSize(
- new Dimension(PREFERRED_WIDTH, PREFERRED_HEIGHT));
-
- Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
- this.setLocation(screenSize.width / 2 - 527 / 2,
- screenSize.height / 2 - 305 / 2);
-
- this.initCloseActions();
- }
-
- /**
- * Initializes the title label.
- *
- * @param titleLabel the title label
- */
- private void initTitleLabel(JLabel titleLabel)
- {
- titleLabel.setFont(
- titleLabel.getFont().deriveFont(Font.BOLD, 28));
- titleLabel.setForeground(Constants.TITLE_COLOR);
- titleLabel.setAlignmentX(Component.RIGHT_ALIGNMENT);
- }
-
- /**
- * Initializes the version label.
- *
- * @param versionLabel the version label
- */
- private void initVersionLabel(JLabel versionLabel)
- {
- versionLabel.setFont(
- versionLabel.getFont().deriveFont(Font.BOLD, 18));
- versionLabel.setForeground(Constants.TITLE_COLOR);
- versionLabel.setAlignmentX(Component.RIGHT_ALIGNMENT);
- }
-
- /**
- * Initializes the logo area.
- *
- * @param logoArea the logo area
- */
- private void initLogoArea(JTextArea logoArea)
- {
- int logoAreaFontSize = BrandingActivator.getResources().
- getSettingsInt("plugin.branding.ABOUT_LOGO_FONT_SIZE");
-
- logoArea.setFont(
- logoArea.getFont().deriveFont(Font.BOLD, logoAreaFontSize));
- logoArea.setForeground(Constants.TITLE_COLOR);
- logoArea.setOpaque(false);
- logoArea.setLineWrap(true);
- logoArea.setWrapStyleWord(true);
- logoArea.setEditable(false);
- logoArea.setPreferredSize(new Dimension(100, 20));
- logoArea.setAlignmentX(Component.RIGHT_ALIGNMENT);
- logoArea.setBorder(BorderFactory
- .createEmptyBorder(20, DEFAULT_TEXT_INDENT, 0, 0));
- }
-
- /**
- * Initializes the copyright area.
- *
- * @param rightsArea the copyright area.
- */
- private void initRightsArea(StyledHTMLEditorPane rightsArea)
- {
- rightsArea.setContentType("text/html");
- rightsArea.appendToEnd(
- BrandingActivator.getResources().getI18NString(
- "plugin.branding.WELCOME_MESSAGE",
- new String[]{
- Constants.TEXT_COLOR,
- APPLICATION_NAME,
- BrandingActivator.getResources()
- .getSettingsString("service.gui.APPLICATION_WEB_SITE")
- }));
-
- rightsArea.setPreferredSize(new Dimension(50, 50));
- rightsArea
- .setBorder(BorderFactory
- .createEmptyBorder(0, DEFAULT_TEXT_INDENT, 0, 0));
- rightsArea.setOpaque(false);
- rightsArea.setEditable(false);
- rightsArea.setAlignmentX(Component.RIGHT_ALIGNMENT);
- }
-
- /**
- * Initializes the license area.
- *
- * @param licenseArea the license area.
- */
- private void initLicenseArea(StyledHTMLEditorPane licenseArea)
- {
- licenseArea.setContentType("text/html");
- licenseArea.appendToEnd(
- BrandingActivator.getResources().getI18NString(
- "plugin.branding.LICENSE",
- new String[]
- {
- Constants.TEXT_COLOR
- }));
-
- licenseArea.setPreferredSize(new Dimension(50, 20));
- licenseArea.setBorder(BorderFactory
- .createEmptyBorder(0, DEFAULT_TEXT_INDENT, 0, 0));
- licenseArea.setOpaque(false);
- licenseArea.setEditable(false);
- licenseArea.setAlignmentX(Component.RIGHT_ALIGNMENT);
- }
-
- private JPanel initLoadingPanel()
- {
- ResourceManagementService resources = BrandingActivator.getResources();
- JLabel loadingLabel
- = new JLabel(
- resources.getI18NString("plugin.branding.LOADING") + ": ");
- JPanel loadingPanel = new JPanel(new BorderLayout());
-
- this.bundleLabel.setFont(loadingLabel.getFont().deriveFont(Font.PLAIN));
-
- loadingPanel.setOpaque(false);
- loadingPanel.add(loadingLabel, BorderLayout.WEST);
- loadingPanel.add(bundleLabel, BorderLayout.CENTER);
-
- int loadingPanelBorder
- = resources
- .getSettingsInt("plugin.branding.LOADING_BUNDLE_PANEL_BORDER");
-
- loadingPanel.setBorder(
- BorderFactory.createEmptyBorder(loadingPanelBorder,
- loadingPanelBorder,
- loadingPanelBorder,
- loadingPanelBorder));
-
- int loadingPanelHeight
- = resources
- .getSettingsInt("plugin.branding.LOADING_BUNDLE_PANEL_HEIGHT");
-
- loadingPanel.setPreferredSize(
- new Dimension(PREFERRED_WIDTH, loadingPanelHeight));
-
- return loadingPanel;
- }
-
- /**
- * Initializes close actions on mouse click and esc key.
- */
- private void initCloseActions()
- {
- // Close the splash screen on simple click or Esc.
- this.getGlassPane().addMouseListener(new MouseAdapter()
- {
- @Override
- public void mouseClicked(MouseEvent e)
- {
- WelcomeWindow.this.close();
- }
- });
-
- this.getGlassPane().setVisible(true);
-
- ActionMap amap = this.getRootPane().getActionMap();
-
- amap.put("close", new CloseAction());
-
- InputMap imap = this.getRootPane().getInputMap(
- JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
-
- imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "close");
- }
-
- /**
- * Disposes this window.
- */
- protected void close()
- {
- this.dispose();
- }
-
- /**
- * Sets the name of the currently loading bundle.
- *
- * @param bundleName the name of the bundle to display
- */
- public void setBundle(String bundleName)
- {
- bundleLabel.setText(bundleName);
-
- bundleLabel.revalidate();
- bundleLabel.getParent().repaint();
- }
-
- /**
- * The action invoked when user presses Escape key.
- */
- private class CloseAction extends UIAction
- {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- public void actionPerformed(ActionEvent e)
- {
- WelcomeWindow.this.close();
- }
- }
-
- /**
- * Constructs the window background in order to have a background image.
- */
- private static class WindowBackground
- extends JPanel
- {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- private BufferedImage cache;
-
- private int cacheHeight;
-
- private int cacheWidth;
-
- private final Image image;
-
- public WindowBackground()
- {
- setOpaque(true);
-
- Image image = null;
- try
- {
- image =
- ImageIO.read(BrandingActivator.getResources().getImageURL(
- "plugin.branding.SPLASH_SCREEN_BACKGROUND"));
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- this.image = image;
-
- if (image != null)
- {
- setPreferredSize(new Dimension(image.getWidth(this), image
- .getHeight(this)));
- }
- }
-
- @Override
- protected void paintComponent(Graphics g)
- {
- super.paintComponent(g);
-
- g = g.create();
- try
- {
- internalPaintComponent(g);
- }
- finally
- {
- g.dispose();
- }
- }
-
- private void internalPaintComponent(Graphics g)
- {
- AntialiasingManager.activateAntialiasing(g);
-
- Graphics2D g2 = (Graphics2D) g;
-
- /*
- * Drawing an Image with a data layout and color model compatible
- * with this JPanel is magnitudes faster so create and use such an
- * Image from the original drawn by this instance.
- */
- int width = getWidth();
- int height = getHeight();
- boolean imageIsChanging = false;
- if ((cache == null) || (cacheWidth != width)
- || (cacheHeight != height))
- {
- cache =
- g2.getDeviceConfiguration().createCompatibleImage(width,
- height);
- cacheWidth = width;
- cacheHeight = height;
-
- Graphics2D cacheGraphics = cache.createGraphics();
- try
- {
- super.paintComponent(cacheGraphics);
-
- AntialiasingManager.activateAntialiasing(cacheGraphics);
-
- imageIsChanging =
- !cacheGraphics.drawImage(image, 0, 0, null);
-
- cacheGraphics.setColor(new Color(150, 150, 150));
- cacheGraphics.drawRoundRect(0, 0, width - 1, height - 1, 5,
- 5);
- }
- finally
- {
- cacheGraphics.dispose();
- }
- }
-
- g2.drawImage(cache, 0, 0, null);
-
- /*
- * Once the original Image drawn by this instance has been fully
- * loaded, we're free to use its "compatible" caching representation
- * for the purposes of optimized execution speed.
- */
- if (imageIsChanging)
- {
- cache = null;
- }
- }
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/busylampfield/BLFActivator.java b/src/net/java/sip/communicator/plugin/busylampfield/BLFActivator.java
index 036442b..94ea374 100644
--- a/src/net/java/sip/communicator/plugin/busylampfield/BLFActivator.java
+++ b/src/net/java/sip/communicator/plugin/busylampfield/BLFActivator.java
@@ -181,15 +181,11 @@ public class BLFActivator
}
else
{
- BLFContactSourceService css
- = new BLFContactSourceService(
+ BLFContactSourceService css = new BLFContactSourceService(
groupName, currentBLFGroups.size() + 1);
- serviceReg = (ServiceRegistration<ContactSourceService>)
- bundleContext.registerService(
- ContactSourceService.class.getName(),
- css,
- null);
+ serviceReg = bundleContext.registerService(
+ ContactSourceService.class, css, null);
currentBLFGroups.put(groupName, serviceReg);
css.addLine(line);
diff --git a/src/net/java/sip/communicator/plugin/certconfig/CertConfigEntryDialog.java b/src/net/java/sip/communicator/plugin/certconfig/CertConfigEntryDialog.java
index 278af62..b729b35 100644
--- a/src/net/java/sip/communicator/plugin/certconfig/CertConfigEntryDialog.java
+++ b/src/net/java/sip/communicator/plugin/certconfig/CertConfigEntryDialog.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,573 +15,573 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.certconfig;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.io.*;
-import java.lang.reflect.*;
-import java.security.*;
-import java.security.cert.*;
-import java.util.*;
-
-import javax.security.auth.callback.*;
-import javax.swing.*;
-import javax.swing.event.*;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.service.certificate.*;
-import net.java.sip.communicator.util.Logger;
-
-import org.jitsi.service.resources.*;
-import org.jitsi.util.*;
-
-/**
- * Dialog window to add/edit client certificate configuration entries.
- *
- * @author Ingo Bauersachs
- */
-public class CertConfigEntryDialog
- extends SIPCommDialog
- implements ActionListener, ItemListener, ChangeListener
-{
- // ------------------------------------------------------------------------
- // Fields and services
- // ------------------------------------------------------------------------
- private static final long serialVersionUID = 8361336563239745007L;
- private static final Logger logger = Logger
- .getLogger(CertConfigEntryDialog.class);
- private ResourceManagementService R = CertConfigActivator.R;
- private CertificateService cs = CertConfigActivator.getCertService();
- private CertificateConfigEntry entry;
- private boolean success = false;
-
- // ------------------------------------------------------------------------
- // GUI members
- // ------------------------------------------------------------------------
- private JButton cmdOk;
- private JButton cmdCancel;
- private JButton cmdBrowse;
- private JTextField txtDisplayName;
- private JTextField txtKeyStore;
- private JComboBox cboKeyStoreTypes;
- private JCheckBox chkSavePassword;
- private JPasswordField txtKeyStorePassword;
- private JComboBox cboAlias;
- private JButton cmdShowCert;
- private KeyStore keyStore;
-
- // ------------------------------------------------------------------------
- // Initialization
- // ------------------------------------------------------------------------
- /**
- * Constructor.
- *
- * @param e the <tt>CertificateConfigEntry</tt>
- */
- public CertConfigEntryDialog(CertificateConfigEntry e)
- {
- super(false);
- entry = e;
- initComponents();
- setPreferredSize(new Dimension(650, 270));
-
- try
- {
- if(entry.getKeyStore() != null)
- {
- txtKeyStorePassword.setText(entry.getKeyStorePassword());
- chkSavePassword.setSelected(entry.isSavePassword());
- cboKeyStoreTypes.setEnabled(true);
- cboKeyStoreTypes.setSelectedItem(entry.getKeyStoreType());
- if(keyStore == null)
- keyStore = loadKeyStore();
- cboAlias.setEnabled(true);
- loadAliases();
- cboAlias.setSelectedItem(entry.getAlias());
- }
- }
- catch (KeyStoreException ex)
- {
- logger.error("Unable to load all data", ex);
- showGenericError("plugin.certconfig.KEYSTORE_EXCEPTION", ex);
- }
- catch (ProviderException ex)
- {
- logger.error("Unable to load all data", ex);
- showGenericError("plugin.certconfig.KEYSTORE_EXCEPTION", ex);
- }
- }
-
- private void initComponents()
- {
- setTitle(R.getI18NString("plugin.certconfig.EDIT_ENTRY"));
- setLayout(new BorderLayout());
- JPanel fields = new TransparentPanel();
- fields.setLayout(new GridBagLayout());
-
- JLabel lblDisplayName = new JLabel();
- lblDisplayName.setText(R.getI18NString("service.gui.DISPLAY_NAME"));
- txtDisplayName = new JTextField();
- txtDisplayName.setText(entry.getDisplayName());
-
- JLabel lblKeyStore = new JLabel();
- lblKeyStore.setText(R.getI18NString("plugin.certconfig.KEYSTORE"));
- txtKeyStore = new JTextField();
- txtKeyStore.setText(entry.getKeyStore());
- txtKeyStore.setEditable(false);
-
- cmdBrowse = new JButton();
- cmdBrowse.setText(R.getI18NString("service.gui.BROWSE"));
- cmdBrowse.addActionListener(this);
-
- JLabel lblKeyStorePassword = new JLabel();
- lblKeyStorePassword.setText(
- R.getI18NString("plugin.certconfig.KEYSTORE_PASSWORD"));
- txtKeyStorePassword = new JPasswordField();
- txtKeyStorePassword.setEditable(false);
-
- chkSavePassword = new SIPCommCheckBox();
- chkSavePassword.setText(
- R.getI18NString("service.gui.REMEMBER_PASSWORD"));
- chkSavePassword.addChangeListener(this);
- chkSavePassword.setEnabled(false);
-
- JLabel lblKeyStoreType = new JLabel();
- lblKeyStoreType.setText(
- R.getI18NString("plugin.certconfig.KEYSTORE_TYPE"));
- cboKeyStoreTypes =
- new JComboBox(cs.getSupportedKeyStoreTypes().toArray());
- cboKeyStoreTypes.addItemListener(this);
- cboKeyStoreTypes.setEnabled(false);
-
- JLabel lblAlias = new JLabel();
- lblAlias.setText(R.getI18NString("plugin.certconfig.ALIAS"));
- cboAlias = new JComboBox();
- cboAlias.addItemListener(this);
- cboAlias.setEnabled(false);
-
- cmdShowCert = new JButton();
- cmdShowCert.setText(R.getI18NString("service.gui.SHOW_CERT") + "...");
- cmdShowCert.addActionListener(this);
- cmdShowCert.setEnabled(false);
-
- cmdCancel = new JButton();
- cmdCancel.setText(R.getI18NString("service.gui.CANCEL"));
- cmdCancel.addActionListener(this);
-
- cmdOk = new JButton();
- cmdOk.setText(R.getI18NString("service.gui.OK"));
- cmdOk.addActionListener(this);
- cmdOk.setPreferredSize(cmdCancel.getPreferredSize());
-
- TransparentPanel buttons = new TransparentPanel();
- buttons.setLayout(new FlowLayout(FlowLayout.RIGHT));
- buttons.add(cmdOk);
- buttons.add(cmdCancel);
-
- GridBagConstraints first = new GridBagConstraints();
- first.gridx = 0;
- first.gridy = 0;
- first.weightx = 0;
- first.anchor = GridBagConstraints.LINE_START;
- first.gridwidth = 1;
- first.insets = new Insets(2,4,2,4);
- first.fill = GridBagConstraints.HORIZONTAL;
-
- GridBagConstraints second = new GridBagConstraints();
- second.gridx = 1;
- second.gridy = 0;
- second.weightx = 2;
- second.anchor = GridBagConstraints.LINE_START;
- second.gridwidth = 1; //GridBagConstraints.REMAINDER;
- second.insets = first.insets;
- second.fill = GridBagConstraints.HORIZONTAL;
-
- GridBagConstraints third = new GridBagConstraints();
- third.gridx = 2;
- third.gridy = 0;
- third.weightx = 1;
- third.anchor = GridBagConstraints.LINE_END;
- third.gridwidth = 1;
- third.insets = first.insets;
- third.fill = GridBagConstraints.HORIZONTAL;
-
- fields.add(lblDisplayName, first);
- fields.add(txtDisplayName, second);
-
- first.gridy = second.gridy = ++third.gridy;
- fields.add(lblKeyStore, first);
- fields.add(txtKeyStore, second);
- fields.add(cmdBrowse, third);
-
- first.gridy = second.gridy = ++third.gridy;
- fields.add(lblKeyStoreType, first);
- fields.add(cboKeyStoreTypes, second);
-
- first.gridy = second.gridy = ++third.gridy;
- fields.add(lblKeyStorePassword, first);
- fields.add(txtKeyStorePassword, second);
-
- first.gridy = second.gridy = ++third.gridy;
- fields.add(chkSavePassword, second);
-
- first.gridy = second.gridy = ++third.gridy;
- fields.add(lblAlias, first);
- fields.add(cboAlias, second);
- fields.add(cmdShowCert, third);
-
- add(fields, BorderLayout.CENTER);
- add(buttons, BorderLayout.SOUTH);
- }
-
- // ------------------------------------------------------------------------
- // Event handling
- // ------------------------------------------------------------------------
- @Override
- protected void close(boolean escaped)
- {
- cmdCancel.doClick();
- }
-
- public void actionPerformed(ActionEvent e)
- {
- if(e.getSource() == cmdOk)
- {
- if(cboAlias.getSelectedItem() == null
- || StringUtils.isNullOrEmpty(txtDisplayName.getText())
- || StringUtils.isNullOrEmpty(txtKeyStore.getText()))
- {
- JOptionPane.showMessageDialog(this,
- R.getI18NString("plugin.certconfig.INCOMPLETE"),
- R.getI18NString("service.gui.ERROR"),
- JOptionPane.ERROR_MESSAGE);
- return;
- }
- entry.setAlias(cboAlias.getSelectedItem().toString());
- entry.setDisplayName(txtDisplayName.getText());
- entry.setSavePassword(chkSavePassword.isSelected());
- entry.setKeyStorePassword(
- new String(txtKeyStorePassword.getPassword()));
- entry.setKeyStoreType(
- (KeyStoreType) cboKeyStoreTypes.getSelectedItem());
- entry.setKeyStore(txtKeyStore.getText());
- success = true;
- dispose();
- }
- if(e.getSource() == cmdCancel)
- {
- dispose();
- }
- if(e.getSource() == cmdBrowse)
- {
- browseKeyStore();
- }
- if(e.getSource() == cmdShowCert)
- {
- showSelectedCertificate();
- }
- }
-
- private void showSelectedCertificate()
- {
- try
- {
- @SuppressWarnings("serial")
- SIPCommDialog dlg = new SIPCommDialog(this, false)
- {
- private JButton cmdClose;
- {
- setTitle(cboAlias.getSelectedItem().toString());
- setLayout(new BorderLayout());
- final JScrollPane certScroll =
- new JScrollPane(new X509CertificatePanel(
- (X509Certificate) keyStore.getCertificate(cboAlias
- .getSelectedItem().toString())));
- certScroll.setPreferredSize(new Dimension(600, 300));
- certScroll.getVerticalScrollBar().setValue(0);
- add(certScroll, BorderLayout.CENTER);
-
- SwingUtilities.invokeLater(new Runnable()
- {
- public void run()
- {
- certScroll.getVerticalScrollBar().setValue(0);
- }
- });
-
- cmdClose = new JButton();
- cmdClose.setText(R.getI18NString("service.gui.CLOSE"));
- cmdClose.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- dispose();
- }
- });
-
- TransparentPanel buttons =
- new TransparentPanel(new FlowLayout(FlowLayout.RIGHT));
- buttons.add(cmdClose);
- add(buttons, BorderLayout.SOUTH);
-
- setLocationRelativeTo(cmdShowCert);
- }
-
- @Override
- protected void close(boolean escaped)
- {
- cmdClose.doClick();
- }
- };
- dlg.setModal(true);
- dlg.setVisible(true);
- }
- catch (KeyStoreException e1)
- {
- logger.error("Unable to show the selected certificate", e1);
- showGenericError("plugin.certconfig.SHOW_CERT_EXCEPTION", e1);
- }
- }
-
- /**
- * Opens a FileChoserDialog to let the user pick a keystore and tries to
- * auto-detect the keystore type using the file extension
- */
- private void browseKeyStore()
- {
- SipCommFileChooser dlg =
- GenericFileDialog.create(null,
- R.getI18NString("plugin.certconfig.BROWSE_KEYSTORE"),
- SipCommFileChooser.LOAD_FILE_OPERATION);
- dlg.setSelectionMode(SipCommFileChooser.FILES_ONLY);
- dlg.addFilter(new SipCommFileFilter()
- {
- @Override
- public String getDescription()
- {
- return R
- .getI18NString("plugin.certconfig.FILE_TYPE_DESCRIPTION");
- }
-
- @Override
- public boolean accept(File f)
- {
- for(KeyStoreType kt : cs.getSupportedKeyStoreTypes())
- for(String ext : kt.getFileExtensions())
- if(f.getName().endsWith(ext))
- return true;
-
- return false;
- }
- });
- File f = dlg.getFileFromDialog();
- if(f != null)
- {
- cboKeyStoreTypes.setEnabled(true);
- cboKeyStoreTypes.setSelectedItem(null);
- cboAlias.setEnabled(true);
-
- txtKeyStore.setText(f.getAbsolutePath());
- for(KeyStoreType kt: cs.getSupportedKeyStoreTypes())
- for(String ext : kt.getFileExtensions())
- if(f.getName().endsWith(ext))
- cboKeyStoreTypes.setSelectedItem(kt);
- }
- }
-
- /**
- * Open the keystore selected by the user. If the type is set as PKCS#11,
- * the file is loaded as a provider. If the store is protected by a
- * password, the user is being asked by an authentication dialog.
- *
- * @return The loaded keystore
- * @throws KeyStoreException when something goes wrong
- */
- private KeyStore loadKeyStore() throws KeyStoreException
- {
- final File f = new File(txtKeyStore.getText());
- final KeyStoreType kt =
- (KeyStoreType) cboKeyStoreTypes.getSelectedItem();
- if("PKCS11".equals(kt.getName()))
- {
- String config =
- "name=" + f.getName() + "\nlibrary=" + f.getAbsoluteFile();
- try
- {
- Class<?> pkcs11c =
- Class.forName("sun.security.pkcs11.SunPKCS11");
- Constructor<?> c = pkcs11c.getConstructor(InputStream.class);
- Provider p =
- (Provider) c.newInstance(new ByteArrayInputStream(config
- .getBytes()));
- Security.insertProviderAt(p, 0);
- }
- catch (Exception e)
- {
- logger.error("Tried to access the PKCS11 provider on an "
- + "unsupported platform or the load failed", e);
- }
- }
- KeyStore.Builder ksBuilder = KeyStore.Builder.newInstance(
- kt.getName(),
- null,
- f,
- new KeyStore.CallbackHandlerProtection(new CallbackHandler()
- {
- public void handle(Callback[] callbacks)
- throws IOException,
- UnsupportedCallbackException
- {
- for(Callback cb : callbacks)
- {
- if(!(cb instanceof PasswordCallback))
- throw new UnsupportedCallbackException(cb);
- PasswordCallback pwcb = (PasswordCallback)cb;
- if(
- (
- txtKeyStorePassword.getPassword() != null
- && txtKeyStorePassword.getPassword().length>0
- )
- || chkSavePassword.isSelected())
- {
- pwcb.setPassword(txtKeyStorePassword.getPassword());
- return;
- }
- AuthenticationWindow aw = new AuthenticationWindow(
- CertConfigEntryDialog.this,
- f.getName(),
- null,
- kt.getName(),
- false,
- null
- );
- aw.setAllowSavePassword(!"PKCS11".equals(kt.getName()));
- aw.setVisible(true);
- if(!aw.isCanceled())
- {
- pwcb.setPassword(aw.getPassword());
- if (!"PKCS11".equals(kt.getName())
- && aw.isRememberPassword())
- {
- txtKeyStorePassword.setText(new String(aw
- .getPassword()));
- }
- chkSavePassword.setSelected(aw
- .isRememberPassword());
- }
- else
- throw new IOException("User cancel");
- }
- }
- }));
- return ksBuilder.getKeyStore();
- }
-
- /**
- * Load the certificate entry aliases from the chosen keystore.
- */
- private void loadAliases()
- {
- String currentDisplayName = txtDisplayName.getText();
- String currentAlias =
- cboAlias.getSelectedItem() == null ? null : cboAlias
- .getSelectedItem().toString();
- try
- {
- cboAlias.removeAllItems();
- Enumeration<String> e = keyStore.aliases();
- while(e.hasMoreElements())
- {
- cboAlias.addItem(e.nextElement());
- }
- // if the display name is empty or identical to the alias, set it
- // to the alias of the newly selected cert
- if(
- (
- StringUtils.isNullOrEmpty(currentDisplayName)
- || (
- currentDisplayName != null
- && currentDisplayName.equals(currentAlias)
- )
- )
- && cboAlias.getSelectedItem() != null)
- {
- txtDisplayName.setText(cboAlias.getSelectedItem().toString());
- }
-
- }
- catch (KeyStoreException e)
- {
- cboAlias.removeAllItems();
- logger.error("Unable to obtain aliases from keystore", e);
- showGenericError("plugin.certconfig.ALIAS_LOAD_EXCEPTION", e);
- }
- }
-
- private void showGenericError(String msg, Throwable e)
- {
- JOptionPane.showMessageDialog(
- this,
- R.getI18NString(msg, new String[]{e.getMessage()}),
- R.getI18NString("service.gui.ERROR"),
- JOptionPane.ERROR_MESSAGE
- );
- }
-
- /**
- * Show this dialog.
- *
- * @return true if OK has been pressed, false otherwise
- */
- public boolean showDialog()
- {
- setModal(true);
- setVisible(true);
- setVisible(false);
- return success;
- }
-
- public void itemStateChanged(ItemEvent e)
- {
- if(e.getStateChange() != ItemEvent.SELECTED)
- return;
- if(e.getSource() == cboKeyStoreTypes)
- {
- KeyStoreType kt = (KeyStoreType)cboKeyStoreTypes.getSelectedItem();
- if(kt == null)
- return;
- try
- {
- if(!"PKCS11".equals(kt.getName()))
- chkSavePassword.setEnabled(true);
- txtKeyStorePassword.setEditable(kt.hasKeyStorePassword()
- && chkSavePassword.isSelected());
-
- keyStore = loadKeyStore();
- loadAliases();
- }
- catch (KeyStoreException ex)
- {
- cboAlias.removeAllItems();
- showGenericError("plugin.certconfig.INVALID_KEYSTORE_TYPE", ex);
- }
- }
- if(e.getSource() == cboAlias)
- {
- cmdShowCert.setEnabled(cboAlias.getSelectedItem() != null);
- }
- }
-
- public void stateChanged(ChangeEvent e)
- {
- if(e.getSource() == chkSavePassword)
- {
- txtKeyStorePassword.setEditable(
- chkSavePassword.isSelected()
- && ((KeyStoreType) cboKeyStoreTypes.getSelectedItem())
- .hasKeyStorePassword()
- );
- }
- }
-}
+package net.java.sip.communicator.plugin.certconfig;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+import java.lang.reflect.*;
+import java.security.*;
+import java.security.cert.*;
+import java.util.*;
+
+import javax.security.auth.callback.*;
+import javax.swing.*;
+import javax.swing.event.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.service.certificate.*;
+import net.java.sip.communicator.util.Logger;
+
+import org.jitsi.service.resources.*;
+import org.jitsi.util.*;
+
+/**
+ * Dialog window to add/edit client certificate configuration entries.
+ *
+ * @author Ingo Bauersachs
+ */
+public class CertConfigEntryDialog
+ extends SIPCommDialog
+ implements ActionListener, ItemListener, ChangeListener
+{
+ // ------------------------------------------------------------------------
+ // Fields and services
+ // ------------------------------------------------------------------------
+ private static final long serialVersionUID = 8361336563239745007L;
+ private static final Logger logger = Logger
+ .getLogger(CertConfigEntryDialog.class);
+ private ResourceManagementService R = CertConfigActivator.R;
+ private CertificateService cs = CertConfigActivator.getCertService();
+ private CertificateConfigEntry entry;
+ private boolean success = false;
+
+ // ------------------------------------------------------------------------
+ // GUI members
+ // ------------------------------------------------------------------------
+ private JButton cmdOk;
+ private JButton cmdCancel;
+ private JButton cmdBrowse;
+ private JTextField txtDisplayName;
+ private JTextField txtKeyStore;
+ private JComboBox cboKeyStoreTypes;
+ private JCheckBox chkSavePassword;
+ private JPasswordField txtKeyStorePassword;
+ private JComboBox cboAlias;
+ private JButton cmdShowCert;
+ private KeyStore keyStore;
+
+ // ------------------------------------------------------------------------
+ // Initialization
+ // ------------------------------------------------------------------------
+ /**
+ * Constructor.
+ *
+ * @param e the <tt>CertificateConfigEntry</tt>
+ */
+ public CertConfigEntryDialog(CertificateConfigEntry e)
+ {
+ super(false);
+ entry = e;
+ initComponents();
+ setPreferredSize(new Dimension(650, 270));
+
+ try
+ {
+ if(entry.getKeyStore() != null)
+ {
+ txtKeyStorePassword.setText(entry.getKeyStorePassword());
+ chkSavePassword.setSelected(entry.isSavePassword());
+ cboKeyStoreTypes.setEnabled(true);
+ cboKeyStoreTypes.setSelectedItem(entry.getKeyStoreType());
+ if(keyStore == null)
+ keyStore = loadKeyStore();
+ cboAlias.setEnabled(true);
+ loadAliases();
+ cboAlias.setSelectedItem(entry.getAlias());
+ }
+ }
+ catch (KeyStoreException ex)
+ {
+ logger.error("Unable to load all data", ex);
+ showGenericError("plugin.certconfig.KEYSTORE_EXCEPTION", ex);
+ }
+ catch (ProviderException ex)
+ {
+ logger.error("Unable to load all data", ex);
+ showGenericError("plugin.certconfig.KEYSTORE_EXCEPTION", ex);
+ }
+ }
+
+ private void initComponents()
+ {
+ setTitle(R.getI18NString("plugin.certconfig.EDIT_ENTRY"));
+ setLayout(new BorderLayout());
+ JPanel fields = new TransparentPanel();
+ fields.setLayout(new GridBagLayout());
+
+ JLabel lblDisplayName = new JLabel();
+ lblDisplayName.setText(R.getI18NString("service.gui.DISPLAY_NAME"));
+ txtDisplayName = new JTextField();
+ txtDisplayName.setText(entry.getDisplayName());
+
+ JLabel lblKeyStore = new JLabel();
+ lblKeyStore.setText(R.getI18NString("plugin.certconfig.KEYSTORE"));
+ txtKeyStore = new JTextField();
+ txtKeyStore.setText(entry.getKeyStore());
+ txtKeyStore.setEditable(false);
+
+ cmdBrowse = new JButton();
+ cmdBrowse.setText(R.getI18NString("service.gui.BROWSE"));
+ cmdBrowse.addActionListener(this);
+
+ JLabel lblKeyStorePassword = new JLabel();
+ lblKeyStorePassword.setText(
+ R.getI18NString("plugin.certconfig.KEYSTORE_PASSWORD"));
+ txtKeyStorePassword = new JPasswordField();
+ txtKeyStorePassword.setEditable(false);
+
+ chkSavePassword = new SIPCommCheckBox();
+ chkSavePassword.setText(
+ R.getI18NString("service.gui.REMEMBER_PASSWORD"));
+ chkSavePassword.addChangeListener(this);
+ chkSavePassword.setEnabled(false);
+
+ JLabel lblKeyStoreType = new JLabel();
+ lblKeyStoreType.setText(
+ R.getI18NString("plugin.certconfig.KEYSTORE_TYPE"));
+ cboKeyStoreTypes =
+ new JComboBox(cs.getSupportedKeyStoreTypes().toArray());
+ cboKeyStoreTypes.addItemListener(this);
+ cboKeyStoreTypes.setEnabled(false);
+
+ JLabel lblAlias = new JLabel();
+ lblAlias.setText(R.getI18NString("plugin.certconfig.ALIAS"));
+ cboAlias = new JComboBox();
+ cboAlias.addItemListener(this);
+ cboAlias.setEnabled(false);
+
+ cmdShowCert = new JButton();
+ cmdShowCert.setText(R.getI18NString("service.gui.SHOW_CERT") + "...");
+ cmdShowCert.addActionListener(this);
+ cmdShowCert.setEnabled(false);
+
+ cmdCancel = new JButton();
+ cmdCancel.setText(R.getI18NString("service.gui.CANCEL"));
+ cmdCancel.addActionListener(this);
+
+ cmdOk = new JButton();
+ cmdOk.setText(R.getI18NString("service.gui.OK"));
+ cmdOk.addActionListener(this);
+ cmdOk.setPreferredSize(cmdCancel.getPreferredSize());
+
+ TransparentPanel buttons = new TransparentPanel();
+ buttons.setLayout(new FlowLayout(FlowLayout.RIGHT));
+ buttons.add(cmdOk);
+ buttons.add(cmdCancel);
+
+ GridBagConstraints first = new GridBagConstraints();
+ first.gridx = 0;
+ first.gridy = 0;
+ first.weightx = 0;
+ first.anchor = GridBagConstraints.LINE_START;
+ first.gridwidth = 1;
+ first.insets = new Insets(2,4,2,4);
+ first.fill = GridBagConstraints.HORIZONTAL;
+
+ GridBagConstraints second = new GridBagConstraints();
+ second.gridx = 1;
+ second.gridy = 0;
+ second.weightx = 2;
+ second.anchor = GridBagConstraints.LINE_START;
+ second.gridwidth = 1; //GridBagConstraints.REMAINDER;
+ second.insets = first.insets;
+ second.fill = GridBagConstraints.HORIZONTAL;
+
+ GridBagConstraints third = new GridBagConstraints();
+ third.gridx = 2;
+ third.gridy = 0;
+ third.weightx = 1;
+ third.anchor = GridBagConstraints.LINE_END;
+ third.gridwidth = 1;
+ third.insets = first.insets;
+ third.fill = GridBagConstraints.HORIZONTAL;
+
+ fields.add(lblDisplayName, first);
+ fields.add(txtDisplayName, second);
+
+ first.gridy = second.gridy = ++third.gridy;
+ fields.add(lblKeyStore, first);
+ fields.add(txtKeyStore, second);
+ fields.add(cmdBrowse, third);
+
+ first.gridy = second.gridy = ++third.gridy;
+ fields.add(lblKeyStoreType, first);
+ fields.add(cboKeyStoreTypes, second);
+
+ first.gridy = second.gridy = ++third.gridy;
+ fields.add(lblKeyStorePassword, first);
+ fields.add(txtKeyStorePassword, second);
+
+ first.gridy = second.gridy = ++third.gridy;
+ fields.add(chkSavePassword, second);
+
+ first.gridy = second.gridy = ++third.gridy;
+ fields.add(lblAlias, first);
+ fields.add(cboAlias, second);
+ fields.add(cmdShowCert, third);
+
+ add(fields, BorderLayout.CENTER);
+ add(buttons, BorderLayout.SOUTH);
+ }
+
+ // ------------------------------------------------------------------------
+ // Event handling
+ // ------------------------------------------------------------------------
+ @Override
+ protected void close(boolean escaped)
+ {
+ cmdCancel.doClick();
+ }
+
+ public void actionPerformed(ActionEvent e)
+ {
+ if(e.getSource() == cmdOk)
+ {
+ if(cboAlias.getSelectedItem() == null
+ || StringUtils.isNullOrEmpty(txtDisplayName.getText())
+ || StringUtils.isNullOrEmpty(txtKeyStore.getText()))
+ {
+ JOptionPane.showMessageDialog(this,
+ R.getI18NString("plugin.certconfig.INCOMPLETE"),
+ R.getI18NString("service.gui.ERROR"),
+ JOptionPane.ERROR_MESSAGE);
+ return;
+ }
+ entry.setAlias(cboAlias.getSelectedItem().toString());
+ entry.setDisplayName(txtDisplayName.getText());
+ entry.setSavePassword(chkSavePassword.isSelected());
+ entry.setKeyStorePassword(
+ new String(txtKeyStorePassword.getPassword()));
+ entry.setKeyStoreType(
+ (KeyStoreType) cboKeyStoreTypes.getSelectedItem());
+ entry.setKeyStore(txtKeyStore.getText());
+ success = true;
+ dispose();
+ }
+ if(e.getSource() == cmdCancel)
+ {
+ dispose();
+ }
+ if(e.getSource() == cmdBrowse)
+ {
+ browseKeyStore();
+ }
+ if(e.getSource() == cmdShowCert)
+ {
+ showSelectedCertificate();
+ }
+ }
+
+ private void showSelectedCertificate()
+ {
+ try
+ {
+ @SuppressWarnings("serial")
+ SIPCommDialog dlg = new SIPCommDialog(this, false)
+ {
+ private JButton cmdClose;
+ {
+ setTitle(cboAlias.getSelectedItem().toString());
+ setLayout(new BorderLayout());
+ final JScrollPane certScroll =
+ new JScrollPane(new X509CertificatePanel(
+ (X509Certificate) keyStore.getCertificate(cboAlias
+ .getSelectedItem().toString())));
+ certScroll.setPreferredSize(new Dimension(600, 300));
+ certScroll.getVerticalScrollBar().setValue(0);
+ add(certScroll, BorderLayout.CENTER);
+
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ certScroll.getVerticalScrollBar().setValue(0);
+ }
+ });
+
+ cmdClose = new JButton();
+ cmdClose.setText(R.getI18NString("service.gui.CLOSE"));
+ cmdClose.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ dispose();
+ }
+ });
+
+ TransparentPanel buttons =
+ new TransparentPanel(new FlowLayout(FlowLayout.RIGHT));
+ buttons.add(cmdClose);
+ add(buttons, BorderLayout.SOUTH);
+
+ setLocationRelativeTo(cmdShowCert);
+ }
+
+ @Override
+ protected void close(boolean escaped)
+ {
+ cmdClose.doClick();
+ }
+ };
+ dlg.setModal(true);
+ dlg.setVisible(true);
+ }
+ catch (KeyStoreException e1)
+ {
+ logger.error("Unable to show the selected certificate", e1);
+ showGenericError("plugin.certconfig.SHOW_CERT_EXCEPTION", e1);
+ }
+ }
+
+ /**
+ * Opens a FileChoserDialog to let the user pick a keystore and tries to
+ * auto-detect the keystore type using the file extension
+ */
+ private void browseKeyStore()
+ {
+ SipCommFileChooser dlg =
+ GenericFileDialog.create(null,
+ R.getI18NString("plugin.certconfig.BROWSE_KEYSTORE"),
+ SipCommFileChooser.LOAD_FILE_OPERATION);
+ dlg.setSelectionMode(SipCommFileChooser.FILES_ONLY);
+ dlg.addFilter(new SipCommFileFilter()
+ {
+ @Override
+ public String getDescription()
+ {
+ return R
+ .getI18NString("plugin.certconfig.FILE_TYPE_DESCRIPTION");
+ }
+
+ @Override
+ public boolean accept(File f)
+ {
+ for(KeyStoreType kt : cs.getSupportedKeyStoreTypes())
+ for(String ext : kt.getFileExtensions())
+ if(f.getName().endsWith(ext))
+ return true;
+
+ return false;
+ }
+ });
+ File f = dlg.getFileFromDialog();
+ if(f != null)
+ {
+ cboKeyStoreTypes.setEnabled(true);
+ cboKeyStoreTypes.setSelectedItem(null);
+ cboAlias.setEnabled(true);
+
+ txtKeyStore.setText(f.getAbsolutePath());
+ for(KeyStoreType kt: cs.getSupportedKeyStoreTypes())
+ for(String ext : kt.getFileExtensions())
+ if(f.getName().endsWith(ext))
+ cboKeyStoreTypes.setSelectedItem(kt);
+ }
+ }
+
+ /**
+ * Open the keystore selected by the user. If the type is set as PKCS#11,
+ * the file is loaded as a provider. If the store is protected by a
+ * password, the user is being asked by an authentication dialog.
+ *
+ * @return The loaded keystore
+ * @throws KeyStoreException when something goes wrong
+ */
+ private KeyStore loadKeyStore() throws KeyStoreException
+ {
+ final File f = new File(txtKeyStore.getText());
+ final KeyStoreType kt =
+ (KeyStoreType) cboKeyStoreTypes.getSelectedItem();
+ if("PKCS11".equals(kt.getName()))
+ {
+ String config =
+ "name=" + f.getName() + "\nlibrary=" + f.getAbsoluteFile();
+ try
+ {
+ Class<?> pkcs11c =
+ Class.forName("sun.security.pkcs11.SunPKCS11");
+ Constructor<?> c = pkcs11c.getConstructor(InputStream.class);
+ Provider p =
+ (Provider) c.newInstance(new ByteArrayInputStream(config
+ .getBytes()));
+ Security.insertProviderAt(p, 0);
+ }
+ catch (Exception e)
+ {
+ logger.error("Tried to access the PKCS11 provider on an "
+ + "unsupported platform or the load failed", e);
+ }
+ }
+ KeyStore.Builder ksBuilder = KeyStore.Builder.newInstance(
+ kt.getName(),
+ null,
+ f,
+ new KeyStore.CallbackHandlerProtection(new CallbackHandler()
+ {
+ public void handle(Callback[] callbacks)
+ throws IOException,
+ UnsupportedCallbackException
+ {
+ for(Callback cb : callbacks)
+ {
+ if(!(cb instanceof PasswordCallback))
+ throw new UnsupportedCallbackException(cb);
+ PasswordCallback pwcb = (PasswordCallback)cb;
+ if(
+ (
+ txtKeyStorePassword.getPassword() != null
+ && txtKeyStorePassword.getPassword().length>0
+ )
+ || chkSavePassword.isSelected())
+ {
+ pwcb.setPassword(txtKeyStorePassword.getPassword());
+ return;
+ }
+ AuthenticationWindow aw = new AuthenticationWindow(
+ CertConfigEntryDialog.this,
+ f.getName(),
+ null,
+ kt.getName(),
+ false,
+ null
+ );
+ aw.setAllowSavePassword(!"PKCS11".equals(kt.getName()));
+ aw.setVisible(true);
+ if(!aw.isCanceled())
+ {
+ pwcb.setPassword(aw.getPassword());
+ if (!"PKCS11".equals(kt.getName())
+ && aw.isRememberPassword())
+ {
+ txtKeyStorePassword.setText(new String(aw
+ .getPassword()));
+ }
+ chkSavePassword.setSelected(aw
+ .isRememberPassword());
+ }
+ else
+ throw new IOException("User cancel");
+ }
+ }
+ }));
+ return ksBuilder.getKeyStore();
+ }
+
+ /**
+ * Load the certificate entry aliases from the chosen keystore.
+ */
+ private void loadAliases()
+ {
+ String currentDisplayName = txtDisplayName.getText();
+ String currentAlias =
+ cboAlias.getSelectedItem() == null ? null : cboAlias
+ .getSelectedItem().toString();
+ try
+ {
+ cboAlias.removeAllItems();
+ Enumeration<String> e = keyStore.aliases();
+ while(e.hasMoreElements())
+ {
+ cboAlias.addItem(e.nextElement());
+ }
+ // if the display name is empty or identical to the alias, set it
+ // to the alias of the newly selected cert
+ if(
+ (
+ StringUtils.isNullOrEmpty(currentDisplayName)
+ || (
+ currentDisplayName != null
+ && currentDisplayName.equals(currentAlias)
+ )
+ )
+ && cboAlias.getSelectedItem() != null)
+ {
+ txtDisplayName.setText(cboAlias.getSelectedItem().toString());
+ }
+
+ }
+ catch (KeyStoreException e)
+ {
+ cboAlias.removeAllItems();
+ logger.error("Unable to obtain aliases from keystore", e);
+ showGenericError("plugin.certconfig.ALIAS_LOAD_EXCEPTION", e);
+ }
+ }
+
+ private void showGenericError(String msg, Throwable e)
+ {
+ JOptionPane.showMessageDialog(
+ this,
+ R.getI18NString(msg, new String[]{e.getMessage()}),
+ R.getI18NString("service.gui.ERROR"),
+ JOptionPane.ERROR_MESSAGE
+ );
+ }
+
+ /**
+ * Show this dialog.
+ *
+ * @return true if OK has been pressed, false otherwise
+ */
+ public boolean showDialog()
+ {
+ setModal(true);
+ setVisible(true);
+ setVisible(false);
+ return success;
+ }
+
+ public void itemStateChanged(ItemEvent e)
+ {
+ if(e.getStateChange() != ItemEvent.SELECTED)
+ return;
+ if(e.getSource() == cboKeyStoreTypes)
+ {
+ KeyStoreType kt = (KeyStoreType)cboKeyStoreTypes.getSelectedItem();
+ if(kt == null)
+ return;
+ try
+ {
+ if(!"PKCS11".equals(kt.getName()))
+ chkSavePassword.setEnabled(true);
+ txtKeyStorePassword.setEditable(kt.hasKeyStorePassword()
+ && chkSavePassword.isSelected());
+
+ keyStore = loadKeyStore();
+ loadAliases();
+ }
+ catch (KeyStoreException ex)
+ {
+ cboAlias.removeAllItems();
+ showGenericError("plugin.certconfig.INVALID_KEYSTORE_TYPE", ex);
+ }
+ }
+ if(e.getSource() == cboAlias)
+ {
+ cmdShowCert.setEnabled(cboAlias.getSelectedItem() != null);
+ }
+ }
+
+ public void stateChanged(ChangeEvent e)
+ {
+ if(e.getSource() == chkSavePassword)
+ {
+ txtKeyStorePassword.setEditable(
+ chkSavePassword.isSelected()
+ && ((KeyStoreType) cboKeyStoreTypes.getSelectedItem())
+ .hasKeyStorePassword()
+ );
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/certconfig/CertConfigPanel.java b/src/net/java/sip/communicator/plugin/certconfig/CertConfigPanel.java
index 57c7606..6f7bf67 100644
--- a/src/net/java/sip/communicator/plugin/certconfig/CertConfigPanel.java
+++ b/src/net/java/sip/communicator/plugin/certconfig/CertConfigPanel.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,267 +15,267 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.certconfig;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.security.*;
-
-import javax.swing.*;
-import javax.swing.border.*;
-import javax.swing.event.*;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.service.certificate.*;
-import net.java.sip.communicator.service.gui.*;
-
-import org.jitsi.service.resources.*;
-import org.jitsi.util.*;
-
-/**
- * Advanced configuration form to define client TLS certificate templates.
- *
- * @author Ingo Bauersachs
- */
-public class CertConfigPanel
- extends TransparentPanel
- implements ConfigurationForm, ActionListener, ListSelectionListener
-{
- // ------------------------------------------------------------------------
- // Fields
- // ------------------------------------------------------------------------
- private static final long serialVersionUID = 2324122652952574574L;
- private ResourceManagementService R;
- private CertConfigTableModel model;
-
- // ------------------------------------------------------------------------
- // GUI members
- // ------------------------------------------------------------------------
- private JButton cmdAdd;
- private JButton cmdRemove;
- private JButton cmdEdit;
- private JTable tblCertList;
- private JRadioButton rdoUseWindows;
- private JRadioButton rdoUseJava;
- private SIPCommCheckBox chkEnableRevocationCheck;
- private SIPCommCheckBox chkEnableOcsp;
-
- // ------------------------------------------------------------------------
- // initialization
- // ------------------------------------------------------------------------
- /**
- * Creates a new instance of this class.
- */
- public CertConfigPanel()
- {
- R = CertConfigActivator.R;
- model = new CertConfigTableModel();
- initComponents();
- valueChanged(null);
- }
-
- private void initComponents()
- {
- this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
-
- // trusted root CA source selection
- if (OSUtils.IS_WINDOWS)
- {
- JPanel pnlCertConfig = new TransparentPanel(new GridLayout(2, 1));
- pnlCertConfig.setBorder(BorderFactory.createTitledBorder(
- R.getI18NString("plugin.certconfig.TRUSTSTORE_CONFIG")));
- add(pnlCertConfig);
-
- ButtonGroup grpTrustStore = new ButtonGroup();
-
- rdoUseJava = new SIPCommRadioButton();
- rdoUseJava.setText(
- R.getI18NString("plugin.certconfig.JAVA_TRUSTSTORE"));
- rdoUseJava.addActionListener(this);
- grpTrustStore.add(rdoUseJava);
- pnlCertConfig.add(rdoUseJava);
-
- rdoUseWindows = new SIPCommRadioButton();
- rdoUseWindows.setText(
- R.getI18NString("plugin.certconfig.WINDOWS_TRUSTSTORE"));
- rdoUseWindows.addActionListener(this);
- grpTrustStore.add(rdoUseWindows);
- pnlCertConfig.add(rdoUseWindows);
-
- if ("Windows-ROOT".equals(CertConfigActivator.getConfigService()
- .getProperty(CertificateService.PNAME_TRUSTSTORE_TYPE)))
- {
- rdoUseWindows.setSelected(true);
- }
- else
- {
- rdoUseJava.setSelected(true);
- }
- }
-
- // revocation options
- JPanel pnlRevocation = new TransparentPanel(new GridLayout(2, 1));
- pnlRevocation.setBorder(BorderFactory.createTitledBorder(
- R.getI18NString("plugin.certconfig.REVOCATION_TITLE")));
- add(pnlRevocation);
-
- chkEnableRevocationCheck = new SIPCommCheckBox(
- R.getI18NString("plugin.certconfig.REVOCATION_CHECK_ENABLED"));
- chkEnableRevocationCheck.addActionListener(this);
- chkEnableRevocationCheck.setSelected(
- "true".equals(
- System.getProperty("com.sun.net.ssl.checkRevocation")));
- pnlRevocation.add(chkEnableRevocationCheck);
-
- chkEnableOcsp = new SIPCommCheckBox(
- R.getI18NString("plugin.certconfig.REVOCATION_OCSP_ENABLED"));
- chkEnableOcsp.addActionListener(this);
- chkEnableOcsp.setSelected(
- "true".equals(Security.getProperty("ocsp.enable")));
- chkEnableOcsp.setEnabled(chkEnableRevocationCheck.isSelected());
- pnlRevocation.add(chkEnableOcsp);
-
- // Client certificate authentication list
- JPanel pnlCertList = new TransparentPanel(new BorderLayout());
- pnlCertList.setBorder(BorderFactory.createTitledBorder(
- R.getI18NString("plugin.certconfig.CERT_LIST_TITLE")));
- add(pnlCertList);
-
- JLabel lblNote = new JLabel();
- lblNote.setText(
- R.getI18NString("plugin.certconfig.CERT_LIST_DESCRIPTION"));
- lblNote.setBorder(new EmptyBorder(7, 7, 7, 7));
- pnlCertList.add(lblNote, BorderLayout.NORTH);
-
- tblCertList = new JTable();
- tblCertList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
- tblCertList.getSelectionModel().addListSelectionListener(this);
- tblCertList.setModel(model);
- pnlCertList.add(new JScrollPane(tblCertList), BorderLayout.CENTER);
-
- TransparentPanel buttons = new TransparentPanel();
- buttons.setLayout(new FlowLayout(FlowLayout.RIGHT));
- pnlCertList.add(buttons, BorderLayout.SOUTH);
-
- cmdAdd = new JButton();
- cmdAdd.setText(R.getI18NString("service.gui.ADD"));
- cmdAdd.addActionListener(this);
- buttons.add(cmdAdd);
-
- cmdRemove = new JButton();
- cmdRemove.setText(R.getI18NString("service.gui.REMOVE"));
- cmdRemove.addActionListener(this);
- buttons.add(cmdRemove);
-
- cmdEdit = new JButton();
- cmdEdit.setText(R.getI18NString("service.gui.EDIT"));
- cmdEdit.addActionListener(this);
- buttons.add(cmdEdit);
- }
-
- // ------------------------------------------------------------------------
- // event handling
- // ------------------------------------------------------------------------
- public void valueChanged(ListSelectionEvent e)
- {
- int row = tblCertList.getSelectedRow();
- cmdRemove.setEnabled(row > -1);
- cmdEdit.setEnabled(row > -1);
- }
-
- public void actionPerformed(ActionEvent e)
- {
- if (e.getSource() == cmdAdd)
- {
- CertificateConfigEntry newEntry = new CertificateConfigEntry();
- CertConfigEntryDialog dlg = new CertConfigEntryDialog(newEntry);
- if (dlg.showDialog())
- CertConfigActivator.getCertService()
- .setClientAuthCertificateConfig(newEntry);
- }
- if (e.getSource() == cmdRemove)
- {
- CertConfigActivator.getCertService()
- .removeClientAuthCertificateConfig(
- model.getItem(tblCertList.getSelectedRow()).getId());
- }
- if (e.getSource() == cmdEdit)
- {
- CertificateConfigEntry entry =
- model.getItem(tblCertList.getSelectedRow());
- CertConfigEntryDialog dlg = new CertConfigEntryDialog(entry);
- if (dlg.showDialog())
- CertConfigActivator.getCertService()
- .setClientAuthCertificateConfig(entry);
- }
- if (e.getSource() == rdoUseJava)
- {
- CertConfigActivator.getConfigService().setProperty(
- CertificateService.PNAME_TRUSTSTORE_TYPE,
- "meta:default");
- CertConfigActivator.getConfigService().removeProperty(
- CertificateService.PNAME_TRUSTSTORE_FILE);
- CertConfigActivator.getCredService().removePassword(
- CertificateService.PNAME_TRUSTSTORE_PASSWORD);
- }
- if (e.getSource() == rdoUseWindows)
- {
- CertConfigActivator.getConfigService().setProperty(
- CertificateService.PNAME_TRUSTSTORE_TYPE, "Windows-ROOT");
- CertConfigActivator.getConfigService().removeProperty(
- CertificateService.PNAME_TRUSTSTORE_FILE);
- CertConfigActivator.getCredService().removePassword(
- CertificateService.PNAME_TRUSTSTORE_PASSWORD);
- }
- if (e.getSource() == chkEnableRevocationCheck)
- {
- CertConfigActivator.getConfigService().setProperty(
- CertificateService.PNAME_REVOCATION_CHECK_ENABLED,
- chkEnableRevocationCheck.isSelected());
-
- String enabled = new Boolean(
- chkEnableRevocationCheck.isSelected()).toString();
- System.setProperty("com.sun.security.enableCRLDP", enabled);
- System.setProperty("com.sun.net.ssl.checkRevocation", enabled);
- chkEnableOcsp.setEnabled(chkEnableRevocationCheck.isSelected());
- }
- if (e.getSource() == chkEnableOcsp)
- {
- CertConfigActivator.getConfigService().setProperty(
- CertificateService.PNAME_OCSP_ENABLED,
- chkEnableOcsp.isSelected());
-
- Security.setProperty("ocsp.enable",
- new Boolean(chkEnableOcsp.isSelected()).toString());
- }
- }
-
- // ------------------------------------------------------------------------
- // Configuration form members
- // ------------------------------------------------------------------------
- public String getTitle()
- {
- return CertConfigActivator.R.getI18NString("plugin.certconfig.TITLE");
- }
-
- public byte[] getIcon()
- {
- return null;
- }
-
- public Object getForm()
- {
- return this;
- }
-
- public int getIndex()
- {
- return -1;
- }
-
- public boolean isAdvanced()
- {
- return true;
- }
-
-}
+package net.java.sip.communicator.plugin.certconfig;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.security.*;
+
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.service.certificate.*;
+import net.java.sip.communicator.service.gui.*;
+
+import org.jitsi.service.resources.*;
+import org.jitsi.util.*;
+
+/**
+ * Advanced configuration form to define client TLS certificate templates.
+ *
+ * @author Ingo Bauersachs
+ */
+public class CertConfigPanel
+ extends TransparentPanel
+ implements ConfigurationForm, ActionListener, ListSelectionListener
+{
+ // ------------------------------------------------------------------------
+ // Fields
+ // ------------------------------------------------------------------------
+ private static final long serialVersionUID = 2324122652952574574L;
+ private ResourceManagementService R;
+ private CertConfigTableModel model;
+
+ // ------------------------------------------------------------------------
+ // GUI members
+ // ------------------------------------------------------------------------
+ private JButton cmdAdd;
+ private JButton cmdRemove;
+ private JButton cmdEdit;
+ private JTable tblCertList;
+ private JRadioButton rdoUseWindows;
+ private JRadioButton rdoUseJava;
+ private SIPCommCheckBox chkEnableRevocationCheck;
+ private SIPCommCheckBox chkEnableOcsp;
+
+ // ------------------------------------------------------------------------
+ // initialization
+ // ------------------------------------------------------------------------
+ /**
+ * Creates a new instance of this class.
+ */
+ public CertConfigPanel()
+ {
+ R = CertConfigActivator.R;
+ model = new CertConfigTableModel();
+ initComponents();
+ valueChanged(null);
+ }
+
+ private void initComponents()
+ {
+ this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+
+ // trusted root CA source selection
+ if (OSUtils.IS_WINDOWS)
+ {
+ JPanel pnlCertConfig = new TransparentPanel(new GridLayout(2, 1));
+ pnlCertConfig.setBorder(BorderFactory.createTitledBorder(
+ R.getI18NString("plugin.certconfig.TRUSTSTORE_CONFIG")));
+ add(pnlCertConfig);
+
+ ButtonGroup grpTrustStore = new ButtonGroup();
+
+ rdoUseJava = new SIPCommRadioButton();
+ rdoUseJava.setText(
+ R.getI18NString("plugin.certconfig.JAVA_TRUSTSTORE"));
+ rdoUseJava.addActionListener(this);
+ grpTrustStore.add(rdoUseJava);
+ pnlCertConfig.add(rdoUseJava);
+
+ rdoUseWindows = new SIPCommRadioButton();
+ rdoUseWindows.setText(
+ R.getI18NString("plugin.certconfig.WINDOWS_TRUSTSTORE"));
+ rdoUseWindows.addActionListener(this);
+ grpTrustStore.add(rdoUseWindows);
+ pnlCertConfig.add(rdoUseWindows);
+
+ if ("Windows-ROOT".equals(CertConfigActivator.getConfigService()
+ .getProperty(CertificateService.PNAME_TRUSTSTORE_TYPE)))
+ {
+ rdoUseWindows.setSelected(true);
+ }
+ else
+ {
+ rdoUseJava.setSelected(true);
+ }
+ }
+
+ // revocation options
+ JPanel pnlRevocation = new TransparentPanel(new GridLayout(2, 1));
+ pnlRevocation.setBorder(BorderFactory.createTitledBorder(
+ R.getI18NString("plugin.certconfig.REVOCATION_TITLE")));
+ add(pnlRevocation);
+
+ chkEnableRevocationCheck = new SIPCommCheckBox(
+ R.getI18NString("plugin.certconfig.REVOCATION_CHECK_ENABLED"));
+ chkEnableRevocationCheck.addActionListener(this);
+ chkEnableRevocationCheck.setSelected(
+ "true".equals(
+ System.getProperty("com.sun.net.ssl.checkRevocation")));
+ pnlRevocation.add(chkEnableRevocationCheck);
+
+ chkEnableOcsp = new SIPCommCheckBox(
+ R.getI18NString("plugin.certconfig.REVOCATION_OCSP_ENABLED"));
+ chkEnableOcsp.addActionListener(this);
+ chkEnableOcsp.setSelected(
+ "true".equals(Security.getProperty("ocsp.enable")));
+ chkEnableOcsp.setEnabled(chkEnableRevocationCheck.isSelected());
+ pnlRevocation.add(chkEnableOcsp);
+
+ // Client certificate authentication list
+ JPanel pnlCertList = new TransparentPanel(new BorderLayout());
+ pnlCertList.setBorder(BorderFactory.createTitledBorder(
+ R.getI18NString("plugin.certconfig.CERT_LIST_TITLE")));
+ add(pnlCertList);
+
+ JLabel lblNote = new JLabel();
+ lblNote.setText(
+ R.getI18NString("plugin.certconfig.CERT_LIST_DESCRIPTION"));
+ lblNote.setBorder(new EmptyBorder(7, 7, 7, 7));
+ pnlCertList.add(lblNote, BorderLayout.NORTH);
+
+ tblCertList = new JTable();
+ tblCertList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ tblCertList.getSelectionModel().addListSelectionListener(this);
+ tblCertList.setModel(model);
+ pnlCertList.add(new JScrollPane(tblCertList), BorderLayout.CENTER);
+
+ TransparentPanel buttons = new TransparentPanel();
+ buttons.setLayout(new FlowLayout(FlowLayout.RIGHT));
+ pnlCertList.add(buttons, BorderLayout.SOUTH);
+
+ cmdAdd = new JButton();
+ cmdAdd.setText(R.getI18NString("service.gui.ADD"));
+ cmdAdd.addActionListener(this);
+ buttons.add(cmdAdd);
+
+ cmdRemove = new JButton();
+ cmdRemove.setText(R.getI18NString("service.gui.REMOVE"));
+ cmdRemove.addActionListener(this);
+ buttons.add(cmdRemove);
+
+ cmdEdit = new JButton();
+ cmdEdit.setText(R.getI18NString("service.gui.EDIT"));
+ cmdEdit.addActionListener(this);
+ buttons.add(cmdEdit);
+ }
+
+ // ------------------------------------------------------------------------
+ // event handling
+ // ------------------------------------------------------------------------
+ public void valueChanged(ListSelectionEvent e)
+ {
+ int row = tblCertList.getSelectedRow();
+ cmdRemove.setEnabled(row > -1);
+ cmdEdit.setEnabled(row > -1);
+ }
+
+ public void actionPerformed(ActionEvent e)
+ {
+ if (e.getSource() == cmdAdd)
+ {
+ CertificateConfigEntry newEntry = new CertificateConfigEntry();
+ CertConfigEntryDialog dlg = new CertConfigEntryDialog(newEntry);
+ if (dlg.showDialog())
+ CertConfigActivator.getCertService()
+ .setClientAuthCertificateConfig(newEntry);
+ }
+ if (e.getSource() == cmdRemove)
+ {
+ CertConfigActivator.getCertService()
+ .removeClientAuthCertificateConfig(
+ model.getItem(tblCertList.getSelectedRow()).getId());
+ }
+ if (e.getSource() == cmdEdit)
+ {
+ CertificateConfigEntry entry =
+ model.getItem(tblCertList.getSelectedRow());
+ CertConfigEntryDialog dlg = new CertConfigEntryDialog(entry);
+ if (dlg.showDialog())
+ CertConfigActivator.getCertService()
+ .setClientAuthCertificateConfig(entry);
+ }
+ if (e.getSource() == rdoUseJava)
+ {
+ CertConfigActivator.getConfigService().setProperty(
+ CertificateService.PNAME_TRUSTSTORE_TYPE,
+ "meta:default");
+ CertConfigActivator.getConfigService().removeProperty(
+ CertificateService.PNAME_TRUSTSTORE_FILE);
+ CertConfigActivator.getCredService().removePassword(
+ CertificateService.PNAME_TRUSTSTORE_PASSWORD);
+ }
+ if (e.getSource() == rdoUseWindows)
+ {
+ CertConfigActivator.getConfigService().setProperty(
+ CertificateService.PNAME_TRUSTSTORE_TYPE, "Windows-ROOT");
+ CertConfigActivator.getConfigService().removeProperty(
+ CertificateService.PNAME_TRUSTSTORE_FILE);
+ CertConfigActivator.getCredService().removePassword(
+ CertificateService.PNAME_TRUSTSTORE_PASSWORD);
+ }
+ if (e.getSource() == chkEnableRevocationCheck)
+ {
+ CertConfigActivator.getConfigService().setProperty(
+ CertificateService.PNAME_REVOCATION_CHECK_ENABLED,
+ chkEnableRevocationCheck.isSelected());
+
+ String enabled = new Boolean(
+ chkEnableRevocationCheck.isSelected()).toString();
+ System.setProperty("com.sun.security.enableCRLDP", enabled);
+ System.setProperty("com.sun.net.ssl.checkRevocation", enabled);
+ chkEnableOcsp.setEnabled(chkEnableRevocationCheck.isSelected());
+ }
+ if (e.getSource() == chkEnableOcsp)
+ {
+ CertConfigActivator.getConfigService().setProperty(
+ CertificateService.PNAME_OCSP_ENABLED,
+ chkEnableOcsp.isSelected());
+
+ Security.setProperty("ocsp.enable",
+ new Boolean(chkEnableOcsp.isSelected()).toString());
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Configuration form members
+ // ------------------------------------------------------------------------
+ public String getTitle()
+ {
+ return CertConfigActivator.R.getI18NString("plugin.certconfig.TITLE");
+ }
+
+ public byte[] getIcon()
+ {
+ return null;
+ }
+
+ public Object getForm()
+ {
+ return this;
+ }
+
+ public int getIndex()
+ {
+ return -1;
+ }
+
+ public boolean isAdvanced()
+ {
+ return true;
+ }
+
+}
diff --git a/src/net/java/sip/communicator/plugin/certconfig/CertConfigTableModel.java b/src/net/java/sip/communicator/plugin/certconfig/CertConfigTableModel.java
index 7ef76d5..99391bf 100644
--- a/src/net/java/sip/communicator/plugin/certconfig/CertConfigTableModel.java
+++ b/src/net/java/sip/communicator/plugin/certconfig/CertConfigTableModel.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,99 +15,99 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.certconfig;
-
-import java.beans.*;
-import java.util.*;
-
-import javax.swing.table.*;
-
-import net.java.sip.communicator.service.certificate.*;
-
-import org.jitsi.service.resources.*;
-
-/**
- * Backing data model for a JTable that displays the client certificate
- * configuration entries.
- *
- * @author Ingo Bauersachs
- */
-public class CertConfigTableModel
- extends AbstractTableModel
- implements PropertyChangeListener
-{
- private static final long serialVersionUID = -6369348252411082340L;
- private CertificateService cvs;
- private List<CertificateConfigEntry> model;
- private ResourceManagementService R = CertConfigActivator.R;
-
- /**
- * Constructor.
- */
- public CertConfigTableModel()
- {
- CertConfigActivator.getConfigService().addPropertyChangeListener(this);
- cvs = CertConfigActivator.getCertService();
- model = cvs.getClientAuthCertificateConfigs();
- }
-
- public int getRowCount()
- {
- return model.size();
- }
-
- public int getColumnCount()
- {
- return 3;
- }
-
- public Object getValueAt(int rowIndex, int columnIndex)
- {
- switch(columnIndex)
- {
- case 0:
- return model.get(rowIndex).getDisplayName();
- case 1:
- return model.get(rowIndex).getAlias();
- case 2:
- return model.get(rowIndex).getKeyStoreType();
- }
- return null;
- }
-
- /**
- * Get <tt>CertificateConfigEntry</tt> located at <tt>rowIndex</tt>.
- *
- * @param rowIndex row index
- * @return <tt>CertificateConfigEntry</tt>
- */
- public CertificateConfigEntry getItem(int rowIndex)
- {
- return model.get(rowIndex);
- }
-
- @Override
- public String getColumnName(int column)
- {
- switch(column)
- {
- case 0:
- return R.getI18NString("service.gui.DISPLAY_NAME");
- case 1:
- return R.getI18NString("plugin.certconfig.ALIAS");
- case 2:
- return R.getI18NString("plugin.certconfig.KEYSTORE_TYPE");
- }
- return super.getColumnName(column);
- }
-
- public void propertyChange(PropertyChangeEvent evt)
- {
- if (evt.getPropertyName().startsWith(
- CertificateService.PNAME_CLIENTAUTH_CERTCONFIG_BASE))
- {
- model = cvs.getClientAuthCertificateConfigs();
- super.fireTableDataChanged();
- }
- }
-}
+package net.java.sip.communicator.plugin.certconfig;
+
+import java.beans.*;
+import java.util.*;
+
+import javax.swing.table.*;
+
+import net.java.sip.communicator.service.certificate.*;
+
+import org.jitsi.service.resources.*;
+
+/**
+ * Backing data model for a JTable that displays the client certificate
+ * configuration entries.
+ *
+ * @author Ingo Bauersachs
+ */
+public class CertConfigTableModel
+ extends AbstractTableModel
+ implements PropertyChangeListener
+{
+ private static final long serialVersionUID = -6369348252411082340L;
+ private CertificateService cvs;
+ private List<CertificateConfigEntry> model;
+ private ResourceManagementService R = CertConfigActivator.R;
+
+ /**
+ * Constructor.
+ */
+ public CertConfigTableModel()
+ {
+ CertConfigActivator.getConfigService().addPropertyChangeListener(this);
+ cvs = CertConfigActivator.getCertService();
+ model = cvs.getClientAuthCertificateConfigs();
+ }
+
+ public int getRowCount()
+ {
+ return model.size();
+ }
+
+ public int getColumnCount()
+ {
+ return 3;
+ }
+
+ public Object getValueAt(int rowIndex, int columnIndex)
+ {
+ switch(columnIndex)
+ {
+ case 0:
+ return model.get(rowIndex).getDisplayName();
+ case 1:
+ return model.get(rowIndex).getAlias();
+ case 2:
+ return model.get(rowIndex).getKeyStoreType();
+ }
+ return null;
+ }
+
+ /**
+ * Get <tt>CertificateConfigEntry</tt> located at <tt>rowIndex</tt>.
+ *
+ * @param rowIndex row index
+ * @return <tt>CertificateConfigEntry</tt>
+ */
+ public CertificateConfigEntry getItem(int rowIndex)
+ {
+ return model.get(rowIndex);
+ }
+
+ @Override
+ public String getColumnName(int column)
+ {
+ switch(column)
+ {
+ case 0:
+ return R.getI18NString("service.gui.DISPLAY_NAME");
+ case 1:
+ return R.getI18NString("plugin.certconfig.ALIAS");
+ case 2:
+ return R.getI18NString("plugin.certconfig.KEYSTORE_TYPE");
+ }
+ return super.getColumnName(column);
+ }
+
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ if (evt.getPropertyName().startsWith(
+ CertificateService.PNAME_CLIENTAUTH_CERTCONFIG_BASE))
+ {
+ model = cvs.getClientAuthCertificateConfigs();
+ super.fireTableDataChanged();
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoActivator.java b/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoActivator.java
index ce1fc18..7783de8 100644
--- a/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoActivator.java
+++ b/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoActivator.java
@@ -1,208 +1,208 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.contactinfo;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.browserlauncher.*;
-import net.java.sip.communicator.service.contactlist.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.configuration.*;
-import org.osgi.framework.*;
-
-/**
- * The Activator of the Contact Info bundle.
- *
- * @author Adam Goldstein
- * @author Yana Stamcheva
- */
-public class ContactInfoActivator implements BundleActivator
-{
- private Logger logger = Logger.getLogger(ContactInfoActivator.class);
-
- /**
- * Indicates if the contact info button is enabled in the chat window.
- */
- private static final String ENABLED_IN_CHAT_WINDOW_PROP
- = "net.java.sip.communicator.plugin.contactinfo." +
- "ENABLED_IN_CHAT_WINDOW_PROP";
-
- /**
- * Indicates if the contact info button is enabled in the call window.
- */
- private static final String ENABLED_IN_CALL_WINDOW_PROP
- = "net.java.sip.communicator.plugin.contactinfo." +
- "ENABLED_IN_CALL_WINDOW_PROP";
-
- private static BrowserLauncherService browserLauncherService;
-
- /**
- * The image loader service implementation.
- */
- private static ImageLoaderService<?> imageLoaderService = null;
-
- /**
- * The contact list service implementation.
- */
- private static MetaContactListService metaCListService;
-
- static BundleContext bundleContext;
-
- /**
- * Starts this bundle.
- */
- public void start(BundleContext bc) throws Exception
- {
- bundleContext = bc;
-
- Hashtable<String, String> containerFilter
- = new Hashtable<String, String>();
- containerFilter.put(
- Container.CONTAINER_ID,
- Container.CONTAINER_CONTACT_RIGHT_BUTTON_MENU.getID());
-
- bundleContext.registerService(
- PluginComponentFactory.class.getName(),
- new ContactInfoPluginComponentFactory(
- Container.CONTAINER_CONTACT_RIGHT_BUTTON_MENU),
- containerFilter);
-
- if(getConfigService().getBoolean(ENABLED_IN_CHAT_WINDOW_PROP, false))
- {
- containerFilter = new Hashtable<String, String>();
- containerFilter.put(
- Container.CONTAINER_ID,
- Container.CONTAINER_CHAT_TOOL_BAR.getID());
-
- bundleContext.registerService(
- PluginComponentFactory.class.getName(),
- new ContactInfoPluginComponentFactory(
- Container.CONTAINER_CHAT_TOOL_BAR),
- containerFilter);
- }
-
- if(getConfigService().getBoolean(ENABLED_IN_CALL_WINDOW_PROP, false))
- {
- containerFilter = new Hashtable<String, String>();
- containerFilter.put(
- Container.CONTAINER_ID,
- Container.CONTAINER_CALL_DIALOG.getID());
-
- bundleContext.registerService(
- PluginComponentFactory.class.getName(),
- new ContactInfoPluginComponentFactory(
- Container.CONTAINER_CALL_DIALOG),
- containerFilter);
- }
-
- if (logger.isInfoEnabled())
- logger.info("CONTACT INFO... [REGISTERED]");
- }
-
- public void stop(BundleContext bc) throws Exception
- {
- }
-
- /**
- * Returns the <tt>BrowserLauncherService</tt> obtained from the bundle
- * context.
- * @return the <tt>BrowserLauncherService</tt> obtained from the bundle
- * context
- */
- public static BrowserLauncherService getBrowserLauncher()
- {
- if (browserLauncherService == null)
- {
- ServiceReference serviceReference = bundleContext
- .getServiceReference(BrowserLauncherService.class.getName());
-
- browserLauncherService = (BrowserLauncherService) bundleContext
- .getService(serviceReference);
- }
-
- return browserLauncherService;
- }
-
- /**
- * Returns the imageLoaderService instance, if missing query osgi for it.
- * @return the imageLoaderService.
- */
- public static ImageLoaderService<?> getImageLoaderService()
- {
- if(imageLoaderService == null)
- {
- imageLoaderService
- = ServiceUtils.getService(
- bundleContext,
- ImageLoaderService.class);
- }
-
- return imageLoaderService;
- }
-
- /**
- * Returns the <tt>MetaContactListService</tt> obtained from the bundle
- * context.
- * @return the <tt>MetaContactListService</tt> obtained from the bundle
- * context
- */
- public static MetaContactListService getContactListService()
- {
- if (metaCListService == null)
- {
- metaCListService
- = ServiceUtils.getService(
- bundleContext,
- MetaContactListService.class);
- }
- return metaCListService;
- }
-
- /**
- * Returns a reference to a ConfigurationService implementation currently
- * registered in the bundle context or null if no such implementation was
- * found.
- *
- * @return a currently valid implementation of the ConfigurationService.
- */
- public static ConfigurationService getConfigService()
- {
- return ServiceUtils.getService(bundleContext,
- ConfigurationService.class);
- }
-
- /**
- * Contact info create factory.
- */
- private class ContactInfoPluginComponentFactory
- extends PluginComponentFactory
- {
- ContactInfoPluginComponentFactory(Container c)
- {
- super(c);
- }
-
- @Override
- protected PluginComponent getPluginInstance()
- {
- return new ContactInfoMenuItem(getContainer(), this);
- }
- }
-}
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.plugin.contactinfo;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.browserlauncher.*;
+import net.java.sip.communicator.service.contactlist.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.configuration.*;
+import org.osgi.framework.*;
+
+/**
+ * The Activator of the Contact Info bundle.
+ *
+ * @author Adam Goldstein
+ * @author Yana Stamcheva
+ */
+public class ContactInfoActivator implements BundleActivator
+{
+ private Logger logger = Logger.getLogger(ContactInfoActivator.class);
+
+ /**
+ * Indicates if the contact info button is enabled in the chat window.
+ */
+ private static final String ENABLED_IN_CHAT_WINDOW_PROP
+ = "net.java.sip.communicator.plugin.contactinfo." +
+ "ENABLED_IN_CHAT_WINDOW_PROP";
+
+ /**
+ * Indicates if the contact info button is enabled in the call window.
+ */
+ private static final String ENABLED_IN_CALL_WINDOW_PROP
+ = "net.java.sip.communicator.plugin.contactinfo." +
+ "ENABLED_IN_CALL_WINDOW_PROP";
+
+ private static BrowserLauncherService browserLauncherService;
+
+ /**
+ * The image loader service implementation.
+ */
+ private static ImageLoaderService<?> imageLoaderService = null;
+
+ /**
+ * The contact list service implementation.
+ */
+ private static MetaContactListService metaCListService;
+
+ static BundleContext bundleContext;
+
+ /**
+ * Starts this bundle.
+ */
+ public void start(BundleContext bc) throws Exception
+ {
+ bundleContext = bc;
+
+ Hashtable<String, String> containerFilter
+ = new Hashtable<String, String>();
+ containerFilter.put(
+ Container.CONTAINER_ID,
+ Container.CONTAINER_CONTACT_RIGHT_BUTTON_MENU.getID());
+
+ bundleContext.registerService(
+ PluginComponentFactory.class.getName(),
+ new ContactInfoPluginComponentFactory(
+ Container.CONTAINER_CONTACT_RIGHT_BUTTON_MENU),
+ containerFilter);
+
+ if(getConfigService().getBoolean(ENABLED_IN_CHAT_WINDOW_PROP, false))
+ {
+ containerFilter = new Hashtable<String, String>();
+ containerFilter.put(
+ Container.CONTAINER_ID,
+ Container.CONTAINER_CHAT_TOOL_BAR.getID());
+
+ bundleContext.registerService(
+ PluginComponentFactory.class.getName(),
+ new ContactInfoPluginComponentFactory(
+ Container.CONTAINER_CHAT_TOOL_BAR),
+ containerFilter);
+ }
+
+ if(getConfigService().getBoolean(ENABLED_IN_CALL_WINDOW_PROP, false))
+ {
+ containerFilter = new Hashtable<String, String>();
+ containerFilter.put(
+ Container.CONTAINER_ID,
+ Container.CONTAINER_CALL_DIALOG.getID());
+
+ bundleContext.registerService(
+ PluginComponentFactory.class.getName(),
+ new ContactInfoPluginComponentFactory(
+ Container.CONTAINER_CALL_DIALOG),
+ containerFilter);
+ }
+
+ if (logger.isInfoEnabled())
+ logger.info("CONTACT INFO... [REGISTERED]");
+ }
+
+ public void stop(BundleContext bc) throws Exception
+ {
+ }
+
+ /**
+ * Returns the <tt>BrowserLauncherService</tt> obtained from the bundle
+ * context.
+ * @return the <tt>BrowserLauncherService</tt> obtained from the bundle
+ * context
+ */
+ public static BrowserLauncherService getBrowserLauncher()
+ {
+ if (browserLauncherService == null)
+ {
+ ServiceReference serviceReference = bundleContext
+ .getServiceReference(BrowserLauncherService.class.getName());
+
+ browserLauncherService = (BrowserLauncherService) bundleContext
+ .getService(serviceReference);
+ }
+
+ return browserLauncherService;
+ }
+
+ /**
+ * Returns the imageLoaderService instance, if missing query osgi for it.
+ * @return the imageLoaderService.
+ */
+ public static ImageLoaderService<?> getImageLoaderService()
+ {
+ if(imageLoaderService == null)
+ {
+ imageLoaderService
+ = ServiceUtils.getService(
+ bundleContext,
+ ImageLoaderService.class);
+ }
+
+ return imageLoaderService;
+ }
+
+ /**
+ * Returns the <tt>MetaContactListService</tt> obtained from the bundle
+ * context.
+ * @return the <tt>MetaContactListService</tt> obtained from the bundle
+ * context
+ */
+ public static MetaContactListService getContactListService()
+ {
+ if (metaCListService == null)
+ {
+ metaCListService
+ = ServiceUtils.getService(
+ bundleContext,
+ MetaContactListService.class);
+ }
+ return metaCListService;
+ }
+
+ /**
+ * Returns a reference to a ConfigurationService implementation currently
+ * registered in the bundle context or null if no such implementation was
+ * found.
+ *
+ * @return a currently valid implementation of the ConfigurationService.
+ */
+ public static ConfigurationService getConfigService()
+ {
+ return ServiceUtils.getService(bundleContext,
+ ConfigurationService.class);
+ }
+
+ /**
+ * Contact info create factory.
+ */
+ private class ContactInfoPluginComponentFactory
+ extends PluginComponentFactory
+ {
+ ContactInfoPluginComponentFactory(Container c)
+ {
+ super(c);
+ }
+
+ @Override
+ protected PluginComponent getPluginInstance()
+ {
+ return new ContactInfoMenuItem(getContainer(), this);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoContactPanel.java b/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoContactPanel.java
index 9fd1bb6..4eba597 100644
--- a/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoContactPanel.java
+++ b/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoContactPanel.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,198 +15,198 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.contactinfo;
-
-import java.awt.*;
-import java.util.*;
-
-import javax.swing.*;
-import javax.swing.event.*;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * The left side panel of ContactInfoDialog. Display all associated subcontacts
- * and their respective protocols in a JList. If a user is selected, the
- * ContactInfoDetailsPanel will be updated to the current contact.
- *
- * @author Adam Goldstein
- * @author Yana Stamcheva
- */
-public class ContactInfoContactPanel
- extends TransparentPanel
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * The list of all subcontacts related to the selected contact.
- */
- private JList contactList = new JList();
-
- /**
- * The scroll pane containing the list of all sub contacts of a selected
- * contact.
- */
- private JScrollPane contactScrollPane = new JScrollPane();
-
- private DefaultListModel contactListModel = new DefaultListModel();
-
- /**
- * The parent dialog that makes the connection between the contacts and
- * the details panel.
- */
- private ContactInfoDialog contactInfoDialog;
-
- /**
- * Create a panel with a list of all sub-contacts associated with the
- * contact that was originally selected. Whenever a sub-contact is picked,
- * notifies the protocolPanel of the change and it will update the displayed
- * details.
- *
- * @param contacts the list of contacts
- * @param dialog the contact info dialog
- */
- public ContactInfoContactPanel( Iterator<Contact> contacts,
- ContactInfoDialog dialog)
- {
- super(new BorderLayout());
-
- this.contactInfoDialog = dialog;
-
- this.setBorder(BorderFactory.createCompoundBorder(BorderFactory
- .createTitledBorder(Resources.getString("service.gui.CONTACTS")),
- BorderFactory.createEmptyBorder(5, 5, 5, 5)));
-
- this.contactList.setOpaque(false);
- this.contactList.setModel(contactListModel);
- this.contactList.setCellRenderer(new ContactPanelCellRenderer());
- this.contactList.addListSelectionListener(new ListSelectionListener()
- {
- public void valueChanged(ListSelectionEvent e)
- {
- // When the user release the mouse button and completes the
- // selection, getValueIsAdjusting() becomes false
- if (!e.getValueIsAdjusting())
- {
- JList list = (JList) e.getSource();
-
- Contact selectedContact
- = (Contact) list.getSelectedValue();
-
- contactInfoDialog.loadContactDetails(selectedContact);
- }
- }
- });
-
- boolean isFirstIter = true;
- while (contacts.hasNext())
- {
- Contact contact = contacts.next();
-
- this.contactListModel.addElement(contact);
-
- if (isFirstIter)
- {
- isFirstIter = false;
- contactInfoDialog.loadContactDetails(contact);
- contactList.setSelectedIndex(0);
- }
- }
-
- this.contactScrollPane.setPreferredSize(new Dimension(100, 200));
- this.contactScrollPane.getViewport().add(contactList);
- this.add(contactScrollPane);
- }
-
- /**
- * A cell renderer that allows both text and icons in our contactList.
- */
- private static class ContactPanelCellRenderer
- extends DefaultListCellRenderer
- {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- private boolean isSelected;
-
- private Color blueGreyBorderColor = new Color(131, 149, 178);
-
- private Color selectedColor = new Color(209, 212, 225);
-
- public ContactPanelCellRenderer()
- {
- this.setOpaque(false);
- }
-
- /**
- * Renders a <tt>Contact</tt> object in a JList, by visualizing
- * the contact name and the protocol icon.
- *
- * @param list the rendered JList
- * @param value the object to be rendered
- * @param index the index of the object in the list
- * @param isSelected indicates if the rendered object is selected
- * @param cellHasFocus indicates if the rendered object is in a focused
- * cell
- */
- @Override
- public Component getListCellRendererComponent( JList list,
- Object value,
- int index,
- boolean isSelected,
- boolean cellHasFocus)
- {
- super.getListCellRendererComponent(list, value, index, isSelected,
- cellHasFocus);
-
- this.isSelected = isSelected;
-
- Contact contact = (Contact) value;
-
- this.setIcon(new ImageIcon(contact.getProtocolProvider()
- .getProtocolIcon().getIcon(ProtocolIcon.ICON_SIZE_16x16)));
- this.setText(((Contact) value).getDisplayName());
-
- return this;
- }
-
- /**
- * Paint a round blue border and background when a cell is selected.
- */
- @Override
- public void paintComponent(Graphics g)
- {
- if (this.isSelected)
- {
- Graphics2D g2 = (Graphics2D) g.create();
-
- try
- {
- AntialiasingManager.activateAntialiasing(g2);
-
- int width = getWidth();
- int height = getHeight();
-
- g2.setColor(selectedColor);
- g2.fillRoundRect(1, 0, width, height, 7, 7);
-
- g2.setColor(blueGreyBorderColor);
- g2.setStroke(new BasicStroke(1.5f));
- g2.drawRoundRect(1, 0, width - 2, height - 1, 7, 7);
- }
- finally
- {
- g2.dispose();
- }
- }
-
- super.paintComponent(g);
- }
- }
-}
+package net.java.sip.communicator.plugin.contactinfo;
+
+import java.awt.*;
+import java.util.*;
+
+import javax.swing.*;
+import javax.swing.event.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The left side panel of ContactInfoDialog. Display all associated subcontacts
+ * and their respective protocols in a JList. If a user is selected, the
+ * ContactInfoDetailsPanel will be updated to the current contact.
+ *
+ * @author Adam Goldstein
+ * @author Yana Stamcheva
+ */
+public class ContactInfoContactPanel
+ extends TransparentPanel
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * The list of all subcontacts related to the selected contact.
+ */
+ private JList contactList = new JList();
+
+ /**
+ * The scroll pane containing the list of all sub contacts of a selected
+ * contact.
+ */
+ private JScrollPane contactScrollPane = new JScrollPane();
+
+ private DefaultListModel contactListModel = new DefaultListModel();
+
+ /**
+ * The parent dialog that makes the connection between the contacts and
+ * the details panel.
+ */
+ private ContactInfoDialog contactInfoDialog;
+
+ /**
+ * Create a panel with a list of all sub-contacts associated with the
+ * contact that was originally selected. Whenever a sub-contact is picked,
+ * notifies the protocolPanel of the change and it will update the displayed
+ * details.
+ *
+ * @param contacts the list of contacts
+ * @param dialog the contact info dialog
+ */
+ public ContactInfoContactPanel( Iterator<Contact> contacts,
+ ContactInfoDialog dialog)
+ {
+ super(new BorderLayout());
+
+ this.contactInfoDialog = dialog;
+
+ this.setBorder(BorderFactory.createCompoundBorder(BorderFactory
+ .createTitledBorder(Resources.getString("service.gui.CONTACTS")),
+ BorderFactory.createEmptyBorder(5, 5, 5, 5)));
+
+ this.contactList.setOpaque(false);
+ this.contactList.setModel(contactListModel);
+ this.contactList.setCellRenderer(new ContactPanelCellRenderer());
+ this.contactList.addListSelectionListener(new ListSelectionListener()
+ {
+ public void valueChanged(ListSelectionEvent e)
+ {
+ // When the user release the mouse button and completes the
+ // selection, getValueIsAdjusting() becomes false
+ if (!e.getValueIsAdjusting())
+ {
+ JList list = (JList) e.getSource();
+
+ Contact selectedContact
+ = (Contact) list.getSelectedValue();
+
+ contactInfoDialog.loadContactDetails(selectedContact);
+ }
+ }
+ });
+
+ boolean isFirstIter = true;
+ while (contacts.hasNext())
+ {
+ Contact contact = contacts.next();
+
+ this.contactListModel.addElement(contact);
+
+ if (isFirstIter)
+ {
+ isFirstIter = false;
+ contactInfoDialog.loadContactDetails(contact);
+ contactList.setSelectedIndex(0);
+ }
+ }
+
+ this.contactScrollPane.setPreferredSize(new Dimension(100, 200));
+ this.contactScrollPane.getViewport().add(contactList);
+ this.add(contactScrollPane);
+ }
+
+ /**
+ * A cell renderer that allows both text and icons in our contactList.
+ */
+ private static class ContactPanelCellRenderer
+ extends DefaultListCellRenderer
+ {
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ private boolean isSelected;
+
+ private Color blueGreyBorderColor = new Color(131, 149, 178);
+
+ private Color selectedColor = new Color(209, 212, 225);
+
+ public ContactPanelCellRenderer()
+ {
+ this.setOpaque(false);
+ }
+
+ /**
+ * Renders a <tt>Contact</tt> object in a JList, by visualizing
+ * the contact name and the protocol icon.
+ *
+ * @param list the rendered JList
+ * @param value the object to be rendered
+ * @param index the index of the object in the list
+ * @param isSelected indicates if the rendered object is selected
+ * @param cellHasFocus indicates if the rendered object is in a focused
+ * cell
+ */
+ @Override
+ public Component getListCellRendererComponent( JList list,
+ Object value,
+ int index,
+ boolean isSelected,
+ boolean cellHasFocus)
+ {
+ super.getListCellRendererComponent(list, value, index, isSelected,
+ cellHasFocus);
+
+ this.isSelected = isSelected;
+
+ Contact contact = (Contact) value;
+
+ this.setIcon(new ImageIcon(contact.getProtocolProvider()
+ .getProtocolIcon().getIcon(ProtocolIcon.ICON_SIZE_16x16)));
+ this.setText(((Contact) value).getDisplayName());
+
+ return this;
+ }
+
+ /**
+ * Paint a round blue border and background when a cell is selected.
+ */
+ @Override
+ public void paintComponent(Graphics g)
+ {
+ if (this.isSelected)
+ {
+ Graphics2D g2 = (Graphics2D) g.create();
+
+ try
+ {
+ AntialiasingManager.activateAntialiasing(g2);
+
+ int width = getWidth();
+ int height = getHeight();
+
+ g2.setColor(selectedColor);
+ g2.fillRoundRect(1, 0, width, height, 7, 7);
+
+ g2.setColor(blueGreyBorderColor);
+ g2.setStroke(new BasicStroke(1.5f));
+ g2.drawRoundRect(1, 0, width - 2, height - 1, 7, 7);
+ }
+ finally
+ {
+ g2.dispose();
+ }
+ }
+
+ super.paintComponent(g);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoDetailsPanel.java b/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoDetailsPanel.java
index 49fdccb..941160a 100644
--- a/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoDetailsPanel.java
+++ b/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoDetailsPanel.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,678 +15,678 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.contactinfo;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.text.*;
-import java.util.*;
-import java.util.regex.*;
-
-import javax.swing.*;
-import javax.swing.event.*;
-import javax.swing.text.html.*;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.ServerStoredDetails.BinaryDetail;
-import net.java.sip.communicator.service.protocol.ServerStoredDetails.BirthDateDetail;
-import net.java.sip.communicator.service.protocol.ServerStoredDetails.CalendarDetail;
-import net.java.sip.communicator.service.protocol.ServerStoredDetails.EmailAddressDetail;
-import net.java.sip.communicator.service.protocol.ServerStoredDetails.FirstNameDetail;
-import net.java.sip.communicator.service.protocol.ServerStoredDetails.GenderDetail;
-import net.java.sip.communicator.service.protocol.ServerStoredDetails.GenericDetail;
-import net.java.sip.communicator.service.protocol.ServerStoredDetails.LastNameDetail;
-import net.java.sip.communicator.service.protocol.ServerStoredDetails.LocaleDetail;
-import net.java.sip.communicator.service.protocol.ServerStoredDetails.MiddleNameDetail;
-import net.java.sip.communicator.service.protocol.ServerStoredDetails.PhoneNumberDetail;
-import net.java.sip.communicator.service.protocol.ServerStoredDetails.TimeZoneDetail;
-
-/**
- * The right side panel of ContactInfoDialog. Shows one tab of a summary of
- * contact information for the selected subcontact, and has an extended tab
- * listing all of the details.
- *
- * @author Adam Goldstein
- * @author Yana Stamcheva
- */
-public class ContactInfoDetailsPanel
- extends TransparentPanel
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * The tabbed pane containing the two different tabs for details.
- */
- private final JTabbedPane tabbedPane = new SIPCommTabbedPane();
-
- /**
- * The operation set giving access to the server stored contact details.
- */
- private OperationSetServerStoredContactInfo contactInfoOpSet;
-
- /**
- * The currently selected sub-contact we are displaying information about.
- */
- private Contact contact;
-
- /**
- * The default width of hte avater area.
- */
- private static final int AVATAR_AREA_WIDTH = 105;
-
- /**
- * The default height of hte avater area.
- */
- private static final int AVATAR_AREA_HEIGHT = 130;
-
- /**
- * Construct a tabbed pane that will have one tab with a summary of info for
- * the selected subcontact and one tab for all of the extended details.
- */
- public ContactInfoDetailsPanel()
- {
- this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
- this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
- this.setPreferredSize(new Dimension(400, 300));
-
- this.tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
- }
-
- /**
- * Retrieve and display the information for the newly selected contact, c.
- *
- * @param c the sub-contact we are now focusing on.
- */
- public void loadContactDetails(Contact c)
- {
- this.contact = c;
-
- ProtocolProviderService pps = contact.getProtocolProvider();
- contactInfoOpSet
- = pps.getOperationSet(OperationSetServerStoredContactInfo.class);
-
- this.removeAll();
-
- if (contactInfoOpSet == null || !pps.isRegistered())
- {
- JPanel unsupportedPanel = createUnsupportedPanel();
-
- this.add(unsupportedPanel);
-
- this.revalidate();
- this.repaint();
-
- return;
- }
-
- this.tabbedPane.removeAll();
-
- ImageIcon icon =
- new ImageIcon(contact.getProtocolProvider().getProtocolIcon()
- .getIcon(ProtocolIcon.ICON_SIZE_16x16));
-
- JPanel summaryPanel = createSummaryInfoPanel();
-
- JPanel extendedPanel = createExtendedInfoPanel();
-
- JScrollPane extendedScrollPane = new JScrollPane(extendedPanel);
-
- this.tabbedPane.addTab(
- Resources.getString("service.gui.SUMMARY"), icon,
- summaryPanel,
- Resources.getString(
- "plugin.contactinfo.CONTACT_SUMMARY_DESCRIPTION")
- + contact.getDisplayName());
-
- this.tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
-
- this.tabbedPane.addTab(
- Resources.getString("plugin.accountinfo.EXTENDED"), icon,
- extendedScrollPane,
- Resources.getString(
- "plugin.contactinfo.CONTACT_EXTENDED_DESCRIPTION")
- + contact.getDisplayName());
-
- this.tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);
-
- this.add(tabbedPane);
-
- this.revalidate();
- this.repaint();
- }
-
- /**
- * Creates the panel that indicates to the user that the currently selected
- * contact does not support server stored contact info.
- *
- * @return the panel that is added and shows a message that the selected
- * sub-contact does not have the operation set for server stored
- * contact info supported.
- */
- private JPanel createUnsupportedPanel()
- {
- JTextArea unsupportedTextArea = new JTextArea(
- Resources.getString("service.gui.CONTACT_INFO_NOT_SUPPORTED"));
-
- unsupportedTextArea.setEditable(false);
- unsupportedTextArea.setLineWrap(true);
-
- JPanel unsupportedPanel = new TransparentPanel(new BorderLayout());
-
- unsupportedPanel.add(unsupportedTextArea);
-
- return unsupportedPanel;
- }
-
- /**
- * Creates a panel that can be added as the summary tab that displays the
- * following details: -
- * <p>
- * Avatar(Contact image) - FirstNameDetail - MiddleNameDetail -
- * LastNameDetail - BirthdateDetail (and calculate age) - GenderDetail -
- * EmailAddressDetail - PhoneNumberDetail. All other details will be* added
- * to our list of extended details.
- *
- * @return the panel that will be added as the summary tab.
- */
- private JPanel createSummaryInfoPanel()
- {
- JPanel summaryPanel = new TransparentPanel();
-
- summaryPanel.setLayout(new BorderLayout(10, 5));
- summaryPanel.setSize(this.getWidth(), this.getHeight());
-
- // Create the avatar panel.
- JPanel avatarPanel = new TransparentPanel();
-
- avatarPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
-
- byte[] bytes = this.contact.getImage();
-
- ImageIcon scaledImage = null;
- // If the user has a contact image, let's use it. If not, add the
- // default
- if (bytes != null)
- {
- scaledImage = ImageUtils.getScaledRoundedIcon(
- bytes,
- AVATAR_AREA_WIDTH,
- AVATAR_AREA_HEIGHT
- );
- }
- else
- scaledImage =
- ImageUtils.getScaledRoundedIcon(Resources
- .getImage("service.gui.DEFAULT_USER_PHOTO"),
- AVATAR_AREA_WIDTH, AVATAR_AREA_HEIGHT);
-
- JLabel label = new JLabel(scaledImage);
- label.setVerticalAlignment(JLabel.CENTER);
- label.setHorizontalAlignment(JLabel.CENTER);
- label.setPreferredSize(new Dimension(
- AVATAR_AREA_WIDTH,
- AVATAR_AREA_HEIGHT)
- );
- avatarPanel.add(label);
- summaryPanel.add(avatarPanel, BorderLayout.WEST);
-
- // Create the summary details panel.
- JPanel detailsPanel = new TransparentPanel();
- detailsPanel.setLayout(new BorderLayout());
- detailsPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
-
- summaryPanel.add(detailsPanel);
-
- // Labels panel.
- JPanel labelsPanel = new TransparentPanel(new GridLayout(0, 1, 5, 5));
- labelsPanel.add(new JLabel(
- Resources.getString("plugin.accountinfo.FIRST_NAME")));
- labelsPanel.add(new JLabel(
- Resources.getString("plugin.accountinfo.MIDDLE_NAME")));
- labelsPanel.add(new JLabel(
- Resources.getString("plugin.accountinfo.LAST_NAME")));
- labelsPanel.add(new JLabel(
- Resources.getString("plugin.accountinfo.GENDER")));
- labelsPanel.add(new JLabel(
- Resources.getString("plugin.accountinfo.BDAY")));
- labelsPanel.add(new JLabel(
- Resources.getString("plugin.accountinfo.AGE")));
- labelsPanel.add(new JLabel(
- Resources.getString("plugin.accountinfo.EMAIL")));
- labelsPanel.add(new JLabel(
- Resources.getString("plugin.accountinfo.PHONE")));
-
- detailsPanel.add(labelsPanel, BorderLayout.WEST);
-
- // Values panel.
- JPanel valuesPanel = new TransparentPanel(new GridLayout(0, 1, 5, 5));
-
- detailsPanel.add(valuesPanel, BorderLayout.CENTER);
-
- Iterator<GenericDetail> contactDetails;
- GenericDetail genericDetail;
-
- // First name details.
- contactDetails =
- contactInfoOpSet.getDetails(contact, FirstNameDetail.class);
-
- String firstNameDetail = "";
- while (contactDetails.hasNext())
- {
- genericDetail = contactDetails.next();
-
- firstNameDetail =
- firstNameDetail + " " + genericDetail.getDetailValue();
- }
-
- if (firstNameDetail.equals(""))
- firstNameDetail
- = Resources.getString("plugin.contactinfo.NOT_SPECIFIED");
-
- valuesPanel.add(new JLabel(firstNameDetail));
-
- // Middle name details.
- contactDetails =
- contactInfoOpSet.getDetails(contact, MiddleNameDetail.class);
-
- String middleNameDetail = "";
- while (contactDetails.hasNext())
- {
- genericDetail = contactDetails.next();
- middleNameDetail =
- middleNameDetail + " " + genericDetail.getDetailValue();
- }
-
- if (middleNameDetail.trim().equals(""))
- middleNameDetail
- = Resources.getString("plugin.contactinfo.NOT_SPECIFIED");
-
- valuesPanel.add(new JLabel(middleNameDetail));
-
- // Last name details.
- contactDetails =
- contactInfoOpSet.getDetails(contact, LastNameDetail.class);
-
- String lastNameDetail = "";
- while (contactDetails.hasNext())
- {
- genericDetail = contactDetails.next();
-
- lastNameDetail =
- lastNameDetail + " " + genericDetail.getDetailValue();
- }
-
- if (lastNameDetail.trim().equals(""))
- lastNameDetail
- = Resources.getString("plugin.contactinfo.NOT_SPECIFIED");
-
- valuesPanel.add(new JLabel(lastNameDetail));
-
- // Gender details.
- contactDetails =
- contactInfoOpSet.getDetails(contact, GenderDetail.class);
-
- String genderDetail = "";
- while (contactDetails.hasNext())
- {
- genericDetail = contactDetails.next();
- genderDetail = genderDetail + " " + genericDetail.getDetailValue();
- }
-
- if (genderDetail.trim().equals(""))
- genderDetail
- = Resources.getString("plugin.contactinfo.NOT_SPECIFIED");
-
- valuesPanel.add(new JLabel(genderDetail));
-
- // Birthday details.
- contactDetails =
- contactInfoOpSet.getDetails(contact, BirthDateDetail.class);
-
- String birthDateDetail = "";
- String ageDetail = "";
- if (contactDetails.hasNext())
- {
- genericDetail = contactDetails.next();
-
- Calendar calendarDetail =
- (Calendar) genericDetail.getDetailValue();
-
- Date birthDate = calendarDetail.getTime();
- DateFormat dateFormat = DateFormat.getDateInstance();
-
- birthDateDetail = dateFormat.format(birthDate).trim();
-
- Calendar c = Calendar.getInstance();
- int age = c.get(Calendar.YEAR) - calendarDetail.get(Calendar.YEAR);
-
- if (c.get(Calendar.MONTH) < calendarDetail.get(Calendar.MONTH))
- age--;
-
- ageDetail = Integer.toString(age).trim();
- }
-
- if (birthDateDetail.equals(""))
- birthDateDetail
- = Resources.getString("plugin.contactinfo.NOT_SPECIFIED");
-
- if (ageDetail.equals(""))
- ageDetail = Resources.getString("plugin.contactinfo.NOT_SPECIFIED");
-
- valuesPanel.add(new JLabel(birthDateDetail));
- valuesPanel.add(new JLabel(ageDetail));
-
- // Email details.
- contactDetails =
- contactInfoOpSet.getDetails(contact, EmailAddressDetail.class);
-
- String emailDetail = "";
- while (contactDetails.hasNext())
- {
- genericDetail = contactDetails.next();
- emailDetail = emailDetail + " " + genericDetail.getDetailValue();
- }
-
- if (emailDetail.trim().equals(""))
- emailDetail
- = Resources.getString("plugin.contactinfo.NOT_SPECIFIED");
-
- valuesPanel.add(new JLabel(emailDetail));
-
- // Phone number details.
- contactDetails =
- contactInfoOpSet.getDetails(contact, PhoneNumberDetail.class);
-
- String phoneNumberDetail = "";
- while (contactDetails.hasNext())
- {
- genericDetail = contactDetails.next();
- phoneNumberDetail =
- phoneNumberDetail + " " + genericDetail.getDetailValue();
- }
-
- if (phoneNumberDetail.trim().equals(""))
- phoneNumberDetail
- = Resources.getString("plugin.contactinfo.NOT_SPECIFIED");
-
- valuesPanel.add(new JLabel(phoneNumberDetail));
-
- return summaryPanel;
- }
-
- /**
- * A panel that displays all of the details retrieved from the opSet.
- *
- * @return a panel that will be added as the extended tab.
- */
- private JPanel createExtendedInfoPanel()
- {
- JPanel mainExtendedPanel = new TransparentPanel(new BorderLayout());
-
- JPanel extendedPanel = new TransparentPanel();
- extendedPanel.setLayout(new BoxLayout(extendedPanel, BoxLayout.Y_AXIS));
-
- JPanel imagePanel = new TransparentPanel();
-
- // The imagePanel will be used for any BinaryDetails and will be added at
- // the bottom so we don't disrupt the standard look of the other details
- imagePanel.setLayout(new BoxLayout(imagePanel, BoxLayout.LINE_AXIS));
- imagePanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
- .createTitledBorder(
- Resources.getString("plugin.contactinfo.USER_PICTURES")),
-
- BorderFactory.createEmptyBorder(0, 5, 5, 5)));
-
- // Obtain all the details for a contact.
- Iterator<GenericDetail> iter
- = contactInfoOpSet.getAllDetailsForContact(contact);
-
- GenericDetail detail;
- JLabel detailLabel;
- JTextArea detailValueArea;
- JPanel detailPanel;
-
- while (iter.hasNext())
- {
- detail = iter.next();
-
- if (detail.getDetailValue().toString().equals(""))
- continue;
-
- detailLabel = new JLabel();
- detailValueArea = new JTextArea();
- detailPanel = new TransparentPanel(new BorderLayout(10, 10));
-
- detailValueArea.setAlignmentX(JTextArea.CENTER_ALIGNMENT);
- detailValueArea.setEditable(false);
- detailValueArea.setLineWrap(true);
-
- detailPanel.add(detailLabel, BorderLayout.WEST);
- detailPanel.add(detailValueArea, BorderLayout.CENTER);
- detailPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
-
- extendedPanel.add(detailPanel);
-
- if (detail instanceof BinaryDetail)
- {
- JLabel imageLabel =
- new JLabel(new ImageIcon((byte[]) detail
- .getDetailValue()));
-
- imagePanel.add(imageLabel);
- }
- else if (detail instanceof CalendarDetail)
- {
- detailLabel.setText(detail.getDetailDisplayName() + ": ");
-
- Date detailDate =
- ((Calendar) detail.getDetailValue()).getTime();
- DateFormat df = DateFormat.getDateInstance();
-
- detailValueArea.setText(df.format(detailDate).trim());
- }
- else if (detail instanceof LocaleDetail)
- {
- detailLabel.setText(detail.getDetailDisplayName() + ": ");
-
- Object value = detail.getDetailValue();
- String valueStr = "";
-
- if(value instanceof Locale)
- valueStr = ((Locale) value).getDisplayName().trim();
- else if(value instanceof String)
- valueStr = (String)value;
-
- detailValueArea.setText(valueStr);
- }
- else if (detail instanceof TimeZoneDetail)
- {
- detailLabel.setText(detail.getDetailDisplayName() + ": ");
-
- detailValueArea.setText(((TimeZone) detail.getDetailValue())
- .getDisplayName().trim());
- }
- else
- {
- detailLabel.setText(detail.getDetailDisplayName() + ": ");
-
- detailValueArea.setText(
- detail.getDetailValue().toString().trim());
- }
- }
-
- // Add users status message to extended details if it exists
- String statusMessage = contact.getStatusMessage();
- if(statusMessage != null && statusMessage.length() > 0)
- {
- detailLabel = new JLabel();
- HTMLTextPane detailValuePane = new HTMLTextPane();
- detailPanel = new TransparentPanel(new BorderLayout(10, 10));
-
- detailValuePane.setEditable(false);
- detailValuePane.setOpaque(false);
-
- detailPanel.add(detailLabel, BorderLayout.WEST);
- detailPanel.add(detailValuePane, BorderLayout.CENTER);
- detailPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
-
- extendedPanel.add(detailPanel);
-
- detailLabel.setText(Resources.getString(
- "plugin.contactinfo.USER_STATUS_MESSAGE") + ": ");
-
- detailValuePane.setText(statusMessage);
- }
-
- // If the contact's protocol supports web info, give them a button to
- // get it
- OperationSetWebContactInfo webContactInfo
- = contact
- .getProtocolProvider()
- .getOperationSet(OperationSetWebContactInfo.class);
-
- if (webContactInfo != null)
- {
- final String urlString
- = webContactInfo.getWebContactInfo(contact).toString();
-
- JLabel webInfoLabel = new JLabel("Click to see web info: ");
- JEditorPane webInfoValue = new JEditorPane();
- JPanel webInfoPanel = new TransparentPanel(new BorderLayout());
-
- webInfoPanel.add(webInfoLabel, BorderLayout.WEST);
- webInfoPanel.add(webInfoValue, BorderLayout.CENTER);
-
- extendedPanel.add(webInfoPanel);
-
- webInfoValue.setOpaque(false);
- webInfoValue.setContentType("text/html");
- webInfoValue.setEditable(false);
- webInfoValue.setText( "<a href='"
- + urlString + "'>"
- + contact.getDisplayName()
- + " web info</a>");
-
- webInfoValue.addHyperlinkListener(new HyperlinkListener()
- {
- public void hyperlinkUpdate(HyperlinkEvent e)
- {
- if (e.getEventType()
- .equals(HyperlinkEvent.EventType.ACTIVATED))
- {
- ContactInfoActivator
- .getBrowserLauncher().openURL(urlString);
- }
- }
- });
- }
-
- if (imagePanel.getComponentCount() > 0)
- mainExtendedPanel.add(imagePanel, BorderLayout.CENTER);
-
- mainExtendedPanel.add(extendedPanel, BorderLayout.NORTH);
-
- return mainExtendedPanel;
- }
-
- /**
- * The <tt>HTMLTextPane</tt> is a pane that handles displaying HTML and
- * hyperlinking urls found in the text.
- */
- private class HTMLTextPane
- extends JTextPane
- implements HyperlinkListener
- {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * The regular expression (in the form of compiled <tt>Pattern</tt>)
- * which matches URLs for the purposed of turning them into links.
- */
- private final Pattern URL_PATTERN = Pattern.compile("("
- + "(\\bwww\\.[^\\s<>\"]+\\.[^\\s<>\"]+/*[?#]*(\\w+[&=;?]\\w+)*\\b)" // wwwURL
- + "|" + "(\\b\\w+://[^\\s<>\"]+/*[?#]*(\\w+[&=;?]\\w+)*\\b)" // protocolURL
- + ")");
-
- private SIPCommHTMLEditorKit editorKit;
- private HTMLDocument document;
-
- /**
- * Creates and instance of <tt>HTMLTextPane</tt>
- */
- public HTMLTextPane()
- {
- editorKit = new SIPCommHTMLEditorKit(this);
-
- this.document = (HTMLDocument) editorKit.createDefaultDocument();
-
- this.addHyperlinkListener(this);
-
- this.setContentType("text/html");
- this.setEditorKitForContentType("text/html", editorKit);
- this.setEditorKit(editorKit);
- this.setDocument(document);
-
- putClientProperty(
- JTextPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
- }
-
-
- /**
- * Override of parent <tt>setText(String)</tt> to search for URLs and
- * set as hyperlinks.
- * @param string <tt>String</tt> to display.
- */
- @Override
- public void setText(String string)
- {
-
- Matcher m = URL_PATTERN.matcher(string);
- StringBuffer msgBuffer = new StringBuffer();
- int prevEnd = 0;
-
- while (m.find())
- {
- String fromPrevEndToStart = string.substring(prevEnd, m.start());
-
- msgBuffer.append(fromPrevEndToStart);
- prevEnd = m.end();
-
- String url = m.group().trim();
-
- msgBuffer.append("<A href=\"");
- if (url.startsWith("www"))
- msgBuffer.append("http://");
- msgBuffer.append(url);
- msgBuffer.append("\">");
- msgBuffer.append(url);
- msgBuffer.append("</A>");
- }
-
- String fromPrevEndToEnd = string.substring(prevEnd);
-
- msgBuffer.append(fromPrevEndToEnd);
-
- super.setText(msgBuffer.toString());
-
- }
-
- /**
- * Handles activations of hyperlinks
- * @param e <tt>HyperlinkEvent</tt> to handle.
- */
- public void hyperlinkUpdate(HyperlinkEvent e)
- {
- if(e.getEventType() == HyperlinkEvent.EventType.ACTIVATED)
- ContactInfoActivator.getBrowserLauncher()
- .openURL(e.getURL().toString());
- }
- }
-}
+package net.java.sip.communicator.plugin.contactinfo;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.text.*;
+import java.util.*;
+import java.util.regex.*;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.html.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.ServerStoredDetails.BinaryDetail;
+import net.java.sip.communicator.service.protocol.ServerStoredDetails.BirthDateDetail;
+import net.java.sip.communicator.service.protocol.ServerStoredDetails.CalendarDetail;
+import net.java.sip.communicator.service.protocol.ServerStoredDetails.EmailAddressDetail;
+import net.java.sip.communicator.service.protocol.ServerStoredDetails.FirstNameDetail;
+import net.java.sip.communicator.service.protocol.ServerStoredDetails.GenderDetail;
+import net.java.sip.communicator.service.protocol.ServerStoredDetails.GenericDetail;
+import net.java.sip.communicator.service.protocol.ServerStoredDetails.LastNameDetail;
+import net.java.sip.communicator.service.protocol.ServerStoredDetails.LocaleDetail;
+import net.java.sip.communicator.service.protocol.ServerStoredDetails.MiddleNameDetail;
+import net.java.sip.communicator.service.protocol.ServerStoredDetails.PhoneNumberDetail;
+import net.java.sip.communicator.service.protocol.ServerStoredDetails.TimeZoneDetail;
+
+/**
+ * The right side panel of ContactInfoDialog. Shows one tab of a summary of
+ * contact information for the selected subcontact, and has an extended tab
+ * listing all of the details.
+ *
+ * @author Adam Goldstein
+ * @author Yana Stamcheva
+ */
+public class ContactInfoDetailsPanel
+ extends TransparentPanel
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * The tabbed pane containing the two different tabs for details.
+ */
+ private final JTabbedPane tabbedPane = new SIPCommTabbedPane();
+
+ /**
+ * The operation set giving access to the server stored contact details.
+ */
+ private OperationSetServerStoredContactInfo contactInfoOpSet;
+
+ /**
+ * The currently selected sub-contact we are displaying information about.
+ */
+ private Contact contact;
+
+ /**
+ * The default width of hte avater area.
+ */
+ private static final int AVATAR_AREA_WIDTH = 105;
+
+ /**
+ * The default height of hte avater area.
+ */
+ private static final int AVATAR_AREA_HEIGHT = 130;
+
+ /**
+ * Construct a tabbed pane that will have one tab with a summary of info for
+ * the selected subcontact and one tab for all of the extended details.
+ */
+ public ContactInfoDetailsPanel()
+ {
+ this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+ this.setPreferredSize(new Dimension(400, 300));
+
+ this.tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
+ }
+
+ /**
+ * Retrieve and display the information for the newly selected contact, c.
+ *
+ * @param c the sub-contact we are now focusing on.
+ */
+ public void loadContactDetails(Contact c)
+ {
+ this.contact = c;
+
+ ProtocolProviderService pps = contact.getProtocolProvider();
+ contactInfoOpSet
+ = pps.getOperationSet(OperationSetServerStoredContactInfo.class);
+
+ this.removeAll();
+
+ if (contactInfoOpSet == null || !pps.isRegistered())
+ {
+ JPanel unsupportedPanel = createUnsupportedPanel();
+
+ this.add(unsupportedPanel);
+
+ this.revalidate();
+ this.repaint();
+
+ return;
+ }
+
+ this.tabbedPane.removeAll();
+
+ ImageIcon icon =
+ new ImageIcon(contact.getProtocolProvider().getProtocolIcon()
+ .getIcon(ProtocolIcon.ICON_SIZE_16x16));
+
+ JPanel summaryPanel = createSummaryInfoPanel();
+
+ JPanel extendedPanel = createExtendedInfoPanel();
+
+ JScrollPane extendedScrollPane = new JScrollPane(extendedPanel);
+
+ this.tabbedPane.addTab(
+ Resources.getString("service.gui.SUMMARY"), icon,
+ summaryPanel,
+ Resources.getString(
+ "plugin.contactinfo.CONTACT_SUMMARY_DESCRIPTION")
+ + contact.getDisplayName());
+
+ this.tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
+
+ this.tabbedPane.addTab(
+ Resources.getString("plugin.accountinfo.EXTENDED"), icon,
+ extendedScrollPane,
+ Resources.getString(
+ "plugin.contactinfo.CONTACT_EXTENDED_DESCRIPTION")
+ + contact.getDisplayName());
+
+ this.tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);
+
+ this.add(tabbedPane);
+
+ this.revalidate();
+ this.repaint();
+ }
+
+ /**
+ * Creates the panel that indicates to the user that the currently selected
+ * contact does not support server stored contact info.
+ *
+ * @return the panel that is added and shows a message that the selected
+ * sub-contact does not have the operation set for server stored
+ * contact info supported.
+ */
+ private JPanel createUnsupportedPanel()
+ {
+ JTextArea unsupportedTextArea = new JTextArea(
+ Resources.getString("service.gui.CONTACT_INFO_NOT_SUPPORTED"));
+
+ unsupportedTextArea.setEditable(false);
+ unsupportedTextArea.setLineWrap(true);
+
+ JPanel unsupportedPanel = new TransparentPanel(new BorderLayout());
+
+ unsupportedPanel.add(unsupportedTextArea);
+
+ return unsupportedPanel;
+ }
+
+ /**
+ * Creates a panel that can be added as the summary tab that displays the
+ * following details: -
+ * <p>
+ * Avatar(Contact image) - FirstNameDetail - MiddleNameDetail -
+ * LastNameDetail - BirthdateDetail (and calculate age) - GenderDetail -
+ * EmailAddressDetail - PhoneNumberDetail. All other details will be* added
+ * to our list of extended details.
+ *
+ * @return the panel that will be added as the summary tab.
+ */
+ private JPanel createSummaryInfoPanel()
+ {
+ JPanel summaryPanel = new TransparentPanel();
+
+ summaryPanel.setLayout(new BorderLayout(10, 5));
+ summaryPanel.setSize(this.getWidth(), this.getHeight());
+
+ // Create the avatar panel.
+ JPanel avatarPanel = new TransparentPanel();
+
+ avatarPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+
+ byte[] bytes = this.contact.getImage();
+
+ ImageIcon scaledImage = null;
+ // If the user has a contact image, let's use it. If not, add the
+ // default
+ if (bytes != null)
+ {
+ scaledImage = ImageUtils.getScaledRoundedIcon(
+ bytes,
+ AVATAR_AREA_WIDTH,
+ AVATAR_AREA_HEIGHT
+ );
+ }
+ else
+ scaledImage =
+ ImageUtils.getScaledRoundedIcon(Resources
+ .getImage("service.gui.DEFAULT_USER_PHOTO"),
+ AVATAR_AREA_WIDTH, AVATAR_AREA_HEIGHT);
+
+ JLabel label = new JLabel(scaledImage);
+ label.setVerticalAlignment(JLabel.CENTER);
+ label.setHorizontalAlignment(JLabel.CENTER);
+ label.setPreferredSize(new Dimension(
+ AVATAR_AREA_WIDTH,
+ AVATAR_AREA_HEIGHT)
+ );
+ avatarPanel.add(label);
+ summaryPanel.add(avatarPanel, BorderLayout.WEST);
+
+ // Create the summary details panel.
+ JPanel detailsPanel = new TransparentPanel();
+ detailsPanel.setLayout(new BorderLayout());
+ detailsPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+
+ summaryPanel.add(detailsPanel);
+
+ // Labels panel.
+ JPanel labelsPanel = new TransparentPanel(new GridLayout(0, 1, 5, 5));
+ labelsPanel.add(new JLabel(
+ Resources.getString("plugin.accountinfo.FIRST_NAME")));
+ labelsPanel.add(new JLabel(
+ Resources.getString("plugin.accountinfo.MIDDLE_NAME")));
+ labelsPanel.add(new JLabel(
+ Resources.getString("plugin.accountinfo.LAST_NAME")));
+ labelsPanel.add(new JLabel(
+ Resources.getString("plugin.accountinfo.GENDER")));
+ labelsPanel.add(new JLabel(
+ Resources.getString("plugin.accountinfo.BDAY")));
+ labelsPanel.add(new JLabel(
+ Resources.getString("plugin.accountinfo.AGE")));
+ labelsPanel.add(new JLabel(
+ Resources.getString("plugin.accountinfo.EMAIL")));
+ labelsPanel.add(new JLabel(
+ Resources.getString("plugin.accountinfo.PHONE")));
+
+ detailsPanel.add(labelsPanel, BorderLayout.WEST);
+
+ // Values panel.
+ JPanel valuesPanel = new TransparentPanel(new GridLayout(0, 1, 5, 5));
+
+ detailsPanel.add(valuesPanel, BorderLayout.CENTER);
+
+ Iterator<GenericDetail> contactDetails;
+ GenericDetail genericDetail;
+
+ // First name details.
+ contactDetails =
+ contactInfoOpSet.getDetails(contact, FirstNameDetail.class);
+
+ String firstNameDetail = "";
+ while (contactDetails.hasNext())
+ {
+ genericDetail = contactDetails.next();
+
+ firstNameDetail =
+ firstNameDetail + " " + genericDetail.getDetailValue();
+ }
+
+ if (firstNameDetail.equals(""))
+ firstNameDetail
+ = Resources.getString("plugin.contactinfo.NOT_SPECIFIED");
+
+ valuesPanel.add(new JLabel(firstNameDetail));
+
+ // Middle name details.
+ contactDetails =
+ contactInfoOpSet.getDetails(contact, MiddleNameDetail.class);
+
+ String middleNameDetail = "";
+ while (contactDetails.hasNext())
+ {
+ genericDetail = contactDetails.next();
+ middleNameDetail =
+ middleNameDetail + " " + genericDetail.getDetailValue();
+ }
+
+ if (middleNameDetail.trim().equals(""))
+ middleNameDetail
+ = Resources.getString("plugin.contactinfo.NOT_SPECIFIED");
+
+ valuesPanel.add(new JLabel(middleNameDetail));
+
+ // Last name details.
+ contactDetails =
+ contactInfoOpSet.getDetails(contact, LastNameDetail.class);
+
+ String lastNameDetail = "";
+ while (contactDetails.hasNext())
+ {
+ genericDetail = contactDetails.next();
+
+ lastNameDetail =
+ lastNameDetail + " " + genericDetail.getDetailValue();
+ }
+
+ if (lastNameDetail.trim().equals(""))
+ lastNameDetail
+ = Resources.getString("plugin.contactinfo.NOT_SPECIFIED");
+
+ valuesPanel.add(new JLabel(lastNameDetail));
+
+ // Gender details.
+ contactDetails =
+ contactInfoOpSet.getDetails(contact, GenderDetail.class);
+
+ String genderDetail = "";
+ while (contactDetails.hasNext())
+ {
+ genericDetail = contactDetails.next();
+ genderDetail = genderDetail + " " + genericDetail.getDetailValue();
+ }
+
+ if (genderDetail.trim().equals(""))
+ genderDetail
+ = Resources.getString("plugin.contactinfo.NOT_SPECIFIED");
+
+ valuesPanel.add(new JLabel(genderDetail));
+
+ // Birthday details.
+ contactDetails =
+ contactInfoOpSet.getDetails(contact, BirthDateDetail.class);
+
+ String birthDateDetail = "";
+ String ageDetail = "";
+ if (contactDetails.hasNext())
+ {
+ genericDetail = contactDetails.next();
+
+ Calendar calendarDetail =
+ (Calendar) genericDetail.getDetailValue();
+
+ Date birthDate = calendarDetail.getTime();
+ DateFormat dateFormat = DateFormat.getDateInstance();
+
+ birthDateDetail = dateFormat.format(birthDate).trim();
+
+ Calendar c = Calendar.getInstance();
+ int age = c.get(Calendar.YEAR) - calendarDetail.get(Calendar.YEAR);
+
+ if (c.get(Calendar.MONTH) < calendarDetail.get(Calendar.MONTH))
+ age--;
+
+ ageDetail = Integer.toString(age).trim();
+ }
+
+ if (birthDateDetail.equals(""))
+ birthDateDetail
+ = Resources.getString("plugin.contactinfo.NOT_SPECIFIED");
+
+ if (ageDetail.equals(""))
+ ageDetail = Resources.getString("plugin.contactinfo.NOT_SPECIFIED");
+
+ valuesPanel.add(new JLabel(birthDateDetail));
+ valuesPanel.add(new JLabel(ageDetail));
+
+ // Email details.
+ contactDetails =
+ contactInfoOpSet.getDetails(contact, EmailAddressDetail.class);
+
+ String emailDetail = "";
+ while (contactDetails.hasNext())
+ {
+ genericDetail = contactDetails.next();
+ emailDetail = emailDetail + " " + genericDetail.getDetailValue();
+ }
+
+ if (emailDetail.trim().equals(""))
+ emailDetail
+ = Resources.getString("plugin.contactinfo.NOT_SPECIFIED");
+
+ valuesPanel.add(new JLabel(emailDetail));
+
+ // Phone number details.
+ contactDetails =
+ contactInfoOpSet.getDetails(contact, PhoneNumberDetail.class);
+
+ String phoneNumberDetail = "";
+ while (contactDetails.hasNext())
+ {
+ genericDetail = contactDetails.next();
+ phoneNumberDetail =
+ phoneNumberDetail + " " + genericDetail.getDetailValue();
+ }
+
+ if (phoneNumberDetail.trim().equals(""))
+ phoneNumberDetail
+ = Resources.getString("plugin.contactinfo.NOT_SPECIFIED");
+
+ valuesPanel.add(new JLabel(phoneNumberDetail));
+
+ return summaryPanel;
+ }
+
+ /**
+ * A panel that displays all of the details retrieved from the opSet.
+ *
+ * @return a panel that will be added as the extended tab.
+ */
+ private JPanel createExtendedInfoPanel()
+ {
+ JPanel mainExtendedPanel = new TransparentPanel(new BorderLayout());
+
+ JPanel extendedPanel = new TransparentPanel();
+ extendedPanel.setLayout(new BoxLayout(extendedPanel, BoxLayout.Y_AXIS));
+
+ JPanel imagePanel = new TransparentPanel();
+
+ // The imagePanel will be used for any BinaryDetails and will be added at
+ // the bottom so we don't disrupt the standard look of the other details
+ imagePanel.setLayout(new BoxLayout(imagePanel, BoxLayout.LINE_AXIS));
+ imagePanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
+ .createTitledBorder(
+ Resources.getString("plugin.contactinfo.USER_PICTURES")),
+
+ BorderFactory.createEmptyBorder(0, 5, 5, 5)));
+
+ // Obtain all the details for a contact.
+ Iterator<GenericDetail> iter
+ = contactInfoOpSet.getAllDetailsForContact(contact);
+
+ GenericDetail detail;
+ JLabel detailLabel;
+ JTextArea detailValueArea;
+ JPanel detailPanel;
+
+ while (iter.hasNext())
+ {
+ detail = iter.next();
+
+ if (detail.getDetailValue().toString().equals(""))
+ continue;
+
+ detailLabel = new JLabel();
+ detailValueArea = new JTextArea();
+ detailPanel = new TransparentPanel(new BorderLayout(10, 10));
+
+ detailValueArea.setAlignmentX(JTextArea.CENTER_ALIGNMENT);
+ detailValueArea.setEditable(false);
+ detailValueArea.setLineWrap(true);
+
+ detailPanel.add(detailLabel, BorderLayout.WEST);
+ detailPanel.add(detailValueArea, BorderLayout.CENTER);
+ detailPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+
+ extendedPanel.add(detailPanel);
+
+ if (detail instanceof BinaryDetail)
+ {
+ JLabel imageLabel =
+ new JLabel(new ImageIcon((byte[]) detail
+ .getDetailValue()));
+
+ imagePanel.add(imageLabel);
+ }
+ else if (detail instanceof CalendarDetail)
+ {
+ detailLabel.setText(detail.getDetailDisplayName() + ": ");
+
+ Date detailDate =
+ ((Calendar) detail.getDetailValue()).getTime();
+ DateFormat df = DateFormat.getDateInstance();
+
+ detailValueArea.setText(df.format(detailDate).trim());
+ }
+ else if (detail instanceof LocaleDetail)
+ {
+ detailLabel.setText(detail.getDetailDisplayName() + ": ");
+
+ Object value = detail.getDetailValue();
+ String valueStr = "";
+
+ if(value instanceof Locale)
+ valueStr = ((Locale) value).getDisplayName().trim();
+ else if(value instanceof String)
+ valueStr = (String)value;
+
+ detailValueArea.setText(valueStr);
+ }
+ else if (detail instanceof TimeZoneDetail)
+ {
+ detailLabel.setText(detail.getDetailDisplayName() + ": ");
+
+ detailValueArea.setText(((TimeZone) detail.getDetailValue())
+ .getDisplayName().trim());
+ }
+ else
+ {
+ detailLabel.setText(detail.getDetailDisplayName() + ": ");
+
+ detailValueArea.setText(
+ detail.getDetailValue().toString().trim());
+ }
+ }
+
+ // Add users status message to extended details if it exists
+ String statusMessage = contact.getStatusMessage();
+ if(statusMessage != null && statusMessage.length() > 0)
+ {
+ detailLabel = new JLabel();
+ HTMLTextPane detailValuePane = new HTMLTextPane();
+ detailPanel = new TransparentPanel(new BorderLayout(10, 10));
+
+ detailValuePane.setEditable(false);
+ detailValuePane.setOpaque(false);
+
+ detailPanel.add(detailLabel, BorderLayout.WEST);
+ detailPanel.add(detailValuePane, BorderLayout.CENTER);
+ detailPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+
+ extendedPanel.add(detailPanel);
+
+ detailLabel.setText(Resources.getString(
+ "plugin.contactinfo.USER_STATUS_MESSAGE") + ": ");
+
+ detailValuePane.setText(statusMessage);
+ }
+
+ // If the contact's protocol supports web info, give them a button to
+ // get it
+ OperationSetWebContactInfo webContactInfo
+ = contact
+ .getProtocolProvider()
+ .getOperationSet(OperationSetWebContactInfo.class);
+
+ if (webContactInfo != null)
+ {
+ final String urlString
+ = webContactInfo.getWebContactInfo(contact).toString();
+
+ JLabel webInfoLabel = new JLabel("Click to see web info: ");
+ JEditorPane webInfoValue = new JEditorPane();
+ JPanel webInfoPanel = new TransparentPanel(new BorderLayout());
+
+ webInfoPanel.add(webInfoLabel, BorderLayout.WEST);
+ webInfoPanel.add(webInfoValue, BorderLayout.CENTER);
+
+ extendedPanel.add(webInfoPanel);
+
+ webInfoValue.setOpaque(false);
+ webInfoValue.setContentType("text/html");
+ webInfoValue.setEditable(false);
+ webInfoValue.setText( "<a href='"
+ + urlString + "'>"
+ + contact.getDisplayName()
+ + " web info</a>");
+
+ webInfoValue.addHyperlinkListener(new HyperlinkListener()
+ {
+ public void hyperlinkUpdate(HyperlinkEvent e)
+ {
+ if (e.getEventType()
+ .equals(HyperlinkEvent.EventType.ACTIVATED))
+ {
+ ContactInfoActivator
+ .getBrowserLauncher().openURL(urlString);
+ }
+ }
+ });
+ }
+
+ if (imagePanel.getComponentCount() > 0)
+ mainExtendedPanel.add(imagePanel, BorderLayout.CENTER);
+
+ mainExtendedPanel.add(extendedPanel, BorderLayout.NORTH);
+
+ return mainExtendedPanel;
+ }
+
+ /**
+ * The <tt>HTMLTextPane</tt> is a pane that handles displaying HTML and
+ * hyperlinking urls found in the text.
+ */
+ private class HTMLTextPane
+ extends JTextPane
+ implements HyperlinkListener
+ {
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * The regular expression (in the form of compiled <tt>Pattern</tt>)
+ * which matches URLs for the purposed of turning them into links.
+ */
+ private final Pattern URL_PATTERN = Pattern.compile("("
+ + "(\\bwww\\.[^\\s<>\"]+\\.[^\\s<>\"]+/*[?#]*(\\w+[&=;?]\\w+)*\\b)" // wwwURL
+ + "|" + "(\\b\\w+://[^\\s<>\"]+/*[?#]*(\\w+[&=;?]\\w+)*\\b)" // protocolURL
+ + ")");
+
+ private SIPCommHTMLEditorKit editorKit;
+ private HTMLDocument document;
+
+ /**
+ * Creates and instance of <tt>HTMLTextPane</tt>
+ */
+ public HTMLTextPane()
+ {
+ editorKit = new SIPCommHTMLEditorKit(this);
+
+ this.document = (HTMLDocument) editorKit.createDefaultDocument();
+
+ this.addHyperlinkListener(this);
+
+ this.setContentType("text/html");
+ this.setEditorKitForContentType("text/html", editorKit);
+ this.setEditorKit(editorKit);
+ this.setDocument(document);
+
+ putClientProperty(
+ JTextPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
+ }
+
+
+ /**
+ * Override of parent <tt>setText(String)</tt> to search for URLs and
+ * set as hyperlinks.
+ * @param string <tt>String</tt> to display.
+ */
+ @Override
+ public void setText(String string)
+ {
+
+ Matcher m = URL_PATTERN.matcher(string);
+ StringBuffer msgBuffer = new StringBuffer();
+ int prevEnd = 0;
+
+ while (m.find())
+ {
+ String fromPrevEndToStart = string.substring(prevEnd, m.start());
+
+ msgBuffer.append(fromPrevEndToStart);
+ prevEnd = m.end();
+
+ String url = m.group().trim();
+
+ msgBuffer.append("<A href=\"");
+ if (url.startsWith("www"))
+ msgBuffer.append("http://");
+ msgBuffer.append(url);
+ msgBuffer.append("\">");
+ msgBuffer.append(url);
+ msgBuffer.append("</A>");
+ }
+
+ String fromPrevEndToEnd = string.substring(prevEnd);
+
+ msgBuffer.append(fromPrevEndToEnd);
+
+ super.setText(msgBuffer.toString());
+
+ }
+
+ /**
+ * Handles activations of hyperlinks
+ * @param e <tt>HyperlinkEvent</tt> to handle.
+ */
+ public void hyperlinkUpdate(HyperlinkEvent e)
+ {
+ if(e.getEventType() == HyperlinkEvent.EventType.ACTIVATED)
+ ContactInfoActivator.getBrowserLauncher()
+ .openURL(e.getURL().toString());
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoDialog.java b/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoDialog.java
index 8e7d9db..3176533 100644
--- a/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoDialog.java
+++ b/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoDialog.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,88 +15,88 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.contactinfo;
-
-import java.awt.*;
-import java.util.*;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.service.contactlist.*;
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * A GUI plug-in for SIP Communicator that will allow cross protocol contact
- * information viewing and editing.
- *
- * @author Adam Goldstein
- * @author Yana Stamcheva
- */
-public class ContactInfoDialog
- extends SIPCommFrame
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * The right side of this frame that contains protocol specific contact
- * details.
- */
- protected ContactInfoDetailsPanel detailsPanel
- = new ContactInfoDetailsPanel();
-
- /**
- * The left side of this frame that contains a list of all sub-contacts
- * associated with the selected contact.
- */
- protected ContactInfoContactPanel contactPanel;
-
- /**
- * The contact that was right clicked on. The sub-contacts of contactItem
- * will be the ones selectable in contactPanel.
- */
- protected MetaContact metaContact;
-
- /**
- * Accepts a MetaContact and constructs a frame with ContactInfoSearchPanel
- * on the left and an information interface, ContactInfoDetailsPanel,
- * on the right.
- * @param metaContact the sub-contacts of this MetaContact that was right
- * clicked on will be the ones selectable in contactPanel.
- */
- public ContactInfoDialog(MetaContact metaContact)
- {
- this.metaContact = metaContact;
-
- this.setTitle(Resources.getString("plugin.contactinfo.TITLE")
- + ": "
- + metaContact.getDisplayName());
-
- Iterator<Contact> subContacts = metaContact.getContacts();
-
- this.contactPanel
- = new ContactInfoContactPanel(subContacts, this);
-
- Container contentPane = getContentPane();
- contentPane.add(contactPanel, BorderLayout.WEST);
- contentPane.add(detailsPanel, BorderLayout.CENTER);
-
- this.pack();
- }
-
- /**
- * Loads the details of the given contact.
- *
- * @param contact the <tt>Contact</tt>, which details we load
- */
- public void loadContactDetails(Contact contact)
- {
- this.detailsPanel.loadContactDetails(contact);
- }
-
- @Override
- protected void close(boolean isEscaped)
- {
- }
-}
+package net.java.sip.communicator.plugin.contactinfo;
+
+import java.awt.*;
+import java.util.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.service.contactlist.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * A GUI plug-in for SIP Communicator that will allow cross protocol contact
+ * information viewing and editing.
+ *
+ * @author Adam Goldstein
+ * @author Yana Stamcheva
+ */
+public class ContactInfoDialog
+ extends SIPCommFrame
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * The right side of this frame that contains protocol specific contact
+ * details.
+ */
+ protected ContactInfoDetailsPanel detailsPanel
+ = new ContactInfoDetailsPanel();
+
+ /**
+ * The left side of this frame that contains a list of all sub-contacts
+ * associated with the selected contact.
+ */
+ protected ContactInfoContactPanel contactPanel;
+
+ /**
+ * The contact that was right clicked on. The sub-contacts of contactItem
+ * will be the ones selectable in contactPanel.
+ */
+ protected MetaContact metaContact;
+
+ /**
+ * Accepts a MetaContact and constructs a frame with ContactInfoSearchPanel
+ * on the left and an information interface, ContactInfoDetailsPanel,
+ * on the right.
+ * @param metaContact the sub-contacts of this MetaContact that was right
+ * clicked on will be the ones selectable in contactPanel.
+ */
+ public ContactInfoDialog(MetaContact metaContact)
+ {
+ this.metaContact = metaContact;
+
+ this.setTitle(Resources.getString("plugin.contactinfo.TITLE")
+ + ": "
+ + metaContact.getDisplayName());
+
+ Iterator<Contact> subContacts = metaContact.getContacts();
+
+ this.contactPanel
+ = new ContactInfoContactPanel(subContacts, this);
+
+ Container contentPane = getContentPane();
+ contentPane.add(contactPanel, BorderLayout.WEST);
+ contentPane.add(detailsPanel, BorderLayout.CENTER);
+
+ this.pack();
+ }
+
+ /**
+ * Loads the details of the given contact.
+ *
+ * @param contact the <tt>Contact</tt>, which details we load
+ */
+ public void loadContactDetails(Contact contact)
+ {
+ this.detailsPanel.loadContactDetails(contact);
+ }
+
+ @Override
+ protected void close(boolean isEscaped)
+ {
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoMenuItem.java b/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoMenuItem.java
index abf4e25..11cea23 100644
--- a/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoMenuItem.java
+++ b/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoMenuItem.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,165 +15,165 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.contactinfo;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.service.contactlist.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.gui.Container;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.resources.*;
-
-/**
- *
- * @author Adam Goldstein
- */
-public class ContactInfoMenuItem
- extends AbstractPluginComponent
- implements ActionListener
-{
- private AbstractButton menuItem = null;
-
- private MetaContact metaContact;
-
- /**
- * The button index, for now placed on last position.
- */
- private final static int CONTACT_INFO_BUTTON_IX = 50;
-
- /**
- * Creates a <tt>ContactInfoMenuItem</tt>.
- */
- public ContactInfoMenuItem(PluginComponentFactory parentFactory)
- {
- this(Container.CONTAINER_CONTACT_RIGHT_BUTTON_MENU, parentFactory);
- }
-
- /**
- * Creates a <tt>ContactInfoMenuItem</tt>.
- */
- public ContactInfoMenuItem(Container container,
- PluginComponentFactory parentFactory)
- {
- super(container, parentFactory);
- }
-
- /**
- * Sets the currently selected <tt>MetaContact</tt>.
- * @param metaContact the currently selected meta contact
- */
- @Override
- public void setCurrentContact(MetaContact metaContact)
- {
- this.metaContact = metaContact;
- }
-
- /*
- * Implements PluginComponent#setCurrentContact(Contact).
- * @param contact the currently selected contact
- */
- @Override
- public void setCurrentContact(Contact contact)
- {
- if(metaContact == null)
- {
- // search for the metacontact
- MetaContactListService mcs =
- ContactInfoActivator.getContactListService();
-
- metaContact =
- mcs.findMetaContactByContact(contact);
- }
- }
-
- /**
- * Initializes and shows the contact details dialog.
- */
- public void actionPerformed(ActionEvent e)
- {
- if(metaContact == null)
- return;
-
- ContactInfoDialog cinfoDialog = new ContactInfoDialog(metaContact);
- Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
-
- cinfoDialog.setLocation(
- screenSize.width/2 - cinfoDialog.getWidth()/2,
- screenSize.height/2 - cinfoDialog.getHeight()/2);
- cinfoDialog.setVisible(true);
- }
-
- public Object getComponent()
- {
- return getMenuItem();
- }
-
- public String getName()
- {
- return getMenuItem().getText();
- }
-
- private AbstractButton getMenuItem()
- {
- if(menuItem == null)
- {
- if(getContainer().equals(Container.CONTAINER_CHAT_TOOL_BAR))
- {
- menuItem =
- new SIPCommButton(null,
- (Image)ContactInfoActivator.getImageLoaderService()
- .getImage(new ImageID(
- "plugin.contactinfo.CONTACT_INFO_TOOLBAR")))
- {
- /**
- * Returns the button index.
- * @return the button index.
- */
- public int getIndex()
- {
- return CONTACT_INFO_BUTTON_IX;
- }
- };
-
- menuItem.setPreferredSize(new Dimension(25, 25));
- menuItem.setToolTipText(
- Resources.getString("service.gui.CONTACT_INFO"));
- }
- else if(getContainer().equals(Container.CONTAINER_CALL_DIALOG))
- {
- menuItem =
- new SIPCommButton(null,
- (Image)ContactInfoActivator.getImageLoaderService()
- .getImage(new ImageID(
- "plugin.contactinfo.CONTACT_INFO_CALL_WINDOW")))
- {
- /**
- * Returns the button index.
- * @return the button index.
- */
- public int getIndex()
- {
- return CONTACT_INFO_BUTTON_IX;
- }
- };
- menuItem.setPreferredSize(new Dimension(44, 38));
- menuItem.setToolTipText(
- Resources.getString("service.gui.CONTACT_INFO"));
- }
- else
- menuItem =
- new JMenuItem(
- Resources.getString("service.gui.CONTACT_INFO"),
- new ImageIcon(Resources.getImage(
- "plugin.contactinfo.CONTACT_INFO_ICON")));
- menuItem.addActionListener(this);
- }
-
- return menuItem;
- }
-}
+package net.java.sip.communicator.plugin.contactinfo;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.service.contactlist.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.gui.Container;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.resources.*;
+
+/**
+ *
+ * @author Adam Goldstein
+ */
+public class ContactInfoMenuItem
+ extends AbstractPluginComponent
+ implements ActionListener
+{
+ private AbstractButton menuItem = null;
+
+ private MetaContact metaContact;
+
+ /**
+ * The button index, for now placed on last position.
+ */
+ private final static int CONTACT_INFO_BUTTON_IX = 50;
+
+ /**
+ * Creates a <tt>ContactInfoMenuItem</tt>.
+ */
+ public ContactInfoMenuItem(PluginComponentFactory parentFactory)
+ {
+ this(Container.CONTAINER_CONTACT_RIGHT_BUTTON_MENU, parentFactory);
+ }
+
+ /**
+ * Creates a <tt>ContactInfoMenuItem</tt>.
+ */
+ public ContactInfoMenuItem(Container container,
+ PluginComponentFactory parentFactory)
+ {
+ super(container, parentFactory);
+ }
+
+ /**
+ * Sets the currently selected <tt>MetaContact</tt>.
+ * @param metaContact the currently selected meta contact
+ */
+ @Override
+ public void setCurrentContact(MetaContact metaContact)
+ {
+ this.metaContact = metaContact;
+ }
+
+ /*
+ * Implements PluginComponent#setCurrentContact(Contact).
+ * @param contact the currently selected contact
+ */
+ @Override
+ public void setCurrentContact(Contact contact)
+ {
+ if(metaContact == null)
+ {
+ // search for the metacontact
+ MetaContactListService mcs =
+ ContactInfoActivator.getContactListService();
+
+ metaContact =
+ mcs.findMetaContactByContact(contact);
+ }
+ }
+
+ /**
+ * Initializes and shows the contact details dialog.
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ if(metaContact == null)
+ return;
+
+ ContactInfoDialog cinfoDialog = new ContactInfoDialog(metaContact);
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+
+ cinfoDialog.setLocation(
+ screenSize.width/2 - cinfoDialog.getWidth()/2,
+ screenSize.height/2 - cinfoDialog.getHeight()/2);
+ cinfoDialog.setVisible(true);
+ }
+
+ public Object getComponent()
+ {
+ return getMenuItem();
+ }
+
+ public String getName()
+ {
+ return getMenuItem().getText();
+ }
+
+ private AbstractButton getMenuItem()
+ {
+ if(menuItem == null)
+ {
+ if(getContainer().equals(Container.CONTAINER_CHAT_TOOL_BAR))
+ {
+ menuItem =
+ new SIPCommButton(null,
+ (Image)ContactInfoActivator.getImageLoaderService()
+ .getImage(new ImageID(
+ "plugin.contactinfo.CONTACT_INFO_TOOLBAR")))
+ {
+ /**
+ * Returns the button index.
+ * @return the button index.
+ */
+ public int getIndex()
+ {
+ return CONTACT_INFO_BUTTON_IX;
+ }
+ };
+
+ menuItem.setPreferredSize(new Dimension(25, 25));
+ menuItem.setToolTipText(
+ Resources.getString("service.gui.CONTACT_INFO"));
+ }
+ else if(getContainer().equals(Container.CONTAINER_CALL_DIALOG))
+ {
+ menuItem =
+ new SIPCommButton(null,
+ (Image)ContactInfoActivator.getImageLoaderService()
+ .getImage(new ImageID(
+ "plugin.contactinfo.CONTACT_INFO_CALL_WINDOW")))
+ {
+ /**
+ * Returns the button index.
+ * @return the button index.
+ */
+ public int getIndex()
+ {
+ return CONTACT_INFO_BUTTON_IX;
+ }
+ };
+ menuItem.setPreferredSize(new Dimension(44, 38));
+ menuItem.setToolTipText(
+ Resources.getString("service.gui.CONTACT_INFO"));
+ }
+ else
+ menuItem =
+ new JMenuItem(
+ Resources.getString("service.gui.CONTACT_INFO"),
+ new ImageIcon(Resources.getImage(
+ "plugin.contactinfo.CONTACT_INFO_ICON")));
+ menuItem.addActionListener(this);
+ }
+
+ return menuItem;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/contactinfo/Resources.java b/src/net/java/sip/communicator/plugin/contactinfo/Resources.java
index 0c8f870..f0f31f1 100644
--- a/src/net/java/sip/communicator/plugin/contactinfo/Resources.java
+++ b/src/net/java/sip/communicator/plugin/contactinfo/Resources.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,79 +15,79 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.contactinfo;
-
-import java.awt.*;
-import java.awt.image.*;
-import java.io.*;
-
-import javax.imageio.*;
-
-import net.java.sip.communicator.service.resources.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.resources.*;
-
-/**
- * The <tt>Resources</tt> class manages the access to the internationalization
- * properties files and the image resources used in this plugin.
- *
- * @author Yana Stamcheva
- */
-public class Resources {
-
- private static Logger log = Logger.getLogger(Resources.class);
-
- private static ResourceManagementService resourcesService;
-
- /**
- * Returns an internationalized string corresponding to the given key.
- * @param key The key of the string.
- * @return An internationalized string corresponding to the given key.
- */
- public static String getString(String key)
- {
- return getResources().getI18NString(key);
- }
-
- /**
- * Loads an image from a given image identifier.
- * @param imageID The identifier of the image.
- * @return The image for the given identifier.
- */
- public static Image getImage(String imageID)
- {
- BufferedImage image = null;
-
- InputStream in =
- getResources().getImageInputStream(imageID);
-
- if(in == null)
- return null;
-
- try
- {
- image = ImageIO.read(in);
- }
- catch (IOException e)
- {
- log.error("Failed to load image:" + imageID, e);
- }
-
- return image;
- }
-
- /**
- * Returns the <tt>ResourceManagementService</tt>.
- *
- * @return the <tt>ResourceManagementService</tt>.
- */
- public static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- resourcesService =
- ResourceManagementServiceUtils
- .getService(ContactInfoActivator.bundleContext);
- return resourcesService;
- }
-}
+package net.java.sip.communicator.plugin.contactinfo;
+
+import java.awt.*;
+import java.awt.image.*;
+import java.io.*;
+
+import javax.imageio.*;
+
+import net.java.sip.communicator.service.resources.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.resources.*;
+
+/**
+ * The <tt>Resources</tt> class manages the access to the internationalization
+ * properties files and the image resources used in this plugin.
+ *
+ * @author Yana Stamcheva
+ */
+public class Resources {
+
+ private static Logger log = Logger.getLogger(Resources.class);
+
+ private static ResourceManagementService resourcesService;
+
+ /**
+ * Returns an internationalized string corresponding to the given key.
+ * @param key The key of the string.
+ * @return An internationalized string corresponding to the given key.
+ */
+ public static String getString(String key)
+ {
+ return getResources().getI18NString(key);
+ }
+
+ /**
+ * Loads an image from a given image identifier.
+ * @param imageID The identifier of the image.
+ * @return The image for the given identifier.
+ */
+ public static Image getImage(String imageID)
+ {
+ BufferedImage image = null;
+
+ InputStream in =
+ getResources().getImageInputStream(imageID);
+
+ if(in == null)
+ return null;
+
+ try
+ {
+ image = ImageIO.read(in);
+ }
+ catch (IOException e)
+ {
+ log.error("Failed to load image:" + imageID, e);
+ }
+
+ return image;
+ }
+
+ /**
+ * Returns the <tt>ResourceManagementService</tt>.
+ *
+ * @return the <tt>ResourceManagementService</tt>.
+ */
+ public static ResourceManagementService getResources()
+ {
+ if (resourcesService == null)
+ resourcesService =
+ ResourceManagementServiceUtils
+ .getService(ContactInfoActivator.bundleContext);
+ return resourcesService;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/desktoputil/ColoredDefaultText.java b/src/net/java/sip/communicator/plugin/desktoputil/ColoredDefaultText.java
index 59dcb5d..e70f57e 100644
--- a/src/net/java/sip/communicator/plugin/desktoputil/ColoredDefaultText.java
+++ b/src/net/java/sip/communicator/plugin/desktoputil/ColoredDefaultText.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,43 +15,43 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.desktoputil;
-
-import java.awt.*;
-
-/**
- * The purpose of this interface is to allow UI components with a default
- * text value to give the default text its own colour, set independently of
- * the normal text colour.
- * @author Tom Denham
- */
-public interface ColoredDefaultText
-{
- /**
- * Sets the foreground color.
- *
- * @param c the color to set for the text field foreground
- */
- public void setForegroundColor(Color c);
-
- /**
- * Gets the foreground color.
- *
- * @return the color of the text
- */
- public Color getForegroundColor();
-
- /**
- * Sets the foreground color of the default text shown in this text field.
- *
- * @param c the color to set
- */
- public void setDefaultTextColor(Color c);
-
- /**
- * Gets the foreground color of the default text shown in this text field.
- *
- * @return the color of the default text
- */
- public Color getDefaultTextColor();
+package net.java.sip.communicator.plugin.desktoputil;
+
+import java.awt.*;
+
+/**
+ * The purpose of this interface is to allow UI components with a default
+ * text value to give the default text its own colour, set independently of
+ * the normal text colour.
+ * @author Tom Denham
+ */
+public interface ColoredDefaultText
+{
+ /**
+ * Sets the foreground color.
+ *
+ * @param c the color to set for the text field foreground
+ */
+ public void setForegroundColor(Color c);
+
+ /**
+ * Gets the foreground color.
+ *
+ * @return the color of the text
+ */
+ public Color getForegroundColor();
+
+ /**
+ * Sets the foreground color of the default text shown in this text field.
+ *
+ * @param c the color to set
+ */
+ public void setDefaultTextColor(Color c);
+
+ /**
+ * Gets the foreground color of the default text shown in this text field.
+ *
+ * @return the color of the default text
+ */
+ public Color getDefaultTextColor();
}
diff --git a/src/net/java/sip/communicator/plugin/desktoputil/SIPCommCheckBox.java b/src/net/java/sip/communicator/plugin/desktoputil/SIPCommCheckBox.java
index e263415..45c2e69 100644
--- a/src/net/java/sip/communicator/plugin/desktoputil/SIPCommCheckBox.java
+++ b/src/net/java/sip/communicator/plugin/desktoputil/SIPCommCheckBox.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,45 +15,45 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.desktoputil;
-
-import javax.swing.*;
-
-import org.jitsi.util.*;
-
-/**
- * @author Lubomir Marinov
- */
-public class SIPCommCheckBox
- extends JCheckBox
-{
- private static final long serialVersionUID = 0L;
-
- private static final boolean setContentAreaFilled = (OSUtils.IS_WINDOWS
- || OSUtils.IS_LINUX);
-
- public SIPCommCheckBox()
- {
- init();
- }
-
- public SIPCommCheckBox(String text)
- {
- super(text);
-
- init();
- }
-
- public SIPCommCheckBox(String text, boolean selected)
- {
- super(text, selected);
-
- init();
- }
-
- private void init()
- {
- if (setContentAreaFilled)
- setContentAreaFilled(false);
- }
-}
+package net.java.sip.communicator.plugin.desktoputil;
+
+import javax.swing.*;
+
+import org.jitsi.util.*;
+
+/**
+ * @author Lubomir Marinov
+ */
+public class SIPCommCheckBox
+ extends JCheckBox
+{
+ private static final long serialVersionUID = 0L;
+
+ private static final boolean setContentAreaFilled = (OSUtils.IS_WINDOWS
+ || OSUtils.IS_LINUX);
+
+ public SIPCommCheckBox()
+ {
+ init();
+ }
+
+ public SIPCommCheckBox(String text)
+ {
+ super(text);
+
+ init();
+ }
+
+ public SIPCommCheckBox(String text, boolean selected)
+ {
+ super(text, selected);
+
+ init();
+ }
+
+ private void init()
+ {
+ if (setContentAreaFilled)
+ setContentAreaFilled(false);
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/desktoputil/SIPCommRadioButton.java b/src/net/java/sip/communicator/plugin/desktoputil/SIPCommRadioButton.java
index 7089c99..1132c72 100644
--- a/src/net/java/sip/communicator/plugin/desktoputil/SIPCommRadioButton.java
+++ b/src/net/java/sip/communicator/plugin/desktoputil/SIPCommRadioButton.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,45 +15,45 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.desktoputil;
-
-import javax.swing.*;
-
-import org.jitsi.util.*;
-
-/**
- * @author Ingo Bauersachs
- */
-public class SIPCommRadioButton
- extends JRadioButton
-{
- private static final long serialVersionUID = 0L;
-
- private static final boolean setContentAreaFilled = (OSUtils.IS_WINDOWS
- || OSUtils.IS_LINUX);
-
- public SIPCommRadioButton()
- {
- init();
- }
-
- public SIPCommRadioButton(String text)
- {
- super(text);
-
- init();
- }
-
- public SIPCommRadioButton(String text, boolean selected)
- {
- super(text, selected);
-
- init();
- }
-
- private void init()
- {
- if (setContentAreaFilled)
- setContentAreaFilled(false);
- }
-}
+package net.java.sip.communicator.plugin.desktoputil;
+
+import javax.swing.*;
+
+import org.jitsi.util.*;
+
+/**
+ * @author Ingo Bauersachs
+ */
+public class SIPCommRadioButton
+ extends JRadioButton
+{
+ private static final long serialVersionUID = 0L;
+
+ private static final boolean setContentAreaFilled = (OSUtils.IS_WINDOWS
+ || OSUtils.IS_LINUX);
+
+ public SIPCommRadioButton()
+ {
+ init();
+ }
+
+ public SIPCommRadioButton(String text)
+ {
+ super(text);
+
+ init();
+ }
+
+ public SIPCommRadioButton(String text, boolean selected)
+ {
+ super(text, selected);
+
+ init();
+ }
+
+ private void init()
+ {
+ if (setContentAreaFilled)
+ setContentAreaFilled(false);
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/desktoputil/X509CertificatePanel.java b/src/net/java/sip/communicator/plugin/desktoputil/X509CertificatePanel.java
index a1284cd..5358030 100644
--- a/src/net/java/sip/communicator/plugin/desktoputil/X509CertificatePanel.java
+++ b/src/net/java/sip/communicator/plugin/desktoputil/X509CertificatePanel.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,490 +15,546 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.desktoputil;
-
-import java.awt.*;
-import java.security.*;
-import java.security.cert.*;
-import java.security.cert.Certificate;
-import java.security.interfaces.*;
-import java.util.*;
-
-import javax.naming.*;
-import javax.naming.ldap.*;
-import javax.security.auth.x500.*;
-import javax.swing.*;
-import javax.swing.border.*;
-import javax.swing.event.*;
-import javax.swing.text.*;
-import javax.swing.tree.*;
-
-import org.jitsi.service.resources.*;
-
-/**
- * Panel that shows the content of an X509Certificate.
- */
-public class X509CertificatePanel
- extends TransparentPanel
-{
- private static final long serialVersionUID = -8368302061995971947L;
-
- private final JEditorPane infoTextPane = new JEditorPane();
-
- private final ResourceManagementService R
- = DesktopUtilActivator.getResources();
-
- /**
- * Constructs a X509 certificate panel from a single certificate.
- * If a chain is available instead use the second constructor.
- * This constructor is kept for backwards compatibility and for convenience
- * when there is only one certificate of interest.
- *
- * @param certificate <tt>X509Certificate</tt> object
- */
- public X509CertificatePanel(Certificate certificate)
- {
- this(new Certificate[]
- {
- certificate
- });
- }
-
- /**
- * Constructs a X509 certificate panel.
- *
- * @param certificates <tt>X509Certificate</tt> objects
- */
- public X509CertificatePanel(Certificate[] certificates)
- {
- setLayout(new BorderLayout(5, 5));
-
- // Certificate chain list
- TransparentPanel topPanel = new TransparentPanel(new BorderLayout());
- topPanel.add(new JLabel("<html><body><b>"
- + R.getI18NString("service.gui.CERT_INFO_CHAIN")
- + "</b></body></html>"), BorderLayout.NORTH);
-
- DefaultMutableTreeNode top = new DefaultMutableTreeNode();
- DefaultMutableTreeNode previous = top;
- for (int i = certificates.length - 1; i >= 0; i--)
- {
- Certificate cert = certificates[i];
- DefaultMutableTreeNode next = new DefaultMutableTreeNode(cert);
- previous.add(next);
- previous = next;
- }
- JTree tree = new JTree(top);
- tree.setBorder(new BevelBorder(BevelBorder.LOWERED));
- tree.setRootVisible(false);
- tree.setExpandsSelectedPaths(true);
- tree.getSelectionModel().setSelectionMode(
- TreeSelectionModel.SINGLE_TREE_SELECTION);
- tree.setCellRenderer(new DefaultTreeCellRenderer()
- {
-
- @Override
- public Component getTreeCellRendererComponent(JTree tree,
- Object value, boolean sel, boolean expanded, boolean leaf,
- int row, boolean hasFocus)
- {
- JLabel component = (JLabel) super.getTreeCellRendererComponent(
- tree, value, sel, expanded, leaf, row, hasFocus);
- if (value instanceof DefaultMutableTreeNode)
- {
- Object o = ((DefaultMutableTreeNode) value).getUserObject();
- if (o instanceof X509Certificate)
- {
- component.setText(
- getSimplifiedName((X509Certificate) o));
- }
- else
- {
- // We don't know how to represent this certificate type,
- // let's use the first 20 characters
- String text = o.toString();
- if (text.length() > 20)
- {
- text = text.substring(0, 20);
- }
- component.setText(text);
- }
- }
- return component;
- }
-
- });
- tree.getSelectionModel().addTreeSelectionListener(
- new TreeSelectionListener()
- {
-
- @Override
- public void valueChanged(TreeSelectionEvent e)
- {
- valueChangedPerformed(e);
- }
- });
- tree.setSelectionPath(new TreePath(((
- (DefaultTreeModel)tree.getModel()).getPathToRoot(previous))));
- topPanel.add(tree, BorderLayout.CENTER);
-
- add(topPanel, BorderLayout.NORTH);
-
- // Certificate details pane
- Caret caret = infoTextPane.getCaret();
- if (caret instanceof DefaultCaret)
- {
- ((DefaultCaret) caret).setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
- }
-
- /*
- * Make JEditorPane respect our default font because we will be using it
- * to just display text.
- */
- infoTextPane.putClientProperty(
- JEditorPane.HONOR_DISPLAY_PROPERTIES,
- true);
-
- infoTextPane.setOpaque(false);
- infoTextPane.setEditable(false);
- infoTextPane.setContentType("text/html");
- infoTextPane.setText(toString(certificates[0]));
-
- final JScrollPane certScroll = new JScrollPane(infoTextPane);
- certScroll.setPreferredSize(new Dimension(300, 500));
- add(certScroll, BorderLayout.CENTER);
- }
-
- /**
- * Creates a String representation of the given object.
- * @param certificate to print
- * @return the String representation
- */
- private String toString(Object certificate)
- {
- final StringBuilder sb = new StringBuilder();
- sb.append("<html><body>\n");
-
- if (certificate instanceof X509Certificate)
- {
- renderX509(sb, (X509Certificate) certificate);
- }
- else
- {
- sb.append("<pre>\n");
- sb.append(certificate.toString());
- sb.append("</pre>\n");
- }
-
- sb.append("</body></html>");
- return sb.toString();
- }
-
- /**
- * Appends an HTML representation of the given X509Certificate.
- * @param sb StringBuilder to append to
- * @param certificate to print
- */
- private void renderX509(StringBuilder sb, X509Certificate certificate)
- {
- X500Principal issuer = certificate.getIssuerX500Principal();
- X500Principal subject = certificate.getSubjectX500Principal();
-
- sb.append("<table cellspacing='1' cellpadding='1'>\n");
-
- // subject
- addTitle(sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_TO"));
- try
- {
- for(Rdn name : new LdapName(subject.getName()).getRdns())
- {
- String nameType = name.getType();
- String lblKey = "service.gui.CERT_INFO_" + nameType;
- String lbl = R.getI18NString(lblKey);
-
- if ((lbl == null) || ("!" + lblKey + "!").equals(lbl))
- lbl = nameType;
-
- final String value;
- Object nameValue = name.getValue();
-
- if (nameValue instanceof byte[])
- {
- byte[] nameValueAsByteArray = (byte[]) nameValue;
-
- value
- = getHex(nameValueAsByteArray) + " ("
- + new String(nameValueAsByteArray) + ")";
- }
- else
- value = nameValue.toString();
-
- addField(sb, lbl, value);
- }
- }
- catch (InvalidNameException ine)
- {
- addField(sb, R.getI18NString("service.gui.CERT_INFO_CN"),
- subject.getName());
- }
-
- // issuer
- addTitle(sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_BY"));
- try
- {
- for(Rdn name : new LdapName(issuer.getName()).getRdns())
- {
- String nameType = name.getType();
- String lblKey = "service.gui.CERT_INFO_" + nameType;
- String lbl = R.getI18NString(lblKey);
-
- if ((lbl == null) || ("!" + lblKey + "!").equals(lbl))
- lbl = nameType;
-
- final String value;
- Object nameValue = name.getValue();
-
- if (nameValue instanceof byte[])
- {
- byte[] nameValueAsByteArray = (byte[]) nameValue;
-
- value
- = getHex(nameValueAsByteArray) + " ("
- + new String(nameValueAsByteArray) + ")";
- }
- else
- value = nameValue.toString();
-
- addField(sb, lbl, value);
- }
- }
- catch (InvalidNameException ine)
- {
- addField(sb, R.getI18NString("service.gui.CERT_INFO_CN"),
- issuer.getName());
- }
-
- // validity
- addTitle(sb, R.getI18NString("service.gui.CERT_INFO_VALIDITY"));
- addField(sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_ON"),
- certificate.getNotBefore().toString());
- addField(sb, R.getI18NString("service.gui.CERT_INFO_EXPIRES_ON"),
- certificate.getNotAfter().toString());
-
- addTitle(sb, R.getI18NString("service.gui.CERT_INFO_FINGERPRINTS"));
- try
- {
- String sha1String = getThumbprint(certificate, "SHA1");
- String md5String = getThumbprint(certificate, "MD5");
-
- addField(sb, "SHA1:", sha1String);
- addField(sb, "MD5:", md5String);
- }
- catch (CertificateException e)
- {
- // do nothing as we cannot show this value
- }
-
- addTitle(sb, R.getI18NString("service.gui.CERT_INFO_CERT_DETAILS"));
-
- addField(sb, R.getI18NString("service.gui.CERT_INFO_SER_NUM"),
- certificate.getSerialNumber().toString());
-
- addField(sb, R.getI18NString("service.gui.CERT_INFO_VER"),
- String.valueOf(certificate.getVersion()));
-
- addField(sb, R.getI18NString("service.gui.CERT_INFO_SIGN_ALG"),
- String.valueOf(certificate.getSigAlgName()));
-
- addTitle(sb, R.getI18NString("service.gui.CERT_INFO_PUB_KEY_INFO"));
-
- addField(sb, R.getI18NString("service.gui.CERT_INFO_ALG"),
- certificate.getPublicKey().getAlgorithm());
-
- if(certificate.getPublicKey().getAlgorithm().equals("RSA"))
- {
- RSAPublicKey key = (RSAPublicKey)certificate.getPublicKey();
-
- addField(sb, R.getI18NString("service.gui.CERT_INFO_PUB_KEY"),
- R.getI18NString(
- "service.gui.CERT_INFO_KEY_BYTES_PRINT",
- new String[]{
- String.valueOf(key.getModulus().toByteArray().length-1),
- key.getModulus().toString(16)
- }));
-
- addField(sb, R.getI18NString("service.gui.CERT_INFO_EXP"),
- key.getPublicExponent().toString());
-
- addField(sb, R.getI18NString("service.gui.CERT_INFO_KEY_SIZE"),
- R.getI18NString(
- "service.gui.CERT_INFO_KEY_BITS_PRINT",
- new String[]{
- String.valueOf(key.getModulus().bitLength())}));
- }
- else if(certificate.getPublicKey().getAlgorithm().equals("DSA"))
- {
- DSAPublicKey key =
- (DSAPublicKey)certificate.getPublicKey();
-
- addField(sb, "Y:", key.getY().toString(16));
- }
-
- addField(sb, R.getI18NString("service.gui.CERT_INFO_SIGN"),
- R.getI18NString(
- "service.gui.CERT_INFO_KEY_BYTES_PRINT",
- new String[]{
- String.valueOf(certificate.getSignature().length),
- getHex(certificate.getSignature())
- }));
-
- sb.append("</table>\n");
- }
-
- /**
- * Add a title.
- *
- * @param sb StringBuilder to append to
- * @param title to print
- */
- private void addTitle(StringBuilder sb, String title)
- {
- sb.append("<tr><td colspan='2'")
- .append(" style='margin-top: 5pt; white-space: nowrap'><p><b>")
- .append(title).append("</b></p></td></tr>\n");
- }
-
- /**
- * Add a field.
- * @param sb StringBuilder to append to
- * @param field name of the certificate field
- * @param value to print
- */
- private void addField(StringBuilder sb, String field, String value)
- {
- sb.append("<tr>")
- .append("<td style='margin-left: 5pt; margin-right: 25pt;")
- .append(" white-space: nowrap'>")
- .append(field).append("</td>")
- .append("<td>").append(value).append("</td>")
- .append("</tr>\n");
- }
-
- /**
- * Converts the byte array to hex string.
- * @param raw the data.
- * @return the hex string.
- */
- private String getHex( byte [] raw )
- {
- if (raw == null)
- return null;
-
- StringBuilder hex = new StringBuilder(2 * raw.length);
- Formatter f = new Formatter(hex);
- try
- {
- for (byte b : raw)
- f.format("%02x", b);
- }
- finally
- {
- f.close();
- }
- return hex.toString();
- }
-
- /**
- * Calculates the hash of the certificate known as the "thumbprint"
- * and returns it as a string representation.
- *
- * @param cert The certificate to hash.
- * @param algorithm The hash algorithm to use.
- * @return The SHA-1 hash of the certificate.
- * @throws CertificateException
- */
- private static String getThumbprint(X509Certificate cert, String algorithm)
- throws CertificateException
- {
- MessageDigest digest;
- try
- {
- digest = MessageDigest.getInstance(algorithm);
- }
- catch (NoSuchAlgorithmException e)
- {
- throw new CertificateException(e);
- }
- byte[] encodedCert = cert.getEncoded();
- StringBuilder sb = new StringBuilder(encodedCert.length * 2);
- Formatter f = new Formatter(sb);
- try
- {
- for (byte b : digest.digest(encodedCert))
- f.format("%02x", b);
- }
- finally
- {
- f.close();
- }
- return sb.toString();
- }
-
- /**
- * Construct a "simplified name" based on the subject DN from the
- * certificate. The purpose is to have something shorter to display in the
- * list. The name used is one of the following DN parts, if
- * available, otherwise the complete DN:
- * 'CN', 'OU' or else 'O'.
- * @param cert to read subject DN from
- * @return the simplified name
- */
- private static String getSimplifiedName(X509Certificate cert)
- {
- final HashMap<String, String> parts = new HashMap<String, String>();
- try
- {
- for (Rdn name : new LdapName(
- cert.getSubjectX500Principal().getName()).getRdns())
- {
- if (name.getType() != null && name.getValue() != null)
- {
- parts.put(name.getType(), name.getValue().toString());
- }
- }
- }
- catch (InvalidNameException ignored) // NOPMD
- {
- }
-
- String result = parts.get("CN");
- if (result == null)
- {
- result = parts.get("OU");
- }
- if (result == null)
- {
- result = parts.get("O");
- }
- if (result == null)
- {
- result = cert.getSubjectX500Principal().getName();
- }
- return result;
- }
-
- /**
- * Called when the selection changed in the tree.
- * Loads the selected certificate.
- * @param e the event
- */
- private void valueChangedPerformed(TreeSelectionEvent e)
- {
- Object o = e.getNewLeadSelectionPath().getLastPathComponent();
- if (o instanceof DefaultMutableTreeNode)
- {
- DefaultMutableTreeNode node = (DefaultMutableTreeNode) o;
- infoTextPane.setText(toString(node.getUserObject()));
- }
- }
-}
+package net.java.sip.communicator.plugin.desktoputil;
+
+import java.awt.*;
+import java.security.*;
+import java.security.cert.*;
+import java.security.cert.Certificate;
+import java.security.interfaces.*;
+import java.util.*;
+
+import javax.naming.*;
+import javax.naming.ldap.*;
+import javax.security.auth.x500.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import javax.swing.text.*;
+import javax.swing.tree.*;
+
+import org.jitsi.service.resources.*;
+
+/**
+ * Panel that shows the content of an X509Certificate.
+ */
+public class X509CertificatePanel
+ extends TransparentPanel
+{
+ private static final long serialVersionUID = -8368302061995971947L;
+
+ private final JEditorPane infoTextPane = new JEditorPane();
+
+ private final ResourceManagementService R
+ = DesktopUtilActivator.getResources();
+
+ /**
+ * Constructs a X509 certificate panel from a single certificate.
+ * If a chain is available instead use the second constructor.
+ * This constructor is kept for backwards compatibility and for convenience
+ * when there is only one certificate of interest.
+ *
+ * @param certificate <tt>X509Certificate</tt> object
+ */
+ public X509CertificatePanel(Certificate certificate)
+ {
+ this(new Certificate[]
+ {
+ certificate
+ });
+ }
+
+ /**
+ * Constructs a X509 certificate panel.
+ *
+ * @param certificates <tt>X509Certificate</tt> objects
+ */
+ public X509CertificatePanel(Certificate[] certificates)
+ {
+ setLayout(new BorderLayout(5, 5));
+
+ // Certificate chain list
+ TransparentPanel topPanel = new TransparentPanel(new BorderLayout());
+ topPanel.add(new JLabel("<html><body><b>"
+ + R.getI18NString("service.gui.CERT_INFO_CHAIN")
+ + "</b></body></html>"), BorderLayout.NORTH);
+
+ DefaultMutableTreeNode top = new DefaultMutableTreeNode();
+ DefaultMutableTreeNode previous = top;
+ for (int i = certificates.length - 1; i >= 0; i--)
+ {
+ Certificate cert = certificates[i];
+ DefaultMutableTreeNode next = new DefaultMutableTreeNode(cert);
+ previous.add(next);
+ previous = next;
+ }
+ JTree tree = new JTree(top);
+ tree.setBorder(new BevelBorder(BevelBorder.LOWERED));
+ tree.setRootVisible(false);
+ tree.setExpandsSelectedPaths(true);
+ tree.getSelectionModel().setSelectionMode(
+ TreeSelectionModel.SINGLE_TREE_SELECTION);
+ tree.setCellRenderer(new DefaultTreeCellRenderer()
+ {
+
+ @Override
+ public Component getTreeCellRendererComponent(JTree tree,
+ Object value, boolean sel, boolean expanded, boolean leaf,
+ int row, boolean hasFocus)
+ {
+ JLabel component = (JLabel) super.getTreeCellRendererComponent(
+ tree, value, sel, expanded, leaf, row, hasFocus);
+ if (value instanceof DefaultMutableTreeNode)
+ {
+ Object o = ((DefaultMutableTreeNode) value).getUserObject();
+ if (o instanceof X509Certificate)
+ {
+ component.setText(
+ getSimplifiedName((X509Certificate) o));
+ }
+ else
+ {
+ // We don't know how to represent this certificate type,
+ // let's use the first 20 characters
+ String text = o.toString();
+ if (text.length() > 20)
+ {
+ text = text.substring(0, 20);
+ }
+ component.setText(text);
+ }
+ }
+ return component;
+ }
+
+ });
+ tree.getSelectionModel().addTreeSelectionListener(
+ new TreeSelectionListener()
+ {
+
+ @Override
+ public void valueChanged(TreeSelectionEvent e)
+ {
+ valueChangedPerformed(e);
+ }
+ });
+ tree.setSelectionPath(new TreePath(((
+ (DefaultTreeModel)tree.getModel()).getPathToRoot(previous))));
+ topPanel.add(tree, BorderLayout.CENTER);
+
+ add(topPanel, BorderLayout.NORTH);
+
+ // Certificate details pane
+ Caret caret = infoTextPane.getCaret();
+ if (caret instanceof DefaultCaret)
+ {
+ ((DefaultCaret) caret).setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
+ }
+
+ /*
+ * Make JEditorPane respect our default font because we will be using it
+ * to just display text.
+ */
+ infoTextPane.putClientProperty(
+ JEditorPane.HONOR_DISPLAY_PROPERTIES,
+ true);
+
+ infoTextPane.setOpaque(false);
+ infoTextPane.setEditable(false);
+ infoTextPane.setContentType("text/html");
+ infoTextPane.setText(toString(certificates[0]));
+
+ final JScrollPane certScroll = new JScrollPane(infoTextPane);
+ certScroll.setPreferredSize(new Dimension(300, 500));
+ add(certScroll, BorderLayout.CENTER);
+ }
+
+ /**
+ * Creates a String representation of the given object.
+ * @param certificate to print
+ * @return the String representation
+ */
+ private String toString(Object certificate)
+ {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("<html><body>\n");
+
+ if (certificate instanceof X509Certificate)
+ {
+ renderX509(sb, (X509Certificate) certificate);
+ }
+ else
+ {
+ sb.append("<pre>\n");
+ sb.append(certificate.toString());
+ sb.append("</pre>\n");
+ }
+
+ sb.append("</body></html>");
+ return sb.toString();
+ }
+
+ /**
+ * Appends an HTML representation of the given X509Certificate.
+ * @param sb StringBuilder to append to
+ * @param certificate to print
+ */
+ private void renderX509(StringBuilder sb, X509Certificate certificate)
+ {
+ X500Principal issuer = certificate.getIssuerX500Principal();
+ X500Principal subject = certificate.getSubjectX500Principal();
+
+ sb.append("<table cellspacing='1' cellpadding='1'>\n");
+
+ // subject
+ addTitle(sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_TO"));
+ try
+ {
+ for(Rdn name : new LdapName(subject.getName()).getRdns())
+ {
+ String nameType = name.getType();
+ String lblKey = "service.gui.CERT_INFO_" + nameType;
+ String lbl = R.getI18NString(lblKey);
+
+ if ((lbl == null) || ("!" + lblKey + "!").equals(lbl))
+ lbl = nameType;
+
+ final String value;
+ Object nameValue = name.getValue();
+
+ if (nameValue instanceof byte[])
+ {
+ byte[] nameValueAsByteArray = (byte[]) nameValue;
+
+ value
+ = getHex(nameValueAsByteArray) + " ("
+ + new String(nameValueAsByteArray) + ")";
+ }
+ else
+ value = nameValue.toString();
+
+ addField(sb, lbl, value);
+ }
+ }
+ catch (InvalidNameException ine)
+ {
+ addField(sb, R.getI18NString("service.gui.CERT_INFO_CN"),
+ subject.getName());
+ }
+
+ // issuer
+ addTitle(sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_BY"));
+ try
+ {
+ for(Rdn name : new LdapName(issuer.getName()).getRdns())
+ {
+ String nameType = name.getType();
+ String lblKey = "service.gui.CERT_INFO_" + nameType;
+ String lbl = R.getI18NString(lblKey);
+
+ if ((lbl == null) || ("!" + lblKey + "!").equals(lbl))
+ lbl = nameType;
+
+ final String value;
+ Object nameValue = name.getValue();
+
+ if (nameValue instanceof byte[])
+ {
+ byte[] nameValueAsByteArray = (byte[]) nameValue;
+
+ value
+ = getHex(nameValueAsByteArray) + " ("
+ + new String(nameValueAsByteArray) + ")";
+ }
+ else
+ value = nameValue.toString();
+
+ addField(sb, lbl, value);
+ }
+ }
+ catch (InvalidNameException ine)
+ {
+ addField(sb, R.getI18NString("service.gui.CERT_INFO_CN"),
+ issuer.getName());
+ }
+
+ // validity
+ addTitle(sb, R.getI18NString("service.gui.CERT_INFO_VALIDITY"));
+ addField(sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_ON"),
+ certificate.getNotBefore().toString());
+ addField(sb, R.getI18NString("service.gui.CERT_INFO_EXPIRES_ON"),
+ certificate.getNotAfter().toString());
+
+ addTitle(sb, R.getI18NString("service.gui.CERT_INFO_FINGERPRINTS"));
+ try
+ {
+ String sha256String = getThumbprint(certificate, "SHA-256");
+ String sha1String = getThumbprint(certificate, "SHA1");
+
+ addField(sb, "SHA256:", sha256String, 48);
+ addField(sb, "SHA1:", sha1String, 72);
+ }
+ catch (CertificateException e)
+ {
+ // do nothing as we cannot show this value
+ }
+
+ addTitle(sb, R.getI18NString("service.gui.CERT_INFO_CERT_DETAILS"));
+
+ addField(sb, R.getI18NString("service.gui.CERT_INFO_SER_NUM"),
+ certificate.getSerialNumber().toString());
+
+ addField(sb, R.getI18NString("service.gui.CERT_INFO_VER"),
+ String.valueOf(certificate.getVersion()));
+
+ addField(sb, R.getI18NString("service.gui.CERT_INFO_SIGN_ALG"),
+ String.valueOf(certificate.getSigAlgName()));
+
+ addTitle(sb, R.getI18NString("service.gui.CERT_INFO_PUB_KEY_INFO"));
+
+ addField(sb, R.getI18NString("service.gui.CERT_INFO_ALG"),
+ certificate.getPublicKey().getAlgorithm());
+
+ if(certificate.getPublicKey().getAlgorithm().equals("RSA"))
+ {
+ RSAPublicKey key = (RSAPublicKey)certificate.getPublicKey();
+
+ addField(sb,
+ R.getI18NString("service.gui.CERT_INFO_PUB_KEY"),
+ R.getI18NString("service.gui.CERT_INFO_KEY_BITS_PRINT",
+ new String[]{
+ String.valueOf(
+ (key.getModulus().toByteArray().length-1)*8)
+ }),
+ getHex(key.getModulus().toByteArray()),
+ 48);
+
+ addField(sb, R.getI18NString("service.gui.CERT_INFO_EXP"),
+ key.getPublicExponent().toString());
+
+ addField(sb, R.getI18NString("service.gui.CERT_INFO_KEY_SIZE"),
+ R.getI18NString(
+ "service.gui.CERT_INFO_KEY_BITS_PRINT",
+ new String[]{
+ String.valueOf(key.getModulus().bitLength())}));
+ }
+ else if(certificate.getPublicKey().getAlgorithm().equals("DSA"))
+ {
+ DSAPublicKey key =
+ (DSAPublicKey)certificate.getPublicKey();
+
+ addField(sb, "Y:", key.getY().toString(16));
+ }
+
+ addField(sb, R.getI18NString("service.gui.CERT_INFO_SIGN"),
+ R.getI18NString(
+ "service.gui.CERT_INFO_KEY_BITS_PRINT",
+ new String[]{
+ String.valueOf(certificate.getSignature().length*8),
+ }),
+ getHex(certificate.getSignature()),
+ 48);
+
+ sb.append("</table>\n");
+ }
+
+ /**
+ * Add a title.
+ *
+ * @param sb StringBuilder to append to
+ * @param title to print
+ */
+ private void addTitle(StringBuilder sb, String title)
+ {
+ sb.append("<tr><td colspan='2'")
+ .append(" style='margin-top: 5pt; white-space: nowrap'><p><b>")
+ .append(title).append("</b></p></td></tr>\n");
+ }
+
+ /**
+ * Add a field.
+ * @param sb StringBuilder to append to
+ * @param field name of the certificate field
+ * @param value to print
+ */
+ private void addField(StringBuilder sb, String field, String value)
+ {
+ addField(sb, field, value, null, 0);
+ }
+
+ /**
+ * Add a field.
+ * @param sb StringBuilder to append to
+ * @param field name of the certificate field
+ * @param value to print
+ * @param wrap force-wrap after number of characters
+ */
+ private void addField(StringBuilder sb, String field, String value,
+ int wrap)
+ {
+ addField(sb, field, value, null, wrap);
+ }
+
+ /**
+ * Add a field.
+ * @param sb StringBuilder to append to
+ * @param field name of the certificate field
+ * @param value to print (not wrapped)
+ * @param otherValue second line of value to print (wrapped)
+ * @param wrap force-wrap after number of characters
+ */
+ private void addField(StringBuilder sb, String field, String value,
+ String otherValue, int wrap)
+ {
+ sb.append("<tr><td style='margin-left: 5pt; margin-right: 25pt;")
+ .append("white-space: nowrap' valign='top'>")
+ .append(field).append("</td><td><span");
+
+ if (otherValue != null)
+ {
+ sb.append('>').append(value).append("</span><br/><span");
+ value = otherValue;
+ }
+
+ if (wrap > 0)
+ {
+ sb.append(" style='font-family:monospace'>");
+ for (int i = 0; i < value.length(); i++)
+ {
+ if (i % wrap == 0 && i > 0)
+ {
+ sb.append("<br/>");
+ }
+
+ sb.append(value.charAt(i));
+ }
+ }
+ else
+ {
+ sb.append(">");
+ sb.append(value);
+ }
+
+ sb.append("</span></td></tr>");
+ }
+
+ /**
+ * Converts the byte array to hex string.
+ * @param raw the data.
+ * @return the hex string.
+ */
+ private String getHex( byte [] raw )
+ {
+ if (raw == null)
+ return null;
+
+ StringBuilder hex = new StringBuilder(2 * raw.length);
+ Formatter f = new Formatter(hex);
+ try
+ {
+ for (byte b : raw)
+ f.format("%02X:", b);
+ }
+ finally
+ {
+ f.close();
+ }
+ return hex.substring(0, hex.length() - 1);
+ }
+
+ /**
+ * Calculates the hash of the certificate known as the "thumbprint"
+ * and returns it as a string representation.
+ *
+ * @param cert The certificate to hash.
+ * @param algorithm The hash algorithm to use.
+ * @return The SHA-1 hash of the certificate.
+ * @throws CertificateException
+ */
+ private static String getThumbprint(X509Certificate cert, String algorithm)
+ throws CertificateException
+ {
+ MessageDigest digest;
+ try
+ {
+ digest = MessageDigest.getInstance(algorithm);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new CertificateException(e);
+ }
+
+ byte[] encodedCert = cert.getEncoded();
+ StringBuilder sb = new StringBuilder(encodedCert.length * 2);
+ Formatter f = new Formatter(sb);
+ try
+ {
+ for (byte b : digest.digest(encodedCert))
+ f.format("%02X:", b);
+ }
+ finally
+ {
+ f.close();
+ }
+
+ return sb.substring(0, sb.length() - 1);
+ }
+
+ /**
+ * Construct a "simplified name" based on the subject DN from the
+ * certificate. The purpose is to have something shorter to display in the
+ * list. The name used is one of the following DN parts, if
+ * available, otherwise the complete DN:
+ * 'CN', 'OU' or else 'O'.
+ * @param cert to read subject DN from
+ * @return the simplified name
+ */
+ private static String getSimplifiedName(X509Certificate cert)
+ {
+ final HashMap<String, String> parts = new HashMap<String, String>();
+ try
+ {
+ for (Rdn name : new LdapName(
+ cert.getSubjectX500Principal().getName()).getRdns())
+ {
+ if (name.getType() != null && name.getValue() != null)
+ {
+ parts.put(name.getType(), name.getValue().toString());
+ }
+ }
+ }
+ catch (InvalidNameException ignored) // NOPMD
+ {
+ }
+
+ String result = parts.get("CN");
+ if (result == null)
+ {
+ result = parts.get("OU");
+ }
+ if (result == null)
+ {
+ result = parts.get("O");
+ }
+ if (result == null)
+ {
+ result = cert.getSubjectX500Principal().getName();
+ }
+ return result;
+ }
+
+ /**
+ * Called when the selection changed in the tree.
+ * Loads the selected certificate.
+ * @param e the event
+ */
+ private void valueChangedPerformed(TreeSelectionEvent e)
+ {
+ Object o = e.getNewLeadSelectionPath().getLastPathComponent();
+ if (o instanceof DefaultMutableTreeNode)
+ {
+ DefaultMutableTreeNode node = (DefaultMutableTreeNode) o;
+ infoTextPane.setText(toString(node.getUserObject()));
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/desktoputil/chat/ChatRoomDestroyReasonDialog.java b/src/net/java/sip/communicator/plugin/desktoputil/chat/ChatRoomDestroyReasonDialog.java
index 443171b..ad05797 100644
--- a/src/net/java/sip/communicator/plugin/desktoputil/chat/ChatRoomDestroyReasonDialog.java
+++ b/src/net/java/sip/communicator/plugin/desktoputil/chat/ChatRoomDestroyReasonDialog.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,175 +15,175 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.desktoputil.chat;
-
-import java.awt.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.resources.*;
-
-/**
- * Dialog with fields for reason and alternate address.
- *
- * @author Hristo Terezov
- */
-public class ChatRoomDestroyReasonDialog extends MessageDialog
-{
- /**
- * The <tt>Logger</tt> used by the <tt>ChatRoomDestroyReasonDialog</tt>
- * class and its instances for logging output.
- */
- private static Logger logger
- = Logger.getLogger(ChatRoomDestroyReasonDialog.class);
-
- /**
- * Serial id.
- */
- private static final long serialVersionUID = -916498752420264164L;
-
- /**
- * Text field for the alternate address.
- */
- private SIPCommTextField alternateAddress
- = new SIPCommTextField("chatroom@example.com");
-
- /**
- * Text field for reason text.
- */
- private JTextField reasonField = new JTextField();
-
- /**
- * Constructs new chat room destroy dialog.
- *
- * @param title the title of the dialog
- * @param message the message shown in this dialog
- */
- public ChatRoomDestroyReasonDialog(String title, String message)
- {
- super(null, title, message,
- DesktopUtilActivator.getResources().getI18NString("service.gui.OK"),
- false);
- this.setIcon((ImageIcon)null);
-
- alternateAddress.setFont(alternateAddress.getFont().deriveFont(12f));
-
- JLabel altAddressLabel
- = new JLabel(DesktopUtilActivator.getResources()
- .getI18NString("service.gui.ALTERNATE_ADDRESS") + ":");
-
- JLabel reasonLabel
- = new JLabel(DesktopUtilActivator.getResources()
- .getI18NString("service.gui.REASON") + ":");
-
- JPanel labelsPanel = new JPanel(new GridLayout(2, 1));
- labelsPanel.add(reasonLabel);
- labelsPanel.add(altAddressLabel);
-
- JPanel valuesPanel = new JPanel(new GridLayout(2, 1));
- valuesPanel.add(reasonField);
- valuesPanel.add(alternateAddress);
-
- JPanel fieldsPanel = new JPanel(new BorderLayout());
- fieldsPanel .add(labelsPanel, BorderLayout.WEST);
-
- fieldsPanel.add(valuesPanel, BorderLayout.CENTER);
- fieldsPanel.add(new JLabel(" "), BorderLayout.EAST);
- fieldsPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
- fieldsPanel.setOpaque(false);
-
-
-
- replaceCheckBoxPanel(fieldsPanel);
- this.pack();
- }
-
- /**
- * Returns the text entered in the alternate address field.
- *
- * @return the text from the alternate address field.
- */
- public String getAlternateAddress()
- {
- return alternateAddress.getText();
- }
-
- /**
- * Returns the text entered in the reason field.
- *
- * @return the text from the reason field.
- */
- public String getReason()
- {
- return reasonField.getText();
- }
-
- /**
- * Opens a dialog with a fields for the reason and alternate address and
- * returns them.
- *
- * @return array with the reason and alternate address values.
- */
- public static String[] getDestroyOptions()
- {
- final ChatRoomDestroyReasonDialog[] res
- = new ChatRoomDestroyReasonDialog[1];
-
- try
- {
- SwingUtilities.invokeAndWait(new Runnable()
- {
- @Override
- public void run()
- {
- ResourceManagementService R
- = DesktopUtilActivator.getResources();
-
- res[0] = new ChatRoomDestroyReasonDialog(
- R.getI18NString("service.gui.DESTROY_CHATROOM"),
- R.getI18NString("service.gui.DESTROY_MESSAGE"));
- }
- });
- }
- catch(Throwable t)
- {
- logger.error("Error creating dialog", t);
- return null;
- }
-
- ChatRoomDestroyReasonDialog reasonDialog = res[0];
-
- int result = reasonDialog.showDialog();
-
- String destroyOptions[] = new String[2];
-
- if (result == MessageDialog.OK_RETURN_CODE)
- {
- destroyOptions[0] = proccessFieldValues(reasonDialog.getReason());
- destroyOptions[1]
- = proccessFieldValues(reasonDialog.getAlternateAddress());
- }
- else
- {
- destroyOptions = null;
- }
-
-
- return destroyOptions;
- }
-
- private static String proccessFieldValues(String value)
- {
- if(value != null)
- {
- value = value.trim();
- if(value.equals(""))
- value = null;
- }
- return value;
- }
-
-}
+package net.java.sip.communicator.plugin.desktoputil.chat;
+
+import java.awt.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.resources.*;
+
+/**
+ * Dialog with fields for reason and alternate address.
+ *
+ * @author Hristo Terezov
+ */
+public class ChatRoomDestroyReasonDialog extends MessageDialog
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>ChatRoomDestroyReasonDialog</tt>
+ * class and its instances for logging output.
+ */
+ private static Logger logger
+ = Logger.getLogger(ChatRoomDestroyReasonDialog.class);
+
+ /**
+ * Serial id.
+ */
+ private static final long serialVersionUID = -916498752420264164L;
+
+ /**
+ * Text field for the alternate address.
+ */
+ private SIPCommTextField alternateAddress
+ = new SIPCommTextField("chatroom@example.com");
+
+ /**
+ * Text field for reason text.
+ */
+ private JTextField reasonField = new JTextField();
+
+ /**
+ * Constructs new chat room destroy dialog.
+ *
+ * @param title the title of the dialog
+ * @param message the message shown in this dialog
+ */
+ public ChatRoomDestroyReasonDialog(String title, String message)
+ {
+ super(null, title, message,
+ DesktopUtilActivator.getResources().getI18NString("service.gui.OK"),
+ false);
+ this.setIcon((ImageIcon)null);
+
+ alternateAddress.setFont(alternateAddress.getFont().deriveFont(12f));
+
+ JLabel altAddressLabel
+ = new JLabel(DesktopUtilActivator.getResources()
+ .getI18NString("service.gui.ALTERNATE_ADDRESS") + ":");
+
+ JLabel reasonLabel
+ = new JLabel(DesktopUtilActivator.getResources()
+ .getI18NString("service.gui.REASON") + ":");
+
+ JPanel labelsPanel = new JPanel(new GridLayout(2, 1));
+ labelsPanel.add(reasonLabel);
+ labelsPanel.add(altAddressLabel);
+
+ JPanel valuesPanel = new JPanel(new GridLayout(2, 1));
+ valuesPanel.add(reasonField);
+ valuesPanel.add(alternateAddress);
+
+ JPanel fieldsPanel = new JPanel(new BorderLayout());
+ fieldsPanel .add(labelsPanel, BorderLayout.WEST);
+
+ fieldsPanel.add(valuesPanel, BorderLayout.CENTER);
+ fieldsPanel.add(new JLabel(" "), BorderLayout.EAST);
+ fieldsPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ fieldsPanel.setOpaque(false);
+
+
+
+ replaceCheckBoxPanel(fieldsPanel);
+ this.pack();
+ }
+
+ /**
+ * Returns the text entered in the alternate address field.
+ *
+ * @return the text from the alternate address field.
+ */
+ public String getAlternateAddress()
+ {
+ return alternateAddress.getText();
+ }
+
+ /**
+ * Returns the text entered in the reason field.
+ *
+ * @return the text from the reason field.
+ */
+ public String getReason()
+ {
+ return reasonField.getText();
+ }
+
+ /**
+ * Opens a dialog with a fields for the reason and alternate address and
+ * returns them.
+ *
+ * @return array with the reason and alternate address values.
+ */
+ public static String[] getDestroyOptions()
+ {
+ final ChatRoomDestroyReasonDialog[] res
+ = new ChatRoomDestroyReasonDialog[1];
+
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ ResourceManagementService R
+ = DesktopUtilActivator.getResources();
+
+ res[0] = new ChatRoomDestroyReasonDialog(
+ R.getI18NString("service.gui.DESTROY_CHATROOM"),
+ R.getI18NString("service.gui.DESTROY_MESSAGE"));
+ }
+ });
+ }
+ catch(Throwable t)
+ {
+ logger.error("Error creating dialog", t);
+ return null;
+ }
+
+ ChatRoomDestroyReasonDialog reasonDialog = res[0];
+
+ int result = reasonDialog.showDialog();
+
+ String destroyOptions[] = new String[2];
+
+ if (result == MessageDialog.OK_RETURN_CODE)
+ {
+ destroyOptions[0] = proccessFieldValues(reasonDialog.getReason());
+ destroyOptions[1]
+ = proccessFieldValues(reasonDialog.getAlternateAddress());
+ }
+ else
+ {
+ destroyOptions = null;
+ }
+
+
+ return destroyOptions;
+ }
+
+ private static String proccessFieldValues(String value)
+ {
+ if(value != null)
+ {
+ value = value.trim();
+ if(value.equals(""))
+ value = null;
+ }
+ return value;
+ }
+
+}
diff --git a/src/net/java/sip/communicator/plugin/desktoputil/chat/ChatRoomJoinOptionsDialog.java b/src/net/java/sip/communicator/plugin/desktoputil/chat/ChatRoomJoinOptionsDialog.java
index 88a5327..db04c56 100644
--- a/src/net/java/sip/communicator/plugin/desktoputil/chat/ChatRoomJoinOptionsDialog.java
+++ b/src/net/java/sip/communicator/plugin/desktoputil/chat/ChatRoomJoinOptionsDialog.java
@@ -1,4 +1,4 @@
-/**
+/**
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,174 +15,174 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.desktoputil.chat;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-import javax.swing.border.*;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Dialog with fields for nickname and subject.
- *
- * @author Hristo Terezov
- */
-public class ChatRoomJoinOptionsDialog extends ChatOperationReasonDialog
-{
- /**
- * Serial id.
- */
- private static final long serialVersionUID = -916498752420264164L;
-
- /**
- * Text field for the subject.
- */
- private SIPCommTextField subject = new SIPCommTextField(DesktopUtilActivator
- .getResources().getI18NString("service.gui.SUBJECT"));
-
- /**
- * Label that hides and shows the subject fields panel on click.
- */
- private JLabel cmdExpandSubjectFields;
-
- /**
- * Panel that holds the subject fields.
- */
- private JPanel subjectFieldsPannel = new JPanel(new BorderLayout());
-
- /**
- * Adds the subject fields to dialog. Sets action listeners.
- *
- * @param title the title of the dialog
- * @param message the message shown in this dialog
- * @param disableOKIfReasonIsEmpty if true the OK button will be
- * disabled if the reason text is empty.
- * @param showReasonLabel specify if we want the "Reason:" label
- * @param dontDisplaySubjectFields if true the sibject fields will be
- * hidden.
- */
- public ChatRoomJoinOptionsDialog(String title, String message,
- boolean showReasonLabel,
- boolean disableOKIfReasonIsEmpty,
- boolean dontDisplaySubjectFields)
- {
- super(title,
- message,
- showReasonLabel,
- disableOKIfReasonIsEmpty);
-
- if(dontDisplaySubjectFields)
- return;
-
- JPanel subjectPanel = new JPanel(new BorderLayout());
- subjectPanel.setOpaque(false);
- subjectPanel.setBorder(
- BorderFactory.createEmptyBorder(10, 0, 0, 0));
-
- subjectFieldsPannel.setBorder(
- BorderFactory.createEmptyBorder(10, 30, 0, 0));
- subjectFieldsPannel.setOpaque(false);
- subjectFieldsPannel.add(subject, BorderLayout.CENTER);
- subjectFieldsPannel.setVisible(false);
- subject.setFont(getFont().deriveFont(12f));
-
- cmdExpandSubjectFields = new JLabel();
- cmdExpandSubjectFields.setBorder(new EmptyBorder(0, 5, 0, 0));
- cmdExpandSubjectFields.setIcon(DesktopUtilActivator.getResources()
- .getImage("service.gui.icons.RIGHT_ARROW_ICON"));
- cmdExpandSubjectFields.setText(DesktopUtilActivator
- .getResources().getI18NString("service.gui.SET_SUBJECT"));
- cmdExpandSubjectFields.addMouseListener(new MouseAdapter()
- {
- @Override
- public void mouseClicked(MouseEvent e)
- {
- cmdExpandSubjectFields.setIcon(
- UtilActivator.getResources().getImage(
- subjectFieldsPannel.isVisible()
- ? "service.gui.icons.RIGHT_ARROW_ICON"
- : "service.gui.icons.DOWN_ARROW_ICON"));
-
- subjectFieldsPannel.setVisible(
- !subjectFieldsPannel.isVisible());
-
- pack();
- }
- });
- subjectPanel.add(cmdExpandSubjectFields,BorderLayout.NORTH);
- subjectPanel.add(subjectFieldsPannel,BorderLayout.CENTER);
- addToReasonFieldPannel(subjectPanel);
- this.pack();
- }
-
- /**
- * Returns the text entered in the subject field.
- *
- * @return the text from the subject field.
- */
- public String getSubject()
- {
- return subject.getText();
- }
-
- /**
- * Opens a dialog with a fields for the nickname and the subject of the room
- * and returns them.
- *
- * @param pps the protocol provider associated with the chat room.
- * @param chatRoomId the id of the chat room.
- * @param defaultNickname the nickname to show if any
- * @return array with the nickname and subject values.
- */
- public static String[] getJoinOptions(ProtocolProviderService pps,
- String chatRoomId, String defaultNickname)
- {
- return getJoinOptions(false, pps, chatRoomId, defaultNickname);
- }
-
- /**
- * Opens a dialog with a fields for the nickname and the subject of the room
- * and returns them.
- *
- * @param dontDisplaySubjectFields if true the subject fields will be hidden
- * @param pps the protocol provider associated with the chat room.
- * @param chatRoomId the id of the chat room.
- * @param defaultNickname the nickname to show if any
- * @return array with the nickname and subject values.
- */
- public static String[] getJoinOptions(boolean dontDisplaySubjectFields,
- ProtocolProviderService pps, String chatRoomId, String defaultNickname)
- {
- String nickName = null;
- ChatRoomJoinOptionsDialog reasonDialog =
- new ChatRoomJoinOptionsDialog(DesktopUtilActivator.getResources()
- .getI18NString("service.gui.CHANGE_NICKNAME"),
- DesktopUtilActivator.getResources().getI18NString(
- "service.gui.CHANGE_NICKNAME_LABEL"), false, true,
- dontDisplaySubjectFields);
- reasonDialog.setIcon(new ImageIcon(DesktopUtilActivator.getImage(
- "service.gui.icons.CHANGE_NICKNAME_16x16")));
-
- if(defaultNickname != null)
- reasonDialog.setReasonFieldText(defaultNickname);
-
- int result = reasonDialog.showDialog();
-
- if (result == MessageDialog.OK_RETURN_CODE)
- {
- nickName = reasonDialog.getReason().trim();
- ConfigurationUtils.updateChatRoomProperty(
- pps,
- chatRoomId, "userNickName", nickName);
-
- }
- String[] joinOptions = {nickName, reasonDialog.getSubject()};
- return joinOptions;
- }
-
-}
+package net.java.sip.communicator.plugin.desktoputil.chat;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+import javax.swing.border.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Dialog with fields for nickname and subject.
+ *
+ * @author Hristo Terezov
+ */
+public class ChatRoomJoinOptionsDialog extends ChatOperationReasonDialog
+{
+ /**
+ * Serial id.
+ */
+ private static final long serialVersionUID = -916498752420264164L;
+
+ /**
+ * Text field for the subject.
+ */
+ private SIPCommTextField subject = new SIPCommTextField(DesktopUtilActivator
+ .getResources().getI18NString("service.gui.SUBJECT"));
+
+ /**
+ * Label that hides and shows the subject fields panel on click.
+ */
+ private JLabel cmdExpandSubjectFields;
+
+ /**
+ * Panel that holds the subject fields.
+ */
+ private JPanel subjectFieldsPannel = new JPanel(new BorderLayout());
+
+ /**
+ * Adds the subject fields to dialog. Sets action listeners.
+ *
+ * @param title the title of the dialog
+ * @param message the message shown in this dialog
+ * @param disableOKIfReasonIsEmpty if true the OK button will be
+ * disabled if the reason text is empty.
+ * @param showReasonLabel specify if we want the "Reason:" label
+ * @param dontDisplaySubjectFields if true the sibject fields will be
+ * hidden.
+ */
+ public ChatRoomJoinOptionsDialog(String title, String message,
+ boolean showReasonLabel,
+ boolean disableOKIfReasonIsEmpty,
+ boolean dontDisplaySubjectFields)
+ {
+ super(title,
+ message,
+ showReasonLabel,
+ disableOKIfReasonIsEmpty);
+
+ if(dontDisplaySubjectFields)
+ return;
+
+ JPanel subjectPanel = new JPanel(new BorderLayout());
+ subjectPanel.setOpaque(false);
+ subjectPanel.setBorder(
+ BorderFactory.createEmptyBorder(10, 0, 0, 0));
+
+ subjectFieldsPannel.setBorder(
+ BorderFactory.createEmptyBorder(10, 30, 0, 0));
+ subjectFieldsPannel.setOpaque(false);
+ subjectFieldsPannel.add(subject, BorderLayout.CENTER);
+ subjectFieldsPannel.setVisible(false);
+ subject.setFont(getFont().deriveFont(12f));
+
+ cmdExpandSubjectFields = new JLabel();
+ cmdExpandSubjectFields.setBorder(new EmptyBorder(0, 5, 0, 0));
+ cmdExpandSubjectFields.setIcon(DesktopUtilActivator.getResources()
+ .getImage("service.gui.icons.RIGHT_ARROW_ICON"));
+ cmdExpandSubjectFields.setText(DesktopUtilActivator
+ .getResources().getI18NString("service.gui.SET_SUBJECT"));
+ cmdExpandSubjectFields.addMouseListener(new MouseAdapter()
+ {
+ @Override
+ public void mouseClicked(MouseEvent e)
+ {
+ cmdExpandSubjectFields.setIcon(
+ UtilActivator.getResources().getImage(
+ subjectFieldsPannel.isVisible()
+ ? "service.gui.icons.RIGHT_ARROW_ICON"
+ : "service.gui.icons.DOWN_ARROW_ICON"));
+
+ subjectFieldsPannel.setVisible(
+ !subjectFieldsPannel.isVisible());
+
+ pack();
+ }
+ });
+ subjectPanel.add(cmdExpandSubjectFields,BorderLayout.NORTH);
+ subjectPanel.add(subjectFieldsPannel,BorderLayout.CENTER);
+ addToReasonFieldPannel(subjectPanel);
+ this.pack();
+ }
+
+ /**
+ * Returns the text entered in the subject field.
+ *
+ * @return the text from the subject field.
+ */
+ public String getSubject()
+ {
+ return subject.getText();
+ }
+
+ /**
+ * Opens a dialog with a fields for the nickname and the subject of the room
+ * and returns them.
+ *
+ * @param pps the protocol provider associated with the chat room.
+ * @param chatRoomId the id of the chat room.
+ * @param defaultNickname the nickname to show if any
+ * @return array with the nickname and subject values.
+ */
+ public static String[] getJoinOptions(ProtocolProviderService pps,
+ String chatRoomId, String defaultNickname)
+ {
+ return getJoinOptions(false, pps, chatRoomId, defaultNickname);
+ }
+
+ /**
+ * Opens a dialog with a fields for the nickname and the subject of the room
+ * and returns them.
+ *
+ * @param dontDisplaySubjectFields if true the subject fields will be hidden
+ * @param pps the protocol provider associated with the chat room.
+ * @param chatRoomId the id of the chat room.
+ * @param defaultNickname the nickname to show if any
+ * @return array with the nickname and subject values.
+ */
+ public static String[] getJoinOptions(boolean dontDisplaySubjectFields,
+ ProtocolProviderService pps, String chatRoomId, String defaultNickname)
+ {
+ String nickName = null;
+ ChatRoomJoinOptionsDialog reasonDialog =
+ new ChatRoomJoinOptionsDialog(DesktopUtilActivator.getResources()
+ .getI18NString("service.gui.CHANGE_NICKNAME"),
+ DesktopUtilActivator.getResources().getI18NString(
+ "service.gui.CHANGE_NICKNAME_LABEL"), false, true,
+ dontDisplaySubjectFields);
+ reasonDialog.setIcon(new ImageIcon(DesktopUtilActivator.getImage(
+ "service.gui.icons.CHANGE_NICKNAME_16x16")));
+
+ if(defaultNickname != null)
+ reasonDialog.setReasonFieldText(defaultNickname);
+
+ int result = reasonDialog.showDialog();
+
+ if (result == MessageDialog.OK_RETURN_CODE)
+ {
+ nickName = reasonDialog.getReason().trim();
+ ConfigurationUtils.updateChatRoomProperty(
+ pps,
+ chatRoomId, "userNickName", nickName);
+
+ }
+ String[] joinOptions = {nickName, reasonDialog.getSubject()};
+ return joinOptions;
+ }
+
+}
diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccRegWizzActivator.java
deleted file mode 100644
index 7911eeb..0000000
--- a/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccRegWizzActivator.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.dictaccregwizz;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.browserlauncher.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * Registers the <tt>DictAccountRegistrationWizard</tt> in the UI Service.
- *
- * @author ROTH Damien
- * @author LITZELMANN Cedric
- */
-public class DictAccRegWizzActivator
- implements BundleActivator
-{
- /**
- * OSGi bundle context.
- */
- public static BundleContext bundleContext;
-
- private static Logger logger = Logger.getLogger(
- DictAccRegWizzActivator.class);
-
- private static BrowserLauncherService browserLauncherService;
-
- private static WizardContainer wizardContainer;
-
- private static DictAccountRegistrationWizard dictWizard;
-
- private static UIService uiService;
-
- /**
- * Starts this bundle.
- *
- * @param bc The bundle context.
- */
- public void start(BundleContext bc) throws Exception {
-
- bundleContext = bc;
-
- ServiceReference uiServiceRef = bundleContext
- .getServiceReference(UIService.class.getName());
-
- uiService = (UIService) bundleContext.getService(uiServiceRef);
-
- wizardContainer = uiService.getAccountRegWizardContainer();
-
- dictWizard = new DictAccountRegistrationWizard(wizardContainer);
-
- //wizardContainer.addAccountRegistrationWizard(dictWizard);
- Hashtable<String, String> containerFilter
- = new Hashtable<String, String>();
-
- containerFilter.put(
- ProtocolProviderFactory.PROTOCOL,
- ProtocolNames.DICT);
-
- bundleContext.registerService(
- AccountRegistrationWizard.class.getName(),
- dictWizard,
- containerFilter);
- }
-
-
- /**
- * Stops this bundle.
- *
- * @param bundleContext The bundle context (unused).
- *
- * @throws Exception Throws an execption from the
- * "wizardContainer.removeAccountRegistrationWizard" method.
- *
- */
- public void stop(BundleContext bundleContext) throws Exception
- {
- //wizardContainer.removeAccountRegistrationWizard(dictWizard);
- }
-
- /**
- * Returns the <tt>ProtocolProviderFactory</tt> for the Dict protocol.
- * @return the <tt>ProtocolProviderFactory</tt> for the Dict protocol
- */
- public static ProtocolProviderFactory getDictProtocolProviderFactory() {
-
- ServiceReference[] serRefs = null;
-
- String osgiFilter = "("
- + ProtocolProviderFactory.PROTOCOL
- + "="+ProtocolNames.DICT+")";
-
- try {
- serRefs = bundleContext.getServiceReferences(
- ProtocolProviderFactory.class.getName(), osgiFilter);
- }
- catch (InvalidSyntaxException ex){
- logger.error("DictAccRegWizzActivator : " + ex);
- }
-
- return (ProtocolProviderFactory) bundleContext.getService(serRefs[0]);
- }
-
- /**
- * Returns the <tt>BrowserLauncherService</tt> obtained from the bundle
- * context.
- * @return the <tt>BrowserLauncherService</tt> obtained from the bundle
- * context
- */
- public static BrowserLauncherService getBrowserLauncher() {
- if (browserLauncherService == null) {
- ServiceReference serviceReference = bundleContext
- .getServiceReference(BrowserLauncherService.class.getName());
-
- browserLauncherService = (BrowserLauncherService) bundleContext
- .getService(serviceReference);
- }
-
- return browserLauncherService;
- }
-
- /**
- * Returns the <tt>UIService</tt>.
- *
- * @return the <tt>UIService</tt>
- */
- public static UIService getUIService()
- {
- return uiService;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccountRegistration.java b/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccountRegistration.java
deleted file mode 100644
index a7aca60..0000000
--- a/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccountRegistration.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.dictaccregwizz;
-
-import net.java.dict4j.*;
-
-/**
- * The <tt>DictAccountRegistration</tt> is used to store all user input data
- * through the <tt>DictAccountRegistrationWizard</tt>.
- *
- * @author ROTH Damien
- * @author LITZELMANN Cedric
- */
-public class DictAccountRegistration
-{
- private String userID;
-
- /**
- * The hostname of the DICT server.
- */
- private String host;
-
- /**
- * The port of the DICT server.
- */
- private int port;
-
- /**
- * The strategy selected for the matching of words in dictionaries.
- */
- private Strategy strategy;
-
- /**
- * Returns the User ID of the dict registration account.
- * @return the User ID of the dict registration account.
- */
- public String getUserID()
- {
- return userID;
- }
-
- /**
- * Returns the port of the dict registration account.
- * @return the port of the dict registration account.
- */
- public int getPort() {
- return this.port;
- }
-
- /**
- * Sets the port of the dict registration account.
- * @param port the port of the dict registration account.
- */
- public void setPort(int port) {
- this.port = port;
- }
-
- /**
- * Returns the host of the dict registration account.
- * @return the host of the dict registration account.
- */
- public String getHost() {
- return this.host;
- }
-
- /**
- * Sets the host of the dict registration account.
- * @param host The host of the dict registration account.
- */
- public void setHost(String host) {
- this.host = host;
- }
-
- /**
- * Returns the strategy that will be used for this dict account.
- * @return the strategy that will be used for this dict account.
- */
- public Strategy getStrategy() {
- return this.strategy;
- }
-
- /**
- * Sets the strategy for this dict account.
- * @param strategy the strategy for this dict account.
- */
- public void setStrategy(Strategy strategy) {
- this.strategy = strategy;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccountRegistrationWizard.java b/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccountRegistrationWizard.java
deleted file mode 100644
index 115d65c..0000000
--- a/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccountRegistrationWizard.java
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.dictaccregwizz;
-
-import java.awt.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * The <tt>DictAccountRegistrationWizard</tt> is an implementation of the
- * <tt>AccountRegistrationWizard</tt> for the Dict protocol. It should allow
- * the user to create and configure a new Dict account.
- *
- * @author ROTH Damien
- * @author LITZELMANN Cedric
- */
-public class DictAccountRegistrationWizard
- extends DesktopAccountRegistrationWizard
-{
- private final Logger logger
- = Logger.getLogger(DictAccountRegistrationWizard.class);
-
- /**
- * The reference to the first page of the wizard.
- */
- private FirstWizardPage firstWizardPage;
-
- /**
- * The registration of the DICT account.
- */
- private DictAccountRegistration registration = new DictAccountRegistration();
-
- /**
- * The protocole provider.
- */
- private ProtocolProviderService protocolProvider;
-
- /**
- * Creates an instance of <tt>DictAccountRegistrationWizard</tt>.
- *
- * @param wizardContainer the wizard container, where this wizard is added
- */
- public DictAccountRegistrationWizard(WizardContainer wizardContainer)
- {
- setWizardContainer(wizardContainer);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getIcon</code> method.
- * @return Returns the icon to be used for this wizard.
- */
- @Override
- public byte[] getIcon()
- {
- return Resources.getImage(Resources.DICT_LOGO);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getPageImage</code>
- * method. Returns the image used to decorate the wizard page
- *
- * @return byte[] the image used to decorate the wizard page
- */
- @Override
- public byte[] getPageImage()
- {
- return Resources.getImage(Resources.PAGE_IMAGE);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getProtocolName</code>
- * method.
- * @return Returns the protocol name for this wizard.
- */
- @Override
- public String getProtocolName()
- {
- return Resources.getString("plugin.dictaccregwizz.PROTOCOL_NAME");
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getProtocolDescription
- * </code> method.
- * @return Returns the description of the protocol for this wizard.
- */
- @Override
- public String getProtocolDescription()
- {
- return Resources.getString("plugin.dictaccregwizz.PROTOCOL_DESCRIPTION");
- }
-
- /**
- * Returns the set of pages contained in this wizard.
- *
- * @return Returns the set of pages contained in this wizard.
- */
- @Override
- public Iterator<WizardPage> getPages()
- {
- java.util.List<WizardPage> pages = new ArrayList<WizardPage>();
- this.firstWizardPage = new FirstWizardPage(this);
- pages.add(this.firstWizardPage);
- return pages.iterator();
- }
-
- /**
- * Returns the set of data that user has entered through this wizard.
- * @return Returns the set of data that user has entered through this wizard.
- */
- @Override
- public Iterator<Map.Entry<String, String>> getSummary()
- {
- Map<String, String> summaryTable = new LinkedHashMap<String, String>();
-
- summaryTable.put("Host", registration.getHost());
- summaryTable.put("Port", String.valueOf(registration.getPort()));
- summaryTable.put("Strategy", registration.getStrategy().getName());
-
- return summaryTable.entrySet().iterator();
- }
-
- /**
- * Defines the operations that will be executed when the user clicks on
- * the wizard "Signin" button.
- * @return the created <tt>ProtocolProviderService</tt> corresponding to the
- * new account
- * @throws OperationFailedException if the operation didn't succeed
- */
- @Override
- public ProtocolProviderService signin()
- throws OperationFailedException
- {
- firstWizardPage.commitPage();
-
- return signin(registration.getUserID(), null);
- }
-
- /**
- * Defines the operations that will be executed when the user clicks on
- * the wizard "Signin" button.
- *
- * @param userName the user name to sign in with
- * @param password the password to sign in with
- * @return the created <tt>ProtocolProviderService</tt> corresponding to the
- * new account
- * @throws OperationFailedException if the operation didn't succeed
- */
- @Override
- public ProtocolProviderService signin(String userName, String password)
- throws OperationFailedException
- {
- ProtocolProviderFactory factory
- = DictAccRegWizzActivator.getDictProtocolProviderFactory();
-
- return this.installAccount(factory, registration.getHost(),
- registration.getPort(),
- registration.getStrategy().getCode());
- }
-
- /**
- * Creates an account for the given user and password.
- *
- * @param providerFactory the ProtocolProviderFactory which will create the
- * account.
- * @param host The hostname of the DICT server.
- * @param port The port used by the DICT server.
- * @param strategy The strategy choosen for matching words in the
- * dictionnaries.
- * @return the <tt>ProtocolProviderService</tt> for the new account.
- */
- public ProtocolProviderService installAccount(
- ProtocolProviderFactory providerFactory,
- String host,
- int port,
- String strategy)
- throws OperationFailedException
- {
- Hashtable<String, String> accountProperties
- = new Hashtable<String, String>();
-
- accountProperties.put( ProtocolProviderFactory.ACCOUNT_ICON_PATH,
- "resources/images/protocol/dict/dict-32x32.png");
-
- // Set this property to indicate that Dict account does not require
- // authentication.
- accountProperties.put(
- ProtocolProviderFactory.NO_PASSWORD_REQUIRED,
- new Boolean(true).toString());
-
- // Save host
- accountProperties.put(ProtocolProviderFactory.SERVER_ADDRESS, host);
- // Save port
- accountProperties.put( ProtocolProviderFactory.SERVER_PORT,
- String.valueOf(port));
- // Save strategy
- accountProperties.put(ProtocolProviderFactory.STRATEGY, strategy);
-
- if (isModification())
- {
- providerFactory.uninstallAccount(protocolProvider.getAccountID());
- this.protocolProvider = null;
- setModification(false);
- }
-
- try
- {
- String uid = this.generateUID();
- AccountID accountID =
- providerFactory.installAccount(uid, accountProperties);
-
- ServiceReference serRef =
- providerFactory.getProviderForAccount(accountID);
-
- protocolProvider =
- (ProtocolProviderService) DictAccRegWizzActivator.bundleContext
- .getService(serRef);
- }
- catch (IllegalStateException exc)
- {
- logger.warn(exc.getMessage());
-
- throw new OperationFailedException(
- "Account already exists.",
- OperationFailedException.IDENTIFICATION_CONFLICT);
- }
- catch (Exception exc)
- {
- logger.warn(exc.getMessage());
-
- throw new OperationFailedException(
- "Failed to add account",
- OperationFailedException.GENERAL_ERROR);
- }
-
-
- return protocolProvider;
- }
-
- /**
- * Fills the UIN and Password fields in this panel with the data coming
- * from the given protocolProvider.
- *
- * @param protocolProvider The <tt>ProtocolProviderService</tt> to load
- * the data from.
- */
- @Override
- public void loadAccount(ProtocolProviderService protocolProvider)
- {
- setModification(true);
-
- this.protocolProvider = protocolProvider;
-
- this.registration = new DictAccountRegistration();
-
- this.firstWizardPage.loadAccount(protocolProvider);
- }
-
- /**
- * Returns the registration object, which will store all the data through
- * the wizard.
- *
- * @return the registration object, which will store all the data through
- * the wizard
- */
- public DictAccountRegistration getRegistration()
- {
- return registration;
- }
-
- /**
- * Returns the size of this wizard.
- * @return the size of this wizard
- */
- @Override
- public Dimension getSize()
- {
- return new Dimension(300, 150);
- }
-
- /**
- * Returns the identifier of the page to show first in the wizard.
- * @return the identifier of the page to show first in the wizard.
- */
- @Override
- public Object getFirstPageIdentifier()
- {
- return firstWizardPage.getIdentifier();
- }
-
- /**
- * Returns the identifier of the page to show last in the wizard.
- * @return the identifier of the page to show last in the wizard.
- */
- @Override
- public Object getLastPageIdentifier()
- {
- return firstWizardPage.getIdentifier();
- }
-
- /**
- * Generate the UID for the acount
- * @return the new UID
- */
- private String generateUID()
- {
- String uid;
- int nbAccounts = this.getNumberOfAccounts();
- String host = this.registration.getHost();
- int nbAccountsForHost = this.getNbAccountForHost(host);
-
- if (nbAccounts == 0 || (this.isModification() && nbAccounts == 1) ||
- nbAccountsForHost == 0
- || (this.isModification() && nbAccountsForHost == 1))
- {
- // We create the first account or we edit the onlyone
- // Or we create the first account for this server or edit the onlyone
- uid = host;
- }
- else
- {
- uid = host + ":" + this.registration.getPort();
- }
-
- return uid;
- }
-
- /**
- * Returns the number of accounts stored for the protocol
- * @return the number of accounts stored for the protocol
- */
- private int getNumberOfAccounts()
- {
- ProtocolProviderFactory factory =
- DictAccRegWizzActivator.getDictProtocolProviderFactory();
-
- return factory.getRegisteredAccounts().size();
- }
-
- /**
- * Returns the number of account for a given host
- * @param hostName the host
- * @return the number of account for a given host
- */
- private int getNbAccountForHost(String host)
- {
- ProtocolProviderFactory factory =
- DictAccRegWizzActivator.getDictProtocolProviderFactory();
-
- ArrayList<AccountID> registeredAccounts
- = factory.getRegisteredAccounts();
- int total = 0;
-
- for (int i = 0; i < registeredAccounts.size(); i++)
- {
- AccountID accountID = registeredAccounts.get(i);
-
- // The host is always stored at the start
- if (accountID.getUserID().startsWith(host.toLowerCase()))
- {
- total++;
- }
- }
- return total;
- }
-
- /**
- * Returns an example string, which should indicate to the user how the
- * user name should look like.
- * @return an example string, which should indicate to the user how the
- * user name should look like.
- */
- @Override
- public String getUserNameExample()
- {
- return null;
- }
-
- /**
- * Indicates whether this wizard enables the simple "sign in" form shown
- * when the user opens the application for the first time. The simple
- * "sign in" form allows user to configure her account in one click, just
- * specifying her username and password and leaving any other configuration
- * as by default.
- * @return <code>true</code> if the simple "Sign in" form is enabled or
- * <code>false</code> otherwise.
- */
- @Override
- public boolean isSimpleFormEnabled()
- {
- return false;
- }
-
- /**
- * Returns a simple account registration form that would be the first form
- * shown to the user. Only if the user needs more settings she'll choose
- * to open the advanced wizard, consisted by all pages.
- *
- * @param isCreateAccount indicates if the simple form should be opened as
- * a create account form or as a login form
- * @return a simple account registration form
- */
- @Override
- public Object getSimpleForm(boolean isCreateAccount)
- {
- firstWizardPage = new FirstWizardPage(this);
-
- return firstWizardPage.getSimpleForm();
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/FirstWizardPage.java b/src/net/java/sip/communicator/plugin/dictaccregwizz/FirstWizardPage.java
deleted file mode 100644
index 59cfd27..0000000
--- a/src/net/java/sip/communicator/plugin/dictaccregwizz/FirstWizardPage.java
+++ /dev/null
@@ -1,637 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.dictaccregwizz;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.util.List;
-
-import javax.swing.*;
-import javax.swing.event.*;
-
-import net.java.dict4j.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * The <tt>FirstWizardPage</tt> is the page, where user could enter the host,
- * port and the strategy of the account.
- *
- * @author ROTH Damien
- * @author LITZELMANN Cedric
- */
-public class FirstWizardPage
- extends TransparentPanel
- implements WizardPage, DocumentListener, ActionListener
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- public static final String FIRST_PAGE_IDENTIFIER = "FirstPageIdentifier";
-
- private JPanel hostPortPanel = new TransparentPanel(new BorderLayout(10, 10));
-
- private JPanel labelsPanel = new TransparentPanel();
-
- private JPanel valuesPanel = new TransparentPanel();
-
- private JLabel hostLabel
- = new JLabel(Resources.getString("plugin.dictaccregwizz.HOST"));
-
- private JPanel emptyPanel = new TransparentPanel();
-
- private JLabel hostExampleLabel = new JLabel("Ex: dict.org");
-
- private JLabel portLabel
- = new JLabel(Resources.getString("service.gui.PORT"));
-
- private JTextField hostField = new JTextField();
-
- private JTextField portField = new JTextField("2628");
-
- private JPanel strategyPanel = new TransparentPanel(new BorderLayout(10, 10));
-
- private JPanel strategyTitleBloc = new TransparentPanel(new BorderLayout());
-
- private JLabel strategyTitle = new JLabel(Resources.getString(
- "plugin.dictaccregwizz.STRATEGY_LIST"));
-
- private JButton strategyLoader
- = new JButton(Resources.getString(
- "plugin.dictaccregwizz.SEARCH_STRATEGIES"));
-
- private StrategiesList strategiesList;
-
- private JTextArea strategyDescription
- = new JTextArea(Resources.getString(
- "plugin.dictaccregwizz.STRATEGY_DESCRIPTION"));
-
- private ProgressPanel searchProgressPanel;
-
- private JPanel mainPanel = new TransparentPanel(new BorderLayout());
-
- private Object nextPageIdentifier = WizardPage.SUMMARY_PAGE_IDENTIFIER;
-
- private DictAccountRegistrationWizard wizard;
-
- private String initstrategy = "";
-
- private ThreadManager searchThread = null;
-
- private boolean firstAccount = false;
-
- private boolean isPageCommitted = false;
-
- /**
- * Initial AccountID (null if new account)
- * Used to check if there are modifications to the account
- */
- private AccountID initAccountID = null;
-
- /**
- * Creates an instance of <tt>FirstWizardPage</tt>.
- *
- * @param wizard the parent wizard
- */
- public FirstWizardPage(DictAccountRegistrationWizard wizard)
- {
- super(new BorderLayout());
-
- this.wizard = wizard;
-
- this.setPreferredSize(new Dimension(300, 150));
-
- mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
-
- this.searchThread = new ThreadManager(this);
- this.searchProgressPanel = new ProgressPanel(this.searchThread);
-
- this.firstAccount = !this.hasAccount();
-
- if (this.firstAccount)
- {
- this.initFirstAccount();
- }
- else
- {
- this.init();
- }
-
- this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
- }
-
- /**
- * Initializes all panels, buttons, etc.
- */
- private void init()
- {
- // Host and port Field
- this.hostField = new JTextField();
- this.portField = new JTextField("2628");
-
- this.hostField.getDocument().addDocumentListener(this);
- this.portField.getDocument().addDocumentListener(this);
-
- this.hostExampleLabel.setForeground(Color.GRAY);
- this.hostExampleLabel.setFont(hostExampleLabel.getFont().deriveFont(8));
- this.emptyPanel.setMaximumSize(new Dimension(40, 35));
- this.hostExampleLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 8,
- 0));
-
- labelsPanel.add(hostLabel);
- labelsPanel.add(emptyPanel);
- labelsPanel.add(portLabel);
-
- valuesPanel.add(hostField);
- valuesPanel.add(hostExampleLabel);
- valuesPanel.add(portField);
-
- hostPortPanel.add(labelsPanel, BorderLayout.WEST);
- hostPortPanel.add(valuesPanel, BorderLayout.CENTER);
-
- hostPortPanel.setBorder(BorderFactory.createTitledBorder(
- Resources.getString("plugin.dictaccregwizz.SERVER_INFO")));
-
- this.labelsPanel.setLayout(new BoxLayout(labelsPanel, BoxLayout.Y_AXIS));
- this.valuesPanel.setLayout(new BoxLayout(valuesPanel, BoxLayout.Y_AXIS));
-
- mainPanel.add(hostPortPanel);
-
- this.portField.addKeyListener(new KeyListener() {
- public void keyTyped(KeyEvent evt)
- {
- // If evt isn't a digit, we don't add it
- if (!Character.isDigit(evt.getKeyChar()))
- {
- evt.consume();
- }
- }
-
- // Not used
- public void keyPressed(KeyEvent evt) {;}
- public void keyReleased(KeyEvent evt) {;}
- });
-
- // Strategies list
- this.strategiesList = new StrategiesList();
-
- JScrollPane scrollPane = new JScrollPane();
- scrollPane.getViewport().add(this.strategiesList);
- this.strategyPanel.add(scrollPane);
-
- // Strategy title + button
- this.strategyTitleBloc.add(this.strategyTitle, BorderLayout.WEST);
- this.strategyTitleBloc.add(this.strategyLoader, BorderLayout.EAST);
-
- // Button action listener
- this.strategyLoader.setActionCommand("populateList");
- this.strategyLoader.addActionListener(this);
-
- // South Panel
- JPanel sSouthPanel = new TransparentPanel(new BorderLayout());
-
- // Description
- this.strategyDescription.setLineWrap(true);
- this.strategyDescription.setLineWrap(true);
- this.strategyDescription.setRows(4);
- this.strategyDescription.setWrapStyleWord(true);
- this.strategyDescription.setAutoscrolls(false);
- sSouthPanel.add(this.strategyDescription);
-
- // Message
- sSouthPanel.add(this.searchProgressPanel, BorderLayout.SOUTH);
-
- this.strategyPanel.add(sSouthPanel, BorderLayout.SOUTH);
-
- this.strategyPanel.add(this.strategyTitleBloc, BorderLayout.NORTH);
- this.strategyPanel.setBorder(BorderFactory.createTitledBorder(
- Resources.getString("plugin.dictaccregwizz.STRATEGY_SELECTION")));
- mainPanel.add(this.strategyPanel);
-
- this.add(mainPanel, BorderLayout.NORTH);
- }
-
- /**
- * Initialize the UI for the first account
- */
- private void initFirstAccount()
- {
- // Data init
- this.hostField = new JTextField("dict.org");
- this.portField = new JTextField("2628");
-
- // Init strategies list
- this.strategiesList = new StrategiesList();
-
- this.mainPanel = new TransparentPanel(new BorderLayout());
-
- JPanel infoTitlePanel
- = new TransparentPanel(new FlowLayout(FlowLayout.CENTER));
- JTextArea firstDescription
- = new JTextArea(Resources.getString(
- "plugin.dictaccregwizz.FIRST_ACCOUNT"));
- JLabel title
- = new JLabel(Resources.getString(
- "plugin.dictaccregwizz.ACCOUNT_INFO_TITLE"));
-
- // Title
- title.setFont(title.getFont().deriveFont(Font.BOLD, 14.0f));
- infoTitlePanel.add(title);
- this.mainPanel.add(infoTitlePanel, BorderLayout.NORTH);
- this.mainPanel.add(this.searchProgressPanel, BorderLayout.SOUTH);
-
- // Description
- firstDescription.setLineWrap(true);
- firstDescription.setEditable(false);
- firstDescription.setOpaque(false);
- firstDescription.setRows(6);
- firstDescription.setWrapStyleWord(true);
- firstDescription.setAutoscrolls(false);
- this.mainPanel.add(firstDescription);
- }
-
- /**
- * Implements the <code>WizardPage.getIdentifier</code> to return this
- * page identifier.
- *
- * @return Returns the identifier of the current (the first) page of the
- * wizard.
- */
- public Object getIdentifier()
- {
- return FIRST_PAGE_IDENTIFIER;
- }
-
- /**
- * Implements the <code>WizardPage.getNextPageIdentifier</code> to return
- * the next page identifier - the summary page.
- *
- * @return Returns the identifier of the next page of the wizard.
- */
- public Object getNextPageIdentifier()
- {
- return nextPageIdentifier;
- }
-
- /**
- * Implements the <code>WizardPage.getBackPageIdentifier</code> to return
- * the back identifier, which is null as this is the first wizard page.
- *
- * @return the identifier of the previous page of the wizard.
- */
- public Object getBackPageIdentifier()
- {
- return null;
- }
-
- /**
- * Implements the <code>WizardPage.getWizardForm</code> to return this
- * panel.
- * @return Returns this form of the wizard.
- */
- public Object getWizardForm()
- {
- return this;
- }
-
- /**
- * Before this page is displayed enables or disables the "Next" wizard
- * button according to whether the UIN field is empty.
- */
- public void pageShowing()
- {
- this.setNextButtonEnabled();
- }
-
- /**
- * Saves the user input when the "Next" wizard buttons is clicked.
- */
- public void commitPage()
- {
- String host = hostField.getText();
- int port = Integer.parseInt(portField.getText());
- boolean isModified = false;
-
- if (this.initAccountID != null)
- { // We check if there are modifications to the server
- String accHost =
- this.initAccountID.getAccountPropertyString(
- ProtocolProviderFactory.SERVER_ADDRESS);
- int accPort =
- Integer.parseInt(this.initAccountID
- .getAccountPropertyString(ProtocolProviderFactory.SERVER_PORT));
-
- if (((accHost == null) ? (host != null) : !accHost.equals(host))
- || (accPort != port))
- {
- isModified = true;
- }
- }
-
- // We check if a strategy has been selected
- if (this.strategiesList.getModel().getSize() == 0)
- { // No Strategy, we get them
- this.populateStrategies();
-
- if (!this.searchThread.waitThread())
- {
- // TODO error dialog : thread interrupted ? no thread ?
- this.strategiesList.clear();
- }
- }
-
- if (this.strategiesList.getModel().getSize() == 0)
- {
- // No strategy, maybe not connected
- // Information message is already on the wizard
- nextPageIdentifier = FIRST_PAGE_IDENTIFIER;
- this.revalidate();
- }
- else
- {
- nextPageIdentifier = SUMMARY_PAGE_IDENTIFIER;
-
- DictAccountRegistration registration = wizard.getRegistration();
-
- registration.setHost(host);
- registration.setPort(port);
- registration.setStrategy(
- (Strategy) this.strategiesList.getSelectedValue());
- }
-
- isPageCommitted = true;
- }
-
- /**
- * Enables or disables the "Next" wizard button according to whether the UIN
- * field is empty.
- */
- private void setNextButtonEnabled()
- {
- boolean hostOK = DictConnection.isUrl(hostField.getText());
- boolean portOK = (this.portField.getText().length() != 0)
- && Integer.parseInt(this.portField.getText()) > 10;
-
- if (this.firstAccount)
- {
- wizard.getWizardContainer().setNextFinishButtonEnabled(true);
- }
- else if (hostOK && portOK)
- {
- this.strategyLoader.setEnabled(true);
- wizard.getWizardContainer().setNextFinishButtonEnabled(true);
- }
- else
- {
- // Disable the finish button
- wizard.getWizardContainer().setNextFinishButtonEnabled(false);
-
- // Clear the list and disable the button
- this.strategiesList.clear();
- this.strategyLoader.setEnabled(false);
- }
- }
-
- /**
- * Handles the <tt>DocumentEvent</tt> triggered when user types in the UIN
- * field. Enables or disables the "Next" wizard button according to whether
- * the UIN field is empty.
- *
- * @param e the <tt>DocumentEvent</tt> triggered when user types in the UIN
- * field.
- */
- public void insertUpdate(DocumentEvent e)
- {
- this.setNextButtonEnabled();
- }
-
- /**
- * Handles the <tt>DocumentEvent</tt> triggered when user deletes letters
- * from the UIN field. Enables or disables the "Next" wizard button
- * according to whether the UIN field is empty.
- *
- * @param e The <tt>DocumentEvent</tt> triggered when user deletes letters
- * from the UIN field.
- */
- public void removeUpdate(DocumentEvent e)
- {
- this.setNextButtonEnabled();
- }
-
- /**
- * Handles the <tt>DocumentEvent</tt> triggered when user changes an
- * attribute or set of attributes from the UIN field.
- * Currently this notification has no effect and is just here to implement
- * the DocumentListener interface.
- *
- * @param e The <tt>DocumentEvent</tt> triggered when an attribute or set of
- * attributes changed from the UIN field.
- */
- public void changedUpdate(DocumentEvent e)
- {
- }
-
- /**
- * Invoked when this WizardPage will be hidden eighter because the user has
- * clicked "Back" or "Next".
- * This function has no effect.
- */
- public void pageHiding()
- {
- }
-
- /**
- * Invoked when this WizardPage will be shown eighter because the user has
- * clicked "Back" on the next wizard page or "Next" on the previous one.
- * This function has no effect.
- */
- public void pageShown()
- {
- }
-
- /**
- * Invoked when user clicks on the "Back" wizard button.
- * This function has no effect.
- */
- public void pageBack()
- {
- }
-
- /**
- * Fills the Host, Port and Strategy fields in this panel with the data comming
- * from the given protocolProvider.
- *
- * @param protocolProvider The <tt>ProtocolProviderService</tt> to load
- * the data from.
- */
- public void loadAccount(ProtocolProviderService protocolProvider)
- {
- AccountID accountID = protocolProvider.getAccountID();
- String host =
- accountID
- .getAccountPropertyString(ProtocolProviderFactory.SERVER_ADDRESS);
- String port =
- accountID
- .getAccountPropertyString(ProtocolProviderFactory.SERVER_PORT);
- String strategy =
- accountID
- .getAccountPropertyString(ProtocolProviderFactory.STRATEGY);
-
- this.initAccountID = accountID;
-
- // Host field
- this.hostField.setText(host);
-
- // Port Field
- this.portField.setText(port);
-
- // Load strategies
- this.initstrategy = strategy;
- this.populateStrategies();
- }
-
- /**
- * Handles the action of the button.
- *
- * @param e The event generated when the button is pressed.
- */
- public void actionPerformed(ActionEvent e)
- {
- // Button action -> populate the list
- if (e.getActionCommand().equals("populateList"))
- {
- this.populateStrategies();
- }
- }
-
- /**
- * Checks if an account is stored for this protocol
- * @return TRUE, if an account is stored - FALSE otherwise
- */
- private boolean hasAccount()
- {
- ProtocolProviderFactory factory =
- DictAccRegWizzActivator.getDictProtocolProviderFactory();
-
- return !factory.getRegisteredAccounts().isEmpty();
- }
-
- /**
- * Start the thread which will populate the Strategies List
- */
- public void populateStrategies()
- {
- // Clear ArrayList
- this.strategiesList.clear();
-
- boolean ok = this.searchThread.submitRequest(this.hostField.getText(),
- Integer.parseInt(this.portField.getText()));
-
- if (!ok)
- {
- // TODO Display error
- }
- }
-
- /**
- * Automatic selection of a strategy
- */
- public void autoSelectStrategy()
- {
- this.strategiesList.autoSelectStrategy(this.initstrategy);
- }
-
- /**
- *
- * @param strategies
- */
- public void setStrategies(List<Strategy> strategies)
- {
- this.strategiesList.setStrategies(strategies);
- }
-
- /**
- * Informs the user of the current status of the search
- * Should only be called by the thread
- * @param message Search status
- */
- public void progressMessage(String message)
- {
- this.searchProgressPanel.nextStep(message);
- }
-
- /**
- * Informs the wizard that the search of the strategies is complete.
- * Should only be called by the thread
- */
- public void strategiesSearchComplete()
- {
- setStrategyButtonEnable(true);
- this.searchProgressPanel.finish();
- }
-
- /**
- * Informs the wizard that the search of the strategies is a failure
- * Should only be called by the thread
- * @param reason Reason message
- * @param de Exception thrown
- */
- public void strategiesSearchFailure(String reason, DictException de)
- {
- strategiesSearchComplete();
- // TODO SHOW ERROR MESSAGE
- }
-
- /**
- * Enables or disable the Next Button and the Strategy Button
- * @param e TRUE enables - FALSE disables
- */
- public void setStrategyButtonEnable(boolean e)
- {
- // During all the process the buttons and the fieldsset are in the same state
-
- this.hostField.setEnabled(e);
- this.portField.setEnabled(e);
-
- this.strategyLoader.setEnabled(e);
- wizard.getWizardContainer().setNextFinishButtonEnabled(e);
- }
-
- public Object getSimpleForm()
- {
- return mainPanel;
- }
-
- /**
- * Indicates if this is the first dict account
- *
- * @return TRUE if this is the first dict account - FALSE otherwise
- */
- public boolean isFirstAccount()
- {
- return this.firstAccount;
- }
-
- public boolean isCommitted()
- {
- return isPageCommitted;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/ProgressPanel.java b/src/net/java/sip/communicator/plugin/dictaccregwizz/ProgressPanel.java
deleted file mode 100644
index 7d46fa5..0000000
--- a/src/net/java/sip/communicator/plugin/dictaccregwizz/ProgressPanel.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.dictaccregwizz;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.plugin.desktoputil.*;
-
-/**
- * Panel showing the current status of the search of the strategies
- *
- * @author ROTH Damien
- */
-public class ProgressPanel
- extends TransparentPanel
- implements ActionListener
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- private JPanel rightPanel;
-
- private JLabel messageLabel;
- private JLabel progressLabel;
- private JButton cancelButton;
-
- private int currentStep;
- private int totalSteps;
-
- private boolean isBuild;
-
- private ThreadManager searchThread;
-
- /**
- * Create an instance of <tt>ProgressPanel</tt>
- * @param searchThread The thread manager
- */
- public ProgressPanel(ThreadManager searchThread)
- {
- super(new BorderLayout());
-
- // Element creation
- this.messageLabel = new JLabel(" ");
- this.progressLabel = new JLabel(" ");
- this.cancelButton
- = new JButton(Resources.getString("service.gui.CANCEL"));
- this.cancelButton.addActionListener(this);
-
- // Right panel init
- this.rightPanel = new TransparentPanel(new FlowLayout(FlowLayout.RIGHT));
- this.rightPanel.add(this.progressLabel);
- this.rightPanel.add(this.cancelButton);
-
- this.searchThread = searchThread;
-
- init();
- this.totalSteps = ThreadManager.NB_STEPS;
- }
-
- /**
- * Init the values
- */
- private void init()
- {
- this.isBuild = false;
- this.currentStep = 1;
-
- this.add(this.messageLabel, BorderLayout.CENTER);
- }
-
- /**
- * Build the UI
- */
- private void build()
- {
- if (this.isBuild)
- {
- return;
- }
-
- this.add(this.messageLabel, BorderLayout.CENTER);
- this.add(this.rightPanel, BorderLayout.EAST);
-
- this.isBuild = true;
- }
-
- /**
- * Move to the next step without updating the message
- */
- public void nextStep()
- {
- nextStep(this.messageLabel.getText());
- }
-
- /**
- * Mode to the next step with a new message
- * @param message Message
- */
- public void nextStep(String message)
- {
- if (this.currentStep > this.totalSteps)
- {
- finish();
- }
-
- build();
- this.messageLabel.setText(message);
- this.progressLabel.setText(currentStep + "/" + totalSteps);
-
- this.currentStep++;
- }
-
- /**
- * Informs the end of the progress. Remove all the components and
- * reset the values
- */
- public void finish()
- {
- // Remove all elements
- this.removeAll();
-
- // Re-init the panel
- this.messageLabel.setText(" ");
- this.progressLabel.setText(" ");
- init();
-
- this.repaint();
- this.validate();
- }
-
- public void actionPerformed(ActionEvent arg0)
- {
- this.searchThread.cancel();
- this.finish();
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/dictaccregwizz/Resources.java
deleted file mode 100644
index 55856be..0000000
--- a/src/net/java/sip/communicator/plugin/dictaccregwizz/Resources.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.dictaccregwizz;
-
-import net.java.sip.communicator.service.resources.*;
-
-import org.jitsi.service.resources.*;
-
-/**
- * The <tt>Resources</tt> class manages the access to the internationalization
- * properties files and the image resources used in this plugin.
- *
- * @author ROTH Damien
- * @author LITZELMAN Cedric
- */
-public class Resources
-{
- private static ResourceManagementService resourcesService;
-
- public static ImageID DICT_LOGO
- = new ImageID("service.protocol.dict.DICT_16x16");
-
- public static ImageID PAGE_IMAGE
- = new ImageID("service.protocol.dict.DICT_64x64");
-
- /**
- * Returns an internationalized string corresponding to the given key.
- *
- * @param key The key of the string.
- * @return An internationalized string corresponding to the given key.
- */
- public static String getString(String key)
- {
- return getResources().getI18NString(key);
- }
-
- /**
- * Loads an image from a given image identifier.
- * @param imageID The identifier of the image.
- * @return The image for the given identifier.
- */
- public static byte[] getImage(ImageID imageID)
- {
- return getResources().getImageInBytes(imageID.getId());
- }
-
- /**
- * Returns the <tt>ResourceManagementService</tt>.
- *
- * @return the <tt>ResourceManagementService</tt>.
- */
- public static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- resourcesService =
- ResourceManagementServiceUtils
- .getService(DictAccRegWizzActivator.bundleContext);
- return resourcesService;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/StrategiesList.java b/src/net/java/sip/communicator/plugin/dictaccregwizz/StrategiesList.java
deleted file mode 100644
index ace9127..0000000
--- a/src/net/java/sip/communicator/plugin/dictaccregwizz/StrategiesList.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.dictaccregwizz;
-
-import java.awt.*;
-import java.util.*;
-import java.util.List;
-
-import javax.swing.*;
-
-import net.java.dict4j.*;
-
-/**
- * Class managing the list of strategies
- *
- * @author ROTH Damien
- */
-public class StrategiesList
- extends JList
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- private ListModel model;
- private CellRenderer renderer;
-
- /**
- * Create an instance of the <tt>StrategiesList</tt>
- */
- public StrategiesList()
- {
- super();
-
- this.model = new ListModel();
- this.renderer = new CellRenderer();
-
- this.setCellRenderer(this.renderer);
- this.setModel(model);
- this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
- this.setVisibleRowCount(6);
- }
-
- /**
- * Stores a new set of strategies
- * @param strategies List of strategies
- */
- public void setStrategies(List<Strategy> strategies)
- {
- this.model.setStrategies(strategies);
- }
-
- /**
- * Remove all the strategies of the list
- */
- public void clear()
- {
- this.model.clear();
- }
-
- /**
- * Automatic selection of strategies
- * @param initStrategy
- */
- public void autoSelectStrategy(String initStrategy)
- {
- int index = -1;
-
- if (initStrategy.length() > 0)
- { // saved strategy
- index = this.model.indexOf(initStrategy);
- }
- if (index < 0)
- {
- // First case : levenstein distance
- index = this.model.indexOf("lev");
- }
- if (index < 0)
- {
- // Second case : soundex
- index = this.model.indexOf("soundex");
- }
- if (index < 0)
- {
- // Last case : prefix
- index = this.model.indexOf("prefix");
- }
-
- // If the index is still < 0, we select the first index
- if (index < 0)
- {
- index = 0;
- }
- if (index < this.getVisibleRowCount())
- {
- // If the index is visible row, we don't need to scroll
- this.setSelectedIndex(index);
- }
- else
- {
- // Otherwise, we scroll to the selected value
- this.setSelectedValue(this.model.getElementAt(index), true);
- }
- }
-
- /**
- * Class managing the list datas
- *
- * @author ROTH Damien
- */
- static class ListModel
- extends AbstractListModel
- {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- private List<Strategy> data;
-
- /**
- * Create an instance of <tt>ListModel</tt>
- */
- public ListModel()
- {
- data = new ArrayList<Strategy>();
- }
-
- /**
- * Stores the strategies into this model
- * @param strategies the strategies list
- */
- public void setStrategies(List<Strategy> strategies)
- {
- data = strategies;
- fireContentsChanged(this, 0, data.size());
- }
-
- /**
- * Remove all the strategies of the list
- */
- public void clear()
- {
- data.clear();
- }
-
- /**
- * Implements <tt>ListModel.getElementAt</tt>
- */
- public Strategy getElementAt(int row)
- {
- return data.get(row);
- }
-
- /**
- * Implements <tt>ListModel.getSize</tt>
- */
- public int getSize()
- {
- return data.size();
- }
-
- /**
- * Find the index of a strategy.
- *
- * @param strategyCode the code of the strategy
- * @return the index of the strategy
- */
- public int indexOf(String strategyCode)
- {
- for (int i = 0, size = data.size(); i < size; i++)
- {
- if (data.get(i).getCode().equals(strategyCode))
- return i;
- }
- return -1;
- }
- }
-
- /**
- * Class managing the cell rendering
- *
- * @author ROTH Damien
- */
- static class CellRenderer
- extends JLabel
- implements ListCellRenderer
- {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * implements <tt>ListCellRenderer.getListCellRendererComponent</tt>
- */
- public Component getListCellRendererComponent(
- JList list,
- Object value,
- int index,
- boolean isSelected,
- boolean cellHasFocus)
- {
- setText(((Strategy) value).getName());
-
- if (isSelected)
- {
- setBackground(list.getSelectionBackground());
- setForeground(list.getSelectionForeground());
- }
- else
- {
- setBackground(list.getBackground());
- setForeground(list.getForeground());
- }
- setEnabled(list.isEnabled());
- setFont(list.getFont());
- setOpaque(true);
-
- return this;
- }
- }
-}
-
diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/ThreadManager.java b/src/net/java/sip/communicator/plugin/dictaccregwizz/ThreadManager.java
deleted file mode 100644
index 4abcc75..0000000
--- a/src/net/java/sip/communicator/plugin/dictaccregwizz/ThreadManager.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.dictaccregwizz;
-
-import java.util.*;
-
-import net.java.dict4j.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Class manager the thread called for searching the strategies' list
- *
- * @author ROTH Damien
- */
-public class ThreadManager
-{
- protected static Logger logger = Logger.getLogger(ThreadManager.class);
- public static int NB_STEPS = 4;
-
- private StrategyThread thread = null;
- private FirstWizardPage wizard = null;
-
- /**
- * Create an instance of <tt>ThreadManager</tt>
- * @param wiz Wizard
- */
- public ThreadManager(FirstWizardPage wiz)
- {
- this.wizard = wiz;
- }
-
- /**
- * Submit a request to launch the thread
- * @param host Server host
- * @param port Server port
- * @return TRUE if the thread is started - FALSE otherwise
- */
- public boolean submitRequest(String host, int port)
- {
- if (this.thread != null)
- {
- return false;
- }
-
- this.thread = new StrategyThread(this.wizard, host, port);
- this.thread.start();
-
- return true;
- }
-
- /**
- * Stop the thread
- */
- public void cancel()
- {
- if (this.thread != null)
- {
- this.thread.interrupt();
- this.thread = null;
- }
- }
-
- /**
- * Wait for the searching thread to stop
- * @return true if success, false otherwise
- */
- public boolean waitThread()
- {
- if (this.thread == null)
- {
- return false;
- }
-
- try
- {
- this.thread.join();
- }
- catch (InterruptedException e)
- {
- if (logger.isInfoEnabled())
- logger.info(e);
- return false;
- }
- return true;
- }
-
- /**
- * Thread used to search the strategies
- *
- * @author ROTH Damien, LITZELMANN Cedric
- */
- static class StrategyThread
- extends Thread
- {
- private final FirstWizardPage wizard;
- private final String host;
- private final int port;
-
- /**
- * Informations messages
- */
- private String[] messages = new String[] {
- Resources.getString(
- "plugin.dictaccregwizz.THREAD_CONNECT"),
- Resources.getString(
- "plugin.dictaccregwizz.THREAD_CONNECT_FAILED"),
- Resources.getString(
- "plugin.dictaccregwizz.RETRIEVING_STRATEGIES"),
- Resources.getString(
- "plugin.dictaccregwizz.NO_STRATEGIES_FOUND"),
- Resources.getString(
- "plugin.dictaccregwizz.POPULATE_LIST"),
- Resources.getString(
- "plugin.dictaccregwizz.CLOSING_CONNECTION")
- };
-
- /**
- * Create an instance of the thread
- * @param wizard The wizard who started the thread
- * @param host Server host
- * @param port Server port
- */
- public StrategyThread(FirstWizardPage wizard, String host, int port)
- {
- this.wizard = wizard;
- this.host = host;
- this.port = port;
- }
-
- @Override
- public void run()
- {
- List<Strategy> strategies = null;
-
- DictConnection dictConnection = new DictConnection(host, port);
-
- // Open the connection to the server
- this.wizard.progressMessage(messages[0]);
- try
- {
- dictConnection.connect();
- }
- catch (DictException e)
- {
- this.wizard.strategiesSearchFailure(this.messages[1], e);
- return;
- }
-
- // Get the strategies
- this.wizard.progressMessage(messages[2]);
- try
- {
- strategies = dictConnection.getStrategies();
- }
- catch (DictException e)
- {
- this.wizard.strategiesSearchFailure(this.messages[3], e);
- return;
- }
-
- // Store the strategies
- this.wizard.progressMessage(messages[4]);
- this.wizard.setStrategies(strategies);
- this.wizard.autoSelectStrategy();
-
- // Close the connection
- this.wizard.progressMessage(messages[5]);
- try
- {
- dictConnection.close();
- }
- catch (DictException e)
- {
- // An error while closing the connection isn't very important
- // We just log it
- ThreadManager.logger.info("DICT search strategies thread : " +
- "Error while closing connection", e);
- }
-
- // End of the search
- this.wizard.strategiesSearchComplete();
- }
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/dictaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/dictaccregwizz/dictaccregwizz.manifest.mf
deleted file mode 100644
index 02dc2c4..0000000
--- a/src/net/java/sip/communicator/plugin/dictaccregwizz/dictaccregwizz.manifest.mf
+++ /dev/null
@@ -1,34 +0,0 @@
-Bundle-Activator: net.java.sip.communicator.plugin.dictaccregwizz.DictAccRegWizzActivator
-Bundle-Name: Dict account registration wizard
-Bundle-Description: Dict account registration wizard.
-Bundle-Vendor: jitsi.org
-Bundle-Version: 0.0.1
-Bundle-SymbolicName: net.java.sip.communicator.plugin.dictaccregwizz
-Import-Package: org.osgi.framework,
- net.java.dict4j,
- net.java.sip.communicator.service.browserlauncher,
- org.jitsi.service.configuration,
- net.java.sip.communicator.service.contactlist,
- net.java.sip.communicator.service.contactlist.event,
- net.java.sip.communicator.service.gui,
- net.java.sip.communicator.service.gui.event,
- net.java.sip.communicator.service.protocol,
- net.java.sip.communicator.service.protocol.event,
- net.java.sip.communicator.service.protocol.icqconstants,
- org.jitsi.service.resources, net.java.sip.communicator.service.resources,
- net.java.sip.communicator.util,
- net.java.sip.communicator.plugin.desktoputil,
- javax.swing,
- javax.swing.event,
- javax.swing.table,
- javax.swing.text,
- javax.swing.text.html,
- javax.accessibility,
- javax.swing.plaf,
- javax.swing.plaf.metal,
- javax.swing.plaf.basic,
- javax.imageio,
- javax.swing.filechooser,
- javax.swing.tree,
- javax.swing.undo,
- javax.swing.border
diff --git a/src/net/java/sip/communicator/plugin/dnsconfig/DnssecPanel.java b/src/net/java/sip/communicator/plugin/dnsconfig/DnssecPanel.java
index 0500c07..27bf565 100644
--- a/src/net/java/sip/communicator/plugin/dnsconfig/DnssecPanel.java
+++ b/src/net/java/sip/communicator/plugin/dnsconfig/DnssecPanel.java
@@ -267,7 +267,7 @@ public class DnssecPanel
if(chkEnabled.isSelected())
{
if(!f.createNewFile() && !f.exists())
- chkEnabled.setSelected(UnboundApi.isAvailable());
+ chkEnabled.setSelected(false);
}
else
{
diff --git a/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccRegWizzActivator.java
deleted file mode 100644
index 2400644..0000000
--- a/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccRegWizzActivator.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.facebookaccregwizz;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.browserlauncher.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.resources.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.resources.*;
-import org.osgi.framework.*;
-
-/**
- * Registers the <tt>FacebookAccountRegistrationWizard</tt> in the UI Service.
- *
- * @author Dai Zhiwei
- */
-public class FacebookAccRegWizzActivator
- extends AbstractServiceDependentActivator
-{
- /**
- * The logger.
- */
- private static Logger logger
- = Logger.getLogger(FacebookAccRegWizzActivator.class.getName());
-
- /**
- * A currently valid bundle context.
- */
- public static BundleContext bundleContext;
-
- /**
- * The container.
- */
- private static WizardContainer wizardContainer;
-
- /**
- * Registration wizard.
- */
- private static FacebookAccountRegistrationWizard facebookWizard;
-
- /**
- * The UI service.
- */
- private static UIService uiService;
-
- /**
- * The browser launcher service.
- */
- private static BrowserLauncherService browserLauncherService;
-
- private static ResourceManagementService resourcesService;
-
- /**
- * Starts this bundle.
- */
- @Override
- public void start(Object dependentService)
- {
- if (logger.isInfoEnabled())
- logger.info("Loading facebook account wizard.");
-
- uiService = (UIService)dependentService;
-
- wizardContainer = uiService.getAccountRegWizardContainer();
-
- facebookWizard
- = new FacebookAccountRegistrationWizard(wizardContainer);
-
- Hashtable<String, String> containerFilter
- = new Hashtable<String, String>();
-
- containerFilter.put(
- ProtocolProviderFactory.PROTOCOL,
- ProtocolNames.FACEBOOK);
-
- bundleContext.registerService(
- AccountRegistrationWizard.class.getName(),
- facebookWizard,
- containerFilter);
-
- if (logger.isInfoEnabled())
- logger.info("Facebook account registration wizard [STARTED].");
- }
-
- /**
- * The dependent class. We are waiting for the ui service.
- * @return the ui service class.
- */
- @Override
- public Class<?> getDependentServiceClass()
- {
- return UIService.class;
- }
-
- /**
- * The bundle context to use.
- * @param context the context to set.
- */
- @Override
- public void setBundleContext(BundleContext context)
- {
- bundleContext = context;
- }
-
- /**
- * Called when this bundle is stopped so the Framework can perform the
- * bundle-specific activities necessary to stop the bundle.
- *
- * @param bundleContext The execution context of the bundle being stopped.
- */
- public void stop(BundleContext bundleContext)
- {
- }
-
- /**
- * Returns the <tt>ProtocolProviderFactory</tt> for the Facebook protocol.
- * @return the <tt>ProtocolProviderFactory</tt> for the Facebook protocol
- */
- public static ProtocolProviderFactory getFacebookProtocolProviderFactory()
- {
-
- ServiceReference[] serRefs = null;
-
- String osgiFilter = "("
- + ProtocolProviderFactory.PROTOCOL
- + "=" + ProtocolNames.JABBER + ")";
-
- try
- {
- serRefs = bundleContext.getServiceReferences(
- ProtocolProviderFactory.class.getName(), osgiFilter);
- }
- catch (InvalidSyntaxException ex)
- {
- logger.error("FacebookAccRegWizzActivator : " + ex);
- }
-
- return (ProtocolProviderFactory) bundleContext.getService(serRefs[0]);
- }
-
- /**
- * Returns the bundleContext that we received when we were started.
- *
- * @return a currently valid instance of a bundleContext.
- */
- public BundleContext getBundleContext()
- {
- return bundleContext;
- }
-
- /**
- * Returns the <tt>UIService</tt>.
- *
- * @return the <tt>UIService</tt>
- */
- public static UIService getUIService()
- {
- return uiService;
- }
-
- /**
- * Gets the browser launcher service.
- * @return the browser launcher service.
- */
- public static BrowserLauncherService getBrowserLauncher()
- {
- if (browserLauncherService == null)
- {
- ServiceReference serviceReference =
- bundleContext.getServiceReference(BrowserLauncherService.class
- .getName());
-
- browserLauncherService =
- (BrowserLauncherService) bundleContext
- .getService(serviceReference);
- }
-
- return browserLauncherService;
- }
-
- /**
- * Returns the <tt>ResourceManagementService</tt>.
- *
- * @return the <tt>ResourceManagementService</tt>.
- */
- public static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- resourcesService =
- ResourceManagementServiceUtils
- .getService(FacebookAccRegWizzActivator.bundleContext);
- return resourcesService;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java b/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java
deleted file mode 100644
index d70282d..0000000
--- a/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.facebookaccregwizz;
-
-import java.util.*;
-
-import net.java.sip.communicator.plugin.jabberaccregwizz.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.jabber.*;
-
-/**
- * The <tt>FacebookAccountRegistrationWizard</tt> is an implementation of the
- * <tt>AccountRegistrationWizard</tt> for the Facebook Chat protocol. It allows
- * the user to create and configure a new Facebook account.
- *
- * @author Dai Zhiwei
- * @author Yana Stamcheva
- */
-public class FacebookAccountRegistrationWizard
- extends JabberAccountRegistrationWizard
-{
- /**
- * The protocol name.
- */
- private static final String PROTOCOL = "Facebook";
-
- /**
- * A constant pointing to the Facebook protocol logo icon.
- */
- private static final String PROTOCOL_ICON
- = "service.protocol.facebook.FACEBOOK_16x16";
-
- /**
- * A constant pointing to the Facebook protocol wizard page image.
- */
- private static final String PAGE_IMAGE
- = "service.protocol.facebook.FACEBOOK_48x48";
-
- private static final String SERVER_ADDRESS = "chat.facebook.com";
-
- /**
- * Creates an instance of <tt>FacebookAccountRegistrationWizard</tt>.
- * @param wizardContainer the wizard container, where this wizard
- * is added
- */
- public FacebookAccountRegistrationWizard(WizardContainer wizardContainer)
- {
- super(wizardContainer);
- }
-
- /**
- * Returns the set of pages contained in this wizard.
- * @return Iterator
- */
- @Override
- public Iterator<WizardPage> getPages()
- {
- JabberAccountRegistration reg = new JabberAccountRegistration();
-
- setPredefinedProperties(reg);
-
- return getPages(reg);
- }
-
- /**
- * Returns a simple account registration form that would be the first form
- * shown to the user. Only if the user needs more settings she'll choose
- * to open the advanced wizard, consisted by all pages.
- *
- * @param isCreateAccount indicates if the simple form should be opened as
- * a create account form or as a login form
- * @return a simple account registration form
- */
- @Override
- public Object getSimpleForm(boolean isCreateAccount)
- {
- JabberAccountRegistration reg = new JabberAccountRegistration();
-
- setPredefinedProperties(reg);
-
- return getSimpleForm(reg, isCreateAccount);
- }
-
- /**
- * Sets all facebook specific properties.
- *
- * @param reg the registration object
- */
- private void setPredefinedProperties(JabberAccountRegistration reg)
- {
- reg.setServerAddress(SERVER_ADDRESS);
- reg.setSendKeepAlive(true);
-
- reg.setServerOverridden(true);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getIcon</code> method.
- * Returns the icon to be used for this wizard.
- * @return byte[]
- */
- @Override
- public byte[] getIcon()
- {
- return FacebookAccRegWizzActivator.getResources()
- .getImageInBytes(PROTOCOL_ICON);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getPageImage</code> method.
- * Returns the image used to decorate the wizard page
- *
- * @return byte[] the image used to decorate the wizard page
- */
- @Override
- public byte[] getPageImage()
- {
- return FacebookAccRegWizzActivator.getResources()
- .getImageInBytes(PAGE_IMAGE);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getProtocolName</code>
- * method. Returns the protocol name for this wizard.
- * @return String
- */
- @Override
- public String getProtocolName()
- {
- return FacebookAccRegWizzActivator.getResources()
- .getI18NString("plugin.facebookaccregwizz.PROTOCOL_NAME");
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getProtocolDescription
- * </code> method. Returns the description of the protocol for this wizard.
- * @return String
- */
- @Override
- public String getProtocolDescription()
- {
- return FacebookAccRegWizzActivator.getResources()
- .getI18NString("plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION");
- }
-
- /**
- * Returns an example string, which should indicate to the user how the
- * user name should look like.
- * @return an example string, which should indicate to the user how the
- * user name should look like.
- */
- @Override
- public String getUserNameExample()
- {
- return "Ex: username";
- }
-
- /**
- * Returns the display label used for the sip id field.
- * @return the sip id display label string.
- */
- @Override
- protected String getUsernameLabel()
- {
- return FacebookAccRegWizzActivator.getResources()
- .getI18NString("plugin.facebookaccregwizz.USERNAME");
- }
-
- /**
- * Return the string for add existing account button.
- * @return the string for add existing account button.
- */
- @Override
- protected String getCreateAccountButtonLabel()
- {
- return null;
- }
-
- /**
- * Return the string for create new account button.
- * @return the string for create new account button.
- */
- @Override
- protected String getCreateAccountLabel()
- {
- return FacebookAccRegWizzActivator.getResources().getI18NString(
- "plugin.facebookaccregwizz.DESCRIPTION");
- }
-
- /**
- * Returns the protocol name as listed in "ProtocolNames" or just the name
- * of the service.
- * @return the protocol name
- */
- @Override
- public String getProtocol()
- {
- return PROTOCOL;
- }
-
- /**
- * Returns the protocol icon path.
- * @return the protocol icon path
- */
- @Override
- public String getProtocolIconPath()
- {
- return "resources/images/protocol/facebook";
- }
-
- /**
- * Returns the account icon path.
- * @return the account icon path
- */
- @Override
- public String getAccountIconPath()
- {
- return "resources/images/protocol/facebook/logo32x32.png";
- }
-
- /**
- * Opens a browser on the sign up page.
- */
- @Override
- public void webSignup() {}
-
- /**
- * Returns <code>true</code> if the web sign up is supported by the current
- * implementation, <code>false</code> - otherwise.
- * @return <code>true</code> if the web sign up is supported by the current
- * implementation, <code>false</code> - otherwise
- */
- @Override
- public boolean isWebSignupSupported()
- {
- return false;
- }
-
- /**
- * Creates an account for the given user and password.
- *
- * @param providerFactory the ProtocolProviderFactory which will create
- * the account
- * @param userName the user identifier
- * @param passwd the password
- * @return the <tt>ProtocolProviderService</tt> for the new account.
- * @throws OperationFailedException if the operation didn't succeed
- */
- @Override
- protected ProtocolProviderService installAccount(
- ProtocolProviderFactory providerFactory,
- String userName,
- String passwd)
- throws OperationFailedException
- {
- // add server part to username
- if(userName.indexOf("@") == -1)
- userName += "@" + SERVER_ADDRESS;
-
- return super.installAccount(providerFactory, userName, passwd);
- }
-
- /**
- * Returns an instance of <tt>CreateAccountService</tt> through which the
- * user could create an account. This method is meant to be implemented by
- * specific protocol provider wizards.
- * @return an instance of <tt>CreateAccountService</tt>
- */
- @Override
- protected JabberAccountCreationFormService getCreateAccountService()
- {
- return null;
- }
-
- /**
- * Whether the advanced configuration is enabled. Gives an option
- * to disable/hide advanced config button.
- * @return whether the advanced configuration is enabled.
- */
- public boolean isAdvancedConfigurationEnabled()
- {
- return false;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/facebookaccregwizz/facebookaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/facebookaccregwizz/facebookaccregwizz.manifest.mf
deleted file mode 100644
index 9c79947..0000000
--- a/src/net/java/sip/communicator/plugin/facebookaccregwizz/facebookaccregwizz.manifest.mf
+++ /dev/null
@@ -1,34 +0,0 @@
-Bundle-Activator: net.java.sip.communicator.plugin.facebookaccregwizz.FacebookAccRegWizzActivator
-Bundle-Name: Facebook account registration wizard
-Bundle-Description: Facebook account registration wizard.
-Bundle-Vendor: jitsi.org
-Bundle-Version: 0.0.1
-Bundle-SymbolicName: net.java.sip.communicator.plugin.facebookaccregwizz
-Import-Package: org.osgi.framework,
- net.java.sip.communicator.service.browserlauncher,
- org.jitsi.service.configuration,
- net.java.sip.communicator.service.contactlist,
- net.java.sip.communicator.service.contactlist.event,
- net.java.sip.communicator.service.gui,
- net.java.sip.communicator.service.gui.event,
- net.java.sip.communicator.service.protocol,
- net.java.sip.communicator.service.protocol.event,
- net.java.sip.communicator.service.protocol.jabber,
- org.jitsi.service.resources, net.java.sip.communicator.service.resources,
- net.java.sip.communicator.util,
- net.java.sip.communicator.plugin.desktoputil,
- net.java.sip.communicator.plugin.jabberaccregwizz,
- javax.accessibility,
- javax.imageio,
- javax.swing,
- javax.swing.border,
- javax.swing.filechooser,
- javax.swing.plaf,
- javax.swing.plaf.basic,
- javax.swing.plaf.metal,
- javax.swing.event,
- javax.swing.table,
- javax.swing.text,
- javax.swing.text.html,
- javax.swing.tree,
- javax.swing.undo
diff --git a/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigPluginActivator.java b/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigPluginActivator.java
index 2f345d7..7222d97 100644
--- a/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigPluginActivator.java
+++ b/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigPluginActivator.java
@@ -108,6 +108,14 @@ public class GeneralConfigPluginActivator
"net.java.sip.communicator.plugin.generalconfig.sipconfig.DISABLED";
/**
+ * Indicates if the XMPP configuration form should be disabled, i.e.
+ * not visible to the user.
+ */
+ private static final String XMPP_CONFIG_DISABLED_PROP
+ =
+ "net.java.sip.communicator.plugin.generalconfig.xmppconfig.DISABLED";
+
+ /**
* Starts this bundle.
*/
@Override
@@ -155,6 +163,22 @@ public class GeneralConfigPluginActivator
52, true),
properties);
}
+ if (!getConfigurationService()
+ .getBoolean(XMPP_CONFIG_DISABLED_PROP, false))
+ {
+ // Registers the XMPP config panel as advanced configuration form.
+ properties.put( ConfigurationForm.FORM_TYPE,
+ ConfigurationForm.ADVANCED_TYPE);
+ bundleContext.registerService(
+ ConfigurationForm.class.getName(),
+ new LazyConfigurationForm(
+ XMPPConfigForm.class.getName(),
+ getClass().getClassLoader(),
+ null,
+ "plugin.generalconfig.XMPP_CONFIG",
+ 52, true),
+ properties);
+ }
properties.put( ConfigurationForm.FORM_TYPE,
ConfigurationForm.ADVANCED_TYPE);
bundleContext.registerService(
diff --git a/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigurationPanel.java b/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigurationPanel.java
index f5e482a..03fc308 100644
--- a/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigurationPanel.java
+++ b/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigurationPanel.java
@@ -98,6 +98,13 @@ public class GeneralConfigurationPanel
=
"net.java.sip.communicator.plugin.generalconfig.localeconfig.DISABLED";
+ /**
+ * Indicates if the systray config panel should be disabled, i.e. not
+ * visible to the user.
+ */
+ private static final String SYSTRAY_CONFIG_DISABLED_PROP =
+ "net.java.sip.communicator.plugin.generalconfig.systrayconfig.DISABLED";
+
/**
* Indicates if the Call configuration panel should be disabled, i.e.
* not visible to the user.
@@ -169,6 +176,13 @@ public class GeneralConfigurationPanel
}
if(!GeneralConfigPluginActivator.getConfigurationService()
+ .getBoolean(SYSTRAY_CONFIG_DISABLED_PROP, false))
+ {
+ mainPanel.add(createSystrayeConfigPanel());
+ mainPanel.add(Box.createVerticalStrut(10));
+ }
+
+ if(!GeneralConfigPluginActivator.getConfigurationService()
.getBoolean(CALL_CONFIG_DISABLED_PROP, false))
{
mainPanel.add(createCallConfigPanel());
@@ -237,6 +251,30 @@ public class GeneralConfigurationPanel
}
/**
+ * Initializes the minimize instead of hide checkbox.
+ */
+ public Component createMinimzeInsteadOfHideCheckBox()
+ {
+ JCheckBox chk = new SIPCommCheckBox();
+
+ chk.setText(
+ Resources.getString("plugin.generalconfig.MINIMIZE_NOT_HIDE"));
+ chk.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ boolean value = ((JCheckBox) e.getSource()).isSelected();
+ ConfigurationUtils.setIsMinimizeInsteadOfHide(value);
+ UtilActivator.getUIService().setMainWindowCanHide(
+ !UtilActivator.getSystrayService().checkInitialized());
+ }
+ });
+
+ chk.setSelected(ConfigurationUtils.isMinimizeInsteadOfHide());
+ return chk;
+ }
+
+ /**
* Creates the message configuration panel.
* @return the created panel
*/
@@ -832,6 +870,72 @@ public class GeneralConfigurationPanel
return localeConfigPanel;
}
+ private static class Item
+ {
+ public String key;
+ public String value;
+
+ public Item(String key, String value)
+ {
+ this.key = key;
+ this.value = value;
+ }
+
+ @Override
+ public String toString()
+ {
+ return GeneralConfigPluginActivator.getResources()
+ .getI18NString(value);
+ }
+ }
+
+ /**
+ * Initializes the systray configuration panel.
+ * @return the created component
+ */
+ private Component createSystrayeConfigPanel()
+ {
+ JPanel panel = GeneralConfigPluginActivator.
+ createConfigSectionComponent(
+ Resources.getString("service.systray.MODE"));
+
+ final JComboBox<Item> systrayModes = new JComboBox<>();
+ SystrayService ss = GeneralConfigPluginActivator.getSystrayService();
+ for (Map.Entry<String, String> mode : ss.getSystrayModes().entrySet())
+ {
+ Item i = new Item(mode.getKey(), mode.getValue());
+ systrayModes.addItem(i);
+ if (mode.getKey().equals(ss.getActiveSystrayMode()))
+ {
+ systrayModes.setSelectedItem(i);
+ }
+ }
+
+ systrayModes.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ GeneralConfigPluginActivator.getConfigurationService()
+ .setProperty(SystrayService.PNMAE_TRAY_MODE,
+ ((Item) systrayModes.getSelectedItem()).key);
+ }
+ });
+
+ panel.add(systrayModes);
+ String label = "<html><body style='width:350px'>* " +
+ Resources.getString("service.systray.CLI_NOTE", new String[]{
+ Resources.getSettingsString("service.gui.APPLICATION_NAME")
+ }) + "</body></html>";
+ JLabel warnLabel = new JLabel(label);
+ warnLabel.setToolTipText(label);
+ warnLabel.setForeground(Color.GRAY);
+ warnLabel.setFont(warnLabel.getFont().deriveFont(8));
+ warnLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 8, 0));
+ panel.add(warnLabel);
+ return panel;
+ }
+
/**
* Creates the call configuration panel.
*
@@ -856,13 +960,11 @@ public class GeneralConfigurationPanel
*/
private Component createNormalizeNumberCheckBox()
{
- JPanel checkBoxPanel = new TransparentPanel(new BorderLayout());
-
- SIPCommCheckBox formatPhoneNumber = new SIPCommCheckBox("",
+ SIPCommCheckBox formatPhoneNumber = new SIPCommCheckBox(
+ GeneralConfigPluginActivator.getResources().getI18NString(
+ "plugin.generalconfig.REMOVE_SPECIAL_PHONE_SYMBOLS"),
ConfigurationUtils.isNormalizePhoneNumber());
- formatPhoneNumber.setAlignmentY(Component.TOP_ALIGNMENT);
-
formatPhoneNumber.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
@@ -872,22 +974,7 @@ public class GeneralConfigurationPanel
}
});
- StyledHTMLEditorPane checkBoxTextLabel = new StyledHTMLEditorPane();
-
- checkBoxTextLabel.setContentType("text/html");
- checkBoxTextLabel.appendToEnd(
- "<html>" + GeneralConfigPluginActivator.getResources().getI18NString(
- "plugin.generalconfig.REMOVE_SPECIAL_PHONE_SYMBOLS") + "</html>");
-
- checkBoxTextLabel.setBorder(
- BorderFactory.createEmptyBorder(3, 0, 0, 0));
- checkBoxTextLabel.setOpaque(false);
- checkBoxTextLabel.setEditable(false);
-
- checkBoxPanel.add(formatPhoneNumber, BorderLayout.WEST);
- checkBoxPanel.add(checkBoxTextLabel, BorderLayout.CENTER);
-
- return checkBoxPanel;
+ return formatPhoneNumber;
}
/**
@@ -897,17 +984,17 @@ public class GeneralConfigurationPanel
*/
private Component createAcceptPhoneNumberWithAlphaCharCheckBox()
{
- JPanel checkBoxPanel = new TransparentPanel(new BorderLayout());
+ JPanel checkBoxPanel = new TransparentPanel();
+ checkBoxPanel.setLayout(new BoxLayout(checkBoxPanel, BoxLayout.Y_AXIS));
// Checkbox to accept string with alphabetical characters as potential
// phone numbers.
- SIPCommCheckBox acceptPhoneNumberWithAlphaChars
- = new SIPCommCheckBox("",
+ SIPCommCheckBox alphaCharNumbers = new SIPCommCheckBox(
+ GeneralConfigPluginActivator.getResources().getI18NString(
+ "plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS"),
ConfigurationUtils.acceptPhoneNumberWithAlphaChars());
- acceptPhoneNumberWithAlphaChars.setAlignmentY(Component.TOP_ALIGNMENT);
-
- acceptPhoneNumberWithAlphaChars.addActionListener(new ActionListener()
+ alphaCharNumbers.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
@@ -916,21 +1003,6 @@ public class GeneralConfigurationPanel
}
});
- StyledHTMLEditorPane acceptPhoneNumberWithAlphaCharsTextLabel
- = new StyledHTMLEditorPane();
-
- acceptPhoneNumberWithAlphaCharsTextLabel.setContentType("text/html");
- acceptPhoneNumberWithAlphaCharsTextLabel.appendToEnd(
- "<html>"
- + GeneralConfigPluginActivator.getResources().getI18NString(
- "plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS")
- + "</html>");
-
- acceptPhoneNumberWithAlphaCharsTextLabel.setBorder(
- BorderFactory.createEmptyBorder(3, 0, 0, 0));
- acceptPhoneNumberWithAlphaCharsTextLabel.setOpaque(false);
- acceptPhoneNumberWithAlphaCharsTextLabel.setEditable(false);
-
// The example of changing letters to numbers in a phone number.
String label = "* " + Resources.getString(
"plugin.generalconfig.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS_EXAMPLE");
@@ -942,14 +1014,8 @@ public class GeneralConfigurationPanel
exampleLabel.setHorizontalAlignment(JLabel.LEFT);
// Adds the components to the current panel.
- checkBoxPanel.add(acceptPhoneNumberWithAlphaChars, BorderLayout.WEST);
- checkBoxPanel.add(
- acceptPhoneNumberWithAlphaCharsTextLabel,
- BorderLayout.CENTER);
- checkBoxPanel.add(
- exampleLabel,
- BorderLayout.SOUTH);
-
+ checkBoxPanel.add(alphaCharNumbers);
+ checkBoxPanel.add(exampleLabel);
return checkBoxPanel;
}
@@ -959,15 +1025,17 @@ public class GeneralConfigurationPanel
*/
public Component createStartupConfigPanel()
{
- if (!OSUtils.IS_WINDOWS)
- return null;
-
JPanel updateConfigPanel = GeneralConfigPluginActivator.
createConfigSectionComponent(
Resources.getString("plugin.generalconfig.STARTUP_CONFIG"));
- updateConfigPanel.add(createAutoStartCheckBox());
- updateConfigPanel.add(createUpdateCheckBox());
+ updateConfigPanel.add(createMinimzeInsteadOfHideCheckBox());
+ if (OSUtils.IS_WINDOWS)
+ {
+ updateConfigPanel.add(createAutoStartCheckBox());
+ updateConfigPanel.add(createUpdateCheckBox());
+ }
+
return updateConfigPanel;
}
diff --git a/src/net/java/sip/communicator/plugin/generalconfig/XMPPConfigForm.java b/src/net/java/sip/communicator/plugin/generalconfig/XMPPConfigForm.java
new file mode 100644
index 0000000..0113232
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/generalconfig/XMPPConfigForm.java
@@ -0,0 +1,101 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.plugin.generalconfig;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+import org.jitsi.service.configuration.*;
+
+import net.java.sip.communicator.plugin.desktoputil.*;
+
+/**
+ * Implementation of the configuration form.
+ *
+ * @author Timur Masar
+ */
+public class XMPPConfigForm
+extends TransparentPanel
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * The name of the property used to control whether to use
+ * all resources to show capabilities
+ */
+ public static final String PROP_XMPP_USE_ALL_RESOURCES_FOR_CAPABILITIES =
+ "net.java.sip.communicator.XMPP_USE_ALL_RESOURCES_FOR_CAPABILITIES";
+
+ /**
+ * The default value for the capabilities setting
+ */
+ public static final boolean USE_ALL_RESOURCES_FOR_CAPABILITIES_DEFAULT =
+ true;
+
+ /**
+ * The <tt>ConfigurationService</tt> to be used to access configuration
+ */
+ private final ConfigurationService configurationService
+ = GeneralConfigPluginActivator.getConfigurationService();
+
+ /**
+ * Creates the form.
+ */
+ public XMPPConfigForm()
+ {
+ super(new BorderLayout());
+ Box box = Box.createVerticalBox();
+ add(box, BorderLayout.NORTH);
+
+ TransparentPanel contentPanel = new TransparentPanel();
+ contentPanel.setLayout(new BorderLayout(10, 10));
+
+ box.add(contentPanel);
+
+ TransparentPanel labelPanel
+ = new TransparentPanel(new GridLayout(0, 1, 2, 2));
+ TransparentPanel valuePanel
+ = new TransparentPanel(new GridLayout(0, 1, 2, 2));
+
+ contentPanel.add(labelPanel, BorderLayout.CENTER);
+ contentPanel.add(valuePanel, BorderLayout.WEST);
+
+ final JCheckBox useAllResourcesForCapabilitiesCheckbox =
+ new SIPCommCheckBox(Resources.getString(
+ "plugin.generalconfig.XMPP_USE_ALL_RESOURCES"));
+
+ useAllResourcesForCapabilitiesCheckbox.addActionListener(
+ new ActionListener() {
+ public void actionPerformed(ActionEvent actionEvent) {
+ configurationService.setProperty(
+ PROP_XMPP_USE_ALL_RESOURCES_FOR_CAPABILITIES,
+ useAllResourcesForCapabilitiesCheckbox.isSelected());
+ }
+ });
+ useAllResourcesForCapabilitiesCheckbox.setSelected(
+ configurationService.getBoolean(
+ PROP_XMPP_USE_ALL_RESOURCES_FOR_CAPABILITIES,
+ USE_ALL_RESOURCES_FOR_CAPABILITIES_DEFAULT));
+ valuePanel.add(useAllResourcesForCapabilitiesCheckbox);
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayWatcher.java b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayWatcher.java
index 38a51c6..37bc48f 100644
--- a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayWatcher.java
+++ b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayWatcher.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,462 +15,462 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.generalconfig.autoaway;
-
-import java.beans.*;
-import java.util.*;
-
-import net.java.sip.communicator.plugin.generalconfig.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.service.sysactivity.*;
-import net.java.sip.communicator.service.sysactivity.event.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * Listens for idle events from SystemActivityNotifications Service.
- *
- * @author Damian Minkov
- */
-public class AutoAwayWatcher
- implements ServiceListener,
- RegistrationStateChangeListener
-{
- /**
- * The logger.
- */
- private static final Logger logger
- = Logger.getLogger(AutoAwayWatcher.class);
-
- /**
- * The states of providers before going to away.
- */
- private final Map<ProtocolProviderService, PresenceStatus> lastStates
- = new HashMap<ProtocolProviderService, PresenceStatus>();
-
- /**
- * Listens for idle events.
- */
- private IdleListener idleListener = null;
-
- /**
- * Creates AutoAway handler.
- */
- public AutoAwayWatcher()
- {
- if (Preferences.isEnabled())
- {
- start();
- }
-
- Preferences.addEnableChangeListener(
- new PropertyChangeListener()
- {
- public void propertyChange(PropertyChangeEvent evt)
- {
- if(Boolean.parseBoolean((String) evt.getNewValue()))
- start();
- else
- stopInner();
- }
- }
- );
-
- // listens for changes in configured value.
- Preferences.addTimerChangeListener(
- new PropertyChangeListener()
- {
- public void propertyChange(PropertyChangeEvent evt)
- {
- stopInner();
- start();
- }
- }
- );
- }
-
- /**
- * Starts and add needed listeners.
- */
- private void start()
- {
- if(idleListener == null)
- {
-
- idleListener = new IdleListener();
-
- SystemActivityNotificationsService
- systemActivityNotificationsService
- = getSystemActivityNotificationsService();
-
- systemActivityNotificationsService.addIdleSystemChangeListener(
- Preferences.getTimer() * 60 * 1000,
- idleListener);
- systemActivityNotificationsService
- .addSystemActivityChangeListener(idleListener);
-
- startListeningForNewProviders();
- }
- }
-
- /**
- * Start listening for new providers and their registration states.
- */
- private void startListeningForNewProviders()
- {
- // listen for new providers
- GeneralConfigPluginActivator.bundleContext.addServiceListener(this);
-
- // lets check current providers
- ServiceReference[] protocolProviderRefs = null;
- try
- {
- protocolProviderRefs = GeneralConfigPluginActivator.bundleContext
- .getServiceReferences(ProtocolProviderService.class.getName(),
- null);
- }
- catch (InvalidSyntaxException ex)
- {
- // this shouldn't happen since we're providing no parameter string
- // but let's log just in case.
- logger.error(
- "Error while retrieving service refs", ex);
- return;
- }
-
- // in case we found any
- if (protocolProviderRefs != null)
- {
- for (int i = 0; i < protocolProviderRefs.length; i++)
- {
- ProtocolProviderService provider = (ProtocolProviderService)
- GeneralConfigPluginActivator.bundleContext
- .getService(protocolProviderRefs[i]);
-
- this.handleProviderAdded(provider);
- }
- }
- }
-
- /**
- * Stop listening for new providers and their registration states.
- */
- private void stopListeningForNewProviders()
- {
- // stop listen for new providers
- GeneralConfigPluginActivator.bundleContext.removeServiceListener(this);
-
- // lets check current providers and remove registration state listener
- ServiceReference[] protocolProviderRefs = null;
- try
- {
- protocolProviderRefs = GeneralConfigPluginActivator.bundleContext
- .getServiceReferences(ProtocolProviderService.class.getName(),
- null);
- }
- catch (InvalidSyntaxException ex)
- {
- // this shouldn't happen since we're providing no parameter string
- // but let's log just in case.
- logger.error(
- "Error while retrieving service refs", ex);
- return;
- }
-
- // in case we found any
- if (protocolProviderRefs != null)
- {
- for (int i = 0; i < protocolProviderRefs.length; i++)
- {
- ProtocolProviderService provider = (ProtocolProviderService)
- GeneralConfigPluginActivator.bundleContext
- .getService(protocolProviderRefs[i]);
-
- this.handleProviderRemoved(provider);
- }
- }
- }
-
- /**
- * Stops and removes the listeners.
- */
- public void stop()
- {
- GeneralConfigPluginActivator.bundleContext.removeServiceListener(this);
- stopInner();
- }
-
- /**
- * Stops and removes the listeners.
- */
- private void stopInner()
- {
- if(idleListener != null)
- {
- SystemActivityNotificationsService
- systemActivityNotificationsService
- = getSystemActivityNotificationsService();
-
- systemActivityNotificationsService.removeIdleSystemChangeListener(
- idleListener);
- systemActivityNotificationsService
- .removeSystemActivityChangeListener(idleListener);
-
- stopListeningForNewProviders();
-
- idleListener = null;
- }
- }
-
- /**
- * Change protocol to away saving status so it can be set again when
- * out of idle state.
- */
- private void changeProtocolsToAway()
- {
- for (ProtocolProviderService protocolProvider
- : GeneralConfigPluginActivator.getProtocolProviders())
- {
- OperationSetPresence presence
- = protocolProvider.getOperationSet(
- OperationSetPresence.class);
-
- if(presence == null)
- continue;
-
- PresenceStatus status = presence.getPresenceStatus();
-
- if (status.getStatus() < PresenceStatus.AVAILABLE_THRESHOLD)
- {
- // already (manually) set to away or lower
- continue;
- }
-
- PresenceStatus newStatus
- = StatusUpdateThread.findAwayStatus(presence);
-
- try
- {
- if (newStatus != null && !status.equals(newStatus))
- {
- addProviderToLastStates(protocolProvider, status);
-
- presence.publishPresenceStatus(
- newStatus,
- newStatus.getStatusName());
- }
- }
- catch (IllegalArgumentException e)
- {
- }
- catch (IllegalStateException e)
- {
- }
- catch (OperationFailedException e)
- {
- }
- }
- }
-
- /**
- * Back to status which was already saved before going to idle.
- */
- private void changeProtocolsToPreviousState()
- {
- for (ProtocolProviderService protocolProvider
- : GeneralConfigPluginActivator.getProtocolProviders())
- {
- PresenceStatus lastState = lastStates.get(protocolProvider);
-
- if (lastState != null)
- {
- OperationSetPresence presence
- = protocolProvider.getOperationSet(
- OperationSetPresence.class);
- try
- {
- presence.publishPresenceStatus(lastState, "");
- }
- catch (IllegalArgumentException e)
- {
- }
- catch (IllegalStateException e)
- {
- }
- catch (OperationFailedException e)
- {
- }
- removeProviderFromLastStates(protocolProvider);
- }
- }
- }
-
- /**
- * The SystemActivityNotifications Service.
- * @return the SystemActivityNotifications Service.
- */
- private SystemActivityNotificationsService
- getSystemActivityNotificationsService()
- {
- return
- ServiceUtils.getService(
- GeneralConfigPluginActivator.bundleContext,
- SystemActivityNotificationsService.class);
- }
-
- /**
- * When new protocol provider is registered we add our
- * registration change listener.
- * If unregistered remove reference to the provider and the
- * registration change listener.
- *
- * @param serviceEvent ServiceEvent
- */
- public void serviceChanged(ServiceEvent serviceEvent)
- {
- Object service
- = GeneralConfigPluginActivator.bundleContext.getService(
- serviceEvent.getServiceReference());
-
- // we don't care if the source service is not a protocol provider
- if (service instanceof ProtocolProviderService)
- {
- int serviceEventType = serviceEvent.getType();
-
- if (serviceEventType == ServiceEvent.REGISTERED)
- handleProviderAdded((ProtocolProviderService) service);
- else if (serviceEventType == ServiceEvent.UNREGISTERING)
- handleProviderRemoved((ProtocolProviderService) service);
- }
- }
-
- /**
- * Used to set registration state change listener.
- *
- * @param provider ProtocolProviderService
- */
- private synchronized void handleProviderAdded(
- ProtocolProviderService provider)
- {
- provider.addRegistrationStateChangeListener(this);
- }
-
- /**
- * Removes the registration change listener.
- *
- * @param provider the ProtocolProviderService that has been unregistered.
- */
- private void handleProviderRemoved(ProtocolProviderService provider)
- {
- provider.removeRegistrationStateChangeListener(this);
- }
-
- /**
- * Remove provider from list with last statuses.
- * If this is the last provider stop listening for idle events.
- * @param provider
- */
- private synchronized void removeProviderFromLastStates(
- ProtocolProviderService provider)
- {
- lastStates.remove(provider);
- }
-
- /**
- * Remember provider's last status, normally before setting it to away.
- * If needed start listening for idle events.
- * @param provider the provider.
- * @param status the status to save.
- */
- private synchronized void addProviderToLastStates(
- ProtocolProviderService provider,
- PresenceStatus status)
- {
- if(lastStates.size() == 0)
- start();
-
- lastStates.put(provider, status);
- }
-
- /**
- * Listens for provider states.
- * @param evt
- */
- public void registrationStateChanged(RegistrationStateChangeEvent evt)
- {
- if(evt.getSource() instanceof ProtocolProviderService)
- {
- if(evt.getNewState().equals(RegistrationState.UNREGISTERED)
- || evt.getNewState().equals(RegistrationState.CONNECTION_FAILED))
- {
- removeProviderFromLastStates(evt.getProvider());
- }
- else if(evt.getNewState().equals(
- RegistrationState.REGISTERED))
- {
- // we have at least one provider, so lets start listening
- if(lastStates.size() == 0)
- {
- start();
- }
- else
- {
- // or check are we away
- if(getSystemActivityNotificationsService()
- .getTimeSinceLastInput()
- > Preferences.getTimer()*60*1000)
- {
- // we are away, so update the newly registered provider
- // do it in new thread to give the provider
- // time dispatch his status
- new Thread(new Runnable()
- {
- public void run()
- {
- try{
- Thread.sleep(1000);
- }
- catch(Throwable t){}
-
- changeProtocolsToAway();
- }
- }).start();
- }
- }
- }
- }
- }
-
- /**
- * Listener waiting for idle state change.
- */
- private class IdleListener
- implements SystemActivityChangeListener
- {
- /**
- * Listens for activities and set corresponding statuses.
- *
- * @param event the <tt>NotificationActionTypeEvent</tt>, which is
- */
- public void activityChanged(SystemActivityEvent event)
- {
- switch(event.getEventID())
- {
- case SystemActivityEvent.EVENT_DISPLAY_SLEEP:
- case SystemActivityEvent.EVENT_SCREEN_LOCKED:
- case SystemActivityEvent.EVENT_SCREENSAVER_START:
- case SystemActivityEvent.EVENT_SYSTEM_IDLE:
- changeProtocolsToAway();
- break;
- case SystemActivityEvent.EVENT_DISPLAY_WAKE:
- case SystemActivityEvent.EVENT_SCREEN_UNLOCKED:
- case SystemActivityEvent.EVENT_SCREENSAVER_STOP:
- case SystemActivityEvent.EVENT_SYSTEM_IDLE_END:
- changeProtocolsToPreviousState();
- break;
- }
- }
- }
-}
+package net.java.sip.communicator.plugin.generalconfig.autoaway;
+
+import java.beans.*;
+import java.util.*;
+
+import net.java.sip.communicator.plugin.generalconfig.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.service.sysactivity.*;
+import net.java.sip.communicator.service.sysactivity.event.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * Listens for idle events from SystemActivityNotifications Service.
+ *
+ * @author Damian Minkov
+ */
+public class AutoAwayWatcher
+ implements ServiceListener,
+ RegistrationStateChangeListener
+{
+ /**
+ * The logger.
+ */
+ private static final Logger logger
+ = Logger.getLogger(AutoAwayWatcher.class);
+
+ /**
+ * The states of providers before going to away.
+ */
+ private final Map<ProtocolProviderService, PresenceStatus> lastStates
+ = new HashMap<ProtocolProviderService, PresenceStatus>();
+
+ /**
+ * Listens for idle events.
+ */
+ private IdleListener idleListener = null;
+
+ /**
+ * Creates AutoAway handler.
+ */
+ public AutoAwayWatcher()
+ {
+ if (Preferences.isEnabled())
+ {
+ start();
+ }
+
+ Preferences.addEnableChangeListener(
+ new PropertyChangeListener()
+ {
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ if(Boolean.parseBoolean((String) evt.getNewValue()))
+ start();
+ else
+ stopInner();
+ }
+ }
+ );
+
+ // listens for changes in configured value.
+ Preferences.addTimerChangeListener(
+ new PropertyChangeListener()
+ {
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ stopInner();
+ start();
+ }
+ }
+ );
+ }
+
+ /**
+ * Starts and add needed listeners.
+ */
+ private void start()
+ {
+ if(idleListener == null)
+ {
+
+ idleListener = new IdleListener();
+
+ SystemActivityNotificationsService
+ systemActivityNotificationsService
+ = getSystemActivityNotificationsService();
+
+ systemActivityNotificationsService.addIdleSystemChangeListener(
+ Preferences.getTimer() * 60 * 1000,
+ idleListener);
+ systemActivityNotificationsService
+ .addSystemActivityChangeListener(idleListener);
+
+ startListeningForNewProviders();
+ }
+ }
+
+ /**
+ * Start listening for new providers and their registration states.
+ */
+ private void startListeningForNewProviders()
+ {
+ // listen for new providers
+ GeneralConfigPluginActivator.bundleContext.addServiceListener(this);
+
+ // lets check current providers
+ ServiceReference[] protocolProviderRefs = null;
+ try
+ {
+ protocolProviderRefs = GeneralConfigPluginActivator.bundleContext
+ .getServiceReferences(ProtocolProviderService.class.getName(),
+ null);
+ }
+ catch (InvalidSyntaxException ex)
+ {
+ // this shouldn't happen since we're providing no parameter string
+ // but let's log just in case.
+ logger.error(
+ "Error while retrieving service refs", ex);
+ return;
+ }
+
+ // in case we found any
+ if (protocolProviderRefs != null)
+ {
+ for (int i = 0; i < protocolProviderRefs.length; i++)
+ {
+ ProtocolProviderService provider = (ProtocolProviderService)
+ GeneralConfigPluginActivator.bundleContext
+ .getService(protocolProviderRefs[i]);
+
+ this.handleProviderAdded(provider);
+ }
+ }
+ }
+
+ /**
+ * Stop listening for new providers and their registration states.
+ */
+ private void stopListeningForNewProviders()
+ {
+ // stop listen for new providers
+ GeneralConfigPluginActivator.bundleContext.removeServiceListener(this);
+
+ // lets check current providers and remove registration state listener
+ ServiceReference[] protocolProviderRefs = null;
+ try
+ {
+ protocolProviderRefs = GeneralConfigPluginActivator.bundleContext
+ .getServiceReferences(ProtocolProviderService.class.getName(),
+ null);
+ }
+ catch (InvalidSyntaxException ex)
+ {
+ // this shouldn't happen since we're providing no parameter string
+ // but let's log just in case.
+ logger.error(
+ "Error while retrieving service refs", ex);
+ return;
+ }
+
+ // in case we found any
+ if (protocolProviderRefs != null)
+ {
+ for (int i = 0; i < protocolProviderRefs.length; i++)
+ {
+ ProtocolProviderService provider = (ProtocolProviderService)
+ GeneralConfigPluginActivator.bundleContext
+ .getService(protocolProviderRefs[i]);
+
+ this.handleProviderRemoved(provider);
+ }
+ }
+ }
+
+ /**
+ * Stops and removes the listeners.
+ */
+ public void stop()
+ {
+ GeneralConfigPluginActivator.bundleContext.removeServiceListener(this);
+ stopInner();
+ }
+
+ /**
+ * Stops and removes the listeners.
+ */
+ private void stopInner()
+ {
+ if(idleListener != null)
+ {
+ SystemActivityNotificationsService
+ systemActivityNotificationsService
+ = getSystemActivityNotificationsService();
+
+ systemActivityNotificationsService.removeIdleSystemChangeListener(
+ idleListener);
+ systemActivityNotificationsService
+ .removeSystemActivityChangeListener(idleListener);
+
+ stopListeningForNewProviders();
+
+ idleListener = null;
+ }
+ }
+
+ /**
+ * Change protocol to away saving status so it can be set again when
+ * out of idle state.
+ */
+ private void changeProtocolsToAway()
+ {
+ for (ProtocolProviderService protocolProvider
+ : GeneralConfigPluginActivator.getProtocolProviders())
+ {
+ OperationSetPresence presence
+ = protocolProvider.getOperationSet(
+ OperationSetPresence.class);
+
+ if(presence == null)
+ continue;
+
+ PresenceStatus status = presence.getPresenceStatus();
+
+ if (status.getStatus() < PresenceStatus.AVAILABLE_THRESHOLD)
+ {
+ // already (manually) set to away or lower
+ continue;
+ }
+
+ PresenceStatus newStatus
+ = StatusUpdateThread.findAwayStatus(presence);
+
+ try
+ {
+ if (newStatus != null && !status.equals(newStatus))
+ {
+ addProviderToLastStates(protocolProvider, status);
+
+ presence.publishPresenceStatus(
+ newStatus,
+ newStatus.getStatusName());
+ }
+ }
+ catch (IllegalArgumentException e)
+ {
+ }
+ catch (IllegalStateException e)
+ {
+ }
+ catch (OperationFailedException e)
+ {
+ }
+ }
+ }
+
+ /**
+ * Back to status which was already saved before going to idle.
+ */
+ private void changeProtocolsToPreviousState()
+ {
+ for (ProtocolProviderService protocolProvider
+ : GeneralConfigPluginActivator.getProtocolProviders())
+ {
+ PresenceStatus lastState = lastStates.get(protocolProvider);
+
+ if (lastState != null)
+ {
+ OperationSetPresence presence
+ = protocolProvider.getOperationSet(
+ OperationSetPresence.class);
+ try
+ {
+ presence.publishPresenceStatus(lastState, "");
+ }
+ catch (IllegalArgumentException e)
+ {
+ }
+ catch (IllegalStateException e)
+ {
+ }
+ catch (OperationFailedException e)
+ {
+ }
+ removeProviderFromLastStates(protocolProvider);
+ }
+ }
+ }
+
+ /**
+ * The SystemActivityNotifications Service.
+ * @return the SystemActivityNotifications Service.
+ */
+ private SystemActivityNotificationsService
+ getSystemActivityNotificationsService()
+ {
+ return
+ ServiceUtils.getService(
+ GeneralConfigPluginActivator.bundleContext,
+ SystemActivityNotificationsService.class);
+ }
+
+ /**
+ * When new protocol provider is registered we add our
+ * registration change listener.
+ * If unregistered remove reference to the provider and the
+ * registration change listener.
+ *
+ * @param serviceEvent ServiceEvent
+ */
+ public void serviceChanged(ServiceEvent serviceEvent)
+ {
+ Object service
+ = GeneralConfigPluginActivator.bundleContext.getService(
+ serviceEvent.getServiceReference());
+
+ // we don't care if the source service is not a protocol provider
+ if (service instanceof ProtocolProviderService)
+ {
+ int serviceEventType = serviceEvent.getType();
+
+ if (serviceEventType == ServiceEvent.REGISTERED)
+ handleProviderAdded((ProtocolProviderService) service);
+ else if (serviceEventType == ServiceEvent.UNREGISTERING)
+ handleProviderRemoved((ProtocolProviderService) service);
+ }
+ }
+
+ /**
+ * Used to set registration state change listener.
+ *
+ * @param provider ProtocolProviderService
+ */
+ private synchronized void handleProviderAdded(
+ ProtocolProviderService provider)
+ {
+ provider.addRegistrationStateChangeListener(this);
+ }
+
+ /**
+ * Removes the registration change listener.
+ *
+ * @param provider the ProtocolProviderService that has been unregistered.
+ */
+ private void handleProviderRemoved(ProtocolProviderService provider)
+ {
+ provider.removeRegistrationStateChangeListener(this);
+ }
+
+ /**
+ * Remove provider from list with last statuses.
+ * If this is the last provider stop listening for idle events.
+ * @param provider
+ */
+ private synchronized void removeProviderFromLastStates(
+ ProtocolProviderService provider)
+ {
+ lastStates.remove(provider);
+ }
+
+ /**
+ * Remember provider's last status, normally before setting it to away.
+ * If needed start listening for idle events.
+ * @param provider the provider.
+ * @param status the status to save.
+ */
+ private synchronized void addProviderToLastStates(
+ ProtocolProviderService provider,
+ PresenceStatus status)
+ {
+ if(lastStates.size() == 0)
+ start();
+
+ lastStates.put(provider, status);
+ }
+
+ /**
+ * Listens for provider states.
+ * @param evt
+ */
+ public void registrationStateChanged(RegistrationStateChangeEvent evt)
+ {
+ if(evt.getSource() instanceof ProtocolProviderService)
+ {
+ if(evt.getNewState().equals(RegistrationState.UNREGISTERED)
+ || evt.getNewState().equals(RegistrationState.CONNECTION_FAILED))
+ {
+ removeProviderFromLastStates(evt.getProvider());
+ }
+ else if(evt.getNewState().equals(
+ RegistrationState.REGISTERED))
+ {
+ // we have at least one provider, so lets start listening
+ if(lastStates.size() == 0)
+ {
+ start();
+ }
+ else
+ {
+ // or check are we away
+ if(getSystemActivityNotificationsService()
+ .getTimeSinceLastInput()
+ > Preferences.getTimer()*60*1000)
+ {
+ // we are away, so update the newly registered provider
+ // do it in new thread to give the provider
+ // time dispatch his status
+ new Thread(new Runnable()
+ {
+ public void run()
+ {
+ try{
+ Thread.sleep(1000);
+ }
+ catch(Throwable t){}
+
+ changeProtocolsToAway();
+ }
+ }).start();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Listener waiting for idle state change.
+ */
+ private class IdleListener
+ implements SystemActivityChangeListener
+ {
+ /**
+ * Listens for activities and set corresponding statuses.
+ *
+ * @param event the <tt>NotificationActionTypeEvent</tt>, which is
+ */
+ public void activityChanged(SystemActivityEvent event)
+ {
+ switch(event.getEventID())
+ {
+ case SystemActivityEvent.EVENT_DISPLAY_SLEEP:
+ case SystemActivityEvent.EVENT_SCREEN_LOCKED:
+ case SystemActivityEvent.EVENT_SCREENSAVER_START:
+ case SystemActivityEvent.EVENT_SYSTEM_IDLE:
+ changeProtocolsToAway();
+ break;
+ case SystemActivityEvent.EVENT_DISPLAY_WAKE:
+ case SystemActivityEvent.EVENT_SCREEN_UNLOCKED:
+ case SystemActivityEvent.EVENT_SCREENSAVER_STOP:
+ case SystemActivityEvent.EVENT_SYSTEM_IDLE_END:
+ changeProtocolsToPreviousState();
+ break;
+ }
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/Preferences.java b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/Preferences.java
index 148da25..bee52df 100644
--- a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/Preferences.java
+++ b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/Preferences.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,133 +15,133 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.generalconfig.autoaway;
-
-import net.java.sip.communicator.plugin.generalconfig.*;
-import org.jitsi.service.configuration.*;
-import org.jitsi.service.resources.*;
-
-import java.beans.*;
-
-/**
- * Preferences for the Status Update
- *
- * @author Thomas Hofer
- *
- */
-public final class Preferences
-{
- /**
- * Property indicating whether status change on away is enabled.
- */
- private static final String ENABLE
- = "net.java.sip.communicator.plugin.statusupdate.enable";
-
- /**
- * Property indicating the time in minutes to consider a pc in idle state.
- */
- private static final String TIMER
- = "net.java.sip.communicator.plugin.statusupdate.timer";
-
- /**
- * The default value to be displayed and to be considered
- * for {@link Preferences#TIMER}.
- */
- public static final int DEFAULT_TIMER = 15;
-
- /**
- * Whether change status on away is enabled.
- * @return whether change status on away is enabled.
- */
- static boolean isEnabled()
- {
- // if enabled start
- String enabledDefault
- = GeneralConfigPluginActivator.getResources().getSettingsString(
- Preferences.ENABLE);
-
- return
- GeneralConfigPluginActivator
- .getConfigurationService()
- .getBoolean(
- Preferences.ENABLE,
- Boolean.parseBoolean(enabledDefault));
- }
-
- /**
- * Returns the time in minutes to consider a pc in idle state.
- * @return the time in minutes to consider a pc in idle state.
- */
- static int getTimer()
- {
- ConfigurationService cfg
- = GeneralConfigPluginActivator.getConfigurationService();
- ResourceManagementService resources
- = GeneralConfigPluginActivator.getResources();
-
- String enabledDefault = resources.getSettingsString(Preferences.ENABLE);
-
- String timerDefaultStr = resources.getSettingsString(Preferences.TIMER);
- int timerDefault = DEFAULT_TIMER;
-
- if (timerDefaultStr != null)
- {
- try
- {
- timerDefault = Integer.parseInt(timerDefaultStr);
- }
- catch (NumberFormatException nfe)
- {
- }
- }
-
- return
- cfg.getBoolean(
- Preferences.ENABLE,
- Boolean.parseBoolean(enabledDefault))
- ? cfg.getInt(Preferences.TIMER, timerDefault)
- : 0;
- }
-
- /**
- * Save data in the configuration file
- * @param enabled is enabled
- * @param timer the time value to save
- */
- static void saveData(boolean enabled, String timer)
- {
- ConfigurationService cfg
- = GeneralConfigPluginActivator.getConfigurationService();
-
- cfg.setProperty(Preferences.ENABLE, Boolean.toString(enabled));
- cfg.setProperty(Preferences.TIMER, timer);
- }
-
- /**
- * Adds listener to detect property changes.
- * @param listener the listener to notify.
- */
- static void addEnableChangeListener(PropertyChangeListener listener)
- {
- // listens for changes in configuration enable/disable
- GeneralConfigPluginActivator
- .getConfigurationService()
- .addPropertyChangeListener(
- ENABLE,
- listener);
- }
-
- /**
- * Adds listener to detect timer property changes.
- * @param listener the listener to notify.
- */
- static void addTimerChangeListener(PropertyChangeListener listener)
- {
- // listens for changes in configuration enable/disable
- GeneralConfigPluginActivator
- .getConfigurationService()
- .addPropertyChangeListener(
- TIMER,
- listener);
- }
-}
+package net.java.sip.communicator.plugin.generalconfig.autoaway;
+
+import net.java.sip.communicator.plugin.generalconfig.*;
+import org.jitsi.service.configuration.*;
+import org.jitsi.service.resources.*;
+
+import java.beans.*;
+
+/**
+ * Preferences for the Status Update
+ *
+ * @author Thomas Hofer
+ *
+ */
+public final class Preferences
+{
+ /**
+ * Property indicating whether status change on away is enabled.
+ */
+ private static final String ENABLE
+ = "net.java.sip.communicator.plugin.statusupdate.enable";
+
+ /**
+ * Property indicating the time in minutes to consider a pc in idle state.
+ */
+ private static final String TIMER
+ = "net.java.sip.communicator.plugin.statusupdate.timer";
+
+ /**
+ * The default value to be displayed and to be considered
+ * for {@link Preferences#TIMER}.
+ */
+ public static final int DEFAULT_TIMER = 15;
+
+ /**
+ * Whether change status on away is enabled.
+ * @return whether change status on away is enabled.
+ */
+ static boolean isEnabled()
+ {
+ // if enabled start
+ String enabledDefault
+ = GeneralConfigPluginActivator.getResources().getSettingsString(
+ Preferences.ENABLE);
+
+ return
+ GeneralConfigPluginActivator
+ .getConfigurationService()
+ .getBoolean(
+ Preferences.ENABLE,
+ Boolean.parseBoolean(enabledDefault));
+ }
+
+ /**
+ * Returns the time in minutes to consider a pc in idle state.
+ * @return the time in minutes to consider a pc in idle state.
+ */
+ static int getTimer()
+ {
+ ConfigurationService cfg
+ = GeneralConfigPluginActivator.getConfigurationService();
+ ResourceManagementService resources
+ = GeneralConfigPluginActivator.getResources();
+
+ String enabledDefault = resources.getSettingsString(Preferences.ENABLE);
+
+ String timerDefaultStr = resources.getSettingsString(Preferences.TIMER);
+ int timerDefault = DEFAULT_TIMER;
+
+ if (timerDefaultStr != null)
+ {
+ try
+ {
+ timerDefault = Integer.parseInt(timerDefaultStr);
+ }
+ catch (NumberFormatException nfe)
+ {
+ }
+ }
+
+ return
+ cfg.getBoolean(
+ Preferences.ENABLE,
+ Boolean.parseBoolean(enabledDefault))
+ ? cfg.getInt(Preferences.TIMER, timerDefault)
+ : 0;
+ }
+
+ /**
+ * Save data in the configuration file
+ * @param enabled is enabled
+ * @param timer the time value to save
+ */
+ static void saveData(boolean enabled, String timer)
+ {
+ ConfigurationService cfg
+ = GeneralConfigPluginActivator.getConfigurationService();
+
+ cfg.setProperty(Preferences.ENABLE, Boolean.toString(enabled));
+ cfg.setProperty(Preferences.TIMER, timer);
+ }
+
+ /**
+ * Adds listener to detect property changes.
+ * @param listener the listener to notify.
+ */
+ static void addEnableChangeListener(PropertyChangeListener listener)
+ {
+ // listens for changes in configuration enable/disable
+ GeneralConfigPluginActivator
+ .getConfigurationService()
+ .addPropertyChangeListener(
+ ENABLE,
+ listener);
+ }
+
+ /**
+ * Adds listener to detect timer property changes.
+ * @param listener the listener to notify.
+ */
+ static void addTimerChangeListener(PropertyChangeListener listener)
+ {
+ // listens for changes in configuration enable/disable
+ GeneralConfigPluginActivator
+ .getConfigurationService()
+ .addPropertyChangeListener(
+ TIMER,
+ listener);
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyPluginActivator.java b/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyPluginActivator.java
index a80633e..7e9dbd5 100644
--- a/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyPluginActivator.java
+++ b/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyPluginActivator.java
@@ -175,9 +175,8 @@ public class GlobalProxyPluginActivator implements BundleActivator
"http.proxyPort", globalProxyPortStr);
}
- // used by some protocols like yahoo
- System.setProperty(
- "proxySet", "true");
+ // used by some protocols
+ System.setProperty("proxySet", "true");
}
else if(globalProxyType.equals(
ProxyInfo.ProxyType.SOCKS4.name()) ||
@@ -196,9 +195,8 @@ public class GlobalProxyPluginActivator implements BundleActivator
"socksProxyPort", globalProxyPortStr);
}
- // used by some protocols like yahoo
- System.setProperty(
- "socksProxySet", "true");
+ // used by some protocols
+ System.setProperty("socksProxySet", "true");
}
Authenticator.setDefault(new AuthenticatorImpl(
diff --git a/src/net/java/sip/communicator/plugin/googletalkaccregwizz/GoogleTalkAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/googletalkaccregwizz/GoogleTalkAccRegWizzActivator.java
index e457fdd..02b84e9 100644
--- a/src/net/java/sip/communicator/plugin/googletalkaccregwizz/GoogleTalkAccRegWizzActivator.java
+++ b/src/net/java/sip/communicator/plugin/googletalkaccregwizz/GoogleTalkAccRegWizzActivator.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,163 +15,163 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.googletalkaccregwizz;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.browserlauncher.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.resources.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.resources.*;
-import org.osgi.framework.*;
-
-/**
- * Registers the <tt>GoogleTalkAccountRegistrationWizard</tt> in the UI Service.
- *
- * @author Lubomir Marinov
- */
-public class GoogleTalkAccRegWizzActivator
- extends AbstractServiceDependentActivator
-{
- /**
- * OSGi bundle context.
- */
- public static BundleContext bundleContext;
-
- private static ResourceManagementService resourcesService;
-
- /**
- * The <tt>Logger</tt> used by the <tt>GoogleTalkAccRegWizzActivator</tt>
- * and its instances for logging output.
- */
- private static final Logger logger
- = Logger.getLogger(GoogleTalkAccRegWizzActivator.class);
-
- private static BrowserLauncherService browserLauncherService;
-
- private static UIService uiService;
-
- /**
- * Starts this bundle.
- */
- @Override
- public void start(Object dependentService)
- {
- uiService = (UIService)dependentService;
-
- GoogleTalkAccountRegistrationWizard wizard =
- new GoogleTalkAccountRegistrationWizard(uiService
- .getAccountRegWizardContainer());
-
- Hashtable<String, String> containerFilter
- = new Hashtable<String, String>();
- containerFilter.put(
- ProtocolProviderFactory.PROTOCOL,
- GoogleTalkAccountRegistrationWizard.PROTOCOL);
-
- bundleContext.registerService(
- AccountRegistrationWizard.class.getName(),
- wizard,
- containerFilter);
- }
-
- /**
- * The dependent class. We are waiting for the ui service.
- * @return
- */
- @Override
- public Class<?> getDependentServiceClass()
- {
- return UIService.class;
- }
-
- /**
- * The bundle context to use.
- * @param context the context to set.
- */
- @Override
- public void setBundleContext(BundleContext context)
- {
- bundleContext = context;
- }
-
- public void stop(BundleContext bundleContext)
- throws Exception
- {
- }
-
- /**
- * Returns the <tt>ProtocolProviderFactory</tt> for the Google Talk
- * protocol.
- *
- * @return the <tt>ProtocolProviderFactory</tt> for the Google Talk
- * protocol
- */
- public static ProtocolProviderFactory getGoogleTalkProtocolProviderFactory()
- {
- ServiceReference[] serRefs = null;
-
- String osgiFilter = "("
- + ProtocolProviderFactory.PROTOCOL
- + "=" + ProtocolNames.JABBER + ")";
-
- try
- {
- serRefs = bundleContext.getServiceReferences(
- ProtocolProviderFactory.class.getName(), osgiFilter);
- }
- catch (InvalidSyntaxException ex)
- {
- logger.error("GoogleTalkAccRegWizzActivator : " + ex);
- }
-
- return (ProtocolProviderFactory) bundleContext.getService(serRefs[0]);
- }
-
- /**
- * Returns the <tt>UIService</tt>.
- *
- * @return the <tt>UIService</tt>
- */
- public static UIService getUIService()
- {
- return uiService;
- }
-
- /**
- * Returns the <tt>BrowserLauncherService</tt> obtained from the bundle
- * context.
- * @return the <tt>BrowserLauncherService</tt> obtained from the bundle
- * context
- */
- public static BrowserLauncherService getBrowserLauncher()
- {
- if (browserLauncherService == null)
- {
- browserLauncherService =
- (BrowserLauncherService) bundleContext
- .getService(bundleContext
- .getServiceReference(BrowserLauncherService.class
- .getName()));
- }
-
- return browserLauncherService;
- }
-
- /**
- * Returns the <tt>ResourceManagementService</tt>.
- *
- * @return the <tt>ResourceManagementService</tt>.
- */
- public static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- resourcesService =
- ResourceManagementServiceUtils
- .getService(GoogleTalkAccRegWizzActivator.bundleContext);
- return resourcesService;
- }
-}
+package net.java.sip.communicator.plugin.googletalkaccregwizz;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.browserlauncher.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.resources.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.resources.*;
+import org.osgi.framework.*;
+
+/**
+ * Registers the <tt>GoogleTalkAccountRegistrationWizard</tt> in the UI Service.
+ *
+ * @author Lubomir Marinov
+ */
+public class GoogleTalkAccRegWizzActivator
+ extends AbstractServiceDependentActivator
+{
+ /**
+ * OSGi bundle context.
+ */
+ public static BundleContext bundleContext;
+
+ private static ResourceManagementService resourcesService;
+
+ /**
+ * The <tt>Logger</tt> used by the <tt>GoogleTalkAccRegWizzActivator</tt>
+ * and its instances for logging output.
+ */
+ private static final Logger logger
+ = Logger.getLogger(GoogleTalkAccRegWizzActivator.class);
+
+ private static BrowserLauncherService browserLauncherService;
+
+ private static UIService uiService;
+
+ /**
+ * Starts this bundle.
+ */
+ @Override
+ public void start(Object dependentService)
+ {
+ uiService = (UIService)dependentService;
+
+ GoogleTalkAccountRegistrationWizard wizard =
+ new GoogleTalkAccountRegistrationWizard(uiService
+ .getAccountRegWizardContainer());
+
+ Hashtable<String, String> containerFilter
+ = new Hashtable<String, String>();
+ containerFilter.put(
+ ProtocolProviderFactory.PROTOCOL,
+ GoogleTalkAccountRegistrationWizard.PROTOCOL);
+
+ bundleContext.registerService(
+ AccountRegistrationWizard.class.getName(),
+ wizard,
+ containerFilter);
+ }
+
+ /**
+ * The dependent class. We are waiting for the ui service.
+ * @return
+ */
+ @Override
+ public Class<?> getDependentServiceClass()
+ {
+ return UIService.class;
+ }
+
+ /**
+ * The bundle context to use.
+ * @param context the context to set.
+ */
+ @Override
+ public void setBundleContext(BundleContext context)
+ {
+ bundleContext = context;
+ }
+
+ public void stop(BundleContext bundleContext)
+ throws Exception
+ {
+ }
+
+ /**
+ * Returns the <tt>ProtocolProviderFactory</tt> for the Google Talk
+ * protocol.
+ *
+ * @return the <tt>ProtocolProviderFactory</tt> for the Google Talk
+ * protocol
+ */
+ public static ProtocolProviderFactory getGoogleTalkProtocolProviderFactory()
+ {
+ ServiceReference[] serRefs = null;
+
+ String osgiFilter = "("
+ + ProtocolProviderFactory.PROTOCOL
+ + "=" + ProtocolNames.JABBER + ")";
+
+ try
+ {
+ serRefs = bundleContext.getServiceReferences(
+ ProtocolProviderFactory.class.getName(), osgiFilter);
+ }
+ catch (InvalidSyntaxException ex)
+ {
+ logger.error("GoogleTalkAccRegWizzActivator : " + ex);
+ }
+
+ return (ProtocolProviderFactory) bundleContext.getService(serRefs[0]);
+ }
+
+ /**
+ * Returns the <tt>UIService</tt>.
+ *
+ * @return the <tt>UIService</tt>
+ */
+ public static UIService getUIService()
+ {
+ return uiService;
+ }
+
+ /**
+ * Returns the <tt>BrowserLauncherService</tt> obtained from the bundle
+ * context.
+ * @return the <tt>BrowserLauncherService</tt> obtained from the bundle
+ * context
+ */
+ public static BrowserLauncherService getBrowserLauncher()
+ {
+ if (browserLauncherService == null)
+ {
+ browserLauncherService =
+ (BrowserLauncherService) bundleContext
+ .getService(bundleContext
+ .getServiceReference(BrowserLauncherService.class
+ .getName()));
+ }
+
+ return browserLauncherService;
+ }
+
+ /**
+ * Returns the <tt>ResourceManagementService</tt>.
+ *
+ * @return the <tt>ResourceManagementService</tt>.
+ */
+ public static ResourceManagementService getResources()
+ {
+ if (resourcesService == null)
+ resourcesService =
+ ResourceManagementServiceUtils
+ .getService(GoogleTalkAccRegWizzActivator.bundleContext);
+ return resourcesService;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/googletalkaccregwizz/GoogleTalkAccountRegistrationWizard.java b/src/net/java/sip/communicator/plugin/googletalkaccregwizz/GoogleTalkAccountRegistrationWizard.java
index c296762..25b3b21 100644
--- a/src/net/java/sip/communicator/plugin/googletalkaccregwizz/GoogleTalkAccountRegistrationWizard.java
+++ b/src/net/java/sip/communicator/plugin/googletalkaccregwizz/GoogleTalkAccountRegistrationWizard.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,254 +15,254 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.googletalkaccregwizz;
-
-import java.util.*;
-
-import net.java.sip.communicator.plugin.jabberaccregwizz.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.jabber.*;
-
-/**
- * The <tt>GoogleTalkAccountRegistrationWizard</tt> is an implementation of the
- * <tt>AccountRegistrationWizard</tt> for the Google Talk protocol. It should
- * allow the user to create and configure a new Google Talk account.
- *
- * @author Lubomir Marinov
- * @author Yana Stamcheva
- */
-public class GoogleTalkAccountRegistrationWizard
- extends JabberAccountRegistrationWizard
-{
- /**
- * The Google Talk protocol name.
- */
- public static final String PROTOCOL = "Google Talk";
-
- /**
- * A constant pointing to the Google Talk protocol logo image.
- */
- public static final String PROTOCOL_ICON
- = "service.protocol.googletalk.GTALK_16x16";
-
- /**
- * A constant pointing to the Aim protocol wizard page image.
- */
- public static final String PAGE_IMAGE
- = "service.protocol.googletalk.GTALK_64x64";
-
- /**
- * Creates an instance of <tt>GoogleTalkAccountRegistrationWizard</tt>.
- * @param wizardContainer the wizard container, where this wizard
- * is added
- */
- public GoogleTalkAccountRegistrationWizard(WizardContainer wizardContainer)
- {
- super(wizardContainer);
- }
-
- /**
- * Returns the set of pages contained in this wizard.
- * @return Iterator
- */
- @Override
- public Iterator<WizardPage> getPages()
- {
- JabberAccountRegistration reg = new JabberAccountRegistration();
-
- setPredefinedProperties(reg);
-
- return getPages(reg);
- }
-
- /**
- * Returns a simple account registration form that would be the first form
- * shown to the user. Only if the user needs more settings she'll choose
- * to open the advanced wizard, consisted by all pages.
- *
- * @param isCreateAccount indicates if the simple form should be opened as
- * a create account form or as a login form
- * @return a simple account registration form
- */
- @Override
- public Object getSimpleForm(boolean isCreateAccount)
- {
- JabberAccountRegistration reg = new JabberAccountRegistration();
-
- setPredefinedProperties(reg);
-
- return getSimpleForm(reg, isCreateAccount);
- }
-
- /**
- * Sets all google talk specific properties.
- *
- * @param reg the registration object
- */
- private void setPredefinedProperties(JabberAccountRegistration reg)
- {
- reg.setDefaultUserSufix("gmail.com");
- reg.setServerAddress("talk.google.com");
-
- reg.setServerOverridden(true);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getIcon</code> method.
- * Returns the icon to be used for this wizard.
- * @return byte[]
- */
- @Override
- public byte[] getIcon()
- {
- return GoogleTalkAccRegWizzActivator.getResources()
- .getImageInBytes(PROTOCOL_ICON);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getPageImage</code> method.
- * Returns the image used to decorate the wizard page
- *
- * @return byte[] the image used to decorate the wizard page
- */
- @Override
- public byte[] getPageImage()
- {
- return GoogleTalkAccRegWizzActivator.getResources()
- .getImageInBytes(PAGE_IMAGE);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getProtocolName</code>
- * method. Returns the protocol name for this wizard.
- * @return String
- */
- @Override
- public String getProtocolName()
- {
- return GoogleTalkAccRegWizzActivator.getResources()
- .getI18NString("plugin.googletalkaccregwizz.PROTOCOL_NAME");
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getProtocolDescription
- * </code> method. Returns the description of the protocol for this wizard.
- * @return String
- */
- @Override
- public String getProtocolDescription()
- {
- return GoogleTalkAccRegWizzActivator.getResources()
- .getI18NString("plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION");
- }
-
- /**
- * Returns an example string, which should indicate to the user how the
- * user name should look like.
- * @return an example string, which should indicate to the user how the
- * user name should look like.
- */
- @Override
- public String getUserNameExample()
- {
- return "Ex: johnsmith@gmail.com or johnsmith";
- }
-
- /**
- * Returns the display label used for the sip id field.
- * @return the sip id display label string.
- */
- @Override
- protected String getUsernameLabel()
- {
- return GoogleTalkAccRegWizzActivator.getResources()
- .getI18NString("plugin.googletalkaccregwizz.USERNAME");
- }
-
- /**
- * Return the string for add existing account button.
- * @return the string for add existing account button.
- */
- @Override
- protected String getCreateAccountButtonLabel()
- {
- return GoogleTalkAccRegWizzActivator.getResources().getI18NString(
- "plugin.googletalkaccregwizz.NEW_ACCOUNT_TITLE");
- }
-
- /**
- * Return the string for create new account button.
- * @return the string for create new account button.
- */
- @Override
- protected String getCreateAccountLabel()
- {
- return GoogleTalkAccRegWizzActivator.getResources().getI18NString(
- "plugin.googletalkaccregwizz.REGISTER_NEW_ACCOUNT_TEXT");
- }
-
- /**
- * Returns the protocol name as listed in "ProtocolNames" or just the name
- * of the service.
- * @return the protocol name
- */
- @Override
- public String getProtocol()
- {
- return PROTOCOL;
- }
-
- /**
- * Returns the protocol icon path.
- * @return the protocol icon path
- */
- @Override
- public String getProtocolIconPath()
- {
- return "resources/images/protocol/googletalk";
- }
-
- /**
- * Returns the account icon path.
- * @return the account icon path
- */
- @Override
- public String getAccountIconPath()
- {
- return "resources/images/protocol/googletalk/logo32x32.png";
- }
-
- /**
- * Opens a browser on the sign up page.
- */
- @Override
- public void webSignup()
- {
- GoogleTalkAccRegWizzActivator.getBrowserLauncher()
- .openURL("https://www.google.com/accounts/NewAccount");
- }
-
- /**
- * Returns <code>true</code> if the web sign up is supported by the current
- * implementation, <code>false</code> - otherwise.
- * @return <code>true</code> if the web sign up is supported by the current
- * implementation, <code>false</code> - otherwise
- */
- @Override
- public boolean isWebSignupSupported()
- {
- return true;
- }
-
- /**
- * Returns an instance of <tt>CreateAccountService</tt> through which the
- * user could create an account. This method is meant to be implemented by
- * specific protocol provider wizards.
- * @return an instance of <tt>CreateAccountService</tt>
- */
- @Override
- protected JabberAccountCreationFormService getCreateAccountService()
- {
- return null;
- }
-}
+package net.java.sip.communicator.plugin.googletalkaccregwizz;
+
+import java.util.*;
+
+import net.java.sip.communicator.plugin.jabberaccregwizz.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.jabber.*;
+
+/**
+ * The <tt>GoogleTalkAccountRegistrationWizard</tt> is an implementation of the
+ * <tt>AccountRegistrationWizard</tt> for the Google Talk protocol. It should
+ * allow the user to create and configure a new Google Talk account.
+ *
+ * @author Lubomir Marinov
+ * @author Yana Stamcheva
+ */
+public class GoogleTalkAccountRegistrationWizard
+ extends JabberAccountRegistrationWizard
+{
+ /**
+ * The Google Talk protocol name.
+ */
+ public static final String PROTOCOL = "Google Talk";
+
+ /**
+ * A constant pointing to the Google Talk protocol logo image.
+ */
+ public static final String PROTOCOL_ICON
+ = "service.protocol.googletalk.GTALK_16x16";
+
+ /**
+ * A constant pointing to the Aim protocol wizard page image.
+ */
+ public static final String PAGE_IMAGE
+ = "service.protocol.googletalk.GTALK_64x64";
+
+ /**
+ * Creates an instance of <tt>GoogleTalkAccountRegistrationWizard</tt>.
+ * @param wizardContainer the wizard container, where this wizard
+ * is added
+ */
+ public GoogleTalkAccountRegistrationWizard(WizardContainer wizardContainer)
+ {
+ super(wizardContainer);
+ }
+
+ /**
+ * Returns the set of pages contained in this wizard.
+ * @return Iterator
+ */
+ @Override
+ public Iterator<WizardPage> getPages()
+ {
+ JabberAccountRegistration reg = new JabberAccountRegistration();
+
+ setPredefinedProperties(reg);
+
+ return getPages(reg);
+ }
+
+ /**
+ * Returns a simple account registration form that would be the first form
+ * shown to the user. Only if the user needs more settings she'll choose
+ * to open the advanced wizard, consisted by all pages.
+ *
+ * @param isCreateAccount indicates if the simple form should be opened as
+ * a create account form or as a login form
+ * @return a simple account registration form
+ */
+ @Override
+ public Object getSimpleForm(boolean isCreateAccount)
+ {
+ JabberAccountRegistration reg = new JabberAccountRegistration();
+
+ setPredefinedProperties(reg);
+
+ return getSimpleForm(reg, isCreateAccount);
+ }
+
+ /**
+ * Sets all google talk specific properties.
+ *
+ * @param reg the registration object
+ */
+ private void setPredefinedProperties(JabberAccountRegistration reg)
+ {
+ reg.setDefaultUserSufix("gmail.com");
+ reg.setServerAddress("talk.google.com");
+
+ reg.setServerOverridden(true);
+ }
+
+ /**
+ * Implements the <code>AccountRegistrationWizard.getIcon</code> method.
+ * Returns the icon to be used for this wizard.
+ * @return byte[]
+ */
+ @Override
+ public byte[] getIcon()
+ {
+ return GoogleTalkAccRegWizzActivator.getResources()
+ .getImageInBytes(PROTOCOL_ICON);
+ }
+
+ /**
+ * Implements the <code>AccountRegistrationWizard.getPageImage</code> method.
+ * Returns the image used to decorate the wizard page
+ *
+ * @return byte[] the image used to decorate the wizard page
+ */
+ @Override
+ public byte[] getPageImage()
+ {
+ return GoogleTalkAccRegWizzActivator.getResources()
+ .getImageInBytes(PAGE_IMAGE);
+ }
+
+ /**
+ * Implements the <code>AccountRegistrationWizard.getProtocolName</code>
+ * method. Returns the protocol name for this wizard.
+ * @return String
+ */
+ @Override
+ public String getProtocolName()
+ {
+ return GoogleTalkAccRegWizzActivator.getResources()
+ .getI18NString("plugin.googletalkaccregwizz.PROTOCOL_NAME");
+ }
+
+ /**
+ * Implements the <code>AccountRegistrationWizard.getProtocolDescription
+ * </code> method. Returns the description of the protocol for this wizard.
+ * @return String
+ */
+ @Override
+ public String getProtocolDescription()
+ {
+ return GoogleTalkAccRegWizzActivator.getResources()
+ .getI18NString("plugin.googletalkaccregwizz.PROTOCOL_DESCRIPTION");
+ }
+
+ /**
+ * Returns an example string, which should indicate to the user how the
+ * user name should look like.
+ * @return an example string, which should indicate to the user how the
+ * user name should look like.
+ */
+ @Override
+ public String getUserNameExample()
+ {
+ return "Ex: johnsmith@gmail.com or johnsmith";
+ }
+
+ /**
+ * Returns the display label used for the sip id field.
+ * @return the sip id display label string.
+ */
+ @Override
+ protected String getUsernameLabel()
+ {
+ return GoogleTalkAccRegWizzActivator.getResources()
+ .getI18NString("plugin.googletalkaccregwizz.USERNAME");
+ }
+
+ /**
+ * Return the string for add existing account button.
+ * @return the string for add existing account button.
+ */
+ @Override
+ protected String getCreateAccountButtonLabel()
+ {
+ return GoogleTalkAccRegWizzActivator.getResources().getI18NString(
+ "plugin.googletalkaccregwizz.NEW_ACCOUNT_TITLE");
+ }
+
+ /**
+ * Return the string for create new account button.
+ * @return the string for create new account button.
+ */
+ @Override
+ protected String getCreateAccountLabel()
+ {
+ return GoogleTalkAccRegWizzActivator.getResources().getI18NString(
+ "plugin.googletalkaccregwizz.REGISTER_NEW_ACCOUNT_TEXT");
+ }
+
+ /**
+ * Returns the protocol name as listed in "ProtocolNames" or just the name
+ * of the service.
+ * @return the protocol name
+ */
+ @Override
+ public String getProtocol()
+ {
+ return PROTOCOL;
+ }
+
+ /**
+ * Returns the protocol icon path.
+ * @return the protocol icon path
+ */
+ @Override
+ public String getProtocolIconPath()
+ {
+ return "resources/images/protocol/googletalk";
+ }
+
+ /**
+ * Returns the account icon path.
+ * @return the account icon path
+ */
+ @Override
+ public String getAccountIconPath()
+ {
+ return "resources/images/protocol/googletalk/logo32x32.png";
+ }
+
+ /**
+ * Opens a browser on the sign up page.
+ */
+ @Override
+ public void webSignup()
+ {
+ GoogleTalkAccRegWizzActivator.getBrowserLauncher()
+ .openURL("https://www.google.com/accounts/NewAccount");
+ }
+
+ /**
+ * Returns <code>true</code> if the web sign up is supported by the current
+ * implementation, <code>false</code> - otherwise.
+ * @return <code>true</code> if the web sign up is supported by the current
+ * implementation, <code>false</code> - otherwise
+ */
+ @Override
+ public boolean isWebSignupSupported()
+ {
+ return true;
+ }
+
+ /**
+ * Returns an instance of <tt>CreateAccountService</tt> through which the
+ * user could create an account. This method is meant to be implemented by
+ * specific protocol provider wizards.
+ * @return an instance of <tt>CreateAccountService</tt>
+ */
+ @Override
+ protected JabberAccountCreationFormService getCreateAccountService()
+ {
+ return null;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/iptelaccregwizz/IptelAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/iptelaccregwizz/IptelAccRegWizzActivator.java
index c50178c..7340901 100644
--- a/src/net/java/sip/communicator/plugin/iptelaccregwizz/IptelAccRegWizzActivator.java
+++ b/src/net/java/sip/communicator/plugin/iptelaccregwizz/IptelAccRegWizzActivator.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,154 +15,154 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.iptelaccregwizz;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.browserlauncher.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.resources.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.resources.*;
-import org.osgi.framework.*;
-
-/**
- * Registers the <tt>GoogleTalkAccountRegistrationWizard</tt> in the UI Service.
- *
- * @author Lubomir Marinov
- */
-public class IptelAccRegWizzActivator
- extends AbstractServiceDependentActivator
-{
- /**
- * OSGi bundle context.
- */
- public static BundleContext bundleContext;
-
- /**
- * The <tt>Logger</tt> used by the <tt>IptelAccRegWizzActivator</tt> class
- * and its instances for logging output.
- */
- private static final Logger logger
- = Logger.getLogger(IptelAccRegWizzActivator.class);
-
- private static BrowserLauncherService browserLauncherService;
-
- private static ResourceManagementService resourcesService;
-
- private static UIService uiService;
-
- /**
- * Starts this bundle.
- */
- @Override
- public void start(Object dependentService)
- {
- uiService = (UIService)dependentService;
-
- IptelAccountRegistrationWizard wizard
- = new IptelAccountRegistrationWizard(uiService
- .getAccountRegWizardContainer());
-
- Hashtable<String, String> containerFilter
- = new Hashtable<String, String>();
- containerFilter.put(
- ProtocolProviderFactory.PROTOCOL,
- IptelAccountRegistrationWizard.PROTOCOL);
-
- bundleContext.registerService(
- AccountRegistrationWizard.class.getName(),
- wizard,
- containerFilter);
- }
-
- /**
- * The dependent class. We are waiting for the ui service.
- * @return the ui service class.
- */
- @Override
- public Class<?> getDependentServiceClass()
- {
- return UIService.class;
- }
-
- /**
- * The bundle context to use.
- * @param context the context to set.
- */
- @Override
- public void setBundleContext(BundleContext context)
- {
- bundleContext = context;
- }
-
- public void stop(BundleContext bundleContext) throws Exception {}
-
- /**
- * Returns the <tt>ProtocolProviderFactory</tt> for the IP Tel protocol.
- *
- * @return the <tt>ProtocolProviderFactory</tt> for the IP Tel protocol
- */
- public static ProtocolProviderFactory getIptelProtocolProviderFactory()
- {
- ServiceReference[] serRefs = null;
-
- String osgiFilter = "("
- + ProtocolProviderFactory.PROTOCOL
- + "=" + ProtocolNames.SIP + ")";
-
- try
- {
- serRefs = bundleContext.getServiceReferences(
- ProtocolProviderFactory.class.getName(), osgiFilter);
- }
- catch (InvalidSyntaxException ex)
- {
- logger.error("IptelAccRegWizzActivator : " + ex);
- }
-
- return (ProtocolProviderFactory) bundleContext.getService(serRefs[0]);
- }
-
- /**
- * Returns the <tt>UIService</tt>.
- *
- * @return the <tt>UIService</tt>
- */
- public static UIService getUIService()
- {
- return uiService;
- }
-
- /**
- * Returns the <tt>BrowserLauncherService</tt> obtained from the bundle
- * context.
- * @return the <tt>BrowserLauncherService</tt> obtained from the bundle
- * context
- */
- public static BrowserLauncherService getBrowserLauncher()
- {
- if (browserLauncherService == null)
- {
- browserLauncherService
- = (BrowserLauncherService) bundleContext.getService(
- bundleContext.getServiceReference(
- BrowserLauncherService.class.getName()));
- }
- return browserLauncherService;
- }
-
- /**
- * Returns the service giving access to resources.
- * @return the service giving access to resources
- */
- public static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- resourcesService = ResourceManagementServiceUtils
- .getService(IptelAccRegWizzActivator.bundleContext);
- return resourcesService;
- }
-}
+package net.java.sip.communicator.plugin.iptelaccregwizz;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.browserlauncher.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.resources.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.resources.*;
+import org.osgi.framework.*;
+
+/**
+ * Registers the <tt>GoogleTalkAccountRegistrationWizard</tt> in the UI Service.
+ *
+ * @author Lubomir Marinov
+ */
+public class IptelAccRegWizzActivator
+ extends AbstractServiceDependentActivator
+{
+ /**
+ * OSGi bundle context.
+ */
+ public static BundleContext bundleContext;
+
+ /**
+ * The <tt>Logger</tt> used by the <tt>IptelAccRegWizzActivator</tt> class
+ * and its instances for logging output.
+ */
+ private static final Logger logger
+ = Logger.getLogger(IptelAccRegWizzActivator.class);
+
+ private static BrowserLauncherService browserLauncherService;
+
+ private static ResourceManagementService resourcesService;
+
+ private static UIService uiService;
+
+ /**
+ * Starts this bundle.
+ */
+ @Override
+ public void start(Object dependentService)
+ {
+ uiService = (UIService)dependentService;
+
+ IptelAccountRegistrationWizard wizard
+ = new IptelAccountRegistrationWizard(uiService
+ .getAccountRegWizardContainer());
+
+ Hashtable<String, String> containerFilter
+ = new Hashtable<String, String>();
+ containerFilter.put(
+ ProtocolProviderFactory.PROTOCOL,
+ IptelAccountRegistrationWizard.PROTOCOL);
+
+ bundleContext.registerService(
+ AccountRegistrationWizard.class.getName(),
+ wizard,
+ containerFilter);
+ }
+
+ /**
+ * The dependent class. We are waiting for the ui service.
+ * @return the ui service class.
+ */
+ @Override
+ public Class<?> getDependentServiceClass()
+ {
+ return UIService.class;
+ }
+
+ /**
+ * The bundle context to use.
+ * @param context the context to set.
+ */
+ @Override
+ public void setBundleContext(BundleContext context)
+ {
+ bundleContext = context;
+ }
+
+ public void stop(BundleContext bundleContext) throws Exception {}
+
+ /**
+ * Returns the <tt>ProtocolProviderFactory</tt> for the IP Tel protocol.
+ *
+ * @return the <tt>ProtocolProviderFactory</tt> for the IP Tel protocol
+ */
+ public static ProtocolProviderFactory getIptelProtocolProviderFactory()
+ {
+ ServiceReference[] serRefs = null;
+
+ String osgiFilter = "("
+ + ProtocolProviderFactory.PROTOCOL
+ + "=" + ProtocolNames.SIP + ")";
+
+ try
+ {
+ serRefs = bundleContext.getServiceReferences(
+ ProtocolProviderFactory.class.getName(), osgiFilter);
+ }
+ catch (InvalidSyntaxException ex)
+ {
+ logger.error("IptelAccRegWizzActivator : " + ex);
+ }
+
+ return (ProtocolProviderFactory) bundleContext.getService(serRefs[0]);
+ }
+
+ /**
+ * Returns the <tt>UIService</tt>.
+ *
+ * @return the <tt>UIService</tt>
+ */
+ public static UIService getUIService()
+ {
+ return uiService;
+ }
+
+ /**
+ * Returns the <tt>BrowserLauncherService</tt> obtained from the bundle
+ * context.
+ * @return the <tt>BrowserLauncherService</tt> obtained from the bundle
+ * context
+ */
+ public static BrowserLauncherService getBrowserLauncher()
+ {
+ if (browserLauncherService == null)
+ {
+ browserLauncherService
+ = (BrowserLauncherService) bundleContext.getService(
+ bundleContext.getServiceReference(
+ BrowserLauncherService.class.getName()));
+ }
+ return browserLauncherService;
+ }
+
+ /**
+ * Returns the service giving access to resources.
+ * @return the service giving access to resources
+ */
+ public static ResourceManagementService getResources()
+ {
+ if (resourcesService == null)
+ resourcesService = ResourceManagementServiceUtils
+ .getService(IptelAccRegWizzActivator.bundleContext);
+ return resourcesService;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/iptelaccregwizz/IptelAccountRegistrationWizard.java b/src/net/java/sip/communicator/plugin/iptelaccregwizz/IptelAccountRegistrationWizard.java
index 699496c..38b7a0a 100644
--- a/src/net/java/sip/communicator/plugin/iptelaccregwizz/IptelAccountRegistrationWizard.java
+++ b/src/net/java/sip/communicator/plugin/iptelaccregwizz/IptelAccountRegistrationWizard.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,205 +15,205 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.iptelaccregwizz;
-
-import java.util.*;
-
-import net.java.sip.communicator.plugin.sipaccregwizz.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.sip.*;
-
-/**
- * The <tt>IptelAccountRegistrationWizard</tt> is an implementation of the
- * <tt>AccountRegistrationWizard</tt> for the SIP protocol. It should allow
- * the user to create and configure a new SIP account.
- *
- * @author Yana Stamcheva
- */
-public class IptelAccountRegistrationWizard
- extends SIPAccountRegistrationWizard
-{
- /**
- * A constant pointing to the IP Tel protocol logo image.
- */
- private static final String PROTOCOL_ICON
- = "service.protocol.iptel.IPTEL_16x16";
-
- /**
- * A constant pointing to the IP Tel protocol wizard page image.
- */
- private static final String PAGE_IMAGE
- = "service.protocol.iptel.IPTEL_64x64";
-
- /**
- * The protocol name.
- */
- public static final String PROTOCOL = "iptel.org";
-
- /**
- * Creates an instance of <tt>IptelAccountRegistrationWizard</tt>.
- * @param wizardContainer the wizard container
- */
- public IptelAccountRegistrationWizard(WizardContainer wizardContainer)
- {
- super(wizardContainer);
- }
-
- /**
- * Returns the set of pages contained in this wizard.
- * @return Iterator
- */
- @Override
- public Iterator<WizardPage> getPages()
- {
- SIPAccountRegistration reg = new SIPAccountRegistration();
-
- setPredefinedProperties(reg);
-
- return getPages(reg);
- }
-
- /**
- * Returns a simple account registration form that would be the first form
- * shown to the user. Only if the user needs more settings she'll choose
- * to open the advanced wizard, consisted by all pages.
- *
- * @param isCreateAccount indicates if the simple form should be opened as
- * a create account form or as a login form
- * @return a simple account registration form
- */
- @Override
- public Object getSimpleForm(boolean isCreateAccount)
- {
- SIPAccountRegistration reg = new SIPAccountRegistration();
-
- setPredefinedProperties(reg);
-
- return getSimpleForm(reg, isCreateAccount);
- }
-
- /**
- * Sets all iptel specific properties.
- *
- * @param reg the registration object
- */
- private void setPredefinedProperties(SIPAccountRegistration reg)
- {
- reg.setDefaultDomain("iptel.org");
- reg.setPreferredTransport("TCP");
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getIcon</code> method.
- * Returns the icon to be used for this wizard.
- * @return byte[]
- */
- @Override
- public byte[] getIcon()
- {
- return IptelAccRegWizzActivator.getResources()
- .getImageInBytes(PROTOCOL_ICON);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getPageImage</code> method.
- * Returns the image used to decorate the wizard page
- *
- * @return byte[] the image used to decorate the wizard page
- */
- @Override
- public byte[] getPageImage()
- {
- return IptelAccRegWizzActivator.getResources()
- .getImageInBytes(PAGE_IMAGE);
- }
-
-
- /**
- * Implements the <code>AccountRegistrationWizard.getProtocolName</code>
- * method. Returns the protocol name for this wizard.
- * @return String
- */
- @Override
- public String getProtocolName()
- {
- return Resources.getString(
- "plugin.iptelaccregwizz.PROTOCOL_NAME");
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getProtocolDescription
- * </code> method. Returns the description of the protocol for this wizard.
- * @return String
- */
- @Override
- public String getProtocolDescription()
- {
- return Resources.getString(
- "plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION");
- }
-
- /**
- * Returns an example string, which should indicate to the user how the
- * user name should look like.
- * @return an example string, which should indicate to the user how the
- * user name should look like.
- */
- @Override
- public String getUserNameExample()
- {
- return "Ex: myusername or myusername@iptel.org";
- }
-
- /**
- * Returns the protocol name as listed in "ProtocolNames" or just the name
- * of the service.
- * @return the protocol name
- */
- @Override
- public String getProtocol()
- {
- return PROTOCOL;
- }
-
- /**
- * Returns the protocol icon path.
- * @return the protocol icon path
- */
- @Override
- public String getProtocolIconPath()
- {
- return "resources/images/protocol/iptel";
- }
-
- /**
- * Returns the account icon path.
- * @return the account icon path
- */
- @Override
- public String getAccountIconPath()
- {
- return "resources/images/protocol/iptel/sip32x32.png";
- }
-
- /**
- * Opens the browser on the page sign up
- */
- @Override
- public void webSignup()
- {
- IptelAccRegWizzActivator.getBrowserLauncher()
- .openURL("https://serweb.iptel.org/user/reg/index.php");
- }
-
- /**
- * Returns the name of the web sign up link.
- * @return the name of the web sign up link
- */
- @Override
- public String getWebSignupLinkName()
- {
- return IptelAccRegWizzActivator.getResources().getI18NString(
- "plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE");
- }
-}
+package net.java.sip.communicator.plugin.iptelaccregwizz;
+
+import java.util.*;
+
+import net.java.sip.communicator.plugin.sipaccregwizz.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.sip.*;
+
+/**
+ * The <tt>IptelAccountRegistrationWizard</tt> is an implementation of the
+ * <tt>AccountRegistrationWizard</tt> for the SIP protocol. It should allow
+ * the user to create and configure a new SIP account.
+ *
+ * @author Yana Stamcheva
+ */
+public class IptelAccountRegistrationWizard
+ extends SIPAccountRegistrationWizard
+{
+ /**
+ * A constant pointing to the IP Tel protocol logo image.
+ */
+ private static final String PROTOCOL_ICON
+ = "service.protocol.iptel.IPTEL_16x16";
+
+ /**
+ * A constant pointing to the IP Tel protocol wizard page image.
+ */
+ private static final String PAGE_IMAGE
+ = "service.protocol.iptel.IPTEL_64x64";
+
+ /**
+ * The protocol name.
+ */
+ public static final String PROTOCOL = "iptel.org";
+
+ /**
+ * Creates an instance of <tt>IptelAccountRegistrationWizard</tt>.
+ * @param wizardContainer the wizard container
+ */
+ public IptelAccountRegistrationWizard(WizardContainer wizardContainer)
+ {
+ super(wizardContainer);
+ }
+
+ /**
+ * Returns the set of pages contained in this wizard.
+ * @return Iterator
+ */
+ @Override
+ public Iterator<WizardPage> getPages()
+ {
+ SIPAccountRegistration reg = new SIPAccountRegistration();
+
+ setPredefinedProperties(reg);
+
+ return getPages(reg);
+ }
+
+ /**
+ * Returns a simple account registration form that would be the first form
+ * shown to the user. Only if the user needs more settings she'll choose
+ * to open the advanced wizard, consisted by all pages.
+ *
+ * @param isCreateAccount indicates if the simple form should be opened as
+ * a create account form or as a login form
+ * @return a simple account registration form
+ */
+ @Override
+ public Object getSimpleForm(boolean isCreateAccount)
+ {
+ SIPAccountRegistration reg = new SIPAccountRegistration();
+
+ setPredefinedProperties(reg);
+
+ return getSimpleForm(reg, isCreateAccount);
+ }
+
+ /**
+ * Sets all iptel specific properties.
+ *
+ * @param reg the registration object
+ */
+ private void setPredefinedProperties(SIPAccountRegistration reg)
+ {
+ reg.setDefaultDomain("iptel.org");
+ reg.setPreferredTransport("TCP");
+ }
+
+ /**
+ * Implements the <code>AccountRegistrationWizard.getIcon</code> method.
+ * Returns the icon to be used for this wizard.
+ * @return byte[]
+ */
+ @Override
+ public byte[] getIcon()
+ {
+ return IptelAccRegWizzActivator.getResources()
+ .getImageInBytes(PROTOCOL_ICON);
+ }
+
+ /**
+ * Implements the <code>AccountRegistrationWizard.getPageImage</code> method.
+ * Returns the image used to decorate the wizard page
+ *
+ * @return byte[] the image used to decorate the wizard page
+ */
+ @Override
+ public byte[] getPageImage()
+ {
+ return IptelAccRegWizzActivator.getResources()
+ .getImageInBytes(PAGE_IMAGE);
+ }
+
+
+ /**
+ * Implements the <code>AccountRegistrationWizard.getProtocolName</code>
+ * method. Returns the protocol name for this wizard.
+ * @return String
+ */
+ @Override
+ public String getProtocolName()
+ {
+ return Resources.getString(
+ "plugin.iptelaccregwizz.PROTOCOL_NAME");
+ }
+
+ /**
+ * Implements the <code>AccountRegistrationWizard.getProtocolDescription
+ * </code> method. Returns the description of the protocol for this wizard.
+ * @return String
+ */
+ @Override
+ public String getProtocolDescription()
+ {
+ return Resources.getString(
+ "plugin.iptelaccregwizz.PROTOCOL_DESCRIPTION");
+ }
+
+ /**
+ * Returns an example string, which should indicate to the user how the
+ * user name should look like.
+ * @return an example string, which should indicate to the user how the
+ * user name should look like.
+ */
+ @Override
+ public String getUserNameExample()
+ {
+ return "Ex: myusername or myusername@iptel.org";
+ }
+
+ /**
+ * Returns the protocol name as listed in "ProtocolNames" or just the name
+ * of the service.
+ * @return the protocol name
+ */
+ @Override
+ public String getProtocol()
+ {
+ return PROTOCOL;
+ }
+
+ /**
+ * Returns the protocol icon path.
+ * @return the protocol icon path
+ */
+ @Override
+ public String getProtocolIconPath()
+ {
+ return "resources/images/protocol/iptel";
+ }
+
+ /**
+ * Returns the account icon path.
+ * @return the account icon path
+ */
+ @Override
+ public String getAccountIconPath()
+ {
+ return "resources/images/protocol/iptel/sip32x32.png";
+ }
+
+ /**
+ * Opens the browser on the page sign up
+ */
+ @Override
+ public void webSignup()
+ {
+ IptelAccRegWizzActivator.getBrowserLauncher()
+ .openURL("https://serweb.iptel.org/user/reg/index.php");
+ }
+
+ /**
+ * Returns the name of the web sign up link.
+ * @return the name of the web sign up link
+ */
+ @Override
+ public String getWebSignupLinkName()
+ {
+ return IptelAccRegWizzActivator.getResources().getI18NString(
+ "plugin.iptelaccregwizz.NEW_ACCOUNT_TITLE");
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/ircaccregwizz/IrcAccountRegistrationWizard.java b/src/net/java/sip/communicator/plugin/ircaccregwizz/IrcAccountRegistrationWizard.java
index f062058..962aeb1 100644
--- a/src/net/java/sip/communicator/plugin/ircaccregwizz/IrcAccountRegistrationWizard.java
+++ b/src/net/java/sip/communicator/plugin/ircaccregwizz/IrcAccountRegistrationWizard.java
@@ -358,8 +358,7 @@ public class IrcAccountRegistrationWizard
ServiceReference<ProtocolProviderService> serRef = providerFactory
.getProviderForAccount(accountID);
- protocolProvider = (ProtocolProviderService)
- IrcAccRegWizzActivator.bundleContext
+ protocolProvider = IrcAccRegWizzActivator.bundleContext
.getService(serRef);
}
catch (IllegalStateException exc)
diff --git a/src/net/java/sip/communicator/plugin/jabberaccregwizz/AccountPanel.java b/src/net/java/sip/communicator/plugin/jabberaccregwizz/AccountPanel.java
index 0467033..c046348 100644
--- a/src/net/java/sip/communicator/plugin/jabberaccregwizz/AccountPanel.java
+++ b/src/net/java/sip/communicator/plugin/jabberaccregwizz/AccountPanel.java
@@ -140,7 +140,7 @@ public class AccountPanel
userIDPassPanel.setBorder(
BorderFactory.createTitledBorder(
Resources.getString(
- "plugin.sipaccregwizz.USERNAME_AND_PASSWORD")));
+ "plugin.jabberaccregwizz.USERNAME_AND_PASSWORD")));
JPanel southPanel = new TransparentPanel(new BorderLayout());
southPanel.add(rememberPassBox, BorderLayout.WEST);
@@ -564,8 +564,7 @@ public class AccountPanel
OperationSetChangePassword.class).supportsPasswordChange())
{
changePasswordMessagePane.setText(Resources.getString(
- "plugin.jabberaccregwizz."
- + "SERVER_NOT_SUPPORT_PASSWORD_CHANGE"));
+ "plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE"));
}
else
{
@@ -683,8 +682,7 @@ public class AccountPanel
getAccountID().getAccountAddress(),
ex);
displayPopupError(Resources.getString(
- "plugin.jabberaccregwizz."
- + "PASSWORD_NOT_STORED"));
+ "plugin.jabberaccregwizz.PASSWORD_NOT_STORED"));
}
}
//now update the password field in AccountPanel,
@@ -705,8 +703,7 @@ public class AccountPanel
}
catch (OperationFailedException ex) {
displayPopupError(Resources.getString(
- "plugin.jabberaccregwizz."
- + "SERVER_NOT_SUPPORT_PASSWORD_CHANGE"));
+ "plugin.jabberaccregwizz.SERVER_NOT_SUPPORT_PASSWORD_CHANGE"));
}
}
}
diff --git a/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountCreationForm.java b/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountCreationForm.java
index 6288821..3e816cf 100644
--- a/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountCreationForm.java
+++ b/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountCreationForm.java
@@ -93,7 +93,7 @@ public class JabberAccountCreationForm
private JButton chooseButton = new JButton();
// Smack objects
- private XMPPConnection xmppConnection = null;
+ private Connection xmppConnection = null;
private AccountManager accountManager = null;
diff --git a/src/net/java/sip/communicator/plugin/keybindingchooser/chooser/BindingChooser.java b/src/net/java/sip/communicator/plugin/keybindingchooser/chooser/BindingChooser.java
index bd8ff0d..12ba3e2 100644
--- a/src/net/java/sip/communicator/plugin/keybindingchooser/chooser/BindingChooser.java
+++ b/src/net/java/sip/communicator/plugin/keybindingchooser/chooser/BindingChooser.java
@@ -24,6 +24,7 @@ import java.util.*;
import javax.swing.*;
import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.plugin.keybindingchooser.KeybindingChooserActivator;
import net.java.sip.communicator.service.keybindings.*;
/**
@@ -51,36 +52,12 @@ public class BindingChooser
// can be selected
private BindingEntry selectedEntry = null; // None selected when null
- private String selectedText = "Press shortcut...";
-
/**
* Keybinding set.
*/
private KeybindingSet set = null;
/**
- * Displays a dialog allowing the user to redefine the keystroke component
- * of key bindings. The top has light blue labels describing the fields and
- * the bottom provides an 'OK' and 'Cancel' option. This uses the default
- * color scheme and indent style. If no entries are selected then the enter
- * key is equivalent to pressing 'OK' and escape is the same as 'Cancel'.
- *
- * @param parent frame to which to apply modal property and center within
- * (centers within screen if null)
- * @param bindings initial mapping of keystrokes to their actions
- * @return redefined mapping of keystrokes to their actions, null if cancel
- * is pressed
- */
- public static LinkedHashMap<KeyStroke, String> showDialog(Component parent,
- Map<KeyStroke, String> bindings)
- {
- BindingChooser display = new BindingChooser();
- display.putAllBindings(bindings);
- return showDialog(parent, display, "Key Bindings", true, display
- .makeAdaptor());
- }
-
- /**
* Adds a collection of new key binding mappings to the end of the listing.
* If any shortcuts are already contained then the previous entries are
* replaced (not triggering the onUpdate method). Disabled shortcuts trigger
@@ -269,22 +246,6 @@ public class BindingChooser
}
/**
- * Sets the message of the selected shortcut field when awaiting user input.
- * By default this is "Press shortcut...".
- *
- * @param message prompt for user input
- */
- public void setSelectedText(String message)
- {
- if (this.selectedEntry != null)
- {
- this.selectedEntry.getField(BindingEntry.Field.SHORTCUT).setText(
- message);
- }
- this.selectedText = message;
- }
-
- /**
* Returns if a binding is currently awaiting input or not.
*
* @return true if a binding is awaiting input, false otherwise
@@ -344,7 +305,8 @@ public class BindingChooser
onUpdate(getBindingIndex(this.selectedEntry), this.selectedEntry,
false);
this.selectedEntry.getField(BindingEntry.Field.SHORTCUT).setText(
- " " + this.selectedText);
+ KeybindingChooserActivator.getResources().getI18NString(
+ "plugin.keybindings.WAITING"));
}
}
diff --git a/src/net/java/sip/communicator/plugin/keybindingchooser/globalchooser/GlobalShortcutDialog.java b/src/net/java/sip/communicator/plugin/keybindingchooser/globalchooser/GlobalShortcutDialog.java
index aab01c5..1e9f83f 100644
--- a/src/net/java/sip/communicator/plugin/keybindingchooser/globalchooser/GlobalShortcutDialog.java
+++ b/src/net/java/sip/communicator/plugin/keybindingchooser/globalchooser/GlobalShortcutDialog.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,489 +15,489 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.keybindingchooser.globalchooser;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.util.*;
-import java.util.List;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.plugin.keybindingchooser.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.plugin.desktoputil.plaf.*;
-import net.java.sip.communicator.service.globalshortcut.*;
-import net.java.sip.communicator.util.skin.*;
-
-import org.jitsi.util.*;
-// disambiguation
-
-/**
- * Dialog to choose the shortcut.
- *
- * @author Sebastien Vincent
- */
-public class GlobalShortcutDialog
- extends SIPCommDialog
- implements ActionListener,
- GlobalShortcutListener
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * Text displayed when no shortcut is configured.
- */
- private static final String PRESS_TO_SETUP_SHORTCUT =
- Resources.getString("plugin.keybindings.globalchooser.PRESS_BTN");
-
- /**
- * The global shortcut entry.
- */
- private final GlobalShortcutEntry entry;
-
- /**
- * OK button.
- */
- private final JButton btnOK = new JButton(
- Resources.getString("service.gui.OK"));
-
- /**
- * Cancel button.
- */
- private final JButton btnCancel = new JButton(
- Resources.getString("service.gui.CANCEL"));
-
- /**
- * Enable or not special key for shortcut.
- */
- private final JCheckBox specialBox = new SIPCommCheckBox(
- Resources.getString("plugin.keybindings.globalchooser.ENABLE_SPECIAL"));
-
- /**
- * First shortcut field.
- */
- private final ShortcutField fldShortcut = new ShortcutField(
- PRESS_TO_SETUP_SHORTCUT);
-
- /**
- * Secondary shortcut field.
- */
- private final ShortcutField fldShortcut2 = new ShortcutField(
- PRESS_TO_SETUP_SHORTCUT);
-
- /**
- * Return code.
- */
- private int retCode = 0;
-
- /**
- * Constructor.
- *
- * @param dialog root dialog
- * @param entry the global shortcut entry
- */
- public GlobalShortcutDialog(Dialog dialog, GlobalShortcutEntry entry)
- {
- super(dialog);
-
- setModal(true);
- setTitle("Global shortcut: " + entry.getAction());
- this.entry = entry;
- init();
- }
-
- /**
- * Initialize components.
- */
- private void init()
- {
- TransparentPanel mainPanel = new TransparentPanel(new BorderLayout());
- JPanel btnPanel = new TransparentPanel(
- new FlowLayout(FlowLayout.RIGHT));
- JPanel shortcutPanel = new TransparentPanel(
- new GridLayout(0, 2, 0, 10));
-
- btnOK.addActionListener(this);
- btnCancel.addActionListener(this);
-
- KeyAdapter keyAdapter = new KeyAdapter()
- {
- private KeyEvent buffer = null;
-
- @Override
- public void keyPressed(KeyEvent event)
- {
- if(event.getKeyCode() == KeyEvent.VK_ESCAPE)
- {
- SIPCommTextField field =
- (SIPCommTextField)event.getSource();
-
- AWTKeyStroke ks = null;
-
- if(field == fldShortcut)
- {
- ks = entry.getShortcut();
- }
- else if(field == fldShortcut2)
- {
- ks = entry.getShortcut2();
- }
-
- if(ks == null)
- field.setText(PRESS_TO_SETUP_SHORTCUT);
- else
- {
-
- if(ks.getModifiers() ==
- GlobalShortcutService.SPECIAL_KEY_MODIFIERS)
- {
- field.setText("Special");
- }
- else
- {
- field.setText(GlobalShortcutEntry.getShortcutText(
- entry.getShortcut()));
- }
- }
- btnOK.requestFocusInWindow();
- return;
- }
-
- if(event.getKeyCode() == 0)
- return;
-
- // Reports KEY_PRESSED events on release to support modifiers
- this.buffer = event;
- }
-
- @Override
- public void keyReleased(KeyEvent event)
- {
- if (buffer != null)
- {
- SIPCommTextField field =
- (SIPCommTextField)event.getSource();
- AWTKeyStroke input = KeyStroke.getKeyStrokeForEvent(buffer);
- buffer = null;
-
- GlobalShortcutEntry en = entry;
- List<AWTKeyStroke> kss = new ArrayList<AWTKeyStroke>();
-
- if(field == fldShortcut)
- {
- kss.add(input);
- kss.add(en.getShortcut2());
- }
- else if(field == fldShortcut2)
- {
- kss.add(en.getShortcut());
- kss.add(input);
- }
-
- en.setShortcuts(kss);
- en.setEditShortcut1(false);
- en.setEditShortcut2(false);
- field.setText(GlobalShortcutEntry.getShortcutText(
- input));
- btnOK.requestFocus();
- }
- }
- };
-
- AWTKeyStroke ks = entry.getShortcut();
- AWTKeyStroke ks2 = entry.getShortcut2();
-
- if(ks != null)
- {
- if(ks.getModifiers() != GlobalShortcutService.SPECIAL_KEY_MODIFIERS)
- {
- fldShortcut.setText(GlobalShortcutEntry.getShortcutText(ks));
- }
- else
- {
- fldShortcut.setText("Special");
- }
- }
-
- if(ks2 != null)
- {
-
- if(ks2.getModifiers() != GlobalShortcutService.SPECIAL_KEY_MODIFIERS)
- {
- fldShortcut2.setText(GlobalShortcutEntry.getShortcutText(ks2));
- }
- else
- {
- fldShortcut2.setText("Special");
- }
- }
-
- fldShortcut.addKeyListener(keyAdapter);
- fldShortcut2.addKeyListener(keyAdapter);
-
- specialBox.addItemListener(new ItemListener()
- {
- public void itemStateChanged(ItemEvent evt)
- {
- KeybindingChooserActivator.getGlobalShortcutService().
- setSpecialKeyDetection(
- (evt.getStateChange() == ItemEvent.SELECTED),
- GlobalShortcutDialog.this);
- }
- });
-
- shortcutPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10,
- 10));
- shortcutPanel.add(new JLabel("Primary shortcut"));
- shortcutPanel.add(fldShortcut);
- shortcutPanel.add(new JLabel("Secondary shortcut"));
- shortcutPanel.add(fldShortcut2);
-
- if(OSUtils.IS_WINDOWS)
- {
- shortcutPanel.add(new TransparentPanel());
- shortcutPanel.add(specialBox);
- }
-
- mainPanel.add(shortcutPanel, BorderLayout.CENTER);
-
- btnPanel.add(btnOK);
- btnPanel.add(btnCancel);
- mainPanel.add(btnPanel, BorderLayout.SOUTH);
-
- btnOK.requestFocus();
-
- getContentPane().add(mainPanel);
- pack();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void close(boolean isEscaped)
- {
- super.close(isEscaped);
- KeybindingChooserActivator.getGlobalShortcutService().
- setSpecialKeyDetection(false, this);
- }
-
- /**
- * Show the dialog and returns if the user has modified something (create
- * or modify entry).
- *
- * @return true if the user has modified something (create
- * or modify entry), false otherwise.
- */
- public int showDialog()
- {
- setVisible(true);
-
- // as the dialog is modal, wait for OK/Cancel button retCode
- setVisible(false);
- return retCode;
- }
-
- /**
- * {@inheritDoc}
- */
- public void actionPerformed(ActionEvent evt)
- {
- Object obj = evt.getSource();
-
- if(obj == btnOK)
- {
- retCode = 1;
- dispose();
- }
- else if(obj == btnCancel)
- {
- retCode = 0;
- dispose();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void shortcutReceived(GlobalShortcutEvent evt)
- {
- AWTKeyStroke ksr = evt.getKeyStroke();
-
- if(ksr.getModifiers() != GlobalShortcutService.SPECIAL_KEY_MODIFIERS)
- {
- return;
- }
-
- if(!fldShortcut.isFocusOwner() && !fldShortcut2.isFocusOwner())
- return;
-
- List<AWTKeyStroke> kss = new ArrayList<AWTKeyStroke>();
-
- if(fldShortcut.isFocusOwner())
- {
- kss.add(ksr);
- kss.add(entry.getShortcut2());
- fldShortcut.setText("Special");
- }
- else if(fldShortcut2.isFocusOwner())
- {
- kss.add(entry.getShortcut());
- kss.add(ksr);
- fldShortcut2.setText("Special");
- }
- entry.setShortcuts(kss);
- KeybindingChooserActivator.getGlobalShortcutService().
- setSpecialKeyDetection(false, this);
- }
-
- /**
- * Clear the text field.
- *
- * @param ui <tt>TextFieldUI</tt> to clear
- */
- public void clearTextField(SIPCommTextFieldUI ui)
- {
- List<AWTKeyStroke> kss = new ArrayList<AWTKeyStroke>();
-
- if(ui == fldShortcut.getUI())
- {
- kss.add(null);
- kss.add(entry.getShortcut2());
- entry.setShortcuts(kss);
- btnOK.requestFocusInWindow();
- }
- else if(ui == fldShortcut2.getUI())
- {
- kss.add(entry.getShortcut());
- kss.add(null);
- entry.setShortcuts(kss);
- btnOK.requestFocusInWindow();
- }
- }
-
- /**
- * A custom call field.
- */
- private class ShortcutField
- extends SIPCommTextField
- implements Skinnable
- {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * The text field ui.
- */
- private ShortcutFieldUI textFieldUI;
-
- /**
- * Creates an instance of the <tt>CallField</tt>.
- *
- * @param text
- */
- public ShortcutField(String text)
- {
- super(text);
-
- textFieldUI = new ShortcutFieldUI();
- textFieldUI.setDeleteButtonEnabled(true);
-
- this.setPreferredSize(new Dimension(200, 23));
- this.setUI(textFieldUI);
- this.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
- this.setOpaque(false);
-
- this.setDragEnabled(true);
-
- loadSkin();
- }
-
- /**
- * Reloads text field UI defs.
- */
- public void loadSkin()
- {
- textFieldUI.loadSkin();
- }
- }
-
- /**
- * A custom text field UI.
- */
- public class ShortcutFieldUI
- extends SIPCommTextFieldUI
- implements Skinnable
- {
- /**
- * Creates a <tt>SIPCommTextFieldUI</tt>.
- */
- public ShortcutFieldUI()
- {
- loadSkin();
- }
-
- /**
- * Adds the custom mouse listeners defined in this class to the installed
- * listeners.
- */
- @Override
- protected void installListeners()
- {
- super.installListeners();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void updateDeleteIcon(MouseEvent evt)
- {
- super.updateDeleteIcon(evt);
-
- Rectangle deleteRect = getDeleteButtonRect();
- if(deleteRect.contains(evt.getX(), evt.getY()) &&
- evt.getID() == MouseEvent.MOUSE_CLICKED)
- {
- clearTextField(this);
- }
- }
-
- /**
- * Implements parent paintSafely method and enables antialiasing.
- * @param g the <tt>Graphics</tt> object that notified us
- */
- @Override
- protected void paintSafely(Graphics g)
- {
- customPaintBackground(g);
- super.paintSafely(g);
- }
-
- /**
- * Paints the background of the associated component.
- * @param g the <tt>Graphics</tt> object used for painting
- */
- @Override
- protected void customPaintBackground(Graphics g)
- {
- Graphics2D g2 = (Graphics2D) g.create();
-
- try
- {
- AntialiasingManager.activateAntialiasing(g2);
- super.customPaintBackground(g2);
- }
- finally
- {
- g2.dispose();
- }
- }
- }
-}
+package net.java.sip.communicator.plugin.keybindingchooser.globalchooser;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.util.List;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.plugin.keybindingchooser.*;
+import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.plugin.desktoputil.plaf.*;
+import net.java.sip.communicator.service.globalshortcut.*;
+import net.java.sip.communicator.util.skin.*;
+
+import org.jitsi.util.*;
+// disambiguation
+
+/**
+ * Dialog to choose the shortcut.
+ *
+ * @author Sebastien Vincent
+ */
+public class GlobalShortcutDialog
+ extends SIPCommDialog
+ implements ActionListener,
+ GlobalShortcutListener
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * Text displayed when no shortcut is configured.
+ */
+ private static final String PRESS_TO_SETUP_SHORTCUT =
+ Resources.getString("plugin.keybindings.globalchooser.PRESS_BTN");
+
+ /**
+ * The global shortcut entry.
+ */
+ private final GlobalShortcutEntry entry;
+
+ /**
+ * OK button.
+ */
+ private final JButton btnOK = new JButton(
+ Resources.getString("service.gui.OK"));
+
+ /**
+ * Cancel button.
+ */
+ private final JButton btnCancel = new JButton(
+ Resources.getString("service.gui.CANCEL"));
+
+ /**
+ * Enable or not special key for shortcut.
+ */
+ private final JCheckBox specialBox = new SIPCommCheckBox(
+ Resources.getString("plugin.keybindings.globalchooser.ENABLE_SPECIAL"));
+
+ /**
+ * First shortcut field.
+ */
+ private final ShortcutField fldShortcut = new ShortcutField(
+ PRESS_TO_SETUP_SHORTCUT);
+
+ /**
+ * Secondary shortcut field.
+ */
+ private final ShortcutField fldShortcut2 = new ShortcutField(
+ PRESS_TO_SETUP_SHORTCUT);
+
+ /**
+ * Return code.
+ */
+ private int retCode = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param dialog root dialog
+ * @param entry the global shortcut entry
+ */
+ public GlobalShortcutDialog(Dialog dialog, GlobalShortcutEntry entry)
+ {
+ super(dialog);
+
+ setModal(true);
+ setTitle("Global shortcut: " + entry.getAction());
+ this.entry = entry;
+ init();
+ }
+
+ /**
+ * Initialize components.
+ */
+ private void init()
+ {
+ TransparentPanel mainPanel = new TransparentPanel(new BorderLayout());
+ JPanel btnPanel = new TransparentPanel(
+ new FlowLayout(FlowLayout.RIGHT));
+ JPanel shortcutPanel = new TransparentPanel(
+ new GridLayout(0, 2, 0, 10));
+
+ btnOK.addActionListener(this);
+ btnCancel.addActionListener(this);
+
+ KeyAdapter keyAdapter = new KeyAdapter()
+ {
+ private KeyEvent buffer = null;
+
+ @Override
+ public void keyPressed(KeyEvent event)
+ {
+ if(event.getKeyCode() == KeyEvent.VK_ESCAPE)
+ {
+ SIPCommTextField field =
+ (SIPCommTextField)event.getSource();
+
+ AWTKeyStroke ks = null;
+
+ if(field == fldShortcut)
+ {
+ ks = entry.getShortcut();
+ }
+ else if(field == fldShortcut2)
+ {
+ ks = entry.getShortcut2();
+ }
+
+ if(ks == null)
+ field.setText(PRESS_TO_SETUP_SHORTCUT);
+ else
+ {
+
+ if(ks.getModifiers() ==
+ GlobalShortcutService.SPECIAL_KEY_MODIFIERS)
+ {
+ field.setText("Special");
+ }
+ else
+ {
+ field.setText(GlobalShortcutEntry.getShortcutText(
+ entry.getShortcut()));
+ }
+ }
+ btnOK.requestFocusInWindow();
+ return;
+ }
+
+ if(event.getKeyCode() == 0)
+ return;
+
+ // Reports KEY_PRESSED events on release to support modifiers
+ this.buffer = event;
+ }
+
+ @Override
+ public void keyReleased(KeyEvent event)
+ {
+ if (buffer != null)
+ {
+ SIPCommTextField field =
+ (SIPCommTextField)event.getSource();
+ AWTKeyStroke input = KeyStroke.getKeyStrokeForEvent(buffer);
+ buffer = null;
+
+ GlobalShortcutEntry en = entry;
+ List<AWTKeyStroke> kss = new ArrayList<AWTKeyStroke>();
+
+ if(field == fldShortcut)
+ {
+ kss.add(input);
+ kss.add(en.getShortcut2());
+ }
+ else if(field == fldShortcut2)
+ {
+ kss.add(en.getShortcut());
+ kss.add(input);
+ }
+
+ en.setShortcuts(kss);
+ en.setEditShortcut1(false);
+ en.setEditShortcut2(false);
+ field.setText(GlobalShortcutEntry.getShortcutText(
+ input));
+ btnOK.requestFocus();
+ }
+ }
+ };
+
+ AWTKeyStroke ks = entry.getShortcut();
+ AWTKeyStroke ks2 = entry.getShortcut2();
+
+ if(ks != null)
+ {
+ if(ks.getModifiers() != GlobalShortcutService.SPECIAL_KEY_MODIFIERS)
+ {
+ fldShortcut.setText(GlobalShortcutEntry.getShortcutText(ks));
+ }
+ else
+ {
+ fldShortcut.setText("Special");
+ }
+ }
+
+ if(ks2 != null)
+ {
+
+ if(ks2.getModifiers() != GlobalShortcutService.SPECIAL_KEY_MODIFIERS)
+ {
+ fldShortcut2.setText(GlobalShortcutEntry.getShortcutText(ks2));
+ }
+ else
+ {
+ fldShortcut2.setText("Special");
+ }
+ }
+
+ fldShortcut.addKeyListener(keyAdapter);
+ fldShortcut2.addKeyListener(keyAdapter);
+
+ specialBox.addItemListener(new ItemListener()
+ {
+ public void itemStateChanged(ItemEvent evt)
+ {
+ KeybindingChooserActivator.getGlobalShortcutService().
+ setSpecialKeyDetection(
+ (evt.getStateChange() == ItemEvent.SELECTED),
+ GlobalShortcutDialog.this);
+ }
+ });
+
+ shortcutPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10,
+ 10));
+ shortcutPanel.add(new JLabel("Primary shortcut"));
+ shortcutPanel.add(fldShortcut);
+ shortcutPanel.add(new JLabel("Secondary shortcut"));
+ shortcutPanel.add(fldShortcut2);
+
+ if(OSUtils.IS_WINDOWS)
+ {
+ shortcutPanel.add(new TransparentPanel());
+ shortcutPanel.add(specialBox);
+ }
+
+ mainPanel.add(shortcutPanel, BorderLayout.CENTER);
+
+ btnPanel.add(btnOK);
+ btnPanel.add(btnCancel);
+ mainPanel.add(btnPanel, BorderLayout.SOUTH);
+
+ btnOK.requestFocus();
+
+ getContentPane().add(mainPanel);
+ pack();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void close(boolean isEscaped)
+ {
+ super.close(isEscaped);
+ KeybindingChooserActivator.getGlobalShortcutService().
+ setSpecialKeyDetection(false, this);
+ }
+
+ /**
+ * Show the dialog and returns if the user has modified something (create
+ * or modify entry).
+ *
+ * @return true if the user has modified something (create
+ * or modify entry), false otherwise.
+ */
+ public int showDialog()
+ {
+ setVisible(true);
+
+ // as the dialog is modal, wait for OK/Cancel button retCode
+ setVisible(false);
+ return retCode;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void actionPerformed(ActionEvent evt)
+ {
+ Object obj = evt.getSource();
+
+ if(obj == btnOK)
+ {
+ retCode = 1;
+ dispose();
+ }
+ else if(obj == btnCancel)
+ {
+ retCode = 0;
+ dispose();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void shortcutReceived(GlobalShortcutEvent evt)
+ {
+ AWTKeyStroke ksr = evt.getKeyStroke();
+
+ if(ksr.getModifiers() != GlobalShortcutService.SPECIAL_KEY_MODIFIERS)
+ {
+ return;
+ }
+
+ if(!fldShortcut.isFocusOwner() && !fldShortcut2.isFocusOwner())
+ return;
+
+ List<AWTKeyStroke> kss = new ArrayList<AWTKeyStroke>();
+
+ if(fldShortcut.isFocusOwner())
+ {
+ kss.add(ksr);
+ kss.add(entry.getShortcut2());
+ fldShortcut.setText("Special");
+ }
+ else if(fldShortcut2.isFocusOwner())
+ {
+ kss.add(entry.getShortcut());
+ kss.add(ksr);
+ fldShortcut2.setText("Special");
+ }
+ entry.setShortcuts(kss);
+ KeybindingChooserActivator.getGlobalShortcutService().
+ setSpecialKeyDetection(false, this);
+ }
+
+ /**
+ * Clear the text field.
+ *
+ * @param ui <tt>TextFieldUI</tt> to clear
+ */
+ public void clearTextField(SIPCommTextFieldUI ui)
+ {
+ List<AWTKeyStroke> kss = new ArrayList<AWTKeyStroke>();
+
+ if(ui == fldShortcut.getUI())
+ {
+ kss.add(null);
+ kss.add(entry.getShortcut2());
+ entry.setShortcuts(kss);
+ btnOK.requestFocusInWindow();
+ }
+ else if(ui == fldShortcut2.getUI())
+ {
+ kss.add(entry.getShortcut());
+ kss.add(null);
+ entry.setShortcuts(kss);
+ btnOK.requestFocusInWindow();
+ }
+ }
+
+ /**
+ * A custom call field.
+ */
+ private class ShortcutField
+ extends SIPCommTextField
+ implements Skinnable
+ {
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * The text field ui.
+ */
+ private ShortcutFieldUI textFieldUI;
+
+ /**
+ * Creates an instance of the <tt>CallField</tt>.
+ *
+ * @param text
+ */
+ public ShortcutField(String text)
+ {
+ super(text);
+
+ textFieldUI = new ShortcutFieldUI();
+ textFieldUI.setDeleteButtonEnabled(true);
+
+ this.setPreferredSize(new Dimension(200, 23));
+ this.setUI(textFieldUI);
+ this.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
+ this.setOpaque(false);
+
+ this.setDragEnabled(true);
+
+ loadSkin();
+ }
+
+ /**
+ * Reloads text field UI defs.
+ */
+ public void loadSkin()
+ {
+ textFieldUI.loadSkin();
+ }
+ }
+
+ /**
+ * A custom text field UI.
+ */
+ public class ShortcutFieldUI
+ extends SIPCommTextFieldUI
+ implements Skinnable
+ {
+ /**
+ * Creates a <tt>SIPCommTextFieldUI</tt>.
+ */
+ public ShortcutFieldUI()
+ {
+ loadSkin();
+ }
+
+ /**
+ * Adds the custom mouse listeners defined in this class to the installed
+ * listeners.
+ */
+ @Override
+ protected void installListeners()
+ {
+ super.installListeners();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void updateDeleteIcon(MouseEvent evt)
+ {
+ super.updateDeleteIcon(evt);
+
+ Rectangle deleteRect = getDeleteButtonRect();
+ if(deleteRect.contains(evt.getX(), evt.getY()) &&
+ evt.getID() == MouseEvent.MOUSE_CLICKED)
+ {
+ clearTextField(this);
+ }
+ }
+
+ /**
+ * Implements parent paintSafely method and enables antialiasing.
+ * @param g the <tt>Graphics</tt> object that notified us
+ */
+ @Override
+ protected void paintSafely(Graphics g)
+ {
+ customPaintBackground(g);
+ super.paintSafely(g);
+ }
+
+ /**
+ * Paints the background of the associated component.
+ * @param g the <tt>Graphics</tt> object used for painting
+ */
+ @Override
+ protected void customPaintBackground(Graphics g)
+ {
+ Graphics2D g2 = (Graphics2D) g.create();
+
+ try
+ {
+ AntialiasingManager.activateAntialiasing(g2);
+ super.customPaintBackground(g2);
+ }
+ finally
+ {
+ g2.dispose();
+ }
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/msofficecomm/Messenger.java b/src/net/java/sip/communicator/plugin/msofficecomm/Messenger.java
index 264f830..51b3a67 100644
--- a/src/net/java/sip/communicator/plugin/msofficecomm/Messenger.java
+++ b/src/net/java/sip/communicator/plugin/msofficecomm/Messenger.java
@@ -28,7 +28,6 @@ import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.service.protocol.jabberconstants.*;
-import net.java.sip.communicator.service.protocol.yahooconstants.*;
import net.java.sip.communicator.util.*;
import org.jitsi.service.configuration.*;
@@ -168,18 +167,16 @@ public class Messenger
static
{
- String lib = "jmsofficecomm";
-
try
{
- System.loadLibrary(lib);
+ System.loadLibrary("jmsofficecomm");
}
catch (Throwable t)
{
- logger.error(
- "Failed to load native library " + lib + ": "
- + t.getMessage());
- RegistryHandler.checkRegistryKeys();
+ logger.error("Couldn't load jmsofficecomm. If you are debugging,"
+ + " make sure that HKLM\\SOFTWARE[\\Wow6432Node]\\Microsoft\\"
+ + "Office\\Outlook\\Call Integration\\IMApplication is set to"
+ + " javaw.exe; " + t.getMessage());
throw new RuntimeException(t);
}
}
@@ -1125,11 +1122,6 @@ public class Messenger
{
mistatus = MISTATUS_ON_THE_PHONE;
}
- else if (ProtocolNames.YAHOO.equalsIgnoreCase(protocolName)
- && YahooStatusEnum.ON_THE_PHONE.equals(presenceStatus))
- {
- mistatus = MISTATUS_ON_THE_PHONE;
- }
else if ((i == 32 /* FIXME */)
&& ProtocolNames.JABBER.equalsIgnoreCase(protocolName)
&& JabberStatusEnum.IN_A_MEETING.equalsIgnoreCase(
diff --git a/src/net/java/sip/communicator/plugin/msofficecomm/MsOfficeCommActivator.java b/src/net/java/sip/communicator/plugin/msofficecomm/MsOfficeCommActivator.java
index 2b108f8..632a933 100644
--- a/src/net/java/sip/communicator/plugin/msofficecomm/MsOfficeCommActivator.java
+++ b/src/net/java/sip/communicator/plugin/msofficecomm/MsOfficeCommActivator.java
@@ -88,7 +88,6 @@ public class MsOfficeCommActivator
}
finally
{
- RegistryHandler.checkRegistryKeys();
if (stopMessenger)
Messenger.stop(bundleContext);
}
diff --git a/src/net/java/sip/communicator/plugin/msofficecomm/OutOfProcessServer.java b/src/net/java/sip/communicator/plugin/msofficecomm/OutOfProcessServer.java
index 7415163..c412e66 100644
--- a/src/net/java/sip/communicator/plugin/msofficecomm/OutOfProcessServer.java
+++ b/src/net/java/sip/communicator/plugin/msofficecomm/OutOfProcessServer.java
@@ -25,11 +25,6 @@ package net.java.sip.communicator.plugin.msofficecomm;
*/
class OutOfProcessServer
{
- static
- {
- System.loadLibrary("jmsofficecomm");
- }
-
static native int start();
static native int stop();
diff --git a/src/net/java/sip/communicator/plugin/msofficecomm/RegistryHandler.java b/src/net/java/sip/communicator/plugin/msofficecomm/RegistryHandler.java
deleted file mode 100644
index 1cb11f6..0000000
--- a/src/net/java/sip/communicator/plugin/msofficecomm/RegistryHandler.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.msofficecomm;
-
-import net.java.sip.communicator.util.Logger;
-
-import com.sun.jna.platform.win32.*;
-
-/**
- * Checks the registry keys used by
- * Outlook.
- *
- * @author Hristo Terezov
- */
-public class RegistryHandler
-{
- /**
- * The logger.
- */
- private static Logger logger = Logger.getLogger(RegistryHandler.class);
-
- /**
- * The key under which the IM application is placed.
- */
- private static String REGISTRY_IM_APPLICATION_KEY
- = "Software\\IM Providers";
-
- /**
- * The value under which the default IM application is placed.
- */
- private static String REGISTRY_DEFAULT_IM_APPLICATION_VALUE
- = "DefaultIMApp";
-
- /**
- * The key for the outlook call integration.
- */
- private static String REGISTRY_CALL_INTEGRATION
- = "Software\\Microsoft\\Office\\Outlook\\Call Integration";
-
- /**
- * The value for the outlook call integration.
- */
- private static String REGISTRY_CALL_INTEGRATION_VALUE
- = "IMApplication";
-
- /**
- * The key for the outlook rtc application.
- */
- private static String REGISTRY_OFFICE11_RTC_APPLICATION
- = "Software\\Microsoft\\Office\\11.0\\Common\\PersonaMenu";
-
- /**
- * The key for the outlook rtc application.
- */
- private static String REGISTRY_OFFICE12_RTC_APPLICATION
- = "Software\\Microsoft\\Office\\12.0\\Common\\PersonaMenu";
-
- /**
- * The value for the rtc application.
- */
- private static String REGISTRY_RTC_APPLICATION_VALUE = "RTCApplication";
-
- /**
- * The key for Communicator IM App.
- */
- private static String REGISTRY_COMMUNICATOR_UP
- = "Software\\IM Providers\\Communicator";
-
- /**
- * Up and running value.
- */
- private static String REGISTRY_UP_RUNNING_VALUE = "UpAndRunning";
-
- /**
- * Checks the existence of the registry keys for outlook call integration.
- */
- private static void checkCallIntegration()
- {
- if(!Advapi32Util.registryKeyExists(WinReg.HKEY_LOCAL_MACHINE,
- REGISTRY_CALL_INTEGRATION)
- || !Advapi32Util.registryValueExists(WinReg.HKEY_LOCAL_MACHINE,
- REGISTRY_CALL_INTEGRATION,
- REGISTRY_CALL_INTEGRATION_VALUE))
- {
- logger.error(REGISTRY_CALL_INTEGRATION +
- " doesn't exists in registry");
- return;
- }
- logger.info("Call integration: " +
- Advapi32Util.registryGetStringValue(
- WinReg.HKEY_LOCAL_MACHINE,
- REGISTRY_CALL_INTEGRATION,
- REGISTRY_CALL_INTEGRATION_VALUE));
- }
-
- /**
- * Checks the existence of the registry keys for outlook rtc application.
- */
- private static void checkRTCApplication()
- {
- if(!Advapi32Util.registryKeyExists(WinReg.HKEY_CURRENT_USER,
- REGISTRY_OFFICE11_RTC_APPLICATION)
- || !Advapi32Util.registryValueExists(WinReg.HKEY_CURRENT_USER,
- REGISTRY_OFFICE11_RTC_APPLICATION,
- REGISTRY_RTC_APPLICATION_VALUE))
- {
- logger.error(REGISTRY_OFFICE11_RTC_APPLICATION +
- " doesn't exists in registry");
- }
- else
- {
- logger.info("RTC application: " +
- Advapi32Util.registryGetIntValue(
- WinReg.HKEY_CURRENT_USER,
- REGISTRY_OFFICE11_RTC_APPLICATION,
- REGISTRY_RTC_APPLICATION_VALUE));
- }
-
- if(!Advapi32Util.registryKeyExists(WinReg.HKEY_CURRENT_USER,
- REGISTRY_OFFICE12_RTC_APPLICATION)
- || !Advapi32Util.registryValueExists(WinReg.HKEY_CURRENT_USER,
- REGISTRY_OFFICE12_RTC_APPLICATION,
- REGISTRY_RTC_APPLICATION_VALUE))
- {
- logger.error(REGISTRY_OFFICE12_RTC_APPLICATION +
- " doesn't exists in registry");
- }
- else
- {
- logger.info("RTC application: " +
- Advapi32Util.registryGetIntValue(
- WinReg.HKEY_CURRENT_USER,
- REGISTRY_OFFICE12_RTC_APPLICATION,
- REGISTRY_RTC_APPLICATION_VALUE));
- }
- }
-
- /**
- * Checks if the registry key for running Jitsi and Communicator.
- */
- private static void checkUpAndRunning()
- {
- if(!Advapi32Util.registryKeyExists(WinReg.HKEY_CURRENT_USER,
- REGISTRY_COMMUNICATOR_UP)
- || !Advapi32Util.registryValueExists(WinReg.HKEY_CURRENT_USER,
- REGISTRY_COMMUNICATOR_UP,
- REGISTRY_UP_RUNNING_VALUE))
- {
- logger.error(REGISTRY_COMMUNICATOR_UP +
- " doesn't exists in registry");
- }
- else
- {
- logger.info("Communicator up and running value: " +
- Advapi32Util.registryGetIntValue(
- WinReg.HKEY_CURRENT_USER,
- REGISTRY_COMMUNICATOR_UP,
- REGISTRY_UP_RUNNING_VALUE));
- }
-
- if(!Advapi32Util.registryKeyExists(WinReg.HKEY_CURRENT_USER,
- REGISTRY_IM_APPLICATION_KEY + "\\" + getApplicationName())
- || !Advapi32Util.registryValueExists(WinReg.HKEY_CURRENT_USER,
- REGISTRY_IM_APPLICATION_KEY + "\\" + getApplicationName(),
- REGISTRY_UP_RUNNING_VALUE))
- {
- logger.error(REGISTRY_IM_APPLICATION_KEY +
- " doesn't exists in registry");
- }
- else
- {
- logger.info("Up and running value: " +
- Advapi32Util.registryGetIntValue(
- WinReg.HKEY_CURRENT_USER,
- REGISTRY_IM_APPLICATION_KEY + "\\"
- + getApplicationName(),
- REGISTRY_UP_RUNNING_VALUE));
- }
- }
-
- /**
- * Logs registry information.
- */
- public static void checkRegistryKeys()
- {
- checkDefaultIMApp();
- checkRegisteredIMApp();
- checkCallIntegration();
- checkRTCApplication();
- checkUpAndRunning();
- }
-
-
- /**
- * Checks whether Jitsi is the default IM application.
- */
- private static void checkDefaultIMApp()
- {
- if(!Advapi32Util.registryKeyExists(WinReg.HKEY_CURRENT_USER,
- REGISTRY_IM_APPLICATION_KEY) ||
- !Advapi32Util.registryValueExists(WinReg.HKEY_CURRENT_USER,
- REGISTRY_IM_APPLICATION_KEY,
- REGISTRY_DEFAULT_IM_APPLICATION_VALUE))
- {
- logger.error(REGISTRY_IM_APPLICATION_KEY
- + " doesn't extsts");
- return;
- }
-
- logger.info("Default IM App: " + Advapi32Util.registryGetStringValue(
- WinReg.HKEY_CURRENT_USER,
- REGISTRY_IM_APPLICATION_KEY,
- REGISTRY_DEFAULT_IM_APPLICATION_VALUE));
- }
-
- /**
- * Checks whether Jitsi is registered as IM provider.
- */
- private static void checkRegisteredIMApp()
- {
- if(!Advapi32Util.registryKeyExists(
- WinReg.HKEY_LOCAL_MACHINE,
- REGISTRY_IM_APPLICATION_KEY + "\\" + getApplicationName()))
- {
- logger.error(REGISTRY_IM_APPLICATION_KEY + "\\" +
- getApplicationName() + " doesn;t exsts");
- return;
- }
-
- logger.info("Registered IM App friendly name: "
- + Advapi32Util.registryGetStringValue(
- WinReg.HKEY_LOCAL_MACHINE,
- REGISTRY_IM_APPLICATION_KEY + "\\" +
- getApplicationName(),
- "FriendlyName"));
- }
-
- /**
- * Returns the application name.
- * @return the application name
- */
- private static String getApplicationName()
- {
- return MsOfficeCommActivator.getResources().getSettingsString(
- "service.gui.APPLICATION_NAME");
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/msofficecomm/msofficecomm.manifest.mf b/src/net/java/sip/communicator/plugin/msofficecomm/msofficecomm.manifest.mf
index 54d8545..2a3a712 100644
--- a/src/net/java/sip/communicator/plugin/msofficecomm/msofficecomm.manifest.mf
+++ b/src/net/java/sip/communicator/plugin/msofficecomm/msofficecomm.manifest.mf
@@ -10,7 +10,6 @@ Import-Package: javax.swing,
net.java.sip.communicator.service.protocol,
net.java.sip.communicator.service.protocol.event,
net.java.sip.communicator.service.protocol.jabberconstants,
- net.java.sip.communicator.service.protocol.yahooconstants,
net.java.sip.communicator.util,
org.jitsi.service.configuration,
org.jitsi.util,
diff --git a/src/net/java/sip/communicator/plugin/otr/OtrConfigurator.java b/src/net/java/sip/communicator/plugin/otr/OtrConfigurator.java
index 42efc97..dd3940b 100644
--- a/src/net/java/sip/communicator/plugin/otr/OtrConfigurator.java
+++ b/src/net/java/sip/communicator/plugin/otr/OtrConfigurator.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,171 +15,171 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.otr;
-
-import java.util.*;
-
-import org.bouncycastle.util.encoders.Base64; // disambiguation
-import org.jitsi.service.configuration.*;
-
-/**
- * A class that gets/sets the OTR configuration values. Introduced to assure our
- * configuration is properly written when <tt>XMLConfigurationStore</tt> is
- * used. Can be seen as a proxy between the {@link ConfigurationService} and the
- * OTR Plugin.
- *
- * @author George Politis
- */
-public class OtrConfigurator
-{
- /**
- * Gets an XML tag friendly {@link String} from a {@link String}.
- *
- * @param s a {@link String}
- * @return an XML friendly {@link String}
- */
- private String getXmlFriendlyString(String s)
- {
- if (s == null || s.length() < 1)
- return s;
-
- // XML Tags are not allowed to start with digits,
- // insert a dummy "p" char.
- if (Character.isDigit(s.charAt(0)))
- s = "p" + s;
-
- char[] cId = new char[s.length()];
-
- for (int i = 0; i < cId.length; i++)
- {
- char c = s.charAt(i);
-
- cId[i] = Character.isLetterOrDigit(c) ? c : '_';
- }
-
- return new String(cId);
- }
-
- /**
- * Puts a given property ID under the OTR namespace and makes sure it is XML
- * tag friendly.
- *
- * @param id the property ID.
- * @return the namespaced ID.
- */
- private String getID(String id)
- {
- return
- "net.java.sip.communicator.plugin.otr." + getXmlFriendlyString(id);
- }
-
- /**
- * Returns the value of the property with the specified name or null if no
- * such property exists ({@link ConfigurationService#getProperty(String)}
- * proxy).
- *
- * @param id of the property that is being queried.
- * @return the <tt>byte[]</tt> value of the property with the specified
- * name.
- */
- public byte[] getPropertyBytes(String id)
- {
- String value = OtrActivator.configService.getString(getID(id));
-
- return (value == null) ? null : Base64.decode(value.getBytes());
- }
-
- /**
- * Gets the value of a specific property as a boolean (
- * {@link ConfigurationService#getBoolean(String, boolean)} proxy).
- *
- * @param id of the property that is being queried.
- * @param defaultValue the value to be returned if the specified property
- * name is not associated with a value.
- * @return the <tt>Boolean</tt> value of the property with the specified
- * name.
- */
- public boolean getPropertyBoolean(String id, boolean defaultValue)
- {
- return
- OtrActivator.configService.getBoolean(getID(id), defaultValue);
- }
-
- /**
- * Sets the property with the specified name to the specified value (
- * {@link ConfigurationService#setProperty(String, Object)} proxy). The
- * value is Base64 encoded.
- *
- * @param id the name of the property to change.
- * @param value the new value of the specified property.
- */
- public void setProperty(String id, byte[] value)
- {
- String valueToStore = new String(Base64.encode(value));
-
- OtrActivator.configService.setProperty(getID(id), valueToStore);
- }
-
- /**
- * Sets the property with the specified name to the specified value (
- * {@link ConfigurationService#setProperty(String, Object)} proxy).
- *
- * @param id the name of the property to change.
- * @param value the new value of the specified property.
- */
- public void setProperty(String id, Object value)
- {
- OtrActivator.configService.setProperty(getID(id), value);
- }
-
- /**
- * Removes the property with the specified name (
- * {@link ConfigurationService#removeProperty(String)} proxy).
- *
- * @param id the name of the property to change.
- */
- public void removeProperty(String id)
- {
- OtrActivator.configService.removeProperty(getID(id));
- }
-
- /**
- * Gets the value of a specific property as a signed decimal integer.
- *
- * @param id the name of the property to change.
- * @param defaultValue the value to be returned if the specified property
- * name is not associated with a value.
- * @return the <tt>int</tt> value of the property
- */
- public int getPropertyInt(String id, int defaultValue)
- {
- return OtrActivator.configService.getInt(getID(id), defaultValue);
- }
-
- /**
- * Appends <tt>value</tt> to the old value of the property with the
- * specified name. The two values will be comma separated.
- *
- * @param id the name of the property to append to
- * @param value the value to append
- */
- public void appendProperty(String id, Object value)
- {
- Object oldValue = OtrActivator.configService.getProperty(getID(id));
-
- String newValue =
- oldValue == null ? value.toString() : oldValue + "," + value;
-
- setProperty(id, newValue);
- }
-
- public List<String> getAppendedProperties(String id)
- {
- String listProperties =
- (String) OtrActivator.configService.getProperty(getID(id));
-
- if (listProperties == null) return new ArrayList<String>();
-
- return Arrays.asList(listProperties.split(","));
- }
-}
+package net.java.sip.communicator.plugin.otr;
+
+import java.util.*;
+
+import org.bouncycastle.util.encoders.Base64; // disambiguation
+import org.jitsi.service.configuration.*;
+
+/**
+ * A class that gets/sets the OTR configuration values. Introduced to assure our
+ * configuration is properly written when <tt>XMLConfigurationStore</tt> is
+ * used. Can be seen as a proxy between the {@link ConfigurationService} and the
+ * OTR Plugin.
+ *
+ * @author George Politis
+ */
+public class OtrConfigurator
+{
+ /**
+ * Gets an XML tag friendly {@link String} from a {@link String}.
+ *
+ * @param s a {@link String}
+ * @return an XML friendly {@link String}
+ */
+ private String getXmlFriendlyString(String s)
+ {
+ if (s == null || s.length() < 1)
+ return s;
+
+ // XML Tags are not allowed to start with digits,
+ // insert a dummy "p" char.
+ if (Character.isDigit(s.charAt(0)))
+ s = "p" + s;
+
+ char[] cId = new char[s.length()];
+
+ for (int i = 0; i < cId.length; i++)
+ {
+ char c = s.charAt(i);
+
+ cId[i] = Character.isLetterOrDigit(c) ? c : '_';
+ }
+
+ return new String(cId);
+ }
+
+ /**
+ * Puts a given property ID under the OTR namespace and makes sure it is XML
+ * tag friendly.
+ *
+ * @param id the property ID.
+ * @return the namespaced ID.
+ */
+ private String getID(String id)
+ {
+ return
+ "net.java.sip.communicator.plugin.otr." + getXmlFriendlyString(id);
+ }
+
+ /**
+ * Returns the value of the property with the specified name or null if no
+ * such property exists ({@link ConfigurationService#getProperty(String)}
+ * proxy).
+ *
+ * @param id of the property that is being queried.
+ * @return the <tt>byte[]</tt> value of the property with the specified
+ * name.
+ */
+ public byte[] getPropertyBytes(String id)
+ {
+ String value = OtrActivator.configService.getString(getID(id));
+
+ return (value == null) ? null : Base64.decode(value.getBytes());
+ }
+
+ /**
+ * Gets the value of a specific property as a boolean (
+ * {@link ConfigurationService#getBoolean(String, boolean)} proxy).
+ *
+ * @param id of the property that is being queried.
+ * @param defaultValue the value to be returned if the specified property
+ * name is not associated with a value.
+ * @return the <tt>Boolean</tt> value of the property with the specified
+ * name.
+ */
+ public boolean getPropertyBoolean(String id, boolean defaultValue)
+ {
+ return
+ OtrActivator.configService.getBoolean(getID(id), defaultValue);
+ }
+
+ /**
+ * Sets the property with the specified name to the specified value (
+ * {@link ConfigurationService#setProperty(String, Object)} proxy). The
+ * value is Base64 encoded.
+ *
+ * @param id the name of the property to change.
+ * @param value the new value of the specified property.
+ */
+ public void setProperty(String id, byte[] value)
+ {
+ String valueToStore = new String(Base64.encode(value));
+
+ OtrActivator.configService.setProperty(getID(id), valueToStore);
+ }
+
+ /**
+ * Sets the property with the specified name to the specified value (
+ * {@link ConfigurationService#setProperty(String, Object)} proxy).
+ *
+ * @param id the name of the property to change.
+ * @param value the new value of the specified property.
+ */
+ public void setProperty(String id, Object value)
+ {
+ OtrActivator.configService.setProperty(getID(id), value);
+ }
+
+ /**
+ * Removes the property with the specified name (
+ * {@link ConfigurationService#removeProperty(String)} proxy).
+ *
+ * @param id the name of the property to change.
+ */
+ public void removeProperty(String id)
+ {
+ OtrActivator.configService.removeProperty(getID(id));
+ }
+
+ /**
+ * Gets the value of a specific property as a signed decimal integer.
+ *
+ * @param id the name of the property to change.
+ * @param defaultValue the value to be returned if the specified property
+ * name is not associated with a value.
+ * @return the <tt>int</tt> value of the property
+ */
+ public int getPropertyInt(String id, int defaultValue)
+ {
+ return OtrActivator.configService.getInt(getID(id), defaultValue);
+ }
+
+ /**
+ * Appends <tt>value</tt> to the old value of the property with the
+ * specified name. The two values will be comma separated.
+ *
+ * @param id the name of the property to append to
+ * @param value the value to append
+ */
+ public void appendProperty(String id, Object value)
+ {
+ Object oldValue = OtrActivator.configService.getProperty(getID(id));
+
+ String newValue =
+ oldValue == null ? value.toString() : oldValue + "," + value;
+
+ setProperty(id, newValue);
+ }
+
+ public List<String> getAppendedProperties(String id)
+ {
+ String listProperties =
+ (String) OtrActivator.configService.getProperty(getID(id));
+
+ if (listProperties == null) return new ArrayList<String>();
+
+ return Arrays.asList(listProperties.split(","));
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java b/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java
index bce2fe7..8e4a235 100644
--- a/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java
+++ b/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,1330 +15,1328 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.otr;
-
-import java.net.*;
-import java.security.*;
-import java.util.*;
-import java.util.concurrent.*;
-
-import net.java.otr4j.*;
-import net.java.otr4j.crypto.*;
-import net.java.otr4j.session.*;
-import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact;
-import net.java.sip.communicator.plugin.otr.authdialog.*;
-import net.java.sip.communicator.service.browserlauncher.*;
-import net.java.sip.communicator.service.contactlist.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- *
- * @author George Politis
- * @author Lyubomir Marinov
- * @author Pawel Domas
- * @author Marin Dzhigarov
- * @author Danny van Heumen
- */
-public class ScOtrEngineImpl
- implements ScOtrEngine,
- ChatLinkClickedListener,
- ServiceListener
-{
- private class ScOtrEngineHost
- implements OtrEngineHost
- {
- @Override
- public KeyPair getLocalKeyPair(SessionID sessionID)
- {
- AccountID accountID =
- OtrActivator.getAccountIDByUID(sessionID.getAccountID());
- KeyPair keyPair =
- OtrActivator.scOtrKeyManager.loadKeyPair(accountID);
- if (keyPair == null)
- OtrActivator.scOtrKeyManager.generateKeyPair(accountID);
-
- return OtrActivator.scOtrKeyManager.loadKeyPair(accountID);
- }
-
- @Override
- public OtrPolicy getSessionPolicy(SessionID sessionID)
- {
- return getContactPolicy(getOtrContact(sessionID).contact);
- }
-
- @Override
- public void injectMessage(SessionID sessionID, String messageText)
- {
- OtrContact otrContact = getOtrContact(sessionID);
- Contact contact = otrContact.contact;
- ContactResource resource = null;
-
- if (contact.supportResources())
- {
- Collection<ContactResource> resources = contact.getResources();
- if (resources != null)
- {
- for (ContactResource r : resources)
- {
- if (r.equals(otrContact.resource))
- {
- resource = r;
- break;
- }
- }
- }
- }
-
- OperationSetBasicInstantMessaging imOpSet
- = contact
- .getProtocolProvider()
- .getOperationSet(
- OperationSetBasicInstantMessaging.class);
-
- // This is a dirty way of detecting whether the injected message
- // contains HTML markup. If this is the case then we should create
- // the message with the appropriate content type so that the remote
- // party can properly display the HTML.
- // When otr4j injects QueryMessages it calls
- // OtrEngineHost.getFallbackMessage() which is currently the only
- // host method that uses HTML so we can simply check if the injected
- // message contains the string that getFallbackMessage() returns.
- String otrHtmlFallbackMessage
- = "<a href=\"http://en.wikipedia.org/wiki/Off-the-Record_Messaging\">";
- String contentType
- = messageText.contains(otrHtmlFallbackMessage)
- ? OperationSetBasicInstantMessaging.HTML_MIME_TYPE
- : OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE;
- Message message
- = imOpSet.createMessage(
- messageText,
- contentType,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING,
- null);
-
- injectedMessageUIDs.add(message.getMessageUID());
- imOpSet.sendInstantMessage(contact, resource, message);
- }
-
- @Override
- public void showError(SessionID sessionID, String err)
- {
- ScOtrEngineImpl.this.showError(sessionID, err);
- }
-
- public void showWarning(SessionID sessionID, String warn)
- {
- OtrContact otrContact = getOtrContact(sessionID);
- if (otrContact == null)
- return;
-
- Contact contact = otrContact.contact;
- OtrActivator.uiService.getChat(contact).addMessage(
- contact.getDisplayName(), new Date(),
- Chat.SYSTEM_MESSAGE, warn,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
- }
-
- @Override
- public void unreadableMessageReceived(SessionID sessionID)
- throws OtrException
- {
- OtrContact otrContact = getOtrContact(sessionID);
- String resourceName = otrContact.resource != null ?
- "/" + otrContact.resource.getResourceName() : "";
-
- Contact contact = otrContact.contact;
- String error =
- OtrActivator.resourceService.getI18NString(
- "plugin.otr.activator.unreadablemsgreceived",
- new String[]
- {contact.getDisplayName() + resourceName});
- OtrActivator.uiService.getChat(contact).addMessage(
- contact.getDisplayName(), new Date(),
- Chat.ERROR_MESSAGE, error,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
- }
-
- @Override
- public void unencryptedMessageReceived(SessionID sessionID, String msg)
- throws OtrException
- {
- OtrContact otrContact = getOtrContact(sessionID);
- if (otrContact == null)
- return;
-
- Contact contact = otrContact.contact;
- String warn =
- OtrActivator.resourceService.getI18NString(
- "plugin.otr.activator.unencryptedmsgreceived");
- OtrActivator.uiService.getChat(contact).addMessage(
- contact.getDisplayName(), new Date(),
- Chat.SYSTEM_MESSAGE, warn,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
- }
-
- @Override
- public void smpError(SessionID sessionID, int tlvType, boolean cheated)
- throws OtrException
- {
- OtrContact otrContact = getOtrContact(sessionID);
- if (otrContact == null)
- return;
-
- Contact contact = otrContact.contact;
- logger.debug("SMP error occurred"
- + ". Contact: " + contact.getDisplayName()
- + ". TLV type: " + tlvType
- + ". Cheated: " + cheated);
-
- String error =
- OtrActivator.resourceService.getI18NString(
- "plugin.otr.activator.smperror");
- OtrActivator.uiService.getChat(contact).addMessage(
- contact.getDisplayName(), new Date(),
- Chat.ERROR_MESSAGE, error,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
-
- SmpProgressDialog progressDialog = progressDialogMap.get(otrContact);
- if (progressDialog == null)
- {
- progressDialog = new SmpProgressDialog(contact);
- progressDialogMap.put(otrContact, progressDialog);
- }
-
- progressDialog.setProgressFail();
- progressDialog.setVisible(true);
- }
-
- @Override
- public void smpAborted(SessionID sessionID) throws OtrException
- {
- OtrContact otrContact = getOtrContact(sessionID);
- if (otrContact == null)
- return;
-
- Contact contact = otrContact.contact;
- Session session = otrEngine.getSession(sessionID);
- if (session.isSmpInProgress())
- {
- String warn =
- OtrActivator.resourceService.getI18NString(
- "plugin.otr.activator.smpaborted",
- new String[] {contact.getDisplayName()});
- OtrActivator.uiService.getChat(contact).addMessage(
- contact.getDisplayName(), new Date(),
- Chat.SYSTEM_MESSAGE, warn,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
-
- SmpProgressDialog progressDialog =
- progressDialogMap.get(otrContact);
- if (progressDialog == null)
- {
- progressDialog = new SmpProgressDialog(contact);
- progressDialogMap.put(otrContact, progressDialog);
- }
-
- progressDialog.setProgressFail();
- progressDialog.setVisible(true);
- }
- }
-
- @Override
- public void finishedSessionMessage(SessionID sessionID, String msgText)
- throws OtrException
- {
- OtrContact otrContact = getOtrContact(sessionID);
- if (otrContact == null)
- return;
-
- String resourceName = otrContact.resource != null ?
- "/" + otrContact.resource.getResourceName() : "";
- Contact contact = otrContact.contact;
- String error =
- OtrActivator.resourceService.getI18NString(
- "plugin.otr.activator.sessionfinishederror",
- new String[]
- {msgText, contact.getDisplayName() + resourceName});
- OtrActivator.uiService.getChat(contact).addMessage(
- contact.getDisplayName(), new Date(),
- Chat.ERROR_MESSAGE, error,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
- }
-
- @Override
- public void requireEncryptedMessage(SessionID sessionID, String msgText)
- throws OtrException
- {
- OtrContact otrContact = getOtrContact(sessionID);
- if (otrContact == null)
- return;
-
- Contact contact = otrContact.contact;
- String error =
- OtrActivator.resourceService.getI18NString(
- "plugin.otr.activator.requireencryption",
- new String[]
- {msgText});
- OtrActivator.uiService.getChat(contact).addMessage(
- contact.getDisplayName(), new Date(),
- Chat.ERROR_MESSAGE, error,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
- }
-
- @Override
- public byte[] getLocalFingerprintRaw(SessionID sessionID)
- {
- AccountID accountID =
- OtrActivator.getAccountIDByUID(sessionID.getAccountID());
- return
- OtrActivator.scOtrKeyManager.getLocalFingerprintRaw(accountID);
- }
-
- @Override
- public void askForSecret(
- SessionID sessionID, InstanceTag receiverTag, String question)
- {
- OtrContact otrContact = getOtrContact(sessionID);
- if (otrContact == null)
- return;
-
- Contact contact = otrContact.contact;
- SmpAuthenticateBuddyDialog dialog =
- new SmpAuthenticateBuddyDialog(
- otrContact, receiverTag, question);
- dialog.setVisible(true);
-
- SmpProgressDialog progressDialog = progressDialogMap.get(otrContact);
- if (progressDialog == null)
- {
- progressDialog = new SmpProgressDialog(contact);
- progressDialogMap.put(otrContact, progressDialog);
- }
-
- progressDialog.init();
- progressDialog.setVisible(true);
- }
-
- @Override
- public void verify(
- SessionID sessionID, String fingerprint, boolean approved)
- {
- OtrContact otrContact = getOtrContact(sessionID);
- if (otrContact == null)
- return;
-
- Contact contact = otrContact.contact;
- OtrActivator.scOtrKeyManager.verify(otrContact, fingerprint);
-
- SmpProgressDialog progressDialog = progressDialogMap.get(otrContact);
- if (progressDialog == null)
- {
- progressDialog = new SmpProgressDialog(contact);
- progressDialogMap.put(otrContact, progressDialog);
- }
-
- progressDialog.setProgressSuccess();
- progressDialog.setVisible(true);
- }
-
- @Override
- public void unverify(SessionID sessionID, String fingerprint)
- {
- OtrContact otrContact = getOtrContact(sessionID);
- if (otrContact == null)
- return;
-
- Contact contact = otrContact.contact;
- OtrActivator.scOtrKeyManager.unverify(otrContact, fingerprint);
-
- SmpProgressDialog progressDialog = progressDialogMap.get(otrContact);
- if (progressDialog == null)
- {
- progressDialog = new SmpProgressDialog(contact);
- progressDialogMap.put(otrContact, progressDialog);
- }
-
- progressDialog.setProgressFail();
- progressDialog.setVisible(true);
- }
-
- @Override
- public String getReplyForUnreadableMessage(SessionID sessionID)
- {
- AccountID accountID =
- OtrActivator.getAccountIDByUID(sessionID.getAccountID());
-
- return OtrActivator.resourceService.getI18NString(
- "plugin.otr.activator.unreadablemsgreply",
- new String[] {accountID.getDisplayName(),
- accountID.getDisplayName()});
- }
-
- @Override
- public String getFallbackMessage(SessionID sessionID)
- {
- AccountID accountID =
- OtrActivator.getAccountIDByUID(sessionID.getAccountID());
-
- return OtrActivator.resourceService.getI18NString(
- "plugin.otr.activator.fallbackmessage",
- new String[] {accountID.getDisplayName()});
- }
-
- @Override
- public void multipleInstancesDetected(SessionID sessionID)
- {
- OtrContact otrContact = getOtrContact(sessionID);
- if (otrContact == null)
- return;
-
- String resourceName = otrContact.resource != null ?
- "/" + otrContact.resource.getResourceName() : "";
- Contact contact = otrContact.contact;
- String message =
- OtrActivator.resourceService.getI18NString(
- "plugin.otr.activator.multipleinstancesdetected",
- new String[]
- {contact.getDisplayName() + resourceName});
- OtrActivator.uiService.getChat(contact).addMessage(
- contact.getDisplayName(),
- new Date(), Chat.SYSTEM_MESSAGE,
- message,
- OperationSetBasicInstantMessaging.HTML_MIME_TYPE);
- }
-
- @Override
- public void messageFromAnotherInstanceReceived(SessionID sessionID)
- {
- OtrContact otrContact = getOtrContact(sessionID);
- if (otrContact == null)
- return;
-
- String resourceName = otrContact.resource != null ?
- "/" + otrContact.resource.getResourceName() : "";
- Contact contact = otrContact.contact;
- String message =
- OtrActivator.resourceService.getI18NString(
- "plugin.otr.activator.msgfromanotherinstance",
- new String[]
- {contact.getDisplayName() + resourceName});
- OtrActivator.uiService.getChat(contact).addMessage(
- contact.getDisplayName(),
- new Date(), Chat.SYSTEM_MESSAGE,
- message,
- OperationSetBasicInstantMessaging.HTML_MIME_TYPE);
- }
-
- /**
- * Provide fragmenter instructions according to the Instant Messaging
- * transport channel of the contact's protocol.
- */
- @Override
- public FragmenterInstructions getFragmenterInstructions(
- final SessionID sessionID)
- {
- final OtrContact otrContact = getOtrContact(sessionID);
- final OperationSetBasicInstantMessagingTransport transport =
- otrContact.contact.getProtocolProvider().getOperationSet(
- OperationSetBasicInstantMessagingTransport.class);
- if (transport == null)
- {
- // There is no operation set for querying transport parameters.
- // Assuming transport capabilities are unlimited.
- if (logger.isDebugEnabled())
- {
- logger.debug("No implementation of "
- + "BasicInstantMessagingTransport available. Assuming "
- + "OTR defaults for OTR fragmentation instructions.");
- }
- return null;
- }
- int messageSize = transport.getMaxMessageSize(otrContact.contact);
- if (messageSize
- == OperationSetBasicInstantMessagingTransport.UNLIMITED)
- {
- messageSize = FragmenterInstructions.UNLIMITED;
- }
- int numberOfMessages =
- transport.getMaxNumberOfMessages(otrContact.contact);
- if (numberOfMessages
- == OperationSetBasicInstantMessagingTransport.UNLIMITED)
- {
- numberOfMessages = FragmenterInstructions.UNLIMITED;
- }
- if (logger.isDebugEnabled())
- {
- logger.debug("OTR fragmentation instructions for sending a "
- + "message to " + otrContact.contact.getDisplayName()
- + " (" + otrContact.contact.getAddress()
- + "). Maximum number of " + "messages: " + numberOfMessages
- + ", maximum message size: " + messageSize);
- }
- return new FragmenterInstructions(numberOfMessages, messageSize);
- }
- }
-
- /**
- * The max timeout period elapsed prior to establishing a TIMED_OUT session.
- */
- private static final int SESSION_TIMEOUT =
- OtrActivator.configService.getInt(
- "net.java.sip.communicator.plugin.otr.SESSION_STATUS_TIMEOUT",
- 30000);
-
- /**
- * Manages the scheduling of TimerTasks that are used to set Contact's
- * ScSessionStatus (to TIMED_OUT) after a period of time.
- */
- private ScSessionStatusScheduler scheduler = new ScSessionStatusScheduler();
-
- /**
- * This mapping is used for taking care of keeping SessionStatus and
- * ScSessionStatus in sync for every Session object.
- */
- private Map<SessionID, ScSessionStatus> scSessionStatusMap =
- new ConcurrentHashMap<SessionID, ScSessionStatus>();
-
- private static final Map<ScSessionID, OtrContact> contactsMap =
- new Hashtable<ScSessionID, OtrContact>();
-
- private static final Map<OtrContact, SmpProgressDialog> progressDialogMap =
- new ConcurrentHashMap<OtrContact, SmpProgressDialog>();
-
- public static OtrContact getOtrContact(SessionID sessionID)
- {
- return contactsMap.get(new ScSessionID(sessionID));
- }
-
- /**
- * Returns the <tt>ScSessionID</tt> for given <tt>UUID</tt>.
- * @param guid the <tt>UUID</tt> identifying <tt>ScSessionID</tt>.
- * @return the <tt>ScSessionID</tt> for given <tt>UUID</tt> or <tt>null</tt>
- * if no matching session found.
- */
- public static ScSessionID getScSessionForGuid(UUID guid)
- {
- for(ScSessionID scSessionID : contactsMap.keySet())
- {
- if(scSessionID.getGUID().equals(guid))
- {
- return scSessionID;
- }
- }
- return null;
- }
-
- public static SessionID getSessionID(OtrContact otrContact)
- {
- ProtocolProviderService pps = otrContact.contact.getProtocolProvider();
- String resourceName = otrContact.resource != null ?
- "/" + otrContact.resource.getResourceName() : "";
- SessionID sessionID
- = new SessionID(
- pps.getAccountID().getAccountUniqueID(),
- otrContact.contact.getAddress() + resourceName,
- pps.getProtocolName());
-
- synchronized (contactsMap)
- {
- if(contactsMap.containsKey(new ScSessionID(sessionID)))
- return sessionID;
-
- ScSessionID scSessionID = new ScSessionID(sessionID);
-
- contactsMap.put(scSessionID, otrContact);
- }
-
- return sessionID;
- }
-
- private final OtrConfigurator configurator = new OtrConfigurator();
-
- private final List<String> injectedMessageUIDs = new Vector<String>();
-
- private final List<ScOtrEngineListener> listeners =
- new Vector<ScOtrEngineListener>();
-
- /**
- * The logger
- */
- private final Logger logger = Logger.getLogger(ScOtrEngineImpl.class);
-
- private final OtrEngineHost otrEngineHost = new ScOtrEngineHost();
-
- private final OtrSessionManager otrEngine;
-
- public ScOtrEngineImpl()
- {
- otrEngine = new OtrSessionManagerImpl(otrEngineHost);
-
- // Clears the map after previous instance
- // This is required because of OSGi restarts in the same VM on Android
- contactsMap.clear();
- scSessionStatusMap.clear();
-
- this.otrEngine.addOtrEngineListener(new OtrEngineListener()
- {
- @Override
- public void sessionStatusChanged(SessionID sessionID)
- {
- OtrContact otrContact = getOtrContact(sessionID);
- if (otrContact == null)
- return;
-
- String resourceName = otrContact.resource != null ?
- "/" + otrContact.resource.getResourceName() : "";
- Contact contact = otrContact.contact;
- // Cancels any scheduled tasks that will change the
- // ScSessionStatus for this Contact
- scheduler.cancel(otrContact);
-
- ScSessionStatus scSessionStatus = getSessionStatus(otrContact);
- String message = "";
- final Session session = otrEngine.getSession(sessionID);
- switch (session.getSessionStatus())
- {
- case ENCRYPTED:
- scSessionStatus = ScSessionStatus.ENCRYPTED;
- scSessionStatusMap.put(sessionID, scSessionStatus);
- PublicKey remotePubKey = session.getRemotePublicKey();
-
- String remoteFingerprint = null;
- try
- {
- remoteFingerprint =
- new OtrCryptoEngineImpl().
- getFingerprint(remotePubKey);
- }
- catch (OtrCryptoException e)
- {
- logger.debug(
- "Could not get the fingerprint from the "
- + "public key of contact: " + contact);
- }
-
- List<String> allFingerprintsOfContact =
- OtrActivator.scOtrKeyManager.
- getAllRemoteFingerprints(contact);
- if (allFingerprintsOfContact != null)
- {
- if (!allFingerprintsOfContact.contains(
- remoteFingerprint))
- {
- OtrActivator.scOtrKeyManager.saveFingerprint(
- contact, remoteFingerprint);
- }
- }
-
- if (!OtrActivator.scOtrKeyManager.isVerified(
- contact, remoteFingerprint))
- {
- OtrActivator.scOtrKeyManager.unverify(
- otrContact, remoteFingerprint);
- UUID sessionGuid = null;
- for(ScSessionID scSessionID : contactsMap.keySet())
- {
- if(scSessionID.getSessionID().equals(sessionID))
- {
- sessionGuid = scSessionID.getGUID();
- break;
- }
- }
-
- OtrActivator.uiService.getChat(contact)
- .addChatLinkClickedListener(ScOtrEngineImpl.this);
-
- String unverifiedSessionWarning
- = OtrActivator.resourceService.getI18NString(
- "plugin.otr.activator"
- + ".unverifiedsessionwarning",
- new String[]
- {
- contact.getDisplayName() + resourceName,
- this.getClass().getName(),
- "AUTHENTIFICATION",
- sessionGuid.toString()
- });
- OtrActivator.uiService.getChat(contact).addMessage(
- contact.getDisplayName(),
- new Date(), Chat.SYSTEM_MESSAGE,
- unverifiedSessionWarning,
- OperationSetBasicInstantMessaging.HTML_MIME_TYPE);
-
- }
-
- // show info whether history is on or off
- String otrAndHistoryMessage;
- if(!OtrActivator.getMessageHistoryService()
- .isHistoryLoggingEnabled() ||
- !isHistoryLoggingEnabled(contact))
- {
- otrAndHistoryMessage =
- OtrActivator.resourceService.getI18NString(
- "plugin.otr.activator.historyoff",
- new String[]{
- OtrActivator.resourceService
- .getSettingsString(
- "service.gui.APPLICATION_NAME"),
- this.getClass().getName(),
- "showHistoryPopupMenu"
- });
- }
- else
- {
- otrAndHistoryMessage =
- OtrActivator.resourceService.getI18NString(
- "plugin.otr.activator.historyon",
- new String[]{
- OtrActivator.resourceService
- .getSettingsString(
- "service.gui.APPLICATION_NAME"),
- this.getClass().getName(),
- "showHistoryPopupMenu"
- });
- }
- OtrActivator.uiService.getChat(contact).addMessage(
- contact.getDisplayName(),
- new Date(), Chat.SYSTEM_MESSAGE,
- otrAndHistoryMessage,
- OperationSetBasicInstantMessaging.HTML_MIME_TYPE);
-
- message =
- OtrActivator.resourceService.getI18NString(
- "plugin.otr.activator.multipleinstancesdetected",
- new String[]
- {contact.getDisplayName()});
-
- if (contact.supportResources()
- && contact.getResources() != null
- && contact.getResources().size() > 1)
- OtrActivator.uiService.getChat(contact).addMessage(
- contact.getDisplayName(),
- new Date(), Chat.SYSTEM_MESSAGE,
- message,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
-
- message
- = OtrActivator.resourceService.getI18NString(
- OtrActivator.scOtrKeyManager.isVerified(
- contact, remoteFingerprint)
- ? "plugin.otr.activator.sessionstared"
- : "plugin.otr.activator"
- + ".unverifiedsessionstared",
- new String[]
- {contact.getDisplayName() + resourceName});
-
- break;
- case FINISHED:
- scSessionStatus = ScSessionStatus.FINISHED;
- scSessionStatusMap.put(sessionID, scSessionStatus);
- message =
- OtrActivator.resourceService.getI18NString(
- "plugin.otr.activator.sessionfinished",
- new String[]
- {contact.getDisplayName() + resourceName});
- break;
- case PLAINTEXT:
- scSessionStatus = ScSessionStatus.PLAINTEXT;
- scSessionStatusMap.put(sessionID, scSessionStatus);
- message =
- OtrActivator.resourceService.getI18NString(
- "plugin.otr.activator.sessionlost", new String[]
- {contact.getDisplayName() + resourceName});
- break;
- }
-
- OtrActivator.uiService.getChat(contact).addMessage(
- contact.getDisplayName(), new Date(),
- Chat.SYSTEM_MESSAGE, message,
- OperationSetBasicInstantMessaging.HTML_MIME_TYPE);
-
- for (ScOtrEngineListener l : getListeners())
- l.sessionStatusChanged(otrContact);
- }
-
- @Override
- public void multipleInstancesDetected(SessionID sessionID)
- {
- OtrContact otrContact = getOtrContact(sessionID);
- if (otrContact == null)
- return;
-
- for (ScOtrEngineListener l : getListeners())
- l.multipleInstancesDetected(otrContact);
- }
-
- @Override
- public void outgoingSessionChanged(SessionID sessionID)
- {
- OtrContact otrContact = getOtrContact(sessionID);
- if (otrContact == null)
- return;
-
- for (ScOtrEngineListener l : getListeners())
- l.outgoingSessionChanged(otrContact);
- }
- });
- }
-
- /**
- * Checks whether history is enabled for the metacontact containing
- * the <tt>contact</tt>.
- * @param contact the contact to check.
- * @return whether chat logging is enabled while chatting
- * with <tt>contact</tt>.
- */
- private boolean isHistoryLoggingEnabled(Contact contact)
- {
- MetaContact metaContact = OtrActivator
- .getContactListService().findMetaContactByContact(contact);
- if(metaContact != null)
- return OtrActivator.getMessageHistoryService()
- .isHistoryLoggingEnabled(metaContact.getMetaUID());
- else
- return true;
- }
-
- @Override
- public void addListener(ScOtrEngineListener l)
- {
- synchronized (listeners)
- {
- if (!listeners.contains(l))
- listeners.add(l);
- }
- }
-
- @Override
- public void chatLinkClicked(URI url)
- {
- String action = url.getPath();
- if(action.equals("/AUTHENTIFICATION"))
- {
- UUID guid = UUID.fromString(url.getQuery());
-
- if(guid == null)
- throw new RuntimeException(
- "No UUID found in OTR authenticate URL");
-
- // Looks for registered action handler
- OtrActionHandler actionHandler
- = ServiceUtils.getService(
- OtrActivator.bundleContext,
- OtrActionHandler.class);
-
- if(actionHandler != null)
- {
- actionHandler.onAuthenticateLinkClicked(guid);
- }
- else
- {
- logger.error("No OtrActionHandler registered");
- }
- }
- }
-
- @Override
- public void endSession(OtrContact otrContact)
- {
- SessionID sessionID = getSessionID(otrContact);
- try
- {
- setSessionStatus(otrContact, ScSessionStatus.PLAINTEXT);
-
- otrEngine.getSession(sessionID).endSession();
- }
- catch (OtrException e)
- {
- showError(sessionID, e.getMessage());
- }
- }
-
- @Override
- public OtrPolicy getContactPolicy(Contact contact)
- {
- ProtocolProviderService pps = contact.getProtocolProvider();
- SessionID sessionID
- = new SessionID(
- pps.getAccountID().getAccountUniqueID(),
- contact.getAddress(),
- pps.getProtocolName());
- int policy =
- this.configurator.getPropertyInt(sessionID + "contact_policy",
- -1);
- if (policy < 0)
- return getGlobalPolicy();
- else
- return new OtrPolicyImpl(policy);
- }
-
- @Override
- public OtrPolicy getGlobalPolicy()
- {
- /*
- * SEND_WHITESPACE_TAG bit will be lowered until we stabilize the OTR.
- */
- int defaultScOtrPolicy =
- OtrPolicy.OTRL_POLICY_DEFAULT & ~OtrPolicy.SEND_WHITESPACE_TAG;
- return new OtrPolicyImpl(this.configurator.getPropertyInt(
- "GLOBAL_POLICY", defaultScOtrPolicy));
- }
-
- /**
- * Gets a copy of the list of <tt>ScOtrEngineListener</tt>s registered with
- * this instance which may safely be iterated without the risk of a
- * <tt>ConcurrentModificationException</tt>.
- *
- * @return a copy of the list of <tt>ScOtrEngineListener<tt>s registered
- * with this instance which may safely be iterated without the risk of a
- * <tt>ConcurrentModificationException</tt>
- */
- private ScOtrEngineListener[] getListeners()
- {
- synchronized (listeners)
- {
- return listeners.toArray(new ScOtrEngineListener[listeners.size()]);
- }
- }
-
- /**
- * Manages the scheduling of TimerTasks that are used to set Contact's
- * ScSessionStatus after a period of time.
- *
- * @author Marin Dzhigarov
- */
- private class ScSessionStatusScheduler
- {
- private final Timer timer = new Timer();
-
- private final Map<OtrContact, TimerTask> tasks =
- new ConcurrentHashMap<OtrContact, TimerTask>();
-
- public void scheduleScSessionStatusChange(
- final OtrContact otrContact, final ScSessionStatus status)
- {
- cancel(otrContact);
-
- TimerTask task
- = new TimerTask()
- {
- @Override
- public void run()
- {
- setSessionStatus(otrContact, status);
- }
- };
- timer.schedule(task, SESSION_TIMEOUT);
- tasks.put(otrContact, task);
- }
-
- public void cancel(final OtrContact otrContact)
- {
- TimerTask task = tasks.get(otrContact);
- if (task != null)
- task.cancel();
- tasks.remove(otrContact);
- }
-
- public void serviceChanged(ServiceEvent ev)
- {
- Object service
- = OtrActivator.bundleContext.getService(
- ev.getServiceReference());
-
- if (!(service instanceof ProtocolProviderService))
- return;
-
- if (ev.getType() == ServiceEvent.UNREGISTERING)
- {
- ProtocolProviderService provider
- = (ProtocolProviderService) service;
-
- Iterator<OtrContact> i = tasks.keySet().iterator();
-
- while (i.hasNext())
- {
- OtrContact otrContact = i.next();
- if (provider.equals(
- otrContact.contact.getProtocolProvider()))
- {
- cancel(otrContact);
- i.remove();
- }
- }
- }
- }
- }
-
- private void setSessionStatus(OtrContact contact, ScSessionStatus status)
- {
- scSessionStatusMap.put(getSessionID(contact), status);
- scheduler.cancel(contact);
- for (ScOtrEngineListener l : getListeners())
- l.sessionStatusChanged(contact);
- }
-
- @Override
- public ScSessionStatus getSessionStatus(OtrContact contact)
- {
- SessionID sessionID = getSessionID(contact);
- SessionStatus sessionStatus = otrEngine.getSession(sessionID).getSessionStatus();
- ScSessionStatus scSessionStatus = null;
- if (!scSessionStatusMap.containsKey(sessionID))
- {
- switch (sessionStatus)
- {
- case PLAINTEXT:
- scSessionStatus = ScSessionStatus.PLAINTEXT;
- break;
- case ENCRYPTED:
- scSessionStatus = ScSessionStatus.ENCRYPTED;
- break;
- case FINISHED:
- scSessionStatus = ScSessionStatus.FINISHED;
- break;
- }
- scSessionStatusMap.put(sessionID, scSessionStatus);
- }
- return scSessionStatusMap.get(sessionID);
- }
-
- @Override
- public boolean isMessageUIDInjected(String mUID)
- {
- return injectedMessageUIDs.contains(mUID);
- }
-
- @Override
- public void launchHelp()
- {
- ServiceReference ref =
- OtrActivator.bundleContext
- .getServiceReference(BrowserLauncherService.class.getName());
-
- if (ref == null)
- return;
-
- BrowserLauncherService service =
- (BrowserLauncherService) OtrActivator.bundleContext.getService(ref);
-
- service.openURL(OtrActivator.resourceService
- .getI18NString("plugin.otr.authbuddydialog.HELP_URI"));
- }
-
- @Override
- public void refreshSession(OtrContact otrContact)
- {
- SessionID sessionID = getSessionID(otrContact);
- try
- {
- otrEngine.getSession(sessionID).refreshSession();
- }
- catch (OtrException e)
- {
- logger.error("Error refreshing session", e);
- showError(sessionID, e.getMessage());
- }
- }
-
- @Override
- public void removeListener(ScOtrEngineListener l)
- {
- synchronized (listeners)
- {
- listeners.remove(l);
- }
- }
-
- /**
- * Cleans the contactsMap when <tt>ProtocolProviderService</tt>
- * gets unregistered.
- */
- @Override
- public void serviceChanged(ServiceEvent ev)
- {
- Object service
- = OtrActivator.bundleContext.getService(ev.getServiceReference());
-
- if (!(service instanceof ProtocolProviderService))
- return;
-
- if (ev.getType() == ServiceEvent.UNREGISTERING)
- {
- if (logger.isDebugEnabled())
- {
- logger.debug(
- "Unregistering a ProtocolProviderService, cleaning"
- + " OTR's ScSessionID to Contact map.");
- logger.debug(
- "Unregistering a ProtocolProviderService, cleaning"
- + " OTR's Contact to SpmProgressDialog map.");
- }
-
- ProtocolProviderService provider
- = (ProtocolProviderService) service;
-
- synchronized(contactsMap)
- {
- Iterator<OtrContact> i = contactsMap.values().iterator();
-
- while (i.hasNext())
+package net.java.sip.communicator.plugin.otr;
+
+import java.net.*;
+import java.security.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import net.java.otr4j.*;
+import net.java.otr4j.crypto.*;
+import net.java.otr4j.session.*;
+import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact;
+import net.java.sip.communicator.plugin.otr.authdialog.*;
+import net.java.sip.communicator.service.browserlauncher.*;
+import net.java.sip.communicator.service.contactlist.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ *
+ * @author George Politis
+ * @author Lyubomir Marinov
+ * @author Pawel Domas
+ * @author Marin Dzhigarov
+ * @author Danny van Heumen
+ */
+public class ScOtrEngineImpl
+ implements ScOtrEngine,
+ ChatLinkClickedListener,
+ ServiceListener
+{
+ private class ScOtrEngineHost
+ implements OtrEngineHost
+ {
+ @Override
+ public KeyPair getLocalKeyPair(SessionID sessionID)
+ {
+ AccountID accountID =
+ OtrActivator.getAccountIDByUID(sessionID.getAccountID());
+ KeyPair keyPair =
+ OtrActivator.scOtrKeyManager.loadKeyPair(accountID);
+ if (keyPair == null)
+ OtrActivator.scOtrKeyManager.generateKeyPair(accountID);
+
+ return OtrActivator.scOtrKeyManager.loadKeyPair(accountID);
+ }
+
+ @Override
+ public OtrPolicy getSessionPolicy(SessionID sessionID)
+ {
+ return getContactPolicy(getOtrContact(sessionID).contact);
+ }
+
+ @Override
+ public void injectMessage(SessionID sessionID, String messageText)
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ Contact contact = otrContact.contact;
+ ContactResource resource = null;
+
+ if (contact.supportResources())
+ {
+ Collection<ContactResource> resources = contact.getResources();
+ if (resources != null)
+ {
+ for (ContactResource r : resources)
+ {
+ if (r.equals(otrContact.resource))
+ {
+ resource = r;
+ break;
+ }
+ }
+ }
+ }
+
+ OperationSetBasicInstantMessaging imOpSet
+ = contact
+ .getProtocolProvider()
+ .getOperationSet(
+ OperationSetBasicInstantMessaging.class);
+
+ // This is a dirty way of detecting whether the injected message
+ // contains HTML markup. If this is the case then we should create
+ // the message with the appropriate content type so that the remote
+ // party can properly display the HTML.
+ // When otr4j injects QueryMessages it calls
+ // OtrEngineHost.getFallbackMessage() which is currently the only
+ // host method that uses HTML so we can simply check if the injected
+ // message contains the string that getFallbackMessage() returns.
+ String otrHtmlFallbackMessage
+ = "<a href=\"http://en.wikipedia.org/wiki/Off-the-Record_Messaging\">";
+ String contentType
+ = messageText.contains(otrHtmlFallbackMessage)
+ ? OperationSetBasicInstantMessaging.HTML_MIME_TYPE
+ : OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE;
+ Message message
+ = imOpSet.createMessage(
+ messageText,
+ contentType,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING,
+ null);
+
+ injectedMessageUIDs.add(message.getMessageUID());
+ imOpSet.sendInstantMessage(contact, resource, message);
+ }
+
+ @Override
+ public void showError(SessionID sessionID, String err)
+ {
+ ScOtrEngineImpl.this.showError(sessionID, err);
+ }
+
+ public void showWarning(SessionID sessionID, String warn)
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ if (otrContact == null)
+ return;
+
+ Contact contact = otrContact.contact;
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(), new Date(),
+ Chat.SYSTEM_MESSAGE, warn,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
+ }
+
+ @Override
+ public void unreadableMessageReceived(SessionID sessionID)
+ throws OtrException
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ String resourceName = otrContact.resource != null ?
+ "/" + otrContact.resource.getResourceName() : "";
+
+ Contact contact = otrContact.contact;
+ String error =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.unreadablemsgreceived",
+ new String[]
+ {contact.getDisplayName() + resourceName});
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(), new Date(),
+ Chat.ERROR_MESSAGE, error,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
+ }
+
+ @Override
+ public void unencryptedMessageReceived(SessionID sessionID, String msg)
+ throws OtrException
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ if (otrContact == null)
+ return;
+
+ Contact contact = otrContact.contact;
+ String warn =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.unencryptedmsgreceived");
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(), new Date(),
+ Chat.SYSTEM_MESSAGE, warn,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
+ }
+
+ @Override
+ public void smpError(SessionID sessionID, int tlvType, boolean cheated)
+ throws OtrException
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ if (otrContact == null)
+ return;
+
+ Contact contact = otrContact.contact;
+ logger.debug("SMP error occurred"
+ + ". Contact: " + contact.getDisplayName()
+ + ". TLV type: " + tlvType
+ + ". Cheated: " + cheated);
+
+ String error =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.smperror");
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(), new Date(),
+ Chat.ERROR_MESSAGE, error,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
+
+ SmpProgressDialog progressDialog = progressDialogMap.get(otrContact);
+ if (progressDialog == null)
+ {
+ progressDialog = new SmpProgressDialog(contact);
+ progressDialogMap.put(otrContact, progressDialog);
+ }
+
+ progressDialog.setProgressFail();
+ progressDialog.setVisible(true);
+ }
+
+ @Override
+ public void smpAborted(SessionID sessionID) throws OtrException
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ if (otrContact == null)
+ return;
+
+ Contact contact = otrContact.contact;
+ Session session = otrEngine.getSession(sessionID);
+ if (session.isSmpInProgress())
+ {
+ String warn =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.smpaborted",
+ new String[] {contact.getDisplayName()});
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(), new Date(),
+ Chat.SYSTEM_MESSAGE, warn,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
+
+ SmpProgressDialog progressDialog =
+ progressDialogMap.get(otrContact);
+ if (progressDialog == null)
+ {
+ progressDialog = new SmpProgressDialog(contact);
+ progressDialogMap.put(otrContact, progressDialog);
+ }
+
+ progressDialog.setProgressFail();
+ progressDialog.setVisible(true);
+ }
+ }
+
+ @Override
+ public void finishedSessionMessage(SessionID sessionID, String msgText)
+ throws OtrException
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ if (otrContact == null)
+ return;
+
+ String resourceName = otrContact.resource != null ?
+ "/" + otrContact.resource.getResourceName() : "";
+ Contact contact = otrContact.contact;
+ String error =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.sessionfinishederror",
+ new String[]
+ {msgText, contact.getDisplayName() + resourceName});
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(), new Date(),
+ Chat.ERROR_MESSAGE, error,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
+ }
+
+ @Override
+ public void requireEncryptedMessage(SessionID sessionID, String msgText)
+ throws OtrException
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ if (otrContact == null)
+ return;
+
+ Contact contact = otrContact.contact;
+ String error =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.requireencryption",
+ new String[]
+ {msgText});
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(), new Date(),
+ Chat.ERROR_MESSAGE, error,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
+ }
+
+ @Override
+ public byte[] getLocalFingerprintRaw(SessionID sessionID)
+ {
+ AccountID accountID =
+ OtrActivator.getAccountIDByUID(sessionID.getAccountID());
+ return
+ OtrActivator.scOtrKeyManager.getLocalFingerprintRaw(accountID);
+ }
+
+ @Override
+ public void askForSecret(
+ SessionID sessionID, InstanceTag receiverTag, String question)
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ if (otrContact == null)
+ return;
+
+ Contact contact = otrContact.contact;
+ SmpAuthenticateBuddyDialog dialog =
+ new SmpAuthenticateBuddyDialog(
+ otrContact, receiverTag, question);
+ dialog.setVisible(true);
+
+ SmpProgressDialog progressDialog = progressDialogMap.get(otrContact);
+ if (progressDialog == null)
+ {
+ progressDialog = new SmpProgressDialog(contact);
+ progressDialogMap.put(otrContact, progressDialog);
+ }
+
+ progressDialog.init();
+ progressDialog.setVisible(true);
+ }
+
+ @Override
+ public void verify(
+ SessionID sessionID, String fingerprint, boolean approved)
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ if (otrContact == null)
+ return;
+
+ Contact contact = otrContact.contact;
+ OtrActivator.scOtrKeyManager.verify(otrContact, fingerprint);
+
+ SmpProgressDialog progressDialog = progressDialogMap.get(otrContact);
+ if (progressDialog == null)
+ {
+ progressDialog = new SmpProgressDialog(contact);
+ progressDialogMap.put(otrContact, progressDialog);
+ }
+
+ progressDialog.setProgressSuccess();
+ progressDialog.setVisible(true);
+ }
+
+ @Override
+ public void unverify(SessionID sessionID, String fingerprint)
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ if (otrContact == null)
+ return;
+
+ Contact contact = otrContact.contact;
+ OtrActivator.scOtrKeyManager.unverify(otrContact, fingerprint);
+
+ SmpProgressDialog progressDialog = progressDialogMap.get(otrContact);
+ if (progressDialog == null)
+ {
+ progressDialog = new SmpProgressDialog(contact);
+ progressDialogMap.put(otrContact, progressDialog);
+ }
+
+ progressDialog.setProgressFail();
+ progressDialog.setVisible(true);
+ }
+
+ @Override
+ public String getReplyForUnreadableMessage(SessionID sessionID)
+ {
+ AccountID accountID =
+ OtrActivator.getAccountIDByUID(sessionID.getAccountID());
+
+ return OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.unreadablemsgreply",
+ new String[] {accountID.getDisplayName(),
+ accountID.getDisplayName()});
+ }
+
+ @Override
+ public String getFallbackMessage(SessionID sessionID)
+ {
+ AccountID accountID =
+ OtrActivator.getAccountIDByUID(sessionID.getAccountID());
+
+ return OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.fallbackmessage",
+ new String[] {accountID.getDisplayName()});
+ }
+
+ @Override
+ public void multipleInstancesDetected(SessionID sessionID)
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ if (otrContact == null)
+ return;
+
+ String resourceName = otrContact.resource != null ?
+ "/" + otrContact.resource.getResourceName() : "";
+ Contact contact = otrContact.contact;
+ String message =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.multipleinstancesdetected",
+ new String[]
+ {contact.getDisplayName() + resourceName});
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(),
+ new Date(), Chat.SYSTEM_MESSAGE,
+ message,
+ OperationSetBasicInstantMessaging.HTML_MIME_TYPE);
+ }
+
+ @Override
+ public void messageFromAnotherInstanceReceived(SessionID sessionID)
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ if (otrContact == null)
+ return;
+
+ String resourceName = otrContact.resource != null ?
+ "/" + otrContact.resource.getResourceName() : "";
+ Contact contact = otrContact.contact;
+ String message =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.msgfromanotherinstance",
+ new String[]
+ {contact.getDisplayName() + resourceName});
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(),
+ new Date(), Chat.SYSTEM_MESSAGE,
+ message,
+ OperationSetBasicInstantMessaging.HTML_MIME_TYPE);
+ }
+
+ /**
+ * Provide fragmenter instructions according to the Instant Messaging
+ * transport channel of the contact's protocol.
+ */
+ @Override
+ public FragmenterInstructions getFragmenterInstructions(
+ final SessionID sessionID)
+ {
+ final OtrContact otrContact = getOtrContact(sessionID);
+ final OperationSetBasicInstantMessagingTransport transport =
+ otrContact.contact.getProtocolProvider().getOperationSet(
+ OperationSetBasicInstantMessagingTransport.class);
+ if (transport == null)
+ {
+ // There is no operation set for querying transport parameters.
+ // Assuming transport capabilities are unlimited.
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("No implementation of "
+ + "BasicInstantMessagingTransport available. Assuming "
+ + "OTR defaults for OTR fragmentation instructions.");
+ }
+ return null;
+ }
+ int messageSize = transport.getMaxMessageSize(otrContact.contact);
+ if (messageSize
+ == OperationSetBasicInstantMessagingTransport.UNLIMITED)
+ {
+ messageSize = FragmenterInstructions.UNLIMITED;
+ }
+ int numberOfMessages =
+ transport.getMaxNumberOfMessages(otrContact.contact);
+ if (numberOfMessages
+ == OperationSetBasicInstantMessagingTransport.UNLIMITED)
+ {
+ numberOfMessages = FragmenterInstructions.UNLIMITED;
+ }
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("OTR fragmentation instructions for sending a "
+ + "message to " + otrContact.contact.getDisplayName()
+ + " (" + otrContact.contact.getAddress()
+ + "). Maximum number of " + "messages: " + numberOfMessages
+ + ", maximum message size: " + messageSize);
+ }
+ return new FragmenterInstructions(numberOfMessages, messageSize);
+ }
+ }
+
+ /**
+ * The max timeout period elapsed prior to establishing a TIMED_OUT session.
+ */
+ private static final int SESSION_TIMEOUT =
+ OtrActivator.configService.getInt(
+ "net.java.sip.communicator.plugin.otr.SESSION_STATUS_TIMEOUT",
+ 30000);
+
+ /**
+ * Manages the scheduling of TimerTasks that are used to set Contact's
+ * ScSessionStatus (to TIMED_OUT) after a period of time.
+ */
+ private ScSessionStatusScheduler scheduler = new ScSessionStatusScheduler();
+
+ /**
+ * This mapping is used for taking care of keeping SessionStatus and
+ * ScSessionStatus in sync for every Session object.
+ */
+ private Map<SessionID, ScSessionStatus> scSessionStatusMap =
+ new ConcurrentHashMap<SessionID, ScSessionStatus>();
+
+ private static final Map<ScSessionID, OtrContact> contactsMap =
+ new Hashtable<ScSessionID, OtrContact>();
+
+ private static final Map<OtrContact, SmpProgressDialog> progressDialogMap =
+ new ConcurrentHashMap<OtrContact, SmpProgressDialog>();
+
+ public static OtrContact getOtrContact(SessionID sessionID)
+ {
+ return contactsMap.get(new ScSessionID(sessionID));
+ }
+
+ /**
+ * Returns the <tt>ScSessionID</tt> for given <tt>UUID</tt>.
+ * @param guid the <tt>UUID</tt> identifying <tt>ScSessionID</tt>.
+ * @return the <tt>ScSessionID</tt> for given <tt>UUID</tt> or <tt>null</tt>
+ * if no matching session found.
+ */
+ public static ScSessionID getScSessionForGuid(UUID guid)
+ {
+ for(ScSessionID scSessionID : contactsMap.keySet())
+ {
+ if(scSessionID.getGUID().equals(guid))
+ {
+ return scSessionID;
+ }
+ }
+ return null;
+ }
+
+ public static SessionID getSessionID(OtrContact otrContact)
+ {
+ ProtocolProviderService pps = otrContact.contact.getProtocolProvider();
+ String resourceName = otrContact.resource != null ?
+ "/" + otrContact.resource.getResourceName() : "";
+ SessionID sessionID
+ = new SessionID(
+ pps.getAccountID().getAccountUniqueID(),
+ otrContact.contact.getAddress() + resourceName,
+ pps.getProtocolName());
+
+ synchronized (contactsMap)
+ {
+ if(contactsMap.containsKey(new ScSessionID(sessionID)))
+ return sessionID;
+
+ ScSessionID scSessionID = new ScSessionID(sessionID);
+
+ contactsMap.put(scSessionID, otrContact);
+ }
+
+ return sessionID;
+ }
+
+ private final OtrConfigurator configurator = new OtrConfigurator();
+
+ private final List<String> injectedMessageUIDs = new Vector<String>();
+
+ private final List<ScOtrEngineListener> listeners =
+ new Vector<ScOtrEngineListener>();
+
+ /**
+ * The logger
+ */
+ private final Logger logger = Logger.getLogger(ScOtrEngineImpl.class);
+
+ private final OtrEngineHost otrEngineHost = new ScOtrEngineHost();
+
+ private final OtrSessionManager otrEngine;
+
+ public ScOtrEngineImpl()
+ {
+ otrEngine = new OtrSessionManagerImpl(otrEngineHost);
+
+ // Clears the map after previous instance
+ // This is required because of OSGi restarts in the same VM on Android
+ contactsMap.clear();
+ scSessionStatusMap.clear();
+
+ this.otrEngine.addOtrEngineListener(new OtrEngineListener()
+ {
+ @Override
+ public void sessionStatusChanged(SessionID sessionID)
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ if (otrContact == null)
+ return;
+
+ String resourceName = otrContact.resource != null ?
+ "/" + otrContact.resource.getResourceName() : "";
+ Contact contact = otrContact.contact;
+ // Cancels any scheduled tasks that will change the
+ // ScSessionStatus for this Contact
+ scheduler.cancel(otrContact);
+
+ ScSessionStatus scSessionStatus = getSessionStatus(otrContact);
+ String message = "";
+ final Session session = otrEngine.getSession(sessionID);
+ switch (session.getSessionStatus())
+ {
+ case ENCRYPTED:
+ scSessionStatus = ScSessionStatus.ENCRYPTED;
+ scSessionStatusMap.put(sessionID, scSessionStatus);
+ PublicKey remotePubKey = session.getRemotePublicKey();
+
+ String remoteFingerprint = null;
+ try
+ {
+ remoteFingerprint =
+ new OtrCryptoEngineImpl().
+ getFingerprint(remotePubKey);
+ }
+ catch (OtrCryptoException e)
+ {
+ logger.debug(
+ "Could not get the fingerprint from the "
+ + "public key of contact: " + contact);
+ }
+
+ List<String> allFingerprintsOfContact =
+ OtrActivator.scOtrKeyManager.
+ getAllRemoteFingerprints(contact);
+ if (allFingerprintsOfContact != null)
+ {
+ if (!allFingerprintsOfContact.contains(
+ remoteFingerprint))
+ {
+ OtrActivator.scOtrKeyManager.saveFingerprint(
+ contact, remoteFingerprint);
+ }
+ }
+
+ if (!OtrActivator.scOtrKeyManager.isVerified(
+ contact, remoteFingerprint))
+ {
+ OtrActivator.scOtrKeyManager.unverify(
+ otrContact, remoteFingerprint);
+ UUID sessionGuid = null;
+ for(ScSessionID scSessionID : contactsMap.keySet())
+ {
+ if(scSessionID.getSessionID().equals(sessionID))
+ {
+ sessionGuid = scSessionID.getGUID();
+ break;
+ }
+ }
+
+ OtrActivator.uiService.getChat(contact)
+ .addChatLinkClickedListener(ScOtrEngineImpl.this);
+
+ String unverifiedSessionWarning
+ = OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.unverifiedsessionwarning",
+ new String[]
+ {
+ contact.getDisplayName() + resourceName,
+ this.getClass().getName(),
+ "AUTHENTIFICATION",
+ sessionGuid.toString()
+ });
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(),
+ new Date(), Chat.SYSTEM_MESSAGE,
+ unverifiedSessionWarning,
+ OperationSetBasicInstantMessaging.HTML_MIME_TYPE);
+
+ }
+
+ // show info whether history is on or off
+ String otrAndHistoryMessage;
+ if(!OtrActivator.getMessageHistoryService()
+ .isHistoryLoggingEnabled() ||
+ !isHistoryLoggingEnabled(contact))
+ {
+ otrAndHistoryMessage =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.historyoff",
+ new String[]{
+ OtrActivator.resourceService
+ .getSettingsString(
+ "service.gui.APPLICATION_NAME"),
+ this.getClass().getName(),
+ "showHistoryPopupMenu"
+ });
+ }
+ else
+ {
+ otrAndHistoryMessage =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.historyon",
+ new String[]{
+ OtrActivator.resourceService
+ .getSettingsString(
+ "service.gui.APPLICATION_NAME"),
+ this.getClass().getName(),
+ "showHistoryPopupMenu"
+ });
+ }
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(),
+ new Date(), Chat.SYSTEM_MESSAGE,
+ otrAndHistoryMessage,
+ OperationSetBasicInstantMessaging.HTML_MIME_TYPE);
+
+ message =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.multipleinstancesdetected",
+ new String[]
+ {contact.getDisplayName()});
+
+ if (contact.supportResources()
+ && contact.getResources() != null
+ && contact.getResources().size() > 1)
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(),
+ new Date(), Chat.SYSTEM_MESSAGE,
+ message,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
+
+ message
+ = OtrActivator.resourceService.getI18NString(
+ OtrActivator.scOtrKeyManager.isVerified(
+ contact, remoteFingerprint)
+ ? "plugin.otr.activator.sessionstared"
+ : "plugin.otr.activator.unverifiedsessionstared",
+ new String[]
+ {contact.getDisplayName() + resourceName});
+
+ break;
+ case FINISHED:
+ scSessionStatus = ScSessionStatus.FINISHED;
+ scSessionStatusMap.put(sessionID, scSessionStatus);
+ message =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.sessionfinished",
+ new String[]
+ {contact.getDisplayName() + resourceName});
+ break;
+ case PLAINTEXT:
+ scSessionStatus = ScSessionStatus.PLAINTEXT;
+ scSessionStatusMap.put(sessionID, scSessionStatus);
+ message =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.sessionlost", new String[]
+ {contact.getDisplayName() + resourceName});
+ break;
+ }
+
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(), new Date(),
+ Chat.SYSTEM_MESSAGE, message,
+ OperationSetBasicInstantMessaging.HTML_MIME_TYPE);
+
+ for (ScOtrEngineListener l : getListeners())
+ l.sessionStatusChanged(otrContact);
+ }
+
+ @Override
+ public void multipleInstancesDetected(SessionID sessionID)
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ if (otrContact == null)
+ return;
+
+ for (ScOtrEngineListener l : getListeners())
+ l.multipleInstancesDetected(otrContact);
+ }
+
+ @Override
+ public void outgoingSessionChanged(SessionID sessionID)
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ if (otrContact == null)
+ return;
+
+ for (ScOtrEngineListener l : getListeners())
+ l.outgoingSessionChanged(otrContact);
+ }
+ });
+ }
+
+ /**
+ * Checks whether history is enabled for the metacontact containing
+ * the <tt>contact</tt>.
+ * @param contact the contact to check.
+ * @return whether chat logging is enabled while chatting
+ * with <tt>contact</tt>.
+ */
+ private boolean isHistoryLoggingEnabled(Contact contact)
+ {
+ MetaContact metaContact = OtrActivator
+ .getContactListService().findMetaContactByContact(contact);
+ if(metaContact != null)
+ return OtrActivator.getMessageHistoryService()
+ .isHistoryLoggingEnabled(metaContact.getMetaUID());
+ else
+ return true;
+ }
+
+ @Override
+ public void addListener(ScOtrEngineListener l)
+ {
+ synchronized (listeners)
+ {
+ if (!listeners.contains(l))
+ listeners.add(l);
+ }
+ }
+
+ @Override
+ public void chatLinkClicked(URI url)
+ {
+ String action = url.getPath();
+ if(action.equals("/AUTHENTIFICATION"))
+ {
+ UUID guid = UUID.fromString(url.getQuery());
+
+ if(guid == null)
+ throw new RuntimeException(
+ "No UUID found in OTR authenticate URL");
+
+ // Looks for registered action handler
+ OtrActionHandler actionHandler
+ = ServiceUtils.getService(
+ OtrActivator.bundleContext,
+ OtrActionHandler.class);
+
+ if(actionHandler != null)
+ {
+ actionHandler.onAuthenticateLinkClicked(guid);
+ }
+ else
+ {
+ logger.error("No OtrActionHandler registered");
+ }
+ }
+ }
+
+ @Override
+ public void endSession(OtrContact otrContact)
+ {
+ SessionID sessionID = getSessionID(otrContact);
+ try
+ {
+ setSessionStatus(otrContact, ScSessionStatus.PLAINTEXT);
+
+ otrEngine.getSession(sessionID).endSession();
+ }
+ catch (OtrException e)
+ {
+ showError(sessionID, e.getMessage());
+ }
+ }
+
+ @Override
+ public OtrPolicy getContactPolicy(Contact contact)
+ {
+ ProtocolProviderService pps = contact.getProtocolProvider();
+ SessionID sessionID
+ = new SessionID(
+ pps.getAccountID().getAccountUniqueID(),
+ contact.getAddress(),
+ pps.getProtocolName());
+ int policy =
+ this.configurator.getPropertyInt(sessionID + "contact_policy",
+ -1);
+ if (policy < 0)
+ return getGlobalPolicy();
+ else
+ return new OtrPolicyImpl(policy);
+ }
+
+ @Override
+ public OtrPolicy getGlobalPolicy()
+ {
+ /*
+ * SEND_WHITESPACE_TAG bit will be lowered until we stabilize the OTR.
+ */
+ int defaultScOtrPolicy =
+ OtrPolicy.OTRL_POLICY_DEFAULT & ~OtrPolicy.SEND_WHITESPACE_TAG;
+ return new OtrPolicyImpl(this.configurator.getPropertyInt(
+ "GLOBAL_POLICY", defaultScOtrPolicy));
+ }
+
+ /**
+ * Gets a copy of the list of <tt>ScOtrEngineListener</tt>s registered with
+ * this instance which may safely be iterated without the risk of a
+ * <tt>ConcurrentModificationException</tt>.
+ *
+ * @return a copy of the list of <tt>ScOtrEngineListener<tt>s registered
+ * with this instance which may safely be iterated without the risk of a
+ * <tt>ConcurrentModificationException</tt>
+ */
+ private ScOtrEngineListener[] getListeners()
+ {
+ synchronized (listeners)
+ {
+ return listeners.toArray(new ScOtrEngineListener[listeners.size()]);
+ }
+ }
+
+ /**
+ * Manages the scheduling of TimerTasks that are used to set Contact's
+ * ScSessionStatus after a period of time.
+ *
+ * @author Marin Dzhigarov
+ */
+ private class ScSessionStatusScheduler
+ {
+ private final Timer timer = new Timer();
+
+ private final Map<OtrContact, TimerTask> tasks =
+ new ConcurrentHashMap<OtrContact, TimerTask>();
+
+ public void scheduleScSessionStatusChange(
+ final OtrContact otrContact, final ScSessionStatus status)
+ {
+ cancel(otrContact);
+
+ TimerTask task
+ = new TimerTask()
+ {
+ @Override
+ public void run()
+ {
+ setSessionStatus(otrContact, status);
+ }
+ };
+ timer.schedule(task, SESSION_TIMEOUT);
+ tasks.put(otrContact, task);
+ }
+
+ public void cancel(final OtrContact otrContact)
+ {
+ TimerTask task = tasks.get(otrContact);
+ if (task != null)
+ task.cancel();
+ tasks.remove(otrContact);
+ }
+
+ public void serviceChanged(ServiceEvent ev)
+ {
+ Object service
+ = OtrActivator.bundleContext.getService(
+ ev.getServiceReference());
+
+ if (!(service instanceof ProtocolProviderService))
+ return;
+
+ if (ev.getType() == ServiceEvent.UNREGISTERING)
+ {
+ ProtocolProviderService provider
+ = (ProtocolProviderService) service;
+
+ Iterator<OtrContact> i = tasks.keySet().iterator();
+
+ while (i.hasNext())
+ {
+ OtrContact otrContact = i.next();
+ if (provider.equals(
+ otrContact.contact.getProtocolProvider()))
+ {
+ cancel(otrContact);
+ i.remove();
+ }
+ }
+ }
+ }
+ }
+
+ private void setSessionStatus(OtrContact contact, ScSessionStatus status)
+ {
+ scSessionStatusMap.put(getSessionID(contact), status);
+ scheduler.cancel(contact);
+ for (ScOtrEngineListener l : getListeners())
+ l.sessionStatusChanged(contact);
+ }
+
+ @Override
+ public ScSessionStatus getSessionStatus(OtrContact contact)
+ {
+ SessionID sessionID = getSessionID(contact);
+ SessionStatus sessionStatus = otrEngine.getSession(sessionID).getSessionStatus();
+ ScSessionStatus scSessionStatus = null;
+ if (!scSessionStatusMap.containsKey(sessionID))
+ {
+ switch (sessionStatus)
+ {
+ case PLAINTEXT:
+ scSessionStatus = ScSessionStatus.PLAINTEXT;
+ break;
+ case ENCRYPTED:
+ scSessionStatus = ScSessionStatus.ENCRYPTED;
+ break;
+ case FINISHED:
+ scSessionStatus = ScSessionStatus.FINISHED;
+ break;
+ }
+ scSessionStatusMap.put(sessionID, scSessionStatus);
+ }
+ return scSessionStatusMap.get(sessionID);
+ }
+
+ @Override
+ public boolean isMessageUIDInjected(String mUID)
+ {
+ return injectedMessageUIDs.contains(mUID);
+ }
+
+ @Override
+ public void launchHelp()
+ {
+ ServiceReference ref =
+ OtrActivator.bundleContext
+ .getServiceReference(BrowserLauncherService.class.getName());
+
+ if (ref == null)
+ return;
+
+ BrowserLauncherService service =
+ (BrowserLauncherService) OtrActivator.bundleContext.getService(ref);
+
+ service.openURL(OtrActivator.resourceService
+ .getI18NString("plugin.otr.authbuddydialog.HELP_URI"));
+ }
+
+ @Override
+ public void refreshSession(OtrContact otrContact)
+ {
+ SessionID sessionID = getSessionID(otrContact);
+ try
+ {
+ otrEngine.getSession(sessionID).refreshSession();
+ }
+ catch (OtrException e)
+ {
+ logger.error("Error refreshing session", e);
+ showError(sessionID, e.getMessage());
+ }
+ }
+
+ @Override
+ public void removeListener(ScOtrEngineListener l)
+ {
+ synchronized (listeners)
+ {
+ listeners.remove(l);
+ }
+ }
+
+ /**
+ * Cleans the contactsMap when <tt>ProtocolProviderService</tt>
+ * gets unregistered.
+ */
+ @Override
+ public void serviceChanged(ServiceEvent ev)
+ {
+ Object service
+ = OtrActivator.bundleContext.getService(ev.getServiceReference());
+
+ if (!(service instanceof ProtocolProviderService))
+ return;
+
+ if (ev.getType() == ServiceEvent.UNREGISTERING)
+ {
+ if (logger.isDebugEnabled())
+ {
+ logger.debug(
+ "Unregistering a ProtocolProviderService, cleaning"
+ + " OTR's ScSessionID to Contact map.");
+ logger.debug(
+ "Unregistering a ProtocolProviderService, cleaning"
+ + " OTR's Contact to SpmProgressDialog map.");
+ }
+
+ ProtocolProviderService provider
+ = (ProtocolProviderService) service;
+
+ synchronized(contactsMap)
+ {
+ Iterator<OtrContact> i = contactsMap.values().iterator();
+
+ while (i.hasNext())
{
- OtrContact otrContact = i.next();
- if (provider.equals(
- otrContact.contact.getProtocolProvider()))
- {
- scSessionStatusMap.remove(getSessionID(otrContact));
- i.remove();
- }
- }
- }
-
- Iterator<OtrContact> i = progressDialogMap.keySet().iterator();
-
- while (i.hasNext())
- {
- if (provider.equals(i.next().contact.getProtocolProvider()))
- i.remove();
- }
- scheduler.serviceChanged(ev);
- }
- }
-
- @Override
- public void setContactPolicy(Contact contact, OtrPolicy policy)
- {
- ProtocolProviderService pps = contact.getProtocolProvider();
- SessionID sessionID
- = new SessionID(
- pps.getAccountID().getAccountUniqueID(),
- contact.getAddress(),
- pps.getProtocolName());
-
- String propertyID = sessionID + "contact_policy";
- if (policy == null)
- this.configurator.removeProperty(propertyID);
- else
- this.configurator.setProperty(propertyID, policy.getPolicy());
-
- for (ScOtrEngineListener l : getListeners())
- l.contactPolicyChanged(contact);
- }
-
- @Override
- public void setGlobalPolicy(OtrPolicy policy)
- {
- if (policy == null)
- this.configurator.removeProperty("GLOBAL_POLICY");
- else
- this.configurator.setProperty("GLOBAL_POLICY", policy.getPolicy());
-
- for (ScOtrEngineListener l : getListeners())
- l.globalPolicyChanged();
- }
-
- public void showError(SessionID sessionID, String err)
- {
- OtrContact otrContact = getOtrContact(sessionID);
- if (otrContact == null)
- return;
-
- Contact contact = otrContact.contact;
- OtrActivator.uiService.getChat(contact).addMessage(
- contact.getDisplayName(), new Date(),
- Chat.ERROR_MESSAGE, err,
- OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
- }
-
- @Override
- public void startSession(OtrContact otrContact)
- {
- SessionID sessionID = getSessionID(otrContact);
-
- ScSessionStatus scSessionStatus = getSessionStatus(otrContact);
- scSessionStatus = ScSessionStatus.LOADING;
- scSessionStatusMap.put(sessionID, scSessionStatus);
- for (ScOtrEngineListener l : getListeners())
- {
- l.sessionStatusChanged(otrContact);
- }
-
- scheduler.scheduleScSessionStatusChange(
- otrContact, ScSessionStatus.TIMED_OUT);
-
- try
- {
- otrEngine.getSession(sessionID).startSession();
- }
- catch (OtrException e)
- {
- logger.error("Error starting session", e);
- showError(sessionID, e.getMessage());
- }
- }
-
- @Override
- public String transformReceiving(OtrContact otrContact, String msgText)
- {
- SessionID sessionID = getSessionID(otrContact);
- try
- {
- return otrEngine.getSession(sessionID).transformReceiving(msgText);
- }
- catch (OtrException e)
- {
- logger.error("Error receiving the message", e);
- showError(sessionID, e.getMessage());
- return null;
- }
- }
-
- @Override
- public String[] transformSending(OtrContact otrContact, String msgText)
- {
- SessionID sessionID = getSessionID(otrContact);
- try
- {
- return otrEngine.getSession(sessionID).transformSending(msgText);
- }
- catch (OtrException e)
- {
- logger.error("Error transforming the message", e);
- showError(sessionID, e.getMessage());
- return null;
- }
- }
-
- private Session getSession(OtrContact contact)
- {
- SessionID sessionID = getSessionID(contact);
- return otrEngine.getSession(sessionID);
- }
-
- @Override
- public void initSmp(OtrContact otrContact, String question, String secret)
- {
- Session session = getSession(otrContact);
- try
- {
- session.initSmp(question, secret);
-
- SmpProgressDialog progressDialog = progressDialogMap.get(otrContact);
- if (progressDialog == null)
- {
- progressDialog = new SmpProgressDialog(otrContact.contact);
- progressDialogMap.put(otrContact, progressDialog);
- }
-
- progressDialog.init();
- progressDialog.setVisible(true);
- }
- catch (OtrException e)
- {
- logger.error("Error initializing SMP session with contact "
- + otrContact.contact.getDisplayName(), e);
- showError(session.getSessionID(), e.getMessage());
- }
- }
-
- @Override
- public void respondSmp( OtrContact otrContact,
- InstanceTag receiverTag,
- String question,
- String secret)
- {
- Session session = getSession(otrContact);
- try
- {
- session.respondSmp(receiverTag, question, secret);
-
- SmpProgressDialog progressDialog = progressDialogMap.get(otrContact);
- if (progressDialog == null)
- {
- progressDialog = new SmpProgressDialog(otrContact.contact);
- progressDialogMap.put(otrContact, progressDialog);
- }
-
- progressDialog.incrementProgress();
- progressDialog.setVisible(true);
- }
- catch (OtrException e)
- {
- logger.error(
- "Error occured when sending SMP response to contact "
- + otrContact.contact.getDisplayName(), e);
- showError(session.getSessionID(), e.getMessage());
- }
- }
-
- @Override
- public void abortSmp(OtrContact otrContact)
- {
- Session session = getSession(otrContact);
- try
- {
- session.abortSmp();
-
- SmpProgressDialog progressDialog = progressDialogMap.get(otrContact);
- if (progressDialog == null)
- {
- progressDialog = new SmpProgressDialog(otrContact.contact);
- progressDialogMap.put(otrContact, progressDialog);
- }
-
- progressDialog.dispose();
- }
- catch (OtrException e)
- {
- logger.error("Error aborting SMP session with contact "
- + otrContact.contact.getDisplayName(), e);
- showError(session.getSessionID(), e.getMessage());
- }
- }
-
- @Override
- public PublicKey getRemotePublicKey(OtrContact otrContact)
- {
- if (otrContact == null)
- return null;
-
- Session session = getSession(otrContact);
-
- return session.getRemotePublicKey();
- }
-
- @Override
- public List<Session> getSessionInstances(OtrContact otrContact)
- {
- if (otrContact == null)
- return Collections.emptyList();
- return getSession(otrContact).getInstances();
- }
-
- @Override
- public boolean setOutgoingSession(OtrContact contact, InstanceTag tag)
- {
- if (contact == null)
- return false;
-
- Session session = getSession(contact);
-
- scSessionStatusMap.remove(session.getSessionID());
- return session.setOutgoingInstance(tag);
- }
-
- @Override
- public Session getOutgoingSession(OtrContact contact)
- {
- if (contact == null)
- return null;
-
- SessionID sessionID = getSessionID(contact);
-
- return otrEngine.getSession(sessionID).getOutgoingInstance();
- }
-}
+ OtrContact otrContact = i.next();
+ if (provider.equals(
+ otrContact.contact.getProtocolProvider()))
+ {
+ scSessionStatusMap.remove(getSessionID(otrContact));
+ i.remove();
+ }
+ }
+ }
+
+ Iterator<OtrContact> i = progressDialogMap.keySet().iterator();
+
+ while (i.hasNext())
+ {
+ if (provider.equals(i.next().contact.getProtocolProvider()))
+ i.remove();
+ }
+ scheduler.serviceChanged(ev);
+ }
+ }
+
+ @Override
+ public void setContactPolicy(Contact contact, OtrPolicy policy)
+ {
+ ProtocolProviderService pps = contact.getProtocolProvider();
+ SessionID sessionID
+ = new SessionID(
+ pps.getAccountID().getAccountUniqueID(),
+ contact.getAddress(),
+ pps.getProtocolName());
+
+ String propertyID = sessionID + "contact_policy";
+ if (policy == null)
+ this.configurator.removeProperty(propertyID);
+ else
+ this.configurator.setProperty(propertyID, policy.getPolicy());
+
+ for (ScOtrEngineListener l : getListeners())
+ l.contactPolicyChanged(contact);
+ }
+
+ @Override
+ public void setGlobalPolicy(OtrPolicy policy)
+ {
+ if (policy == null)
+ this.configurator.removeProperty("GLOBAL_POLICY");
+ else
+ this.configurator.setProperty("GLOBAL_POLICY", policy.getPolicy());
+
+ for (ScOtrEngineListener l : getListeners())
+ l.globalPolicyChanged();
+ }
+
+ public void showError(SessionID sessionID, String err)
+ {
+ OtrContact otrContact = getOtrContact(sessionID);
+ if (otrContact == null)
+ return;
+
+ Contact contact = otrContact.contact;
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(), new Date(),
+ Chat.ERROR_MESSAGE, err,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
+ }
+
+ @Override
+ public void startSession(OtrContact otrContact)
+ {
+ SessionID sessionID = getSessionID(otrContact);
+
+ ScSessionStatus scSessionStatus = getSessionStatus(otrContact);
+ scSessionStatus = ScSessionStatus.LOADING;
+ scSessionStatusMap.put(sessionID, scSessionStatus);
+ for (ScOtrEngineListener l : getListeners())
+ {
+ l.sessionStatusChanged(otrContact);
+ }
+
+ scheduler.scheduleScSessionStatusChange(
+ otrContact, ScSessionStatus.TIMED_OUT);
+
+ try
+ {
+ otrEngine.getSession(sessionID).startSession();
+ }
+ catch (OtrException e)
+ {
+ logger.error("Error starting session", e);
+ showError(sessionID, e.getMessage());
+ }
+ }
+
+ @Override
+ public String transformReceiving(OtrContact otrContact, String msgText)
+ {
+ SessionID sessionID = getSessionID(otrContact);
+ try
+ {
+ return otrEngine.getSession(sessionID).transformReceiving(msgText);
+ }
+ catch (OtrException e)
+ {
+ logger.error("Error receiving the message", e);
+ showError(sessionID, e.getMessage());
+ return null;
+ }
+ }
+
+ @Override
+ public String[] transformSending(OtrContact otrContact, String msgText)
+ {
+ SessionID sessionID = getSessionID(otrContact);
+ try
+ {
+ return otrEngine.getSession(sessionID).transformSending(msgText);
+ }
+ catch (OtrException e)
+ {
+ logger.error("Error transforming the message", e);
+ showError(sessionID, e.getMessage());
+ return null;
+ }
+ }
+
+ private Session getSession(OtrContact contact)
+ {
+ SessionID sessionID = getSessionID(contact);
+ return otrEngine.getSession(sessionID);
+ }
+
+ @Override
+ public void initSmp(OtrContact otrContact, String question, String secret)
+ {
+ Session session = getSession(otrContact);
+ try
+ {
+ session.initSmp(question, secret);
+
+ SmpProgressDialog progressDialog = progressDialogMap.get(otrContact);
+ if (progressDialog == null)
+ {
+ progressDialog = new SmpProgressDialog(otrContact.contact);
+ progressDialogMap.put(otrContact, progressDialog);
+ }
+
+ progressDialog.init();
+ progressDialog.setVisible(true);
+ }
+ catch (OtrException e)
+ {
+ logger.error("Error initializing SMP session with contact "
+ + otrContact.contact.getDisplayName(), e);
+ showError(session.getSessionID(), e.getMessage());
+ }
+ }
+
+ @Override
+ public void respondSmp( OtrContact otrContact,
+ InstanceTag receiverTag,
+ String question,
+ String secret)
+ {
+ Session session = getSession(otrContact);
+ try
+ {
+ session.respondSmp(receiverTag, question, secret);
+
+ SmpProgressDialog progressDialog = progressDialogMap.get(otrContact);
+ if (progressDialog == null)
+ {
+ progressDialog = new SmpProgressDialog(otrContact.contact);
+ progressDialogMap.put(otrContact, progressDialog);
+ }
+
+ progressDialog.incrementProgress();
+ progressDialog.setVisible(true);
+ }
+ catch (OtrException e)
+ {
+ logger.error(
+ "Error occured when sending SMP response to contact "
+ + otrContact.contact.getDisplayName(), e);
+ showError(session.getSessionID(), e.getMessage());
+ }
+ }
+
+ @Override
+ public void abortSmp(OtrContact otrContact)
+ {
+ Session session = getSession(otrContact);
+ try
+ {
+ session.abortSmp();
+
+ SmpProgressDialog progressDialog = progressDialogMap.get(otrContact);
+ if (progressDialog == null)
+ {
+ progressDialog = new SmpProgressDialog(otrContact.contact);
+ progressDialogMap.put(otrContact, progressDialog);
+ }
+
+ progressDialog.dispose();
+ }
+ catch (OtrException e)
+ {
+ logger.error("Error aborting SMP session with contact "
+ + otrContact.contact.getDisplayName(), e);
+ showError(session.getSessionID(), e.getMessage());
+ }
+ }
+
+ @Override
+ public PublicKey getRemotePublicKey(OtrContact otrContact)
+ {
+ if (otrContact == null)
+ return null;
+
+ Session session = getSession(otrContact);
+
+ return session.getRemotePublicKey();
+ }
+
+ @Override
+ public List<Session> getSessionInstances(OtrContact otrContact)
+ {
+ if (otrContact == null)
+ return Collections.emptyList();
+ return getSession(otrContact).getInstances();
+ }
+
+ @Override
+ public boolean setOutgoingSession(OtrContact contact, InstanceTag tag)
+ {
+ if (contact == null)
+ return false;
+
+ Session session = getSession(contact);
+
+ scSessionStatusMap.remove(session.getSessionID());
+ return session.setOutgoingInstance(tag);
+ }
+
+ @Override
+ public Session getOutgoingSession(OtrContact contact)
+ {
+ if (contact == null)
+ return null;
+
+ SessionID sessionID = getSessionID(contact);
+
+ return otrEngine.getSession(sessionID).getOutgoingInstance();
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java
index 183eed7..ae50390 100644
--- a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java
+++ b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,44 +15,44 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.otr;
-
-import java.security.*;
-import java.util.*;
-
-import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact;
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- *
- * @author George Politis
- *
- */
-public interface ScOtrKeyManager
-{
-
- public abstract void addListener(ScOtrKeyManagerListener l);
-
- public abstract void removeListener(ScOtrKeyManagerListener l);
-
- public abstract void verify(OtrContact contact, String fingerprint);
-
- public abstract void unverify(OtrContact contact, String fingerprint);
-
- public abstract boolean isVerified(Contact contact, String fingerprint);
-
- public abstract String getFingerprintFromPublicKey(PublicKey pubKey);
-
- public abstract List<String> getAllRemoteFingerprints(Contact contact);
-
- public abstract String getLocalFingerprint(AccountID account);
-
- public abstract byte[] getLocalFingerprintRaw(AccountID account);
-
- public abstract void saveFingerprint(Contact contact, String fingerprint);
-
- public abstract KeyPair loadKeyPair(AccountID accountID);
-
- public abstract void generateKeyPair(AccountID accountID);
-
+package net.java.sip.communicator.plugin.otr;
+
+import java.security.*;
+import java.util.*;
+
+import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ *
+ * @author George Politis
+ *
+ */
+public interface ScOtrKeyManager
+{
+
+ public abstract void addListener(ScOtrKeyManagerListener l);
+
+ public abstract void removeListener(ScOtrKeyManagerListener l);
+
+ public abstract void verify(OtrContact contact, String fingerprint);
+
+ public abstract void unverify(OtrContact contact, String fingerprint);
+
+ public abstract boolean isVerified(Contact contact, String fingerprint);
+
+ public abstract String getFingerprintFromPublicKey(PublicKey pubKey);
+
+ public abstract List<String> getAllRemoteFingerprints(Contact contact);
+
+ public abstract String getLocalFingerprint(AccountID account);
+
+ public abstract byte[] getLocalFingerprintRaw(AccountID account);
+
+ public abstract void saveFingerprint(Contact contact, String fingerprint);
+
+ public abstract KeyPair loadKeyPair(AccountID accountID);
+
+ public abstract void generateKeyPair(AccountID accountID);
+
}
diff --git a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerImpl.java b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerImpl.java
index 890211e..cb57ba4 100644
--- a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerImpl.java
+++ b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerImpl.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,311 +15,311 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.otr;
-
-import java.security.*;
-import java.security.spec.*;
-import java.util.*;
-
-import net.java.otr4j.crypto.*;
-import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact;
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- *
- * @author George Politis
- * @author Lyubomir Marinov
- */
-public class ScOtrKeyManagerImpl
- implements ScOtrKeyManager
-{
- private final OtrConfigurator configurator = new OtrConfigurator();
-
- private final List<ScOtrKeyManagerListener> listeners =
- new Vector<ScOtrKeyManagerListener>();
-
- public void addListener(ScOtrKeyManagerListener l)
- {
- synchronized (listeners)
- {
- if (!listeners.contains(l))
- listeners.add(l);
- }
- }
-
- /**
- * Gets a copy of the list of <tt>ScOtrKeyManagerListener</tt>s registered
- * with this instance which may safely be iterated without the risk of a
- * <tt>ConcurrentModificationException</tt>.
- *
- * @return a copy of the list of <tt>ScOtrKeyManagerListener<tt>s registered
- * with this instance which may safely be iterated without the risk of a
- * <tt>ConcurrentModificationException</tt>
- */
- private ScOtrKeyManagerListener[] getListeners()
- {
- synchronized (listeners)
- {
- return
- listeners.toArray(
- new ScOtrKeyManagerListener[listeners.size()]);
- }
- }
-
- public void removeListener(ScOtrKeyManagerListener l)
- {
- synchronized (listeners)
- {
- listeners.remove(l);
- }
- }
-
- public void verify(OtrContact otrContact, String fingerprint)
- {
- if ((fingerprint == null) || otrContact == null)
- return;
-
- this.configurator.setProperty(otrContact.contact.getAddress() + fingerprint
- + ".fingerprint.verified", true);
-
- for (ScOtrKeyManagerListener l : getListeners())
- l.contactVerificationStatusChanged(otrContact);
- }
-
- public void unverify(OtrContact otrContact, String fingerprint)
- {
- if ((fingerprint == null) || otrContact == null)
- return;
-
- this.configurator.setProperty(otrContact.contact.getAddress() + fingerprint
- + ".fingerprint.verified", false);
-
- for (ScOtrKeyManagerListener l : getListeners())
- l.contactVerificationStatusChanged(otrContact);
- }
-
- public boolean isVerified(Contact contact, String fingerprint)
- {
- if (fingerprint == null || contact == null)
- return false;
-
- return this.configurator.getPropertyBoolean(
- contact.getAddress() + fingerprint
- + ".fingerprint.verified", false);
- }
-
- public List<String> getAllRemoteFingerprints(Contact contact)
- {
- if (contact == null)
- return null;
-
- /*
- * The following lines are needed for backward compatibility with old
- * versions of the otr plugin. Instead of lists of fingerprints the otr
- * plugin used to store one public key for every contact in the form of
- * "userID.publicKey=..." and one boolean property in the form of
- * "userID.publicKey.verified=...". In order not to loose these old
- * properties we have to convert them to match the new format.
- */
- String userID = contact.getAddress();
-
- byte[] b64PubKey =
- this.configurator.getPropertyBytes(userID + ".publicKey");
- if (b64PubKey != null)
- {
- // We delete the old format property because we are going to convert
- // it in the new format
- this.configurator.removeProperty(userID + ".publicKey");
-
- X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b64PubKey);
-
- KeyFactory keyFactory;
- try
- {
- keyFactory = KeyFactory.getInstance("DSA");
- PublicKey pubKey = keyFactory.generatePublic(publicKeySpec);
-
- boolean isVerified =
- this.configurator.getPropertyBoolean(userID
- + ".publicKey.verified", false);
-
- // We also make sure to delete this old format property if it
- // exists.
- this.configurator.removeProperty(userID + ".publicKey.verified");
-
- String fingerprint = getFingerprintFromPublicKey(pubKey);
-
- // Now we can store the old properties in the new format.
- if (isVerified)
- verify(OtrContactManager.getOtrContact(contact, null), fingerprint);
- else
- unverify(OtrContactManager.getOtrContact(contact, null), fingerprint);
-
- // Finally we append the new fingerprint to out stored list of
- // fingerprints.
- this.configurator.appendProperty(
- userID + ".fingerprints", fingerprint);
- }
- catch (NoSuchAlgorithmException e)
- {
- e.printStackTrace();
- }
- catch (InvalidKeySpecException e)
- {
- e.printStackTrace();
- }
- }
-
- // Now we can safely return our list of fingerprints for this contact
- // without worrying that we missed an old format property.
- return this.configurator.getAppendedProperties(
- contact.getAddress() + ".fingerprints");
- }
-
- public String getFingerprintFromPublicKey(PublicKey pubKey)
- {
- try
- {
- return new OtrCryptoEngineImpl().getFingerprint(pubKey);
- }
- catch (OtrCryptoException e)
- {
- e.printStackTrace();
- return null;
- }
- }
-
- public String getLocalFingerprint(AccountID account)
- {
- KeyPair keyPair = loadKeyPair(account);
-
- if (keyPair == null)
- return null;
-
- PublicKey pubKey = keyPair.getPublic();
-
- try
- {
- return new OtrCryptoEngineImpl().getFingerprint(pubKey);
- }
- catch (OtrCryptoException e)
- {
- e.printStackTrace();
- return null;
- }
- }
-
- public byte[] getLocalFingerprintRaw(AccountID account)
- {
- KeyPair keyPair = loadKeyPair(account);
-
- if (keyPair == null)
- return null;
-
- PublicKey pubKey = keyPair.getPublic();
-
- try
- {
- return new OtrCryptoEngineImpl().getFingerprintRaw(pubKey);
- }
- catch (OtrCryptoException e)
- {
- e.printStackTrace();
- return null;
- }
- }
-
- public void saveFingerprint(Contact contact, String fingerprint)
- {
- if (contact == null)
- return;
-
- this.configurator.appendProperty(contact.getAddress() + ".fingerprints",
- fingerprint);
-
- this.configurator.setProperty(contact.getAddress() + fingerprint
- + ".fingerprint.verified", false);
- }
-
- public KeyPair loadKeyPair(AccountID account)
- {
- if (account == null)
- return null;
-
- String accountID = account.getAccountUniqueID();
- // Load Private Key.
- byte[] b64PrivKey =
- this.configurator.getPropertyBytes(accountID + ".privateKey");
- if (b64PrivKey == null)
- return null;
-
- PKCS8EncodedKeySpec privateKeySpec =
- new PKCS8EncodedKeySpec(b64PrivKey);
-
- // Load Public Key.
- byte[] b64PubKey =
- this.configurator.getPropertyBytes(accountID + ".publicKey");
- if (b64PubKey == null)
- return null;
-
- X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b64PubKey);
-
- PublicKey publicKey;
- PrivateKey privateKey;
-
- // Generate KeyPair.
- KeyFactory keyFactory;
- try
- {
- keyFactory = KeyFactory.getInstance("DSA");
- publicKey = keyFactory.generatePublic(publicKeySpec);
- privateKey = keyFactory.generatePrivate(privateKeySpec);
- }
- catch (NoSuchAlgorithmException e)
- {
- e.printStackTrace();
- return null;
- }
- catch (InvalidKeySpecException e)
- {
- e.printStackTrace();
- return null;
- }
-
- return new KeyPair(publicKey, privateKey);
- }
-
- public void generateKeyPair(AccountID account)
- {
- if (account == null)
- return;
-
- String accountID = account.getAccountUniqueID();
- KeyPair keyPair;
- try
- {
- keyPair = KeyPairGenerator.getInstance("DSA").genKeyPair();
- }
- catch (NoSuchAlgorithmException e)
- {
- e.printStackTrace();
- return;
- }
-
- // Store Public Key.
- PublicKey pubKey = keyPair.getPublic();
- X509EncodedKeySpec x509EncodedKeySpec =
- new X509EncodedKeySpec(pubKey.getEncoded());
-
- this.configurator.setProperty(accountID + ".publicKey",
- x509EncodedKeySpec.getEncoded());
-
- // Store Private Key.
- PrivateKey privKey = keyPair.getPrivate();
- PKCS8EncodedKeySpec pkcs8EncodedKeySpec =
- new PKCS8EncodedKeySpec(privKey.getEncoded());
-
- this.configurator.setProperty(accountID + ".privateKey",
- pkcs8EncodedKeySpec.getEncoded());
- }
-}
+package net.java.sip.communicator.plugin.otr;
+
+import java.security.*;
+import java.security.spec.*;
+import java.util.*;
+
+import net.java.otr4j.crypto.*;
+import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ *
+ * @author George Politis
+ * @author Lyubomir Marinov
+ */
+public class ScOtrKeyManagerImpl
+ implements ScOtrKeyManager
+{
+ private final OtrConfigurator configurator = new OtrConfigurator();
+
+ private final List<ScOtrKeyManagerListener> listeners =
+ new Vector<ScOtrKeyManagerListener>();
+
+ public void addListener(ScOtrKeyManagerListener l)
+ {
+ synchronized (listeners)
+ {
+ if (!listeners.contains(l))
+ listeners.add(l);
+ }
+ }
+
+ /**
+ * Gets a copy of the list of <tt>ScOtrKeyManagerListener</tt>s registered
+ * with this instance which may safely be iterated without the risk of a
+ * <tt>ConcurrentModificationException</tt>.
+ *
+ * @return a copy of the list of <tt>ScOtrKeyManagerListener<tt>s registered
+ * with this instance which may safely be iterated without the risk of a
+ * <tt>ConcurrentModificationException</tt>
+ */
+ private ScOtrKeyManagerListener[] getListeners()
+ {
+ synchronized (listeners)
+ {
+ return
+ listeners.toArray(
+ new ScOtrKeyManagerListener[listeners.size()]);
+ }
+ }
+
+ public void removeListener(ScOtrKeyManagerListener l)
+ {
+ synchronized (listeners)
+ {
+ listeners.remove(l);
+ }
+ }
+
+ public void verify(OtrContact otrContact, String fingerprint)
+ {
+ if ((fingerprint == null) || otrContact == null)
+ return;
+
+ this.configurator.setProperty(otrContact.contact.getAddress() + fingerprint
+ + ".fingerprint.verified", true);
+
+ for (ScOtrKeyManagerListener l : getListeners())
+ l.contactVerificationStatusChanged(otrContact);
+ }
+
+ public void unverify(OtrContact otrContact, String fingerprint)
+ {
+ if ((fingerprint == null) || otrContact == null)
+ return;
+
+ this.configurator.setProperty(otrContact.contact.getAddress() + fingerprint
+ + ".fingerprint.verified", false);
+
+ for (ScOtrKeyManagerListener l : getListeners())
+ l.contactVerificationStatusChanged(otrContact);
+ }
+
+ public boolean isVerified(Contact contact, String fingerprint)
+ {
+ if (fingerprint == null || contact == null)
+ return false;
+
+ return this.configurator.getPropertyBoolean(
+ contact.getAddress() + fingerprint
+ + ".fingerprint.verified", false);
+ }
+
+ public List<String> getAllRemoteFingerprints(Contact contact)
+ {
+ if (contact == null)
+ return null;
+
+ /*
+ * The following lines are needed for backward compatibility with old
+ * versions of the otr plugin. Instead of lists of fingerprints the otr
+ * plugin used to store one public key for every contact in the form of
+ * "userID.publicKey=..." and one boolean property in the form of
+ * "userID.publicKey.verified=...". In order not to loose these old
+ * properties we have to convert them to match the new format.
+ */
+ String userID = contact.getAddress();
+
+ byte[] b64PubKey =
+ this.configurator.getPropertyBytes(userID + ".publicKey");
+ if (b64PubKey != null)
+ {
+ // We delete the old format property because we are going to convert
+ // it in the new format
+ this.configurator.removeProperty(userID + ".publicKey");
+
+ X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b64PubKey);
+
+ KeyFactory keyFactory;
+ try
+ {
+ keyFactory = KeyFactory.getInstance("DSA");
+ PublicKey pubKey = keyFactory.generatePublic(publicKeySpec);
+
+ boolean isVerified =
+ this.configurator.getPropertyBoolean(userID
+ + ".publicKey.verified", false);
+
+ // We also make sure to delete this old format property if it
+ // exists.
+ this.configurator.removeProperty(userID + ".publicKey.verified");
+
+ String fingerprint = getFingerprintFromPublicKey(pubKey);
+
+ // Now we can store the old properties in the new format.
+ if (isVerified)
+ verify(OtrContactManager.getOtrContact(contact, null), fingerprint);
+ else
+ unverify(OtrContactManager.getOtrContact(contact, null), fingerprint);
+
+ // Finally we append the new fingerprint to out stored list of
+ // fingerprints.
+ this.configurator.appendProperty(
+ userID + ".fingerprints", fingerprint);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ e.printStackTrace();
+ }
+ catch (InvalidKeySpecException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ // Now we can safely return our list of fingerprints for this contact
+ // without worrying that we missed an old format property.
+ return this.configurator.getAppendedProperties(
+ contact.getAddress() + ".fingerprints");
+ }
+
+ public String getFingerprintFromPublicKey(PublicKey pubKey)
+ {
+ try
+ {
+ return new OtrCryptoEngineImpl().getFingerprint(pubKey);
+ }
+ catch (OtrCryptoException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public String getLocalFingerprint(AccountID account)
+ {
+ KeyPair keyPair = loadKeyPair(account);
+
+ if (keyPair == null)
+ return null;
+
+ PublicKey pubKey = keyPair.getPublic();
+
+ try
+ {
+ return new OtrCryptoEngineImpl().getFingerprint(pubKey);
+ }
+ catch (OtrCryptoException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public byte[] getLocalFingerprintRaw(AccountID account)
+ {
+ KeyPair keyPair = loadKeyPair(account);
+
+ if (keyPair == null)
+ return null;
+
+ PublicKey pubKey = keyPair.getPublic();
+
+ try
+ {
+ return new OtrCryptoEngineImpl().getFingerprintRaw(pubKey);
+ }
+ catch (OtrCryptoException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public void saveFingerprint(Contact contact, String fingerprint)
+ {
+ if (contact == null)
+ return;
+
+ this.configurator.appendProperty(contact.getAddress() + ".fingerprints",
+ fingerprint);
+
+ this.configurator.setProperty(contact.getAddress() + fingerprint
+ + ".fingerprint.verified", false);
+ }
+
+ public KeyPair loadKeyPair(AccountID account)
+ {
+ if (account == null)
+ return null;
+
+ String accountID = account.getAccountUniqueID();
+ // Load Private Key.
+ byte[] b64PrivKey =
+ this.configurator.getPropertyBytes(accountID + ".privateKey");
+ if (b64PrivKey == null)
+ return null;
+
+ PKCS8EncodedKeySpec privateKeySpec =
+ new PKCS8EncodedKeySpec(b64PrivKey);
+
+ // Load Public Key.
+ byte[] b64PubKey =
+ this.configurator.getPropertyBytes(accountID + ".publicKey");
+ if (b64PubKey == null)
+ return null;
+
+ X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b64PubKey);
+
+ PublicKey publicKey;
+ PrivateKey privateKey;
+
+ // Generate KeyPair.
+ KeyFactory keyFactory;
+ try
+ {
+ keyFactory = KeyFactory.getInstance("DSA");
+ publicKey = keyFactory.generatePublic(publicKeySpec);
+ privateKey = keyFactory.generatePrivate(privateKeySpec);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ catch (InvalidKeySpecException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+
+ return new KeyPair(publicKey, privateKey);
+ }
+
+ public void generateKeyPair(AccountID account)
+ {
+ if (account == null)
+ return;
+
+ String accountID = account.getAccountUniqueID();
+ KeyPair keyPair;
+ try
+ {
+ keyPair = KeyPairGenerator.getInstance("DSA").genKeyPair();
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ e.printStackTrace();
+ return;
+ }
+
+ // Store Public Key.
+ PublicKey pubKey = keyPair.getPublic();
+ X509EncodedKeySpec x509EncodedKeySpec =
+ new X509EncodedKeySpec(pubKey.getEncoded());
+
+ this.configurator.setProperty(accountID + ".publicKey",
+ x509EncodedKeySpec.getEncoded());
+
+ // Store Private Key.
+ PrivateKey privKey = keyPair.getPrivate();
+ PKCS8EncodedKeySpec pkcs8EncodedKeySpec =
+ new PKCS8EncodedKeySpec(privKey.getEncoded());
+
+ this.configurator.setProperty(accountID + ".privateKey",
+ pkcs8EncodedKeySpec.getEncoded());
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerListener.java b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerListener.java
index aeabf75..95403d3 100644
--- a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerListener.java
+++ b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerListener.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,15 +15,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.otr;
-
-import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact;
-
-/**
- *
- * @author George Politis
- */
-public interface ScOtrKeyManagerListener
-{
- public void contactVerificationStatusChanged(OtrContact contact);
-}
+package net.java.sip.communicator.plugin.otr;
+
+import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact;
+
+/**
+ *
+ * @author George Politis
+ */
+public interface ScOtrKeyManagerListener
+{
+ public void contactVerificationStatusChanged(OtrContact contact);
+}
diff --git a/src/net/java/sip/communicator/plugin/otr/ScSessionID.java b/src/net/java/sip/communicator/plugin/otr/ScSessionID.java
index 4392045..1a55fcd 100644
--- a/src/net/java/sip/communicator/plugin/otr/ScSessionID.java
+++ b/src/net/java/sip/communicator/plugin/otr/ScSessionID.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,83 +15,83 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.otr;
-
-import java.util.*;
-
-import net.java.otr4j.session.*;
-
-/**
- * Class used to associate a random UUID to an OTR4J SessionID.
- *
- * @author Daniel Perren
- */
-public class ScSessionID
-{
- private final UUID guid = UUID.randomUUID();
-
- private final SessionID sessionID;
-
- /**
- * Creates a new instance of this class.
- *
- * @param sessionID the OTR4J SessionID that is being wrapped.
- */
- public ScSessionID(SessionID sessionID)
- {
- this.sessionID = sessionID;
- }
-
- /**
- * Overrides equals() for the ability to get the hashcode from sessionID.
- *
- * @param obj the object to compare
- * @return true if the objects are considered equal.
- */
- @Override
- public boolean equals(Object obj)
- {
- return (obj != null) && sessionID.toString().equals(obj.toString());
- }
-
- /**
- * Get the current GUID.
- *
- * @return The GUID generated for this SessionID.
- */
- public UUID getGUID()
- {
- return guid;
- }
-
- /**
- * Gets the wrapped session ID
- *
- * @return sessionID
- */
- public SessionID getSessionID()
- {
- return sessionID;
- }
-
- /**
- * Returns {@link SessionID#hashCode()} of the wrapped SessionID.
- *
- * @return HashCode of the wrapped SessionID.
- */
- @Override
- public int hashCode()
- {
- return sessionID.hashCode();
- }
-
- /**
- * Returns {@link SessionID#toString()} of the wrapped SessionID.
- * @return String representation of the wrapped SessionID.
- */
- @Override
- public String toString()
- {
- return sessionID.toString();
- }
-}
+package net.java.sip.communicator.plugin.otr;
+
+import java.util.*;
+
+import net.java.otr4j.session.*;
+
+/**
+ * Class used to associate a random UUID to an OTR4J SessionID.
+ *
+ * @author Daniel Perren
+ */
+public class ScSessionID
+{
+ private final UUID guid = UUID.randomUUID();
+
+ private final SessionID sessionID;
+
+ /**
+ * Creates a new instance of this class.
+ *
+ * @param sessionID the OTR4J SessionID that is being wrapped.
+ */
+ public ScSessionID(SessionID sessionID)
+ {
+ this.sessionID = sessionID;
+ }
+
+ /**
+ * Overrides equals() for the ability to get the hashcode from sessionID.
+ *
+ * @param obj the object to compare
+ * @return true if the objects are considered equal.
+ */
+ @Override
+ public boolean equals(Object obj)
+ {
+ return (obj != null) && sessionID.toString().equals(obj.toString());
+ }
+
+ /**
+ * Get the current GUID.
+ *
+ * @return The GUID generated for this SessionID.
+ */
+ public UUID getGUID()
+ {
+ return guid;
+ }
+
+ /**
+ * Gets the wrapped session ID
+ *
+ * @return sessionID
+ */
+ public SessionID getSessionID()
+ {
+ return sessionID;
+ }
+
+ /**
+ * Returns {@link SessionID#hashCode()} of the wrapped SessionID.
+ *
+ * @return HashCode of the wrapped SessionID.
+ */
+ @Override
+ public int hashCode()
+ {
+ return sessionID.hashCode();
+ }
+
+ /**
+ * Returns {@link SessionID#toString()} of the wrapped SessionID.
+ * @return String representation of the wrapped SessionID.
+ */
+ @Override
+ public String toString()
+ {
+ return sessionID.toString();
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java
index 3f916a7..954f5d5 100644
--- a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java
+++ b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,79 +15,79 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.phonenumbercontactsource;
-
-import net.java.sip.communicator.service.contactsource.*;
-
-/**
- * The <tt>PhoneNumberContactSource</tt> is a source of phone numbers coming
- * from the server stored contact info of all contacts for all protocol
- * providers.
- *
- * @author Yana Stamcheva
- */
-public class PhoneNumberContactSource
- implements ContactSourceService
-{
- /**
- * Returns DEFAULT_TYPE to indicate that this contact source is a default
- * source.
- *
- * @return the type of this contact source
- */
- public int getType()
- {
- return DEFAULT_TYPE;
- }
-
- /**
- * Returns a user-friendly string that identifies this contact source.
- *
- * @return the display name of this contact source
- */
- public String getDisplayName()
- {
- return PNContactSourceActivator.getResources().getI18NString(
- "plugin.phonenumbercontactsource.DISPLAY_NAME");
- }
-
- /**
- * Creates query for the given <tt>queryString</tt>.
- *
- * @param queryString the string to search for
- * @return the created query
- */
- public ContactQuery createContactQuery(String queryString)
- {
- return createContactQuery(queryString, -1);
- }
-
- /**
- * Creates query for the given <tt>queryString</tt>.
- *
- * @param queryString the string to search for
- * @param contactCount the maximum count of result contacts
- * @return the created query
- */
- public ContactQuery createContactQuery( String queryString,
- int contactCount)
- {
- if (queryString == null)
- queryString = "";
-
- PhoneNumberContactQuery contactQuery
- = new PhoneNumberContactQuery(this, queryString, contactCount);
-
- return contactQuery;
- }
-
- /**
- * Returns the index of the contact source in the result list.
- *
- * @return the index of the contact source in the result list
- */
- public int getIndex()
- {
- return -1;
- }
-}
+package net.java.sip.communicator.plugin.phonenumbercontactsource;
+
+import net.java.sip.communicator.service.contactsource.*;
+
+/**
+ * The <tt>PhoneNumberContactSource</tt> is a source of phone numbers coming
+ * from the server stored contact info of all contacts for all protocol
+ * providers.
+ *
+ * @author Yana Stamcheva
+ */
+public class PhoneNumberContactSource
+ implements ContactSourceService
+{
+ /**
+ * Returns DEFAULT_TYPE to indicate that this contact source is a default
+ * source.
+ *
+ * @return the type of this contact source
+ */
+ public int getType()
+ {
+ return DEFAULT_TYPE;
+ }
+
+ /**
+ * Returns a user-friendly string that identifies this contact source.
+ *
+ * @return the display name of this contact source
+ */
+ public String getDisplayName()
+ {
+ return PNContactSourceActivator.getResources().getI18NString(
+ "plugin.phonenumbercontactsource.DISPLAY_NAME");
+ }
+
+ /**
+ * Creates query for the given <tt>queryString</tt>.
+ *
+ * @param queryString the string to search for
+ * @return the created query
+ */
+ public ContactQuery createContactQuery(String queryString)
+ {
+ return createContactQuery(queryString, -1);
+ }
+
+ /**
+ * Creates query for the given <tt>queryString</tt>.
+ *
+ * @param queryString the string to search for
+ * @param contactCount the maximum count of result contacts
+ * @return the created query
+ */
+ public ContactQuery createContactQuery( String queryString,
+ int contactCount)
+ {
+ if (queryString == null)
+ queryString = "";
+
+ PhoneNumberContactQuery contactQuery
+ = new PhoneNumberContactQuery(this, queryString, contactCount);
+
+ return contactQuery;
+ }
+
+ /**
+ * Returns the index of the contact source in the result list.
+ *
+ * @return the index of the contact source in the result list
+ */
+ public int getIndex()
+ {
+ return -1;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberSourceContact.java b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberSourceContact.java
index ef7352f..d7ec804 100644
--- a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberSourceContact.java
+++ b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberSourceContact.java
@@ -107,6 +107,18 @@ public class PhoneNumberSourceContact
return true;
}
+ @Override
+ public int hashCode()
+ {
+ String dn = getDisplayName();
+ if (dn != null)
+ {
+ return getDisplayName().hashCode();
+ }
+
+ return 37;
+ }
+
/**
* Returns the protocol contact used.
* @return the protocol contact used.
diff --git a/src/net/java/sip/communicator/plugin/pluginmanager/BundleComparator.java b/src/net/java/sip/communicator/plugin/pluginmanager/BundleComparator.java
index 06d2db4..48a4305 100644
--- a/src/net/java/sip/communicator/plugin/pluginmanager/BundleComparator.java
+++ b/src/net/java/sip/communicator/plugin/pluginmanager/BundleComparator.java
@@ -37,8 +37,8 @@ public class BundleComparator implements Comparator<Bundle>
*/
public int compare(Bundle arg0, Bundle arg1)
{
- String n1 = (String) arg0.getHeaders().get(Constants.BUNDLE_NAME);
- String n2 = (String) arg1.getHeaders().get(Constants.BUNDLE_NAME);
+ String n1 = arg0.getHeaders().get(Constants.BUNDLE_NAME);
+ String n2 = arg1.getHeaders().get(Constants.BUNDLE_NAME);
if (n1 == null)
{
diff --git a/src/net/java/sip/communicator/plugin/profiler4j/ProfilerActivator.java b/src/net/java/sip/communicator/plugin/profiler4j/ProfilerActivator.java
deleted file mode 100644
index f3844a2..0000000
--- a/src/net/java/sip/communicator/plugin/profiler4j/ProfilerActivator.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.profiler4j;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * Activates the profiler plug-in.
- *
- * @author Vladimir Skarupelov
- */
-public class ProfilerActivator implements BundleActivator {
-
- /**
- * OSGi bundle context.
- */
- public static BundleContext bundleContext;
-
- Logger logger = Logger.getLogger(ProfilerActivator.class);
-
- private ServiceRegistration menuRegistration = null;
-
- public void start(BundleContext bc) throws Exception {
- bundleContext = bc;
-
- Hashtable<String, String> toolsMenuFilter =
- new Hashtable<String, String>();
- toolsMenuFilter.put(Container.CONTAINER_ID,
- Container.CONTAINER_TOOLS_MENU.getID());
-
- menuRegistration = bc.registerService(
- PluginComponentFactory.class.getName(),
- new PluginComponentFactory(Container.CONTAINER_TOOLS_MENU)
- {
- @Override
- protected PluginComponent getPluginInstance()
- {
- return new SettingsWindowMenuEntry(
- Container.CONTAINER_TOOLS_MENU, this);
- }
- },
- toolsMenuFilter);
-
- if (logger.isInfoEnabled())
- logger.info("PROFILER4J [REGISTERED]");
-
- }
-
- public void stop(BundleContext bc) throws Exception {
- if (menuRegistration != null)
- {
- menuRegistration.unregister();
- if (logger.isInfoEnabled())
- logger.info("PROFILER4J [UNREGISTERED]");
- }
- }
-
-}
diff --git a/src/net/java/sip/communicator/plugin/profiler4j/Resources.java b/src/net/java/sip/communicator/plugin/profiler4j/Resources.java
deleted file mode 100644
index c69a8a5..0000000
--- a/src/net/java/sip/communicator/plugin/profiler4j/Resources.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.profiler4j;
-
-import net.java.sip.communicator.service.resources.*;
-
-import org.jitsi.service.resources.*;
-
-/**
- * The Messages class manages the access to the internationalization properties
- * files.
- *
- * @author Vladimir Skarupelov;
- */
-public class Resources
-{
- private static ResourceManagementService resourcesService = null;
-
- /**
- * Returns an internationalized string corresponding to the given key.
- *
- * @param key The key of the string.
- * @return An internationalized string corresponding to the given key.
- */
- public static String getString(String key)
- {
- return getResources().getI18NString(key);
- }
-
- /**
- * Returns the <tt>ResourceManagementService</tt>.
- *
- * @return the <tt>ResourceManagementService</tt>.
- */
- public static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- resourcesService =
- ResourceManagementServiceUtils
- .getService(ProfilerActivator.bundleContext);
- return resourcesService;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/profiler4j/SettingsWindowMenuEntry.java b/src/net/java/sip/communicator/plugin/profiler4j/SettingsWindowMenuEntry.java
deleted file mode 100644
index f8ab3a6..0000000
--- a/src/net/java/sip/communicator/plugin/profiler4j/SettingsWindowMenuEntry.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.profiler4j;
-
-import java.awt.event.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.service.gui.*;
-import net.sf.profiler4j.console.*;
-
-/**
- * Menu entry for the profiler plug-in
- *
- * @author Vladimir Skarupelov
- */
-public class SettingsWindowMenuEntry
- extends AbstractPluginComponent
-{
- private static final String PROFILER_NAME = "plugin.profiler.PLUGIN_NAME";
- private JMenuItem settingsMenuEntry;
-
- public SettingsWindowMenuEntry(Container container,
- PluginComponentFactory parentFactory)
- {
- super(container, parentFactory);
-
- settingsMenuEntry = new JMenuItem(Resources.getString( PROFILER_NAME ));
- settingsMenuEntry.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- Prefs prefs = new Prefs();
-
- System.setProperty("swing.aatext",
- String.valueOf(prefs.isAntialiasing()));
-
- final Console app = new Console(prefs);
- app.connect();
- MainFrame f = new MainFrame(app);
- app.setMainFrame(f);
- f.pack();
- f.setVisible(true);
- }
- });
- }
-
- public Object getComponent()
- {
- return settingsMenuEntry;
- }
-
- public String getName()
- {
- return Resources.getString( PROFILER_NAME );
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/profiler4j/profiler4j.manifest.mf b/src/net/java/sip/communicator/plugin/profiler4j/profiler4j.manifest.mf
deleted file mode 100644
index 9e3ebf4..0000000
--- a/src/net/java/sip/communicator/plugin/profiler4j/profiler4j.manifest.mf
+++ /dev/null
@@ -1,24 +0,0 @@
-Bundle-Activator: net.java.sip.communicator.plugin.profiler4j.ProfilerActivator
-Bundle-Name: Integrated profiler plugin
-Bundle-Description: A bundle that provides profile cpu and memory of the running app.
-Bundle-Vendor: jitsi.org
-Bundle-Version: 0.0.1
-Bundle-SymbolicName: net.java.sip.communicator.plugin.profiler4j
-Import-Package: org.apache.commons.logging,
- org.osgi.framework,
- org.xml.sax,
- org.xml.sax.ext,
- org.xml.sax.helpers,
- net.java.sip.communicator.service.contactlist,
- net.java.sip.communicator.service.gui,
- org.jitsi.service.resources, net.java.sip.communicator.service.resources,
- net.java.sip.communicator.service.protocol,
- net.java.sip.communicator.util,
- javax.swing,
- javax.swing.border,
- javax.swing.event,
- javax.swing.filechooser,
- javax.swing.table,
- javax.swing.text,
- javax.swing.tree,
- javax.xml.parsers
diff --git a/src/net/java/sip/communicator/plugin/simpleaccreg/InitialAccountRegistrationFrame.java b/src/net/java/sip/communicator/plugin/simpleaccreg/InitialAccountRegistrationFrame.java
index b8d6a2a..e1213ce 100644
--- a/src/net/java/sip/communicator/plugin/simpleaccreg/InitialAccountRegistrationFrame.java
+++ b/src/net/java/sip/communicator/plugin/simpleaccreg/InitialAccountRegistrationFrame.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,736 +15,736 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.simpleaccreg;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.io.*;
-import java.util.*;
-import java.util.List;
-
-import javax.imageio.*;
-import javax.swing.*;
-import javax.swing.text.*;
-
-import net.java.sip.communicator.service.contactlist.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
-
-import org.jitsi.service.configuration.*;
-import org.osgi.framework.*;
-
-/**
- * The <tt>NoAccountFoundPage</tt> is the page shown in the account
- * registration wizard shown in the beginning of the program, when no registered
- * accounts are found.
- *
- * @author Yana Stamcheva
- * @author Lubomir Marinov
- */
-public class InitialAccountRegistrationFrame
- extends SIPCommFrame
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- private ConfigurationService configurationService;
-
- /**
- * The <tt>Logger</tt> used by this <tt>InitialAccountRegistrationFrame</tt>
- * for logging output.
- */
- private final Logger logger
- = Logger.getLogger(InitialAccountRegistrationFrame.class);
-
- private final TransparentPanel mainAccountsPanel
- = new TransparentPanel(new BorderLayout(10, 10));
-
- private final TransparentPanel accountsPanel
- = new TransparentPanel(new GridLayout(0, 2, 10, 10));
-
- private final TransparentPanel southPanel
- = new TransparentPanel(new BorderLayout());
-
- private final JButton signinButton
- = new JButton(Resources.getString("service.gui.SIGN_IN"));
-
- private final Collection<AccountRegistrationPanel> registrationForms =
- new Vector<AccountRegistrationPanel>();
-
- /**
- * Creates an instance of <tt>NoAccountFoundPage</tt>.
- */
- public InitialAccountRegistrationFrame()
- {
- super(false);
- setDefaultCloseOperation(DISPOSE_ON_CLOSE);
-
- TransparentPanel mainPanel
- = new TransparentPanel(new BorderLayout());
- mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
-
- JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
- southPanel.add(buttonPanel, BorderLayout.EAST);
- JButton cancelButton
- = new JButton(Resources.getString("service.gui.CANCEL"));
-
- this.setTitle(Resources.getString("service.gui.SIGN_IN"));
-
- this.setIconImage(
- Resources.getImage("service.gui.SIP_COMMUNICATOR_LOGO").getImage());
-
- // In order to have the same icon when using option panes
- JOptionPane.getRootFrame().setIconImage(
- Resources.getImage("service.gui.SIP_COMMUNICATOR_LOGO").getImage());
-
- mainAccountsPanel.setBorder(
- BorderFactory.createEmptyBorder(10, 10, 10, 10));
-
- this.getContentPane().add(mainPanel);
-
- mainPanel.add(createTitleComponent(), BorderLayout.NORTH);
- JScrollPane scroller = new JScrollPane(mainAccountsPanel);
- scroller.setOpaque(false);
- scroller.getViewport().setOpaque(false);
- mainPanel.add(scroller, BorderLayout.CENTER);
- mainPanel.add(southPanel, BorderLayout.SOUTH);
-
- mainAccountsPanel.add(accountsPanel, BorderLayout.CENTER);
-
- initProvisioningPanel();
-
- mainAccountsPanel.setOpaque(false);
- accountsPanel.setOpaque(false);
- buttonPanel.setOpaque(false);
-
- SigninActionListener actionListener = new SigninActionListener();
-
- signinButton.addActionListener(actionListener);
- cancelButton.addActionListener(actionListener);
-
- buttonPanel.add(signinButton);
- buttonPanel.add(cancelButton);
-
- this.getRootPane().setDefaultButton(signinButton);
-
- this.initAccountWizards();
-
- // Create the default group
- String groupName
- = Resources.getApplicationProperty("impl.gui.DEFAULT_GROUP_NAME");
-
- if(groupName != null && groupName.length() > 0)
- {
- MetaContactListService contactList =
- SimpleAccountRegistrationActivator.getContactList();
- Iterator<MetaContactGroup> iter
- = contactList.getRoot().getSubgroups();
- while (iter.hasNext())
- {
- MetaContactGroup gr = iter.next();
- if (groupName.equals(gr.getGroupName()))
- return;
- }
-
- contactList
- .createMetaContactGroup(contactList.getRoot(), groupName);
-
- getConfigurationService()
- .setProperty(
- "net.java.sip.communicator.impl.gui.addcontact.lastContactParent",
- groupName);
- }
-
- this.getRootPane().validate();
- this.pack();
-
- // if the screen height is sufficiently large, expand the window size
- // so that no scrolling is needed
- if (scroller.getViewport().getHeight()
- < Toolkit.getDefaultToolkit().getScreenSize().getHeight() - 230)
- {
- this.setSize(scroller.getViewport().getWidth() + 100,
- scroller.getViewport().getHeight() + 150);
- }
- else
- {
- // otherwise add some width so that no horizontal scrolling is
- // needed
- this.setSize(this.getSize().width + 20,
- this.getSize().height - 10);
- }
- }
-
- /**
- * Initializes the provisioning panel.
- */
- private void initProvisioningPanel()
- {
- String isInitialProv = SimpleAccountRegistrationActivator.getResources()
- .getSettingsString(
- "plugin.provisioning.IS_INITIAL_PROVISIONING_LINK");
-
- if (isInitialProv != null && isInitialProv.length() > 0
- && !Boolean.parseBoolean(isInitialProv))
- return;
-
- String useProvisioningString = SimpleAccountRegistrationActivator
- .getResources().getI18NString("service.gui.USE_PROVISIONING");
-
- final JLabel provisioningLabel =
- new JLabel("<html><a href=''>"
- + useProvisioningString
- + "</a></html>");
-
- provisioningLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
- provisioningLabel.setToolTipText(useProvisioningString);
-
- provisioningLabel.addMouseListener(new MouseAdapter()
- {
- @Override
- public void mousePressed(MouseEvent e)
- {
- ConfigurationContainer configContainer
- = SimpleAccountRegistrationActivator.getUIService()
- .getConfigurationContainer();
-
- ConfigurationForm advancedConfigForm
- = SimpleAccountRegistrationActivator.getAdvancedConfigForm();
-
- if (advancedConfigForm != null)
- {
- configContainer.setSelected(advancedConfigForm);
-
- if (advancedConfigForm instanceof ConfigurationContainer)
- {
- ConfigurationForm provisioningForm
- = SimpleAccountRegistrationActivator
- .getProvisioningConfigForm();
-
- if (provisioningForm != null)
- {
- ((ConfigurationContainer) advancedConfigForm)
- .setSelected(provisioningForm);
- }
- }
- }
-
- configContainer.setVisible(true);
- }
- });
-
- southPanel.add(provisioningLabel, BorderLayout.WEST);
- }
-
- private void initAccountWizards()
- {
- String simpleWizards
- = SimpleAccountRegistrationActivator.getConfigService()
- .getString("plugin.simpleaccreg.PROTOCOL_ORDER");
-
- StringTokenizer tokenizer = new StringTokenizer(simpleWizards, "|");
-
- ServiceReference[] serviceRefs = null;
- while (tokenizer.hasMoreTokens())
- {
- String protocolToken = tokenizer.nextToken();
-
- String osgiFilter = "("
- + ProtocolProviderFactory.PROTOCOL
- + "="+protocolToken+")";
-
- try
- {
- serviceRefs = SimpleAccountRegistrationActivator.bundleContext
- .getServiceReferences(
- AccountRegistrationWizard.class.getName(), osgiFilter);
-
- if (serviceRefs != null && serviceRefs.length > 0)
- {
- AccountRegistrationWizard wizard
- = (AccountRegistrationWizard)
-
- SimpleAccountRegistrationActivator
- .bundleContext.getService(serviceRefs[0]);
-
- this.addAccountRegistrationForm(wizard);
- }
- }
- catch (InvalidSyntaxException ex)
- {
- logger.error("GuiActivator : ", ex);
- }
- }
- }
-
- /**
- * The account registration panel.
- */
- private class AccountRegistrationPanel
- extends JPanel
- {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- private JLabel usernameLabel
- = new JLabel(Resources.getString(
- "plugin.simpleaccregwizz.LOGIN_USERNAME"));
-
- private JLabel passwordLabel
- = new JLabel(Resources.getString("service.gui.PASSWORD"));
-
- private JTextField usernameField = new JTextField();
-
- private JLabel usernameExampleLabel = new JLabel();
-
- private JPasswordField passwordField = new JPasswordField();
-
- private JPanel labelsPanel = new JPanel(new GridLayout(0, 1, 5, 0));
-
- private JPanel fieldsPanel = new JPanel(new GridLayout(0, 1, 5, 0));
-
- private JPanel emptyPanel = new JPanel();
-
- private JPanel inputPanel = new JPanel(new BorderLayout(5, 5));
-
- private JPanel iconDescriptionPanel = new JPanel(new BorderLayout());
-
- private JTextArea descriptionArea = new JTextArea();
-
- private final AccountRegistrationWizard wizard;
-
- public AccountRegistrationPanel(
- AccountRegistrationWizard accountWizard,
- boolean isPreferredWizard)
- {
- super(new BorderLayout(5, 5));
-
- this.wizard = accountWizard;
-
- // Obtain the simple form in order to initialize all predefined
- // values.
- // TODO: Use the simple form instead of creating new fields and
- // panels here.
- wizard.getSimpleForm(false);
-
- JLabel protocolLabel = new JLabel();
- JPanel inputRegisterPanel = new JPanel(new BorderLayout());
-
- this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
-
- this.setOpaque(false);
-
- this.inputPanel.setOpaque(false);
- this.labelsPanel.setOpaque(false);
- this.fieldsPanel.setOpaque(false);
- this.emptyPanel.setOpaque(false);
- inputRegisterPanel.setOpaque(false);
- this.iconDescriptionPanel.setOpaque(false);
-
- this.add(inputRegisterPanel, BorderLayout.CENTER);
-
- inputRegisterPanel.add(inputPanel, BorderLayout.NORTH);
-
- if (((wizard instanceof ExtendedAccountRegistrationWizard)
- && ((ExtendedAccountRegistrationWizard) wizard)
- .isSignupSupported()) || wizard.isWebSignupSupported())
- {
- String textKey =
- isPreferredWizard ? "plugin.simpleaccregwizz.SPECIAL_SIGNUP"
- : "plugin.simpleaccregwizz.SIGNUP";
- JLabel signupLabel =
- new JLabel("<html><a href=''>"
- + Resources.getString(textKey) + "</a></html>",
- JLabel.RIGHT);
-
- signupLabel.setFont(signupLabel.getFont().deriveFont(10f));
- signupLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
- signupLabel.setToolTipText(
- Resources.getString(
- "plugin.simpleaccregwizz.SPECIAL_SIGNUP"));
- signupLabel.addMouseListener(new MouseAdapter()
- {
- @Override
- public void mousePressed(MouseEvent e)
- {
- try
- {
- if ((wizard
- instanceof ExtendedAccountRegistrationWizard)
- && ((ExtendedAccountRegistrationWizard) wizard)
- .isSignupSupported())
- {
- showCreateAccountWindow(wizard);
- dispose();
- }
- else if (wizard.isWebSignupSupported())
- {
- wizard.webSignup();
- }
- }
- catch (UnsupportedOperationException ex)
- {
- // This should not happen, because we check if the
- // operation is supported, before adding the sign
- // up.
- logger.error("The web sign up is not supported.",
- ex);
- }
- }
- });
-
- inputRegisterPanel.add(signupLabel, BorderLayout.SOUTH);
- }
-
- this.inputPanel.add(labelsPanel, BorderLayout.WEST);
-
- this.inputPanel.add(fieldsPanel, BorderLayout.CENTER);
-
- this.iconDescriptionPanel.add(
- protocolLabel, BorderLayout.NORTH);
-
- protocolLabel.setFont(
- protocolLabel.getFont().deriveFont(Font.BOLD, 14f));
- this.usernameExampleLabel.setForeground(Color.DARK_GRAY);
- this.usernameExampleLabel.setFont(
- usernameExampleLabel.getFont().deriveFont(8f));
- this.emptyPanel.setMaximumSize(new Dimension(40, 25));
-
- this.labelsPanel.add(usernameLabel);
- this.labelsPanel.add(emptyPanel);
- this.labelsPanel.add(passwordLabel);
-
- this.fieldsPanel.add(usernameField);
- this.fieldsPanel.add(usernameExampleLabel);
- this.fieldsPanel.add(passwordField);
-
- this.usernameExampleLabel.setText(wizard.getUserNameExample());
-
- protocolLabel.setText(wizard.getProtocolName());
-
- Image image = null;
- try
- {
- image = ImageIO.read(
- new ByteArrayInputStream(wizard.getPageImage()));
- }
- catch (IOException e)
- {
- logger.error("Unable to load image.", e);
- }
-
- if (image != null)
- {
- image = image.getScaledInstance(28, 28, Image.SCALE_SMOOTH);
-
- protocolLabel.setIcon(new ImageIcon(image));
- }
-
- if (isPreferredWizard)
- {
- descriptionArea.setBorder(BorderFactory
- .createEmptyBorder(10, 0, 0, 0));
-
- descriptionArea.setFont(
- descriptionArea.getFont().deriveFont(10f));
- descriptionArea.setPreferredSize(new Dimension(220, 50));
- descriptionArea.setLineWrap(true);
- descriptionArea.setWrapStyleWord(true);
- descriptionArea.setText(wizard.getProtocolDescription());
- descriptionArea.setEditable(false);
- descriptionArea.setOpaque(false);
-
- this.iconDescriptionPanel.add(
- descriptionArea, BorderLayout.CENTER);
-
- this.add(iconDescriptionPanel, BorderLayout.WEST);
- }
- else
- {
- this.add(iconDescriptionPanel, BorderLayout.NORTH);
- }
- }
-
- @Override
- public void paintComponent(Graphics g)
- {
- // do the superclass behavior first
- super.paintComponent(g);
-
- g = g.create();
- try
- {
- AntialiasingManager.activateAntialiasing(g);
-
- Graphics2D g2d = (Graphics2D) g;
-
- // paint the background with the chosen color
- g2d.setColor(Color.GRAY);
- g2d.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 15, 15);
- }
- finally
- {
- g.dispose();
- }
- }
-
- public boolean isFilled()
- {
- String username = usernameField.getText();
- return (username != null) && (username.length() > 0);
- }
-
- public void signin() throws OperationFailedException
- {
- ProtocolProviderService protocolProvider =
- wizard.signin(usernameField.getText(), new String(passwordField
- .getPassword()));
-
- saveAccountWizard(protocolProvider, wizard);
- }
- }
-
- /**
- * Adds a simple account registration form corresponding to the given
- * <tt>AccountRegistrationWizard</tt>.
- *
- * @param wizard the <tt>AccountRegistrationWizard</tt>, which gives us
- * information to fill our simple form.
- */
- private void addAccountRegistrationForm(AccountRegistrationWizard wizard)
- {
- // We don't need to add wizards that are not interested in a
- // simple sign in form.
- if (!wizard.isSimpleFormEnabled())
- return;
-
- String preferredWizardName
- = Resources.getLoginProperty("impl.gui.PREFERRED_ACCOUNT_WIZARD");
-
- AccountRegistrationPanel accountPanel;
-
- if (preferredWizardName != null
- && preferredWizardName.equals(wizard.getClass().getName()))
- {
- accountPanel = new AccountRegistrationPanel(wizard, true);
-
- mainAccountsPanel.add(
- accountPanel,
- BorderLayout.NORTH);
-
- mainAccountsPanel.validate();
- }
- else
- {
- accountPanel = new AccountRegistrationPanel(wizard, false);
-
- accountsPanel.add(accountPanel);
-
- accountsPanel.validate();
- }
-
- this.registrationForms.add(accountPanel);
- }
-
- /**
- * Handles the event triggered by the "service.gui.SIGN_IN" button.
- */
- private class SigninActionListener implements ActionListener
- {
- public void actionPerformed(ActionEvent evt)
- {
- JButton button = (JButton) evt.getSource();
-
- if (button.equals(signinButton))
- {
- Iterator<AccountRegistrationPanel> regIterator =
- registrationForms.iterator();
-
- if (regIterator.hasNext())
- setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
-
- while(regIterator.hasNext())
- {
- AccountRegistrationPanel regForm = regIterator.next();
-
- try
- {
- if (regForm.isFilled())
- regForm.signin();
- }
- catch (OperationFailedException e)
- {
- if (logger.isDebugEnabled())
- logger.debug("The sign in operation has failed.");
-
- PopupDialog popupDialog
- = SimpleAccountRegistrationActivator.getUIService()
- .getPopupDialog();
-
- if (e.getErrorCode()
- == OperationFailedException.ILLEGAL_ARGUMENT)
- {
- popupDialog.showMessagePopupDialog(
- Resources.getString(
- "service.gui.USERNAME_NULL"),
- Resources.getString(
- "service.gui.ERROR"),
- PopupDialog.ERROR_MESSAGE);
- }
- else if (e.getErrorCode()
- == OperationFailedException
- .IDENTIFICATION_CONFLICT)
- {
- popupDialog.showMessagePopupDialog(
- Resources.getString(
- "service.gui.USER_EXISTS_ERROR"),
- Resources.getString(
- "service.gui.ERROR"),
- PopupDialog.ERROR_MESSAGE);
- }
- else if (e.getErrorCode()
- == OperationFailedException
- .SERVER_NOT_SPECIFIED)
- {
- popupDialog.showMessagePopupDialog(
- Resources.getString(
- "service.gui.SPECIFY_SERVER"),
- Resources.getString(
- "service.gui.ERROR"),
- PopupDialog.ERROR_MESSAGE);
- }
- }
- }
- }
-
- InitialAccountRegistrationFrame initialAccountRegistrationFrame =
- InitialAccountRegistrationFrame.this;
- initialAccountRegistrationFrame.setVisible(false);
- initialAccountRegistrationFrame.dispose();
- }
- }
-
- /**
- * Saves the (protocol provider, wizard) pair in through the
- * <tt>ConfigurationService</tt>.
- *
- * @param protocolProvider the protocol provider to save
- * @param wizard the wizard to save
- */
- private void saveAccountWizard(ProtocolProviderService protocolProvider,
- AccountRegistrationWizard wizard)
- {
- String prefix = "net.java.sip.communicator.impl.gui.accounts";
-
- ConfigurationService configService = getConfigurationService();
-
- List<String> accounts = configService.getPropertyNamesByPrefix(prefix, true);
- boolean savedAccount = false;
-
- for (String accountRootPropName : accounts)
- {
- String accountUID = configService.getString(accountRootPropName);
-
- if (accountUID.equals(protocolProvider.getAccountID()
- .getAccountUniqueID()))
- {
-
- configService.setProperty(accountRootPropName + ".wizard",
- wizard.getClass().getName().replace('.', '_'));
-
- savedAccount = true;
- }
- }
-
- if (!savedAccount)
- {
- String accNodeName =
- "acc" + Long.toString(System.currentTimeMillis());
-
- String accountPackage =
- "net.java.sip.communicator.impl.gui.accounts." + accNodeName;
-
- configService.setProperty(accountPackage, protocolProvider
- .getAccountID().getAccountUniqueID());
-
- configService.setProperty(accountPackage + ".wizard", wizard);
- }
- }
-
- /**
- * Returns the <tt>ConfigurationService</tt>.
- *
- * @return the <tt>ConfigurationService</tt>
- */
- public ConfigurationService getConfigurationService()
- {
- if (configurationService == null)
- {
- BundleContext bundleContext =
- SimpleAccountRegistrationActivator.bundleContext;
- ServiceReference configReference =
- bundleContext.getServiceReference(ConfigurationService.class
- .getName());
-
- configurationService =
- (ConfigurationService) bundleContext
- .getService(configReference);
- }
- return configurationService;
- }
-
- /**
- * Creates the title component.
- * @return the newly created title component
- */
- private JComponent createTitleComponent()
- {
- JTextPane titlePane = new JTextPane();
- SimpleAttributeSet aSet = new SimpleAttributeSet();
- StyleConstants.setAlignment(aSet, StyleConstants.ALIGN_CENTER);
- StyleConstants.setBold(aSet, true);
- StyleConstants.setFontFamily(aSet, titlePane.getFont().getFamily());
-
- titlePane.setParagraphAttributes(aSet, true);
- titlePane.setEditable(false);
- titlePane.setText(Resources.getString(
- "plugin.simpleaccregwizz.INITIAL_ACCOUNT_REGISTRATION"));
- titlePane.setOpaque(false);
-
- return titlePane;
- }
-
- /**
- * Show the create account window for the given wizard.
- *
- * @param wizard the <tt>AccountRegistrationWizard</tt>, for which we're
- * opening the window
- */
- private void showCreateAccountWindow(AccountRegistrationWizard wizard)
- {
- CreateAccountWindow createAccountWindow
- = SimpleAccountRegistrationActivator
- .getUIService().getCreateAccountWindow();
-
- createAccountWindow.setSelectedWizard(wizard, true);
-
- if (wizard instanceof ExtendedAccountRegistrationWizard)
- {
- ((ExtendedAccountRegistrationWizard) wizard).setCreateAccountView();
- }
-
- createAccountWindow.setVisible(true);
- }
-
- @Override
- protected void close(boolean isEscaped)
- {
- }
-}
+package net.java.sip.communicator.plugin.simpleaccreg;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+import java.util.*;
+import java.util.List;
+
+import javax.imageio.*;
+import javax.swing.*;
+import javax.swing.text.*;
+
+import net.java.sip.communicator.service.contactlist.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+import net.java.sip.communicator.plugin.desktoputil.*;
+
+import org.jitsi.service.configuration.*;
+import org.osgi.framework.*;
+
+/**
+ * The <tt>NoAccountFoundPage</tt> is the page shown in the account
+ * registration wizard shown in the beginning of the program, when no registered
+ * accounts are found.
+ *
+ * @author Yana Stamcheva
+ * @author Lubomir Marinov
+ */
+public class InitialAccountRegistrationFrame
+ extends SIPCommFrame
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ private ConfigurationService configurationService;
+
+ /**
+ * The <tt>Logger</tt> used by this <tt>InitialAccountRegistrationFrame</tt>
+ * for logging output.
+ */
+ private final Logger logger
+ = Logger.getLogger(InitialAccountRegistrationFrame.class);
+
+ private final TransparentPanel mainAccountsPanel
+ = new TransparentPanel(new BorderLayout(10, 10));
+
+ private final TransparentPanel accountsPanel
+ = new TransparentPanel(new GridLayout(0, 2, 10, 10));
+
+ private final TransparentPanel southPanel
+ = new TransparentPanel(new BorderLayout());
+
+ private final JButton signinButton
+ = new JButton(Resources.getString("service.gui.SIGN_IN"));
+
+ private final Collection<AccountRegistrationPanel> registrationForms =
+ new Vector<AccountRegistrationPanel>();
+
+ /**
+ * Creates an instance of <tt>NoAccountFoundPage</tt>.
+ */
+ public InitialAccountRegistrationFrame()
+ {
+ super(false);
+ setDefaultCloseOperation(DISPOSE_ON_CLOSE);
+
+ TransparentPanel mainPanel
+ = new TransparentPanel(new BorderLayout());
+ mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+
+ JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+ southPanel.add(buttonPanel, BorderLayout.EAST);
+ JButton cancelButton
+ = new JButton(Resources.getString("service.gui.CANCEL"));
+
+ this.setTitle(Resources.getString("service.gui.SIGN_IN"));
+
+ this.setIconImage(
+ Resources.getImage("service.gui.SIP_COMMUNICATOR_LOGO").getImage());
+
+ // In order to have the same icon when using option panes
+ JOptionPane.getRootFrame().setIconImage(
+ Resources.getImage("service.gui.SIP_COMMUNICATOR_LOGO").getImage());
+
+ mainAccountsPanel.setBorder(
+ BorderFactory.createEmptyBorder(10, 10, 10, 10));
+
+ this.getContentPane().add(mainPanel);
+
+ mainPanel.add(createTitleComponent(), BorderLayout.NORTH);
+ JScrollPane scroller = new JScrollPane(mainAccountsPanel);
+ scroller.setOpaque(false);
+ scroller.getViewport().setOpaque(false);
+ mainPanel.add(scroller, BorderLayout.CENTER);
+ mainPanel.add(southPanel, BorderLayout.SOUTH);
+
+ mainAccountsPanel.add(accountsPanel, BorderLayout.CENTER);
+
+ initProvisioningPanel();
+
+ mainAccountsPanel.setOpaque(false);
+ accountsPanel.setOpaque(false);
+ buttonPanel.setOpaque(false);
+
+ SigninActionListener actionListener = new SigninActionListener();
+
+ signinButton.addActionListener(actionListener);
+ cancelButton.addActionListener(actionListener);
+
+ buttonPanel.add(signinButton);
+ buttonPanel.add(cancelButton);
+
+ this.getRootPane().setDefaultButton(signinButton);
+
+ this.initAccountWizards();
+
+ // Create the default group
+ String groupName
+ = Resources.getApplicationProperty("impl.gui.DEFAULT_GROUP_NAME");
+
+ if(groupName != null && groupName.length() > 0)
+ {
+ MetaContactListService contactList =
+ SimpleAccountRegistrationActivator.getContactList();
+ Iterator<MetaContactGroup> iter
+ = contactList.getRoot().getSubgroups();
+ while (iter.hasNext())
+ {
+ MetaContactGroup gr = iter.next();
+ if (groupName.equals(gr.getGroupName()))
+ return;
+ }
+
+ contactList
+ .createMetaContactGroup(contactList.getRoot(), groupName);
+
+ getConfigurationService()
+ .setProperty(
+ "net.java.sip.communicator.impl.gui.addcontact.lastContactParent",
+ groupName);
+ }
+
+ this.getRootPane().validate();
+ this.pack();
+
+ // if the screen height is sufficiently large, expand the window size
+ // so that no scrolling is needed
+ if (scroller.getViewport().getHeight()
+ < Toolkit.getDefaultToolkit().getScreenSize().getHeight() - 230)
+ {
+ this.setSize(scroller.getViewport().getWidth() + 100,
+ scroller.getViewport().getHeight() + 150);
+ }
+ else
+ {
+ // otherwise add some width so that no horizontal scrolling is
+ // needed
+ this.setSize(this.getSize().width + 20,
+ this.getSize().height - 10);
+ }
+ }
+
+ /**
+ * Initializes the provisioning panel.
+ */
+ private void initProvisioningPanel()
+ {
+ String isInitialProv = SimpleAccountRegistrationActivator.getResources()
+ .getSettingsString(
+ "plugin.provisioning.IS_INITIAL_PROVISIONING_LINK");
+
+ if (isInitialProv != null && isInitialProv.length() > 0
+ && !Boolean.parseBoolean(isInitialProv))
+ return;
+
+ String useProvisioningString = SimpleAccountRegistrationActivator
+ .getResources().getI18NString("service.gui.USE_PROVISIONING");
+
+ final JLabel provisioningLabel =
+ new JLabel("<html><a href=''>"
+ + useProvisioningString
+ + "</a></html>");
+
+ provisioningLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
+ provisioningLabel.setToolTipText(useProvisioningString);
+
+ provisioningLabel.addMouseListener(new MouseAdapter()
+ {
+ @Override
+ public void mousePressed(MouseEvent e)
+ {
+ ConfigurationContainer configContainer
+ = SimpleAccountRegistrationActivator.getUIService()
+ .getConfigurationContainer();
+
+ ConfigurationForm advancedConfigForm
+ = SimpleAccountRegistrationActivator.getAdvancedConfigForm();
+
+ if (advancedConfigForm != null)
+ {
+ configContainer.setSelected(advancedConfigForm);
+
+ if (advancedConfigForm instanceof ConfigurationContainer)
+ {
+ ConfigurationForm provisioningForm
+ = SimpleAccountRegistrationActivator
+ .getProvisioningConfigForm();
+
+ if (provisioningForm != null)
+ {
+ ((ConfigurationContainer) advancedConfigForm)
+ .setSelected(provisioningForm);
+ }
+ }
+ }
+
+ configContainer.setVisible(true);
+ }
+ });
+
+ southPanel.add(provisioningLabel, BorderLayout.WEST);
+ }
+
+ private void initAccountWizards()
+ {
+ String simpleWizards
+ = SimpleAccountRegistrationActivator.getConfigService()
+ .getString("plugin.simpleaccreg.PROTOCOL_ORDER");
+
+ StringTokenizer tokenizer = new StringTokenizer(simpleWizards, "|");
+
+ ServiceReference[] serviceRefs = null;
+ while (tokenizer.hasMoreTokens())
+ {
+ String protocolToken = tokenizer.nextToken();
+
+ String osgiFilter = "("
+ + ProtocolProviderFactory.PROTOCOL
+ + "="+protocolToken+")";
+
+ try
+ {
+ serviceRefs = SimpleAccountRegistrationActivator.bundleContext
+ .getServiceReferences(
+ AccountRegistrationWizard.class.getName(), osgiFilter);
+
+ if (serviceRefs != null && serviceRefs.length > 0)
+ {
+ AccountRegistrationWizard wizard
+ = (AccountRegistrationWizard)
+
+ SimpleAccountRegistrationActivator
+ .bundleContext.getService(serviceRefs[0]);
+
+ this.addAccountRegistrationForm(wizard);
+ }
+ }
+ catch (InvalidSyntaxException ex)
+ {
+ logger.error("GuiActivator : ", ex);
+ }
+ }
+ }
+
+ /**
+ * The account registration panel.
+ */
+ private class AccountRegistrationPanel
+ extends JPanel
+ {
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ private JLabel usernameLabel
+ = new JLabel(Resources.getString(
+ "plugin.simpleaccregwizz.LOGIN_USERNAME"));
+
+ private JLabel passwordLabel
+ = new JLabel(Resources.getString("service.gui.PASSWORD"));
+
+ private JTextField usernameField = new JTextField();
+
+ private JLabel usernameExampleLabel = new JLabel();
+
+ private JPasswordField passwordField = new JPasswordField();
+
+ private JPanel labelsPanel = new JPanel(new GridLayout(0, 1, 5, 0));
+
+ private JPanel fieldsPanel = new JPanel(new GridLayout(0, 1, 5, 0));
+
+ private JPanel emptyPanel = new JPanel();
+
+ private JPanel inputPanel = new JPanel(new BorderLayout(5, 5));
+
+ private JPanel iconDescriptionPanel = new JPanel(new BorderLayout());
+
+ private JTextArea descriptionArea = new JTextArea();
+
+ private final AccountRegistrationWizard wizard;
+
+ public AccountRegistrationPanel(
+ AccountRegistrationWizard accountWizard,
+ boolean isPreferredWizard)
+ {
+ super(new BorderLayout(5, 5));
+
+ this.wizard = accountWizard;
+
+ // Obtain the simple form in order to initialize all predefined
+ // values.
+ // TODO: Use the simple form instead of creating new fields and
+ // panels here.
+ wizard.getSimpleForm(false);
+
+ JLabel protocolLabel = new JLabel();
+ JPanel inputRegisterPanel = new JPanel(new BorderLayout());
+
+ this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+
+ this.setOpaque(false);
+
+ this.inputPanel.setOpaque(false);
+ this.labelsPanel.setOpaque(false);
+ this.fieldsPanel.setOpaque(false);
+ this.emptyPanel.setOpaque(false);
+ inputRegisterPanel.setOpaque(false);
+ this.iconDescriptionPanel.setOpaque(false);
+
+ this.add(inputRegisterPanel, BorderLayout.CENTER);
+
+ inputRegisterPanel.add(inputPanel, BorderLayout.NORTH);
+
+ if (((wizard instanceof ExtendedAccountRegistrationWizard)
+ && ((ExtendedAccountRegistrationWizard) wizard)
+ .isSignupSupported()) || wizard.isWebSignupSupported())
+ {
+ String textKey =
+ isPreferredWizard ? "plugin.simpleaccregwizz.SPECIAL_SIGNUP"
+ : "plugin.simpleaccregwizz.SIGNUP";
+ JLabel signupLabel =
+ new JLabel("<html><a href=''>"
+ + Resources.getString(textKey) + "</a></html>",
+ JLabel.RIGHT);
+
+ signupLabel.setFont(signupLabel.getFont().deriveFont(10f));
+ signupLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
+ signupLabel.setToolTipText(
+ Resources.getString(
+ "plugin.simpleaccregwizz.SPECIAL_SIGNUP"));
+ signupLabel.addMouseListener(new MouseAdapter()
+ {
+ @Override
+ public void mousePressed(MouseEvent e)
+ {
+ try
+ {
+ if ((wizard
+ instanceof ExtendedAccountRegistrationWizard)
+ && ((ExtendedAccountRegistrationWizard) wizard)
+ .isSignupSupported())
+ {
+ showCreateAccountWindow(wizard);
+ dispose();
+ }
+ else if (wizard.isWebSignupSupported())
+ {
+ wizard.webSignup();
+ }
+ }
+ catch (UnsupportedOperationException ex)
+ {
+ // This should not happen, because we check if the
+ // operation is supported, before adding the sign
+ // up.
+ logger.error("The web sign up is not supported.",
+ ex);
+ }
+ }
+ });
+
+ inputRegisterPanel.add(signupLabel, BorderLayout.SOUTH);
+ }
+
+ this.inputPanel.add(labelsPanel, BorderLayout.WEST);
+
+ this.inputPanel.add(fieldsPanel, BorderLayout.CENTER);
+
+ this.iconDescriptionPanel.add(
+ protocolLabel, BorderLayout.NORTH);
+
+ protocolLabel.setFont(
+ protocolLabel.getFont().deriveFont(Font.BOLD, 14f));
+ this.usernameExampleLabel.setForeground(Color.DARK_GRAY);
+ this.usernameExampleLabel.setFont(
+ usernameExampleLabel.getFont().deriveFont(8f));
+ this.emptyPanel.setMaximumSize(new Dimension(40, 25));
+
+ this.labelsPanel.add(usernameLabel);
+ this.labelsPanel.add(emptyPanel);
+ this.labelsPanel.add(passwordLabel);
+
+ this.fieldsPanel.add(usernameField);
+ this.fieldsPanel.add(usernameExampleLabel);
+ this.fieldsPanel.add(passwordField);
+
+ this.usernameExampleLabel.setText(wizard.getUserNameExample());
+
+ protocolLabel.setText(wizard.getProtocolName());
+
+ Image image = null;
+ try
+ {
+ image = ImageIO.read(
+ new ByteArrayInputStream(wizard.getPageImage()));
+ }
+ catch (IOException e)
+ {
+ logger.error("Unable to load image.", e);
+ }
+
+ if (image != null)
+ {
+ image = image.getScaledInstance(28, 28, Image.SCALE_SMOOTH);
+
+ protocolLabel.setIcon(new ImageIcon(image));
+ }
+
+ if (isPreferredWizard)
+ {
+ descriptionArea.setBorder(BorderFactory
+ .createEmptyBorder(10, 0, 0, 0));
+
+ descriptionArea.setFont(
+ descriptionArea.getFont().deriveFont(10f));
+ descriptionArea.setPreferredSize(new Dimension(220, 50));
+ descriptionArea.setLineWrap(true);
+ descriptionArea.setWrapStyleWord(true);
+ descriptionArea.setText(wizard.getProtocolDescription());
+ descriptionArea.setEditable(false);
+ descriptionArea.setOpaque(false);
+
+ this.iconDescriptionPanel.add(
+ descriptionArea, BorderLayout.CENTER);
+
+ this.add(iconDescriptionPanel, BorderLayout.WEST);
+ }
+ else
+ {
+ this.add(iconDescriptionPanel, BorderLayout.NORTH);
+ }
+ }
+
+ @Override
+ public void paintComponent(Graphics g)
+ {
+ // do the superclass behavior first
+ super.paintComponent(g);
+
+ g = g.create();
+ try
+ {
+ AntialiasingManager.activateAntialiasing(g);
+
+ Graphics2D g2d = (Graphics2D) g;
+
+ // paint the background with the chosen color
+ g2d.setColor(Color.GRAY);
+ g2d.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 15, 15);
+ }
+ finally
+ {
+ g.dispose();
+ }
+ }
+
+ public boolean isFilled()
+ {
+ String username = usernameField.getText();
+ return (username != null) && (username.length() > 0);
+ }
+
+ public void signin() throws OperationFailedException
+ {
+ ProtocolProviderService protocolProvider =
+ wizard.signin(usernameField.getText(), new String(passwordField
+ .getPassword()));
+
+ saveAccountWizard(protocolProvider, wizard);
+ }
+ }
+
+ /**
+ * Adds a simple account registration form corresponding to the given
+ * <tt>AccountRegistrationWizard</tt>.
+ *
+ * @param wizard the <tt>AccountRegistrationWizard</tt>, which gives us
+ * information to fill our simple form.
+ */
+ private void addAccountRegistrationForm(AccountRegistrationWizard wizard)
+ {
+ // We don't need to add wizards that are not interested in a
+ // simple sign in form.
+ if (!wizard.isSimpleFormEnabled())
+ return;
+
+ String preferredWizardName
+ = Resources.getLoginProperty("impl.gui.PREFERRED_ACCOUNT_WIZARD");
+
+ AccountRegistrationPanel accountPanel;
+
+ if (preferredWizardName != null
+ && preferredWizardName.equals(wizard.getClass().getName()))
+ {
+ accountPanel = new AccountRegistrationPanel(wizard, true);
+
+ mainAccountsPanel.add(
+ accountPanel,
+ BorderLayout.NORTH);
+
+ mainAccountsPanel.validate();
+ }
+ else
+ {
+ accountPanel = new AccountRegistrationPanel(wizard, false);
+
+ accountsPanel.add(accountPanel);
+
+ accountsPanel.validate();
+ }
+
+ this.registrationForms.add(accountPanel);
+ }
+
+ /**
+ * Handles the event triggered by the "service.gui.SIGN_IN" button.
+ */
+ private class SigninActionListener implements ActionListener
+ {
+ public void actionPerformed(ActionEvent evt)
+ {
+ JButton button = (JButton) evt.getSource();
+
+ if (button.equals(signinButton))
+ {
+ Iterator<AccountRegistrationPanel> regIterator =
+ registrationForms.iterator();
+
+ if (regIterator.hasNext())
+ setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+
+ while(regIterator.hasNext())
+ {
+ AccountRegistrationPanel regForm = regIterator.next();
+
+ try
+ {
+ if (regForm.isFilled())
+ regForm.signin();
+ }
+ catch (OperationFailedException e)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("The sign in operation has failed.");
+
+ PopupDialog popupDialog
+ = SimpleAccountRegistrationActivator.getUIService()
+ .getPopupDialog();
+
+ if (e.getErrorCode()
+ == OperationFailedException.ILLEGAL_ARGUMENT)
+ {
+ popupDialog.showMessagePopupDialog(
+ Resources.getString(
+ "service.gui.USERNAME_NULL"),
+ Resources.getString(
+ "service.gui.ERROR"),
+ PopupDialog.ERROR_MESSAGE);
+ }
+ else if (e.getErrorCode()
+ == OperationFailedException
+ .IDENTIFICATION_CONFLICT)
+ {
+ popupDialog.showMessagePopupDialog(
+ Resources.getString(
+ "service.gui.USER_EXISTS_ERROR"),
+ Resources.getString(
+ "service.gui.ERROR"),
+ PopupDialog.ERROR_MESSAGE);
+ }
+ else if (e.getErrorCode()
+ == OperationFailedException
+ .SERVER_NOT_SPECIFIED)
+ {
+ popupDialog.showMessagePopupDialog(
+ Resources.getString(
+ "service.gui.SPECIFY_SERVER"),
+ Resources.getString(
+ "service.gui.ERROR"),
+ PopupDialog.ERROR_MESSAGE);
+ }
+ }
+ }
+ }
+
+ InitialAccountRegistrationFrame initialAccountRegistrationFrame =
+ InitialAccountRegistrationFrame.this;
+ initialAccountRegistrationFrame.setVisible(false);
+ initialAccountRegistrationFrame.dispose();
+ }
+ }
+
+ /**
+ * Saves the (protocol provider, wizard) pair in through the
+ * <tt>ConfigurationService</tt>.
+ *
+ * @param protocolProvider the protocol provider to save
+ * @param wizard the wizard to save
+ */
+ private void saveAccountWizard(ProtocolProviderService protocolProvider,
+ AccountRegistrationWizard wizard)
+ {
+ String prefix = "net.java.sip.communicator.impl.gui.accounts";
+
+ ConfigurationService configService = getConfigurationService();
+
+ List<String> accounts = configService.getPropertyNamesByPrefix(prefix, true);
+ boolean savedAccount = false;
+
+ for (String accountRootPropName : accounts)
+ {
+ String accountUID = configService.getString(accountRootPropName);
+
+ if (accountUID.equals(protocolProvider.getAccountID()
+ .getAccountUniqueID()))
+ {
+
+ configService.setProperty(accountRootPropName + ".wizard",
+ wizard.getClass().getName().replace('.', '_'));
+
+ savedAccount = true;
+ }
+ }
+
+ if (!savedAccount)
+ {
+ String accNodeName =
+ "acc" + Long.toString(System.currentTimeMillis());
+
+ String accountPackage =
+ "net.java.sip.communicator.impl.gui.accounts." + accNodeName;
+
+ configService.setProperty(accountPackage, protocolProvider
+ .getAccountID().getAccountUniqueID());
+
+ configService.setProperty(accountPackage + ".wizard", wizard);
+ }
+ }
+
+ /**
+ * Returns the <tt>ConfigurationService</tt>.
+ *
+ * @return the <tt>ConfigurationService</tt>
+ */
+ public ConfigurationService getConfigurationService()
+ {
+ if (configurationService == null)
+ {
+ BundleContext bundleContext =
+ SimpleAccountRegistrationActivator.bundleContext;
+ ServiceReference configReference =
+ bundleContext.getServiceReference(ConfigurationService.class
+ .getName());
+
+ configurationService =
+ (ConfigurationService) bundleContext
+ .getService(configReference);
+ }
+ return configurationService;
+ }
+
+ /**
+ * Creates the title component.
+ * @return the newly created title component
+ */
+ private JComponent createTitleComponent()
+ {
+ JTextPane titlePane = new JTextPane();
+ SimpleAttributeSet aSet = new SimpleAttributeSet();
+ StyleConstants.setAlignment(aSet, StyleConstants.ALIGN_CENTER);
+ StyleConstants.setBold(aSet, true);
+ StyleConstants.setFontFamily(aSet, titlePane.getFont().getFamily());
+
+ titlePane.setParagraphAttributes(aSet, true);
+ titlePane.setEditable(false);
+ titlePane.setText(Resources.getString(
+ "plugin.simpleaccregwizz.INITIAL_ACCOUNT_REGISTRATION"));
+ titlePane.setOpaque(false);
+
+ return titlePane;
+ }
+
+ /**
+ * Show the create account window for the given wizard.
+ *
+ * @param wizard the <tt>AccountRegistrationWizard</tt>, for which we're
+ * opening the window
+ */
+ private void showCreateAccountWindow(AccountRegistrationWizard wizard)
+ {
+ CreateAccountWindow createAccountWindow
+ = SimpleAccountRegistrationActivator
+ .getUIService().getCreateAccountWindow();
+
+ createAccountWindow.setSelectedWizard(wizard, true);
+
+ if (wizard instanceof ExtendedAccountRegistrationWizard)
+ {
+ ((ExtendedAccountRegistrationWizard) wizard).setCreateAccountView();
+ }
+
+ createAccountWindow.setVisible(true);
+ }
+
+ @Override
+ protected void close(boolean isEscaped)
+ {
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/simpleaccreg/Resources.java b/src/net/java/sip/communicator/plugin/simpleaccreg/Resources.java
index 7249e66..f62093f 100644
--- a/src/net/java/sip/communicator/plugin/simpleaccreg/Resources.java
+++ b/src/net/java/sip/communicator/plugin/simpleaccreg/Resources.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,92 +15,92 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.simpleaccreg;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.service.resources.*;
-
-import org.jitsi.service.resources.*;
-
-/**
- * The <tt>Resources</tt> class manages the access to the internationalization
- * properties files and the image resources used in this plugin.
- *
- * @author Yana Stamcheva
- */
-public class Resources
-{
- private static ResourceManagementService resourcesService;
-
- /**
- * Returns an internationalized string corresponding to the given key.
- *
- * @param key The key of the string.
- * @return An internationalized string corresponding to the given key.
- */
- public static String getString(String key)
- {
- return getResources().getI18NString(key);
- }
-
- /**
- * Returns an int RGB color corresponding to the given key.
- *
- * @param key The key of the string.
- *
- * @return An internationalized string corresponding to the given key.
- */
- public static int getColor(String key)
- {
- return getResources().getColor(key);
- }
-
- /**
- * Returns the application property corresponding to the given key.
- *
- * @param key The key of the string.
- *
- * @return the application property corresponding to the given key
- */
- public static String getLoginProperty(String key)
- {
- return getResources().getSettingsString(key);
- }
-
- /**
- * Returns the application property corresponding to the given key.
- *
- * @param key The key of the string.
- *
- * @return the application property corresponding to the given key
- */
- public static String getApplicationProperty(String key)
- {
- return getResources().getSettingsString(key);
- }
-
- /**
- * Loads an image from a given image identifier.
- * @param imageID The identifier of the image.
- * @return The image for the given identifier.
- */
- public static ImageIcon getImage(String imageID)
- {
- return getResources().getImage(imageID);
- }
-
- /**
- * Returns the <tt>ResourceManagementService</tt>.
- *
- * @return the <tt>ResourceManagementService</tt>.
- */
- public static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- resourcesService =
- ResourceManagementServiceUtils
- .getService(SimpleAccountRegistrationActivator.bundleContext);
- return resourcesService;
- }
-}
+package net.java.sip.communicator.plugin.simpleaccreg;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.service.resources.*;
+
+import org.jitsi.service.resources.*;
+
+/**
+ * The <tt>Resources</tt> class manages the access to the internationalization
+ * properties files and the image resources used in this plugin.
+ *
+ * @author Yana Stamcheva
+ */
+public class Resources
+{
+ private static ResourceManagementService resourcesService;
+
+ /**
+ * Returns an internationalized string corresponding to the given key.
+ *
+ * @param key The key of the string.
+ * @return An internationalized string corresponding to the given key.
+ */
+ public static String getString(String key)
+ {
+ return getResources().getI18NString(key);
+ }
+
+ /**
+ * Returns an int RGB color corresponding to the given key.
+ *
+ * @param key The key of the string.
+ *
+ * @return An internationalized string corresponding to the given key.
+ */
+ public static int getColor(String key)
+ {
+ return getResources().getColor(key);
+ }
+
+ /**
+ * Returns the application property corresponding to the given key.
+ *
+ * @param key The key of the string.
+ *
+ * @return the application property corresponding to the given key
+ */
+ public static String getLoginProperty(String key)
+ {
+ return getResources().getSettingsString(key);
+ }
+
+ /**
+ * Returns the application property corresponding to the given key.
+ *
+ * @param key The key of the string.
+ *
+ * @return the application property corresponding to the given key
+ */
+ public static String getApplicationProperty(String key)
+ {
+ return getResources().getSettingsString(key);
+ }
+
+ /**
+ * Loads an image from a given image identifier.
+ * @param imageID The identifier of the image.
+ * @return The image for the given identifier.
+ */
+ public static ImageIcon getImage(String imageID)
+ {
+ return getResources().getImage(imageID);
+ }
+
+ /**
+ * Returns the <tt>ResourceManagementService</tt>.
+ *
+ * @return the <tt>ResourceManagementService</tt>.
+ */
+ public static ResourceManagementService getResources()
+ {
+ if (resourcesService == null)
+ resourcesService =
+ ResourceManagementServiceUtils
+ .getService(SimpleAccountRegistrationActivator.bundleContext);
+ return resourcesService;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/CreateSip2SipAccountForm.java b/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/CreateSip2SipAccountForm.java
deleted file mode 100644
index aa38c69..0000000
--- a/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/CreateSip2SipAccountForm.java
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.sip2sipaccregwizz;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.io.*;
-import java.net.*;
-
-import javax.swing.*;
-import javax.swing.text.*;
-
-import net.java.sip.communicator.plugin.ippiaccregwizz.*;
-import net.java.sip.communicator.plugin.sipaccregwizz.*;
-import net.java.sip.communicator.util.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
-
-import org.json.simple.*;
-
-/**
- * @author Yana Stamcheva
- */
-public class CreateSip2SipAccountForm
- extends TransparentPanel
- implements SIPAccountCreationFormService
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * The logger.
- */
- private static final Logger logger
- = Logger.getLogger(CreateSip2SipAccountForm.class);
-
- /**
- * The user name text field.
- */
- private final JTextField usernameField = new TrimTextField();
-
- /**
- * The display name text field.
- */
- private final JTextField displayNameField = new JTextField();
-
- /**
- * The password field.
- */
- private final JPasswordField passField = new JPasswordField();
-
- /**
- * The retype password field.
- */
- private final JPasswordField retypePassField = new JPasswordField();
-
- /**
- * The email field.
- */
- private final JTextField emailField = new JTextField();
-
- /**
- * The error text pane.
- */
- private final JTextPane errorPane = new JTextPane();
-
- /**
- * The register link.
- */
- private static String registerLink
- = "https://enrollment.sipthor.net/enrollment.phtml?";
-
- /**
- * Creates an instance of <tt>RegisterSip2SipAccountForm</tt>.
- */
- public CreateSip2SipAccountForm()
- {
- super(new BorderLayout());
-
- this.init();
- }
-
- /**
- * Initializes this panel.
- */
- private void init()
- {
- JPanel mainPanel = new TransparentPanel(new BorderLayout());
-
- mainPanel.setBorder(BorderFactory.createTitledBorder(
- Sip2SipAccRegWizzActivator.getResources()
- .getI18NString("plugin.sipaccregwizz.CREATE_ACCOUNT_TITLE")));
-
- JPanel labelsPanel = new TransparentPanel(new GridLayout(0, 1));
-
- JPanel valuesPanel = new TransparentPanel(new GridLayout(0, 1));
-
- JLabel usernameLabel
- = new JLabel(Sip2SipAccRegWizzActivator.getResources()
- .getI18NString("plugin.sip2sipaccregwizz.USERNAME"));
-
- JLabel displayNameLabel
- = new JLabel(Sip2SipAccRegWizzActivator.getResources()
- .getI18NString("plugin.sipaccregwizz.DISPLAY_NAME"));
-
- JLabel passLabel
- = new JLabel(Sip2SipAccRegWizzActivator.getResources()
- .getI18NString("service.gui.PASSWORD"));
-
- JLabel retypePasswordLabel
- = new JLabel(Sip2SipAccRegWizzActivator.getResources()
- .getI18NString("plugin.sip2sipaccregwizz.RETYPE_PASSWORD"));
-
- JLabel emailLabel
- = new JLabel(Sip2SipAccRegWizzActivator.getResources()
- .getI18NString("plugin.sip2sipaccregwizz.EMAIL"));
-
- labelsPanel.add(displayNameLabel);
- labelsPanel.add(usernameLabel);
- labelsPanel.add(passLabel);
- labelsPanel.add(retypePasswordLabel);
- labelsPanel.add(emailLabel);
-
- valuesPanel.add(displayNameField);
- valuesPanel.add(usernameField);
- valuesPanel.add(passField);
- valuesPanel.add(retypePassField);
- valuesPanel.add(emailField);
-
- JLabel emailDescriptionLabel
- = new JLabel(Sip2SipAccRegWizzActivator.getResources()
- .getI18NString("plugin.sip2sipaccregwizz.EMAIL_NOTE"),
- SwingConstants.CENTER);
- emailDescriptionLabel.setForeground(Color.GRAY);
- emailDescriptionLabel.setFont(emailDescriptionLabel.getFont().deriveFont(8));
- emailDescriptionLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 8, 10));
-
- initErrorArea();
-
- mainPanel.add(labelsPanel, BorderLayout.WEST);
- mainPanel.add(valuesPanel, BorderLayout.CENTER);
- mainPanel.add(emailDescriptionLabel, BorderLayout.SOUTH);
-
- this.add(mainPanel, BorderLayout.CENTER);
-
- JLabel infoLabel
- = new JLabel(Sip2SipAccRegWizzActivator.getResources()
- .getI18NString("plugin.sip2sipaccregwizz.INFO_NOTE"),
- SwingConstants.RIGHT);
- infoLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
- infoLabel.setForeground(Color.GRAY);
- infoLabel.setFont(emailDescriptionLabel.getFont().deriveFont(8));
- infoLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 8, 0));
- infoLabel.addMouseListener(new MouseAdapter()
- {
- @Override
- public void mousePressed(MouseEvent e)
- {
- Sip2SipAccRegWizzActivator.getBrowserLauncher()
- .openURL("http://wiki.sip2sip.info");
- }
- });
-
- this.add(infoLabel, BorderLayout.SOUTH);
- }
-
- /**
- * Creates the error area component.
- */
- private void initErrorArea()
- {
- SimpleAttributeSet attribs = new SimpleAttributeSet();
- StyleConstants.setAlignment(attribs, StyleConstants.ALIGN_RIGHT);
- StyleConstants.setFontFamily(attribs, errorPane.getFont().getFamily());
- StyleConstants.setForeground(attribs, Color.RED);
- errorPane.setParagraphAttributes(attribs, true);
- errorPane.setPreferredSize(new Dimension(100, 50));
- errorPane.setMinimumSize(new Dimension(100, 50));
- errorPane.setOpaque(false);
- }
-
- /**
- * Creates this account on the server.
- * @return the created account
- */
- public NewAccount createAccount()
- {
- // Check if the two passwords match.
- String pass1 = new String( passField.getPassword());
- String pass2 = new String( retypePassField.getPassword());
- if (!pass1.equals(pass2))
- {
- showErrorMessage(
- IppiAccRegWizzActivator.getResources().getI18NString(
- "plugin.sipaccregwizz.NOT_SAME_PASSWORD"));
-
- return null;
- }
-
- NewAccount newAccount = null;
- try
- {
- StringBuilder registerLinkBuilder = new StringBuilder(registerLink);
- registerLinkBuilder
- .append(URLEncoder.encode("email", "UTF-8"))
- .append("=").append(
- URLEncoder.encode(emailField.getText(), "UTF-8"))
- .append("&").append(URLEncoder.encode("password", "UTF-8"))
- .append("=").append(
- URLEncoder.encode(new String(passField.getPassword()), "UTF-8"))
- .append("&").append(URLEncoder.encode("display_name", "UTF-8"))
- .append("=").append(
- URLEncoder.encode(displayNameField.getText(), "UTF-8"))
- .append("&").append(URLEncoder.encode("username", "UTF-8"))
- .append("=").append(
- URLEncoder.encode(usernameField.getText(), "UTF-8"))
- .append("&").append(URLEncoder.encode("user_agent", "UTF-8"))
- .append("=").append(
- URLEncoder.encode("sip-communicator.org", "UTF-8"));
-
- URL url = new URL(registerLinkBuilder.toString());
- URLConnection conn = url.openConnection();
-
- // If this is not an http connection we have nothing to do here.
- if (!(conn instanceof HttpURLConnection))
- {
- return null;
- }
-
- HttpURLConnection httpConn = (HttpURLConnection) conn;
-
- int responseCode = httpConn.getResponseCode();
-
- if (responseCode == HttpURLConnection.HTTP_OK)
- {
- // Read all the text returned by the server
- BufferedReader in = new BufferedReader(
- new InputStreamReader(conn.getInputStream()));
- String str;
-
- StringBuffer stringBuffer = new StringBuffer();
- while ((str = in.readLine()) != null)
- {
- stringBuffer.append(str);
- }
-
- if (logger.isInfoEnabled())
- logger.info("JSON response to create account request: "
- + stringBuffer.toString());
-
- newAccount = parseHttpResponse(stringBuffer.toString());
- }
- }
- catch (MalformedURLException e1)
- {
- if (logger.isInfoEnabled())
- logger.info("Failed to create URL with string: "
- + registerLink, e1);
- }
- catch (IOException e1)
- {
- if (logger.isInfoEnabled())
- logger.info("Failed to open connection.", e1);
- }
- return newAccount;
- }
-
- /**
- * Returns the form, which would be used by the user to create a new
- * account.
- * @return the component of the form
- */
- public Component getForm()
- {
- return this;
- }
-
- /**
- * Clears all the data previously entered in the form.
- */
- public void clear()
- {
- usernameField.setText("");
- displayNameField.setText("");
- passField.setText("");
- retypePassField.setText("");
- emailField.setText("");
- errorPane.setText("");
-
- remove(errorPane);
- }
-
- /**
- * Parses the given http response.
- * @param response the http response to parse
- * @return the new account
- */
- private NewAccount parseHttpResponse(String response)
- {
- NewAccount newAccount = null;
- try
- {
- JSONObject jsonObject = (JSONObject)JSONValue
- .parseWithException(response);
- boolean isSuccess = (Boolean)jsonObject.get("success");
-
- if (isSuccess)
- {
- newAccount = new NewAccount(
- (String)jsonObject.get("sip_address"),
- passField.getPassword(),
- null,
- (String)jsonObject.get("outbound_proxy"));
-
- String xcapRoot = (String)jsonObject.get("xcap_root");
-
- // as sip2sip adds @sip2sip.info at the end of the
- // xcap_uri but doesn't report it in resullt after
- // creating account, we add it
- String domain = null;
- int delimIndex = newAccount.getUserName().indexOf("@");
- if (delimIndex != -1)
- {
- domain = newAccount.getUserName().substring(delimIndex);
- }
- if(domain != null)
- {
- if(xcapRoot.endsWith("/"))
- xcapRoot =
- xcapRoot.substring(0, xcapRoot.length() - 1)
- + domain;
- else
- xcapRoot += domain;
- }
-
- newAccount.setXcapRoot(xcapRoot);
- }
- else
- {
- showErrorMessage((String)jsonObject.get("error_message"));
- }
- }
- catch (Throwable e1)
- {
- if (logger.isInfoEnabled())
- logger.info("Failed Json parsing.", e1);
- }
-
- return newAccount;
- }
-
- /**
- * Shows the given error message.
- *
- * @param text the text of the error
- */
- private void showErrorMessage(String text)
- {
- errorPane.setText(text);
-
- if (errorPane.getParent() == null)
- add(errorPane, BorderLayout.NORTH);
-
- SwingUtilities.getWindowAncestor(CreateSip2SipAccountForm.this).pack();
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/Sip2SipAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/Sip2SipAccRegWizzActivator.java
deleted file mode 100644
index 6263508..0000000
--- a/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/Sip2SipAccRegWizzActivator.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.sip2sipaccregwizz;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.browserlauncher.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.resources.*;
-
-import org.jitsi.service.resources.*;
-import org.osgi.framework.*;
-
-/**
- * Registers the <tt>GoogleTalkAccountRegistrationWizard</tt> in the UI Service.
- *
- * @author Lubomir Marinov
- * @author Yana Stamcheva
- */
-public class Sip2SipAccRegWizzActivator
- implements BundleActivator
-{
- /**
- * The bundle context.
- */
- public static BundleContext bundleContext;
-
- /**
- * The browser launcher service.
- */
- private static BrowserLauncherService browserLauncherService;
-
- /**
- * The resources service.
- */
- private static ResourceManagementService resourcesService;
-
- /**
- * The ui service.
- */
- private static UIService uiService;
-
- /**
- * Starts this bundle.
- * @param bc BundleContext
- * @throws Exception
- */
- public void start(BundleContext bc)
- throws Exception
- {
- bundleContext = bc;
-
- System.setProperty(
- "http.agent",
- System.getProperty("sip-communicator.application.name")
- + "/"
- + System.getProperty("sip-communicator.version"));
-
- uiService =
- (UIService) bundleContext.getService(bundleContext
- .getServiceReference(UIService.class.getName()));
-
- Sip2SipAccountRegistrationWizard wizard
- = new Sip2SipAccountRegistrationWizard(uiService
- .getAccountRegWizardContainer());
-
- Hashtable<String, String> containerFilter
- = new Hashtable<String, String>();
- containerFilter.put(
- ProtocolProviderFactory.PROTOCOL,
- Sip2SipAccountRegistrationWizard.PROTOCOL);
-
- bundleContext.registerService(
- AccountRegistrationWizard.class.getName(),
- wizard,
- containerFilter);
- }
-
- public void stop(BundleContext bundleContext) throws Exception {}
-
- /**
- * Returns the <tt>UIService</tt>.
- *
- * @return the <tt>UIService</tt>
- */
- public static UIService getUIService()
- {
- return uiService;
- }
-
- /**
- * Returns the <tt>BrowserLauncherService</tt> obtained from the bundle
- * context.
- * @return the <tt>BrowserLauncherService</tt> obtained from the bundle
- * context
- */
- public static BrowserLauncherService getBrowserLauncher()
- {
- if (browserLauncherService == null)
- {
- browserLauncherService
- = (BrowserLauncherService) bundleContext.getService(
- bundleContext.getServiceReference(
- BrowserLauncherService.class.getName()));
- }
- return browserLauncherService;
- }
-
- /**
- * Returns the service giving access to resources.
- * @return the service giving access to resources
- */
- public static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- resourcesService = ResourceManagementServiceUtils
- .getService(Sip2SipAccRegWizzActivator.bundleContext);
- return resourcesService;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/Sip2SipAccountRegistrationWizard.java b/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/Sip2SipAccountRegistrationWizard.java
deleted file mode 100644
index d6b09d8..0000000
--- a/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/Sip2SipAccountRegistrationWizard.java
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.sip2sipaccregwizz;
-
-import java.util.*;
-
-import net.java.sip.communicator.plugin.sipaccregwizz.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.sip.*;
-
-/**
- * The <tt>Sip2SipAccountRegistrationWizard</tt> is an implementation of the
- * <tt>AccountRegistrationWizard</tt> for the SIP protocol. It should allow
- * the user to create and configure a new IP Tel SIP account.
- *
- * @author Yana Stamcheva
- */
-public class Sip2SipAccountRegistrationWizard
- extends SIPAccountRegistrationWizard
-{
- /**
- * A constant pointing to the IP Tel protocol logo image.
- */
- private static final String PROTOCOL_ICON
- = "service.protocol.sip2sip.SIP2SIP_16x16";
-
- /**
- * A constant pointing to the IP Tel protocol wizard page image.
- */
- private static final String PAGE_IMAGE
- = "service.protocol.sip2sip.SIP2SIP_64x64";
-
- /**
- * The protocol name.
- */
- public static final String PROTOCOL = "sip2sip.info";
-
- /**
- * The create account form.
- */
- CreateSip2SipAccountForm createAccountForm = new CreateSip2SipAccountForm();
-
- /**
- * Creates an instance of <tt>IptelAccountRegistrationWizard</tt>.
- * @param wizardContainer the wizard container
- */
- public Sip2SipAccountRegistrationWizard(WizardContainer wizardContainer)
- {
- super(wizardContainer);
- }
-
- /**
- * Returns the set of pages contained in this wizard.
- * @return Iterator
- */
- @Override
- public Iterator<WizardPage> getPages()
- {
- SIPAccountRegistration reg = new SIPAccountRegistration();
-
- setPredefinedProperties(reg);
-
- return getPages(reg);
- }
-
- /**
- * Returns a simple account registration form that would be the first form
- * shown to the user. Only if the user needs more settings she'll choose
- * to open the advanced wizard, consisted by all pages.
- *
- * @param isCreateAccount indicates if the simple form should be opened as
- * a create account form or as a login form
- * @return a simple account registration form
- */
- @Override
- public Object getSimpleForm(boolean isCreateAccount)
- {
- SIPAccountRegistration reg = new SIPAccountRegistration();
-
- setPredefinedProperties(reg);
-
- return getSimpleForm(reg, isCreateAccount);
- }
-
- /**
- * Sets all predefined properties specific for this account wizard.
- *
- * @param reg the registration object
- */
- private void setPredefinedProperties(SIPAccountRegistration reg)
- {
- // set properties common for sip2sip
- reg.setKeepAliveMethod("NONE");
- reg.setDefaultDomain("sip2sip.info");
- reg.setXCapEnable(true);
- reg.setClistOptionServerUri(
- "https://xcap.sipthor.net/xcap-root@sip2sip.info");
- reg.setClistOptionUseSipCredentials(true);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getIcon</code> method.
- * Returns the icon to be used for this wizard.
- * @return byte[]
- */
- @Override
- public byte[] getIcon()
- {
- return Sip2SipAccRegWizzActivator.getResources()
- .getImageInBytes(PROTOCOL_ICON);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getPageImage</code> method.
- * Returns the image used to decorate the wizard page
- *
- * @return byte[] the image used to decorate the wizard page
- */
- @Override
- public byte[] getPageImage()
- {
- return Sip2SipAccRegWizzActivator.getResources()
- .getImageInBytes(PAGE_IMAGE);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getProtocolName</code>
- * method. Returns the protocol name for this wizard.
- * @return String
- */
- @Override
- public String getProtocolName()
- {
- return Resources.getString(
- "plugin.sip2sipaccregwizz.PROTOCOL_NAME");
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getProtocolDescription
- * </code> method. Returns the description of the protocol for this wizard.
- * @return String
- */
- @Override
- public String getProtocolDescription()
- {
- return Resources.getString(
- "plugin.sip2sipaccregwizz.PROTOCOL_DESCRIPTION");
- }
-
- /**
- * Returns an example string, which should indicate to the user how the
- * user name should look like.
- * @return an example string, which should indicate to the user how the
- * user name should look like.
- */
- @Override
- public String getUserNameExample()
- {
- return "Ex: myusername or myusername@sip2sip.info";
- }
-
- /**
- * Returns the protocol name as listed in "ProtocolNames" or just the name
- * of the service.
- * @return the protocol name
- */
- @Override
- public String getProtocol()
- {
- return PROTOCOL;
- }
-
- /**
- * Returns the protocol icon path.
- * @return the protocol icon path
- */
- @Override
- public String getProtocolIconPath()
- {
- return "resources/images/protocol/sip2sip";
- }
-
- /**
- * Returns the account icon path.
- * @return the account icon path
- */
- @Override
- public String getAccountIconPath()
- {
- return "resources/images/protocol/sip2sip/sip32x32.png";
- }
-
- /**
- * Opens the browser on the page sign up
- */
- @Override
- public void webSignup()
- {
- Sip2SipAccRegWizzActivator.getBrowserLauncher()
- .openURL("http://wiki.sip2sip.info");
- }
-
- /**
- * Returns the name of the web sign up link.
- * @return the name of the web sign up link
- */
- @Override
- public String getWebSignupLinkName()
- {
- return Resources.getString("plugin.sip2sipaccregwizz.NEW_ACCOUNT_TITLE");
- }
-
- /**
- * Returns an instance of <tt>CreateAccountService</tt> through which the
- * user could create an account. This method is meant to be implemented by
- * specific protocol provider wizards.
- * @return an instance of <tt>CreateAccountService</tt>
- */
- @Override
- protected SIPAccountCreationFormService getCreateAccountService()
- {
- return createAccountForm;
- }
-
- /**
- * Returns the display label used for the sip id field.
- * @return the sip id display label string.
- */
- @Override
- protected String getUsernameLabel()
- {
- return Resources.getString("plugin.sip2sipaccregwizz.USERNAME");
- }
-
- /**
- * Return the string for add existing account button.
- * @return the string for add existing account button.
- */
- @Override
- protected String getExistingAccountLabel()
- {
- return Resources.getString("plugin.sip2sipaccregwizz.EXISTING_ACCOUNT");
- }
-
- /**
- * Return the string for create new account button.
- * @return the string for create new account button.
- */
- @Override
- protected String getCreateAccountLabel()
- {
- return Resources.getString("plugin.sip2sipaccregwizz.CREATE_ACCOUNT");
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/sip2sipaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/sip2sipaccregwizz.manifest.mf
deleted file mode 100644
index 7ebbd1c..0000000
--- a/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/sip2sipaccregwizz.manifest.mf
+++ /dev/null
@@ -1,43 +0,0 @@
-Bundle-Activator: net.java.sip.communicator.plugin.sip2sipaccregwizz.Sip2SipAccRegWizzActivator
-Bundle-Name: Sip 2 Sip account registration wizard
-Bundle-Description: Sip 2 Sip account registration wizard.
-Bundle-Vendor: jitsi.org
-Bundle-Version: 0.0.1
-Bundle-SymbolicName: net.java.sip.communicator.plugin.sip2sipaccregwizz
-Import-Package: org.osgi.framework,
- net.java.sip.communicator.service.browserlauncher,
- org.jitsi.service.configuration,
- net.java.sip.communicator.service.contactlist,
- net.java.sip.communicator.service.contactlist.event,
- org.jitsi.service.fileaccess,
- net.java.sip.communicator.service.gui,
- net.java.sip.communicator.service.gui.event,
- net.java.sip.communicator.service.protocol,
- net.java.sip.communicator.service.protocol.event,
- net.java.sip.communicator.service.protocol.icqconstants,
- net.java.sip.communicator.service.protocol.sip,
- org.jitsi.service.resources, net.java.sip.communicator.service.resources,
- net.java.sip.communicator.util,
- net.java.sip.communicator.plugin.desktoputil,
- net.java.sip.communicator.plugin.sipaccregwizz,
- javax.naming,
- javax.naming.directory,
- javax.xml.parsers,
- org.w3c.dom,
- org.xml.sax,
- org.json.simple,
- javax.swing,
- javax.swing.event,
- javax.swing.table,
- javax.swing.text,
- javax.swing.text.html,
- javax.accessibility,
- javax.swing.plaf,
- javax.swing.plaf.metal,
- javax.swing.plaf.basic,
- javax.imageio,
- javax.swing.filechooser,
- javax.swing.tree,
- javax.swing.undo,
- javax.swing.border,
- org.jivesoftware.smack
diff --git a/src/net/java/sip/communicator/plugin/skinmanager/BundleComparator.java b/src/net/java/sip/communicator/plugin/skinmanager/BundleComparator.java
index b77bbbe..251052a 100644
--- a/src/net/java/sip/communicator/plugin/skinmanager/BundleComparator.java
+++ b/src/net/java/sip/communicator/plugin/skinmanager/BundleComparator.java
@@ -38,8 +38,8 @@ public class BundleComparator
*/
public int compare(Bundle arg0, Bundle arg1)
{
- String n1 = (String) arg0.getHeaders().get(Constants.BUNDLE_NAME);
- String n2 = (String) arg1.getHeaders().get(Constants.BUNDLE_NAME);
+ String n1 = arg0.getHeaders().get(Constants.BUNDLE_NAME);
+ String n2 = arg1.getHeaders().get(Constants.BUNDLE_NAME);
if (n1 == null)
{
diff --git a/src/net/java/sip/communicator/plugin/spellcheck/SpellCheckerConfigDialog.java b/src/net/java/sip/communicator/plugin/spellcheck/SpellCheckerConfigDialog.java
index 35ef36b..6882d36 100644
--- a/src/net/java/sip/communicator/plugin/spellcheck/SpellCheckerConfigDialog.java
+++ b/src/net/java/sip/communicator/plugin/spellcheck/SpellCheckerConfigDialog.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,423 +15,423 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.spellcheck;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.util.List;
-
-import javax.swing.*;
-import javax.swing.event.*;
-import javax.swing.text.*;
-
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.util.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
-
-import org.dts.spell.dictionary.*;
-import org.jitsi.service.resources.*;
-
-/**
- * The spell check dialog that would be opened from the right click menu in the
- * chat window.
- *
- * @author Purvesh Sahoo
- */
-public class SpellCheckerConfigDialog
- extends SIPCommDialog
- implements ActionListener
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- private static final Logger logger = Logger
- .getLogger(SpellCheckerConfigDialog.class);
-
- /**
- * UI Components
- */
- private JTextComponent currentWord;
-
- private JList suggestionList;
-
- private JScrollPane suggestionScroll;
-
- private JButton changeButton;
-
- private JButton nextButton;
-
- private JButton addButton;
-
- private JPanel checkPanel;
-
- private JPanel buttonsPanel;
-
- private JPanel topPanel;
-
- private JPanel suggestionPanel;
-
- private SpellDictionary dict;
-
- private Chat chat;
-
- private final ResourceManagementService resources = Resources
- .getResources();
-
- private String word;
-
- private int index;
-
- private Word clickedWord;
-
- public SpellCheckerConfigDialog(Chat chat, Word clickedWord,
- SpellDictionary dict)
- {
-
- super(false);
-
- this.dict = dict;
- this.chat = chat;
-
- initComponents(clickedWord);
-
- this.setTitle(resources.getI18NString("plugin.spellcheck.TITLE"));
- this.setMinimumSize(new Dimension(450, 320));
- this.setPreferredSize(new Dimension(450, 320));
- this.setResizable(false);
-
- JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
- mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
-
- mainPanel.add(topPanel);
-
- this.getContentPane().add(mainPanel);
-
- this.pack();
- Toolkit toolkit = Toolkit.getDefaultToolkit();
- Dimension screenSize = toolkit.getScreenSize();
-
- int x = (screenSize.width - this.getWidth()) / 2;
- int y = (screenSize.height - this.getHeight()) / 2;
-
- this.setLocation(x, y);
-
- if (!currentWord.getText().equals(" ")
- && this.dict.isCorrect(currentWord.getText()))
- {
- nextButton.doClick();
- }
- }
-
- /**
- * Initialises the UI components.
- */
- private void initComponents(final Word clickWord)
- {
-
- clickedWord =
- (clickWord == null) ? Word.getWord(" ", 1, false) : clickWord;
-
- topPanel = new TransparentPanel(new BorderLayout());
- topPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
- topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
-
- checkPanel = new TransparentPanel(new BorderLayout(10, 10));
- checkPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
- checkPanel.setLayout(new BoxLayout(checkPanel, BoxLayout.X_AXIS));
-
- currentWord = new JTextField(clickedWord.getText());
-
- currentWord.setAlignmentX(LEFT_ALIGNMENT);
- currentWord.setMaximumSize(new Dimension(550, 30));
-
- currentWord.setText(clickedWord.getText());
- currentWord.selectAll();
-
- // JPanel wordPanel = new TransparentPanel(new BorderLayout());
- // wordPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
- // wordPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 5));
- // wordPanel.add(currentWord);
-
- buttonsPanel =
- new TransparentPanel(new FlowLayout(FlowLayout.RIGHT, 0, 10));
- changeButton =
- new JButton(
- resources.getI18NString("plugin.spellcheck.dialog.REPLACE"));
- changeButton.setMnemonic(resources
- .getI18nMnemonic("plugin.spellcheck.dialog.REPLACE"));
-
- changeButton.addActionListener(new ActionListener()
- {
-
- public void actionPerformed(ActionEvent e)
- {
- if (suggestionList.getSelectedValue() != null)
- {
-
- StringBuffer newMessage =
- new StringBuffer(chat.getMessage());
- int endIndex;
-
- if (word != null)
- {
- endIndex = index + currentWord.getText().length();
- newMessage.replace(index, endIndex,
- (String) suggestionList.getSelectedValue());
- word = (String) suggestionList.getSelectedValue();
- }
- else
- {
- endIndex =
- clickedWord.getStart()
- + clickedWord.getText().length();
- newMessage.replace(clickedWord.getStart(), endIndex,
- (String) suggestionList.getSelectedValue());
- }
- currentWord.setText((String) suggestionList
- .getSelectedValue());
- chat.setMessage(newMessage.toString());
-
- }
- }
- });
- changeButton.setEnabled(false);
-
- nextButton =
- new JButton(
- resources.getI18NString("plugin.spellcheck.dialog.FIND"));
- nextButton.setMnemonic(resources
- .getI18nMnemonic("plugin.spellcheck.dialog.FIND"));
-
- nextButton.addActionListener(new ActionListener()
- {
-
- public Word getNextWord()
- {
-
- Word nextWord;
- int wordIndex;
-
- if (word == null)
- {
- if (currentWord.getText().equals(" "))
- {
- String words[] = chat.getMessage().split(" ");
- currentWord.setText(words[0]);
-
- }
-
- wordIndex =
- chat.getMessage().indexOf(currentWord.getText());
- if (dict.isCorrect(currentWord.getText()))
- currentWord.setText("");
- }
- else
- {
- wordIndex = chat.getMessage().indexOf(word, index);
- }
-
- Word presentWord =
- Word.getWord(chat.getMessage(), wordIndex, false);
-
- if (presentWord.getEnd() == chat.getMessage().length())
- {
- nextWord = Word.getWord(chat.getMessage(), 0, false);
-
- }
- else
- {
- nextWord =
- Word.getWord(chat.getMessage(),
- presentWord.getEnd() + 1, false);
- }
-
- index = nextWord.getStart();
- word = nextWord.getText();
-
- return nextWord;
- }
-
- public void actionPerformed(ActionEvent e)
- {
- Word nextWord = getNextWord();
- int breakIndex = nextWord.getStart();
- if(breakIndex == 0)
- breakIndex = nextWord.getEnd() + 1;
-
- if(nextWord.getText().length() == 0)
- {
- breakIndex++;
- nextWord = getNextWord();
- }
-
- while (dict.isCorrect(nextWord.getText())
- && nextWord.getEnd() + 1 != breakIndex)
- {
- nextWord = getNextWord();
-
- }
-
- if (!dict.isCorrect(nextWord.getText()))
- {
- word = nextWord.getText();
- currentWord.setText(nextWord.getText());
-
- String clickedWord = currentWord.getText();
- setSuggestionModel(clickedWord);
- }
-
- }
- });
-
- buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.Y_AXIS));
- buttonsPanel.add(changeButton);
- buttonsPanel.add(nextButton);
-
- checkPanel.add(currentWord, BorderLayout.NORTH);
- checkPanel.add(Box.createHorizontalStrut(10));
- checkPanel.add(buttonsPanel, BorderLayout.EAST);
-
- topPanel.add(checkPanel, BorderLayout.NORTH);
- topPanel.add(Box.createVerticalStrut(10));
-
- DefaultListModel dataModel = new DefaultListModel();
- suggestionList = new JList(dataModel);
-
- suggestionScroll = new JScrollPane(suggestionList);
- suggestionScroll.setAlignmentX(LEFT_ALIGNMENT);
-
- if (!dict.isCorrect(clickedWord.getText()))
- setSuggestionModel(clickedWord.getText());
-
- suggestionList.addListSelectionListener(new ListSelectionListener()
- {
-
- public void valueChanged(ListSelectionEvent e)
- {
-
- if (!e.getValueIsAdjusting())
- {
- changeButton.setEnabled(true);
- }
- }
- });
-
- MouseListener clickListener = new MouseAdapter()
- {
- @Override
- public void mouseClicked(MouseEvent e)
- {
- if (e.getClickCount() == 2)
- {
-
- StringBuffer newMessage =
- new StringBuffer(chat.getMessage());
- int endIndex;
-
- if (word != null)
- {
- endIndex = index + currentWord.getText().length();
- newMessage.replace(index, endIndex,
- (String) suggestionList.getSelectedValue());
- word = (String) suggestionList.getSelectedValue();
- }
- else
- {
- endIndex =
- clickedWord.getStart()
- + clickedWord.getText().length();
- newMessage.replace(clickedWord.getStart(), endIndex,
- (String) suggestionList.getSelectedValue());
- }
- currentWord.setText((String) suggestionList
- .getSelectedValue());
- chat.setMessage(newMessage.toString());
-
- }
- }
- };
-
- suggestionList.addMouseListener(clickListener);
-
- addButton =
- new JButton(resources.getI18NString("plugin.spellcheck.dialog.ADD"));
- addButton.setMnemonic(resources
- .getI18nMnemonic("plugin.spellcheck.dialog.ADD"));
-
- addButton.addActionListener(new ActionListener()
- {
-
- public void actionPerformed(ActionEvent e)
- {
-
- try
- {
- dict.addWord(currentWord.getText());
- chat.promptRepaint();
- }
- catch (SpellDictionaryException exc)
- {
- String msg = "Unable to add word to personal dictionary";
- logger.error(msg, exc);
- }
- }
- });
-
- suggestionPanel = new TransparentPanel(new BorderLayout(10, 10));
- suggestionPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
- suggestionPanel.setLayout(new BoxLayout(suggestionPanel,
- BoxLayout.X_AXIS));
- suggestionPanel.add(suggestionScroll);
- suggestionPanel.add(Box.createHorizontalStrut(10));
- suggestionPanel.add(addButton);
-
- topPanel.add(suggestionPanel, BorderLayout.SOUTH);
-
- }
-
- /**
- * Sets the model for the suggestion list
- *
- * @param clickedWord
- */
- private void setSuggestionModel(String clickedWord)
- {
-
- DefaultListModel dataModel = new DefaultListModel();
- List<String> corrections = this.dict.getSuggestions(clickedWord);
- for (String correction : corrections)
- {
- dataModel.addElement(correction);
- }
-
- suggestionList.setModel(dataModel);
- }
-
- /**
- * Returns the selected correction value
- *
- * @return selected value from suggestion list
- */
- public Object getCorrection()
- {
-
- return suggestionList.getSelectedValue();
- }
-
- public void actionPerformed(ActionEvent e)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- protected void close(boolean escaped)
- {
- // TODO Auto-generated method stub
-
- }
-
-}
+package net.java.sip.communicator.plugin.spellcheck;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.List;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.*;
+
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.util.*;
+import net.java.sip.communicator.plugin.desktoputil.*;
+
+import org.dts.spell.dictionary.*;
+import org.jitsi.service.resources.*;
+
+/**
+ * The spell check dialog that would be opened from the right click menu in the
+ * chat window.
+ *
+ * @author Purvesh Sahoo
+ */
+public class SpellCheckerConfigDialog
+ extends SIPCommDialog
+ implements ActionListener
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ private static final Logger logger = Logger
+ .getLogger(SpellCheckerConfigDialog.class);
+
+ /**
+ * UI Components
+ */
+ private JTextComponent currentWord;
+
+ private JList suggestionList;
+
+ private JScrollPane suggestionScroll;
+
+ private JButton changeButton;
+
+ private JButton nextButton;
+
+ private JButton addButton;
+
+ private JPanel checkPanel;
+
+ private JPanel buttonsPanel;
+
+ private JPanel topPanel;
+
+ private JPanel suggestionPanel;
+
+ private SpellDictionary dict;
+
+ private Chat chat;
+
+ private final ResourceManagementService resources = Resources
+ .getResources();
+
+ private String word;
+
+ private int index;
+
+ private Word clickedWord;
+
+ public SpellCheckerConfigDialog(Chat chat, Word clickedWord,
+ SpellDictionary dict)
+ {
+
+ super(false);
+
+ this.dict = dict;
+ this.chat = chat;
+
+ initComponents(clickedWord);
+
+ this.setTitle(resources.getI18NString("plugin.spellcheck.TITLE"));
+ this.setMinimumSize(new Dimension(450, 320));
+ this.setPreferredSize(new Dimension(450, 320));
+ this.setResizable(false);
+
+ JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
+ mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+
+ mainPanel.add(topPanel);
+
+ this.getContentPane().add(mainPanel);
+
+ this.pack();
+ Toolkit toolkit = Toolkit.getDefaultToolkit();
+ Dimension screenSize = toolkit.getScreenSize();
+
+ int x = (screenSize.width - this.getWidth()) / 2;
+ int y = (screenSize.height - this.getHeight()) / 2;
+
+ this.setLocation(x, y);
+
+ if (!currentWord.getText().equals(" ")
+ && this.dict.isCorrect(currentWord.getText()))
+ {
+ nextButton.doClick();
+ }
+ }
+
+ /**
+ * Initialises the UI components.
+ */
+ private void initComponents(final Word clickWord)
+ {
+
+ clickedWord =
+ (clickWord == null) ? Word.getWord(" ", 1, false) : clickWord;
+
+ topPanel = new TransparentPanel(new BorderLayout());
+ topPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
+ topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
+
+ checkPanel = new TransparentPanel(new BorderLayout(10, 10));
+ checkPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
+ checkPanel.setLayout(new BoxLayout(checkPanel, BoxLayout.X_AXIS));
+
+ currentWord = new JTextField(clickedWord.getText());
+
+ currentWord.setAlignmentX(LEFT_ALIGNMENT);
+ currentWord.setMaximumSize(new Dimension(550, 30));
+
+ currentWord.setText(clickedWord.getText());
+ currentWord.selectAll();
+
+ // JPanel wordPanel = new TransparentPanel(new BorderLayout());
+ // wordPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
+ // wordPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 5));
+ // wordPanel.add(currentWord);
+
+ buttonsPanel =
+ new TransparentPanel(new FlowLayout(FlowLayout.RIGHT, 0, 10));
+ changeButton =
+ new JButton(
+ resources.getI18NString("plugin.spellcheck.dialog.REPLACE"));
+ changeButton.setMnemonic(resources
+ .getI18nMnemonic("plugin.spellcheck.dialog.REPLACE"));
+
+ changeButton.addActionListener(new ActionListener()
+ {
+
+ public void actionPerformed(ActionEvent e)
+ {
+ if (suggestionList.getSelectedValue() != null)
+ {
+
+ StringBuffer newMessage =
+ new StringBuffer(chat.getMessage());
+ int endIndex;
+
+ if (word != null)
+ {
+ endIndex = index + currentWord.getText().length();
+ newMessage.replace(index, endIndex,
+ (String) suggestionList.getSelectedValue());
+ word = (String) suggestionList.getSelectedValue();
+ }
+ else
+ {
+ endIndex =
+ clickedWord.getStart()
+ + clickedWord.getText().length();
+ newMessage.replace(clickedWord.getStart(), endIndex,
+ (String) suggestionList.getSelectedValue());
+ }
+ currentWord.setText((String) suggestionList
+ .getSelectedValue());
+ chat.setMessage(newMessage.toString());
+
+ }
+ }
+ });
+ changeButton.setEnabled(false);
+
+ nextButton =
+ new JButton(
+ resources.getI18NString("plugin.spellcheck.dialog.FIND"));
+ nextButton.setMnemonic(resources
+ .getI18nMnemonic("plugin.spellcheck.dialog.FIND"));
+
+ nextButton.addActionListener(new ActionListener()
+ {
+
+ public Word getNextWord()
+ {
+
+ Word nextWord;
+ int wordIndex;
+
+ if (word == null)
+ {
+ if (currentWord.getText().equals(" "))
+ {
+ String words[] = chat.getMessage().split(" ");
+ currentWord.setText(words[0]);
+
+ }
+
+ wordIndex =
+ chat.getMessage().indexOf(currentWord.getText());
+ if (dict.isCorrect(currentWord.getText()))
+ currentWord.setText("");
+ }
+ else
+ {
+ wordIndex = chat.getMessage().indexOf(word, index);
+ }
+
+ Word presentWord =
+ Word.getWord(chat.getMessage(), wordIndex, false);
+
+ if (presentWord.getEnd() == chat.getMessage().length())
+ {
+ nextWord = Word.getWord(chat.getMessage(), 0, false);
+
+ }
+ else
+ {
+ nextWord =
+ Word.getWord(chat.getMessage(),
+ presentWord.getEnd() + 1, false);
+ }
+
+ index = nextWord.getStart();
+ word = nextWord.getText();
+
+ return nextWord;
+ }
+
+ public void actionPerformed(ActionEvent e)
+ {
+ Word nextWord = getNextWord();
+ int breakIndex = nextWord.getStart();
+ if(breakIndex == 0)
+ breakIndex = nextWord.getEnd() + 1;
+
+ if(nextWord.getText().length() == 0)
+ {
+ breakIndex++;
+ nextWord = getNextWord();
+ }
+
+ while (dict.isCorrect(nextWord.getText())
+ && nextWord.getEnd() + 1 != breakIndex)
+ {
+ nextWord = getNextWord();
+
+ }
+
+ if (!dict.isCorrect(nextWord.getText()))
+ {
+ word = nextWord.getText();
+ currentWord.setText(nextWord.getText());
+
+ String clickedWord = currentWord.getText();
+ setSuggestionModel(clickedWord);
+ }
+
+ }
+ });
+
+ buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.Y_AXIS));
+ buttonsPanel.add(changeButton);
+ buttonsPanel.add(nextButton);
+
+ checkPanel.add(currentWord, BorderLayout.NORTH);
+ checkPanel.add(Box.createHorizontalStrut(10));
+ checkPanel.add(buttonsPanel, BorderLayout.EAST);
+
+ topPanel.add(checkPanel, BorderLayout.NORTH);
+ topPanel.add(Box.createVerticalStrut(10));
+
+ DefaultListModel dataModel = new DefaultListModel();
+ suggestionList = new JList(dataModel);
+
+ suggestionScroll = new JScrollPane(suggestionList);
+ suggestionScroll.setAlignmentX(LEFT_ALIGNMENT);
+
+ if (!dict.isCorrect(clickedWord.getText()))
+ setSuggestionModel(clickedWord.getText());
+
+ suggestionList.addListSelectionListener(new ListSelectionListener()
+ {
+
+ public void valueChanged(ListSelectionEvent e)
+ {
+
+ if (!e.getValueIsAdjusting())
+ {
+ changeButton.setEnabled(true);
+ }
+ }
+ });
+
+ MouseListener clickListener = new MouseAdapter()
+ {
+ @Override
+ public void mouseClicked(MouseEvent e)
+ {
+ if (e.getClickCount() == 2)
+ {
+
+ StringBuffer newMessage =
+ new StringBuffer(chat.getMessage());
+ int endIndex;
+
+ if (word != null)
+ {
+ endIndex = index + currentWord.getText().length();
+ newMessage.replace(index, endIndex,
+ (String) suggestionList.getSelectedValue());
+ word = (String) suggestionList.getSelectedValue();
+ }
+ else
+ {
+ endIndex =
+ clickedWord.getStart()
+ + clickedWord.getText().length();
+ newMessage.replace(clickedWord.getStart(), endIndex,
+ (String) suggestionList.getSelectedValue());
+ }
+ currentWord.setText((String) suggestionList
+ .getSelectedValue());
+ chat.setMessage(newMessage.toString());
+
+ }
+ }
+ };
+
+ suggestionList.addMouseListener(clickListener);
+
+ addButton =
+ new JButton(resources.getI18NString("plugin.spellcheck.dialog.ADD"));
+ addButton.setMnemonic(resources
+ .getI18nMnemonic("plugin.spellcheck.dialog.ADD"));
+
+ addButton.addActionListener(new ActionListener()
+ {
+
+ public void actionPerformed(ActionEvent e)
+ {
+
+ try
+ {
+ dict.addWord(currentWord.getText());
+ chat.promptRepaint();
+ }
+ catch (SpellDictionaryException exc)
+ {
+ String msg = "Unable to add word to personal dictionary";
+ logger.error(msg, exc);
+ }
+ }
+ });
+
+ suggestionPanel = new TransparentPanel(new BorderLayout(10, 10));
+ suggestionPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
+ suggestionPanel.setLayout(new BoxLayout(suggestionPanel,
+ BoxLayout.X_AXIS));
+ suggestionPanel.add(suggestionScroll);
+ suggestionPanel.add(Box.createHorizontalStrut(10));
+ suggestionPanel.add(addButton);
+
+ topPanel.add(suggestionPanel, BorderLayout.SOUTH);
+
+ }
+
+ /**
+ * Sets the model for the suggestion list
+ *
+ * @param clickedWord
+ */
+ private void setSuggestionModel(String clickedWord)
+ {
+
+ DefaultListModel dataModel = new DefaultListModel();
+ List<String> corrections = this.dict.getSuggestions(clickedWord);
+ for (String correction : corrections)
+ {
+ dataModel.addElement(correction);
+ }
+
+ suggestionList.setModel(dataModel);
+ }
+
+ /**
+ * Returns the selected correction value
+ *
+ * @return selected value from suggestion list
+ */
+ public Object getCorrection()
+ {
+
+ return suggestionList.getSelectedValue();
+ }
+
+ public void actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ protected void close(boolean escaped)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/src/net/java/sip/communicator/plugin/sshaccregwizz/FirstWizardPage.java b/src/net/java/sip/communicator/plugin/sshaccregwizz/FirstWizardPage.java
deleted file mode 100644
index f553815..0000000
--- a/src/net/java/sip/communicator/plugin/sshaccregwizz/FirstWizardPage.java
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.sshaccregwizz;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.io.*;
-
-import javax.swing.*;
-import javax.swing.event.*;
-
-import net.java.sip.communicator.impl.protocol.ssh.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
-
-/**
- * The <tt>FirstWizardPage</tt> is the page, where user could enter the user ID
- * and the password of the account.
- *
- * @author Shobhit Jindal
- */
-public class FirstWizardPage
- extends TransparentPanel
- implements WizardPage, DocumentListener
-{
- private static final long serialVersionUID = 8576006544813706541L;
-
- public static final String FIRST_PAGE_IDENTIFIER = "FirstPageIdentifier";
-
- private JPanel accountPanel = new TransparentPanel(new BorderLayout(10, 10));
-
- private JPanel labelsPanel = new TransparentPanel();
-
- private JPanel valuesPanel = new TransparentPanel();
-
- private JLabel accountID
- = new JLabel(Resources.getString("plugin.sshaccregwizz.USERNAME"));
-
- private JLabel identityFile
- = new JLabel(Resources.getString("plugin.sshaccregwizz.IDENTITY_FILE"));
-
- private JLabel knownHostsFile
- = new JLabel(Resources.getString("plugin.sshaccregwizz.KNOWN_HOSTS"));
-
- private JPanel emptyPanel1 = new TransparentPanel();
-
- private JPanel emptyPanel2 = new TransparentPanel();
-
- private JPanel emptyPanel3 = new TransparentPanel();
-
- private JPanel emptyPanel4 = new TransparentPanel();
-
- private JPanel emptyPanel5 = new TransparentPanel();
-
- private JPanel emptyPanel6 = new TransparentPanel();
-
- private JPanel emptyPanel7 = new TransparentPanel();
-
- private JPanel emptyPanel8 = new TransparentPanel();
-
- private JPanel emptyPanel9 = new TransparentPanel();
-
- private JTextField userIDField = new TrimTextField();
-
- private JTextField identityFileField = new JTextField(
- Resources.getString("plugin.sshaccregwizz.OPTIONAL"));
-
- private JButton identityFileButton = new JButton(
- Resources.getString("service.gui.BROWSE"));
-
- private SipCommFileChooser identityFileChooser;
-
- private JPanel identityFilePanel = new TransparentPanel();
-
- private JTextField knownHostsFileField = new JTextField(
- Resources.getString("plugin.sshaccregwizz.KNOWN_HOSTS"));
-
- private JButton knownHostsFileButton = new JButton(
- Resources.getString("service.gui.BROWSE"));
-
- private SipCommFileChooser knownHostsFileChooser;
-
- private JPanel knownHostsFilePanel = new TransparentPanel();
-
- private JPanel mainPanel = new TransparentPanel();
-
- private Object nextPageIdentifier = WizardPage.SUMMARY_PAGE_IDENTIFIER;
-
- private SSHAccountRegistration registration = null;
-
- private WizardContainer wizardContainer;
-
- private boolean isCommitted = false;
-
- /**
- * Creates an instance of <tt>FirstWizardPage</tt>.
- * @param registration the <tt>SSHAccountRegistration</tt>, where
- * all data through the wizard are stored
- * @param wizardContainer the wizardContainer, where this page will
- * be added
- */
- public FirstWizardPage(SSHAccountRegistration registration,
- WizardContainer wizardContainer)
- {
-
- super(new BorderLayout());
-
- this.wizardContainer = wizardContainer;
-
- this.registration = registration;
-
- this.setPreferredSize(new Dimension(300, 150));
-
- mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
-
- identityFileField.setEditable(false);
-
- knownHostsFileField.setEditable(false);
-
- //identityFileChooser.setFileHidingEnabled(false);
-
- //knownHostsFileChooser.setFileHidingEnabled(false);
-
- this.init();
-
- this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
-
- this.labelsPanel.setLayout(new BoxLayout(labelsPanel,
- BoxLayout.Y_AXIS));
-
- this.valuesPanel.setLayout(new BoxLayout(valuesPanel,
- BoxLayout.Y_AXIS));
-
- this.identityFilePanel.setLayout(new BoxLayout(identityFilePanel,
- BoxLayout.X_AXIS));
-
- this.knownHostsFilePanel.setLayout(new BoxLayout(knownHostsFilePanel,
- BoxLayout.X_AXIS));
- }
-
- /**
- * Initializes all panels, buttons, etc.
- */
- private void init()
- {
- this.mainPanel.setOpaque(false);
- this.labelsPanel.setOpaque(false);
- this.valuesPanel.setOpaque(false);
- this.accountPanel.setOpaque(false);
- this.identityFilePanel.setOpaque(false);
- this.knownHostsFilePanel.setOpaque(false);
- this.emptyPanel1.setOpaque(false);
- this.emptyPanel2.setOpaque(false);
- this.emptyPanel3.setOpaque(false);
- this.emptyPanel4.setOpaque(false);
- this.emptyPanel5.setOpaque(false);
- this.emptyPanel6.setOpaque(false);
- this.emptyPanel7.setOpaque(false);
- this.emptyPanel8.setOpaque(false);
- this.emptyPanel9.setOpaque(false);
-
- this.userIDField.getDocument().addDocumentListener(this);
-
- /*
- * Following empty panels cover the space needed between key labels
- * WRT Height 2 key lables = 1 text field
- */
- this.emptyPanel1.setMaximumSize(new Dimension(40, 35));
- this.emptyPanel2.setMaximumSize(new Dimension(40, 35));
- this.emptyPanel3.setMaximumSize(new Dimension(40, 35));
- this.emptyPanel4.setMaximumSize(new Dimension(40, 35));
- this.emptyPanel5.setMaximumSize(new Dimension(40, 35));
- this.emptyPanel6.setMaximumSize(new Dimension(40, 35));
- this.emptyPanel7.setMaximumSize(new Dimension(40, 35));
-
- identityFilePanel.add(identityFileField);
- identityFilePanel.add(identityFileButton);
-
- knownHostsFilePanel.add(knownHostsFileField);
- knownHostsFilePanel.add(knownHostsFileButton);
-
- labelsPanel.add(emptyPanel1);
- labelsPanel.add(accountID);
- labelsPanel.add(emptyPanel2);
- labelsPanel.add(emptyPanel3);
- labelsPanel.add(identityFile);
- labelsPanel.add(emptyPanel4);
- labelsPanel.add(emptyPanel5);
- labelsPanel.add(knownHostsFile);
- labelsPanel.add(emptyPanel6);
-
- valuesPanel.add(userIDField);
- valuesPanel.add(emptyPanel7);
- valuesPanel.add(identityFilePanel);
- valuesPanel.add(emptyPanel8);
- valuesPanel.add(knownHostsFilePanel);
- labelsPanel.add(emptyPanel9);
-
- accountPanel.add(labelsPanel, BorderLayout.WEST);
- accountPanel.add(valuesPanel, BorderLayout.CENTER);
-
- identityFileButton.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent event)
- {
- identityFileChooser = GenericFileDialog.create(
- null, "Select Identify File",
- SipCommFileChooser.LOAD_FILE_OPERATION);
- File f = identityFileChooser.getFileFromDialog();
-
- if(f != null)
- identityFileField.setText(f.getAbsolutePath());
- }
- }
- );
-
- knownHostsFileButton.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent event)
- {
- knownHostsFileChooser = GenericFileDialog.create(
- null, "Select SSH Known Hosts File",
- SipCommFileChooser.LOAD_FILE_OPERATION);
- File f = knownHostsFileChooser.getFileFromDialog();
-
- if(f != null)
- knownHostsFileField.setText(f.getAbsolutePath());
- }
- }
- );
-
- accountPanel.setBorder(BorderFactory
- .createTitledBorder(Resources.getString(
- "plugin.sshaccregwizz.ACCOUNT_DETAILS")));
-
- this.add(accountPanel, BorderLayout.NORTH);
- }
-
- /**
- * Fills the Account ID, Identity File and Known Hosts File fields in this
- * panel with the data coming from the given protocolProvider.
- *
- * @param protocolProvider The <tt>ProtocolProviderService</tt> to load the
- * data from.
- */
- public void loadAccount(ProtocolProviderService protocolProvider)
- {
- if (!(protocolProvider instanceof ProtocolProviderServiceSSHImpl))
- throw new ClassCastException("protocolProvider");
-
- AccountID accountID = protocolProvider.getAccountID();
-
- String identityFile =
- accountID
- .getAccountPropertyString(ProtocolProviderFactorySSH.IDENTITY_FILE);
-
- String knownHostsFile =
- accountID
- .getAccountPropertyString(ProtocolProviderFactorySSH.KNOWN_HOSTS_FILE);
-
- this.userIDField.setText(accountID.getUserID());
-
- this.identityFileField.setText(identityFile);
-
- this.knownHostsFileField.setText(knownHostsFile);
- }
-
- /**
- * Implements the <code>WizardPage.getIdentifier</code> to return
- * this page identifier.
- *
- * @return the Identifier of the first page in this wizard.
- */
- public Object getIdentifier()
- {
- return FIRST_PAGE_IDENTIFIER;
- }
-
- /**
- * Implements the <code>WizardPage.getNextPageIdentifier</code> to return
- * the next page identifier - the summary page.
- *
- * @return the identifier of the page following this one.
- */
- public Object getNextPageIdentifier()
- {
- return nextPageIdentifier;
- }
-
- /**
- * Implements the <code>WizardPage.getBackPageIdentifier</code> to return
- * the back identifier. In this case it's null because this is the first
- * wizard page.
- *
- * @return the identifier of the previous wizard page
- */
- public Object getBackPageIdentifier()
- {
- return null;
- }
-
- /**
- * Implements the <code>WizardPage.getWizardForm</code> to return
- * this panel.
- *
- * @return the component to be displayed in this wizard page.
- */
- public Object getWizardForm()
- {
- return this;
- }
-
- /**
- * Before this page is displayed enables or disables the "Next" wizard
- * button according to whether the UserID field is empty.
- */
- public void pageShowing()
- {
- this.setNextButtonAccordingToUserID();
- }
-
- /**
- * Saves the user input when the "Next" wizard buttons is clicked.
- */
- public void commitPage()
- {
- String userID = userIDField.getText();
-
- if(userID == null || userID.trim().length() == 0)
- throw new IllegalStateException("No user ID provided.");
-
- registration.setUserID(userID);
- registration.setIdentityFile(identityFileField.getText());
- registration.setKnownHostsFile(knownHostsFileField.getText());
-
- nextPageIdentifier = SUMMARY_PAGE_IDENTIFIER;
-
- isCommitted = true;
- }
-
- /**
- * Enables or disables the "Next" wizard button according to whether the
- * User ID field is empty.
- */
- private void setNextButtonAccordingToUserID()
- {
- if (userIDField.getText() == null || userIDField.getText()
- .equals(""))
- {
- wizardContainer.setNextFinishButtonEnabled(false);
- }
- else
- {
- wizardContainer.setNextFinishButtonEnabled(true);
- }
- }
-
- /**
- * Handles the <tt>DocumentEvent</tt> triggered when user types in the
- * User ID field. Enables or disables the "Next" wizard button according to
- * whether the User ID field is empty.
- *
- * @param event the event containing the update.
- */
- public void insertUpdate(DocumentEvent event)
- {
- this.setNextButtonAccordingToUserID();
- }
-
- /**
- * Handles the <tt>DocumentEvent</tt> triggered when user deletes letters
- * from the UserID field. Enables or disables the "Next" wizard button
- * according to whether the UserID field is empty.
- *
- * @param event the event containing the update.
- */
- public void removeUpdate(DocumentEvent event)
- {
- this.setNextButtonAccordingToUserID();
- }
-
- public void changedUpdate(DocumentEvent event)
- {
- }
-
- public void pageHiding()
- {
- }
-
- public void pageShown()
- {
- }
-
- public void pageBack()
- {
- }
-
- public Object getSimpleForm()
- {
- return accountPanel;
- }
-
- public boolean isCommitted()
- {
- return isCommitted;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/sshaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/sshaccregwizz/Resources.java
deleted file mode 100644
index 3c2f462..0000000
--- a/src/net/java/sip/communicator/plugin/sshaccregwizz/Resources.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.sshaccregwizz;
-
-import net.java.sip.communicator.service.resources.*;
-
-import org.jitsi.service.resources.*;
-
-/**
- * The <tt>Resources</tt> class manages the access to the internationalization
- * properties files and the image resources used in this plugin.
- *
- * @author Shobhit Jindal
- */
-public class Resources
-{
- private static ResourceManagementService resourcesService;
-
- public static ImageID SSH_LOGO
- = new ImageID("service.protocol.ssh.SSH_16x16");
-
- public static ImageID PAGE_IMAGE
- = new ImageID("service.protocol.ssh.SSH_64x64");
-
- /**
- * Returns an internationalized string corresponding to the given key.
- * @param key The key of the string.
- * @return An internationalized string corresponding to the given key.
- */
- public static String getString(String key)
- {
- return getResources().getI18NString(key);
- }
-
- /**
- * Loads an image from a given image identifier.
- *
- * @param imageID The identifier of the image.
- * @return The image for the given identifier.
- */
- public static byte[] getImage(ImageID imageID)
- {
- return getResources().getImageInBytes(imageID.getId());
- }
-
- /**
- * Returns the <tt>ResourceManagementService</tt>.
- *
- * @return the <tt>ResourceManagementService</tt>.
- */
- public static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- resourcesService =
- ResourceManagementServiceUtils
- .getService(SSHAccRegWizzActivator.bundleContext);
- return resourcesService;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/sshaccregwizz/SSHAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/sshaccregwizz/SSHAccRegWizzActivator.java
deleted file mode 100644
index 459fb39..0000000
--- a/src/net/java/sip/communicator/plugin/sshaccregwizz/SSHAccRegWizzActivator.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.sshaccregwizz;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * Registers the <tt>SSHAccountRegistrationWizard</tt> in the UI Service.
- *
- * @author Shobhit Jindal
- */
-public class SSHAccRegWizzActivator
- implements BundleActivator
-{
- private static final Logger logger =
- Logger.getLogger(SSHAccRegWizzActivator.class);
-
- /**
- * A currently valid bundle context.
- */
- public static BundleContext bundleContext;
-
- private static WizardContainer wizardContainer;
-
- private static SSHAccountRegistrationWizard sshWizard;
-
- private static UIService uiService;
-
- /**
- * Starts this bundle.
- * @param bc the currently valid <tt>BundleContext</tt>.
- */
- public void start(BundleContext bc)
- {
- if (logger.isInfoEnabled())
- logger.info("Loading ssh account wizard.");
-
- bundleContext = bc;
-
- ServiceReference uiServiceRef = bundleContext
- .getServiceReference(UIService.class.getName());
-
- uiService = (UIService) bundleContext
- .getService(uiServiceRef);
-
- wizardContainer = uiService.getAccountRegWizardContainer();
-
- sshWizard
- = new SSHAccountRegistrationWizard(wizardContainer);
-
- Hashtable<String, String> containerFilter
- = new Hashtable<String, String>();
-
- containerFilter.put(
- ProtocolProviderFactory.PROTOCOL,
- ProtocolNames.SSH);
-
- bundleContext.registerService(
- AccountRegistrationWizard.class.getName(),
- sshWizard,
- containerFilter);
-
- if (logger.isInfoEnabled())
- logger.info("SSH account registration wizard [STARTED].");
- }
-
- /**
- * Called when this bundle is stopped so the Framework can perform the
- * bundle-specific activities necessary to stop the bundle.
- *
- * @param bundleContext The execution context of the bundle being stopped.
- */
- public void stop(BundleContext bundleContext) throws Exception
- {
- }
-
- /**
- * Returns the <tt>ProtocolProviderFactory</tt> for the SSH protocol.
- * @return the <tt>ProtocolProviderFactory</tt> for the SSH protocol
- */
- public static ProtocolProviderFactory getSSHProtocolProviderFactory()
- {
- ServiceReference[] serRefs = null;
- String osgiFilter = "(" + ProtocolProviderFactory.PROTOCOL + "=SSH)";
-
- try
- {
- serRefs
- = bundleContext.getServiceReferences(
- ProtocolProviderFactory.class.getName(),
- osgiFilter);
- }
- catch (InvalidSyntaxException ex)
- {
- logger.error(ex);
- }
-
- return
- (serRefs == null)
- ? null
- : (ProtocolProviderFactory)
- bundleContext.getService(serRefs[0]);
- }
-
- /**
- * Returns the bundleContext that we received when we were started.
- *
- * @return a currently valid instance of a bundleContext.
- */
- public BundleContext getBundleContext()
- {
- return bundleContext;
- }
-
- /**
- * Returns the <tt>UIService</tt>.
- *
- * @return the <tt>UIService</tt>
- */
- public static UIService getUIService()
- {
- return uiService;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/sshaccregwizz/SSHAccountRegistration.java b/src/net/java/sip/communicator/plugin/sshaccregwizz/SSHAccountRegistration.java
deleted file mode 100644
index 023ffee..0000000
--- a/src/net/java/sip/communicator/plugin/sshaccregwizz/SSHAccountRegistration.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.java.sip.communicator.plugin.sshaccregwizz;
-
-/**
- * The <tt>SSHAccountRegistration</tt> is used to store all user input data
- * through the <tt>SSHAccountRegistrationWizard</tt>.
- *
- * @author Shobhit Jindal
- */
-public class SSHAccountRegistration
-{
- private String accountID;
-
- /**
- * Stored public keys[SSH] of remote server
- */
- private String knownHostsFile;
-
- /**
- * Identity file is a private[default] key of the user which is one
- * of the methods of authentication
- */
- private String identityFile;
-
- /**
- * Returns the Account ID of the ssh registration account.
- * @return accountID
- */
- public String getAccountID()
- {
- return accountID;
- }
-
- /**
- * Sets the Account ID of the ssh registration account.
- *
- * @param accountID the accountID of the ssh registration account.
- */
- public void setUserID(String accountID)
- {
- this.accountID = accountID;
- }
-
- /**
- * Returns the Known Hosts of the ssh registration account.
- *
- * @return knownHostsFile
- */
- public String getKnownHostsFile()
- {
- return knownHostsFile;
- }
-
- /**
- * Sets the Known Hosts of the ssh registration account.
- *
- * @param knownHostsFile
- */
- public void setKnownHostsFile(String knownHostsFile)
- {
- this.knownHostsFile = knownHostsFile;
- }
-
- /**
- * Returns the Identity File of the ssh registration account.
- *
- * @return identityFile
- */
- public String getIdentityFile()
- {
- return identityFile;
- }
-
- /**
- * Sets the Machine Port of the ssh registration account.
- *
- * @param machinePort
- */
- public void setIdentityFile(String machinePort)
- {
- this.identityFile = machinePort;
- }
-}
-
diff --git a/src/net/java/sip/communicator/plugin/sshaccregwizz/SSHAccountRegistrationWizard.java b/src/net/java/sip/communicator/plugin/sshaccregwizz/SSHAccountRegistrationWizard.java
deleted file mode 100644
index 77c398b..0000000
--- a/src/net/java/sip/communicator/plugin/sshaccregwizz/SSHAccountRegistrationWizard.java
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.java.sip.communicator.plugin.sshaccregwizz;
-
-import java.awt.*;
-import java.util.*;
-
-import net.java.sip.communicator.impl.protocol.ssh.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * The <tt>SSHAccountRegistrationWizard</tt> is an implementation of the
- * <tt>AccountRegistrationWizard</tt> for the SSH protocol. It allows
- * the user to create and configure a new SSH account.
- *
- * @author Shobhit Jindal
- */
-public class SSHAccountRegistrationWizard
- extends DesktopAccountRegistrationWizard
-{
- private final Logger logger
- = Logger.getLogger(SSHAccountRegistrationWizard.class);
-
- /**
- * The first page of the ssh account registration wizard.
- */
- private FirstWizardPage firstWizardPage;
-
- /**
- * The object that we use to store details on an account that we will be
- * creating.
- */
- private SSHAccountRegistration registration
- = new SSHAccountRegistration();
-
- private ProtocolProviderService protocolProvider;
-
- /**
- * Creates an instance of <tt>SSHAccountRegistrationWizard</tt>.
- * @param wizardContainer the wizard container, where this wizard
- * is added
- */
- public SSHAccountRegistrationWizard(WizardContainer wizardContainer)
- {
- setWizardContainer(wizardContainer);
-
- wizardContainer.setFinishButtonText(
- Resources.getString("service.gui.SIGN_IN"));
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getIcon</code> method.
- * Returns the icon to be used for this wizard.
- * @return byte[]
- */
- @Override
- public byte[] getIcon()
- {
- return Resources.getImage(Resources.SSH_LOGO);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getPageImage</code>
- * method.
- * Returns the image used to decorate the wizard page
- *
- * @return byte[] the image used to decorate the wizard page
- */
- @Override
- public byte[] getPageImage()
- {
- return Resources.getImage(Resources.PAGE_IMAGE);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getProtocolName</code>
- * method. Returns the protocol name for this wizard.
- * @return String
- */
- @Override
- public String getProtocolName()
- {
- return Resources.getString("plugin.sshaccregwizz.PROTOCOL_NAME");
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getProtocolDescription
- * </code> method. Returns the description of the protocol for this wizard.
- * @return String
- */
- @Override
- public String getProtocolDescription()
- {
- return Resources.getString("plugin.sshaccregwizz.PROTOCOL_DESCRIPTION");
- }
-
- /**
- * Returns the set of pages contained in this wizard.
- * @return Iterator
- */
- @Override
- public Iterator<WizardPage> getPages()
- {
- java.util.List<WizardPage> pages = new ArrayList<WizardPage>();
- firstWizardPage
- = new FirstWizardPage(registration, getWizardContainer());
-
- pages.add(firstWizardPage);
-
- return pages.iterator();
- }
-
- /**
- * Returns the set of data that user has entered through this wizard.
- * @return Iterator
- */
- @Override
- public Iterator<Map.Entry<String, String>> getSummary() {
- Hashtable<String, String> summaryTable
- = new Hashtable<String, String>();
-
- /*
- * Hashtable arranges the entries alphabetically so the order
- * of appearance is
- * - Computer Name / IP
- * - Port
- * - User ID
- */
- summaryTable.put("Account ID", registration.getAccountID());
- summaryTable.put("Known Hosts", registration.getKnownHostsFile());
- summaryTable.put("Identity", registration.getIdentityFile());
-
- return summaryTable.entrySet().iterator();
- }
-
- /**
- * Defines the operations that will be executed when the user clicks on
- * the wizard "Signin" button.
- * @return the created <tt>ProtocolProviderService</tt> corresponding to the
- * new account
- * @throws OperationFailedException if the operation didn't succeed
- */
- @Override
- public ProtocolProviderService signin()
- throws OperationFailedException
- {
- firstWizardPage.commitPage();
-
- return signin(registration.getAccountID(), null);
- }
-
- /**
- * Defines the operations that will be executed when the user clicks on
- * the wizard "Signin" button.
- *
- * @param userName the user name to sign in with
- * @param password the password to sign in with
- * @return the created <tt>ProtocolProviderService</tt> corresponding to the
- * new account
- * @throws OperationFailedException if the operation didn't succeed
- */
- @Override
- public ProtocolProviderService signin(String userName, String password)
- throws OperationFailedException
- {
- ProtocolProviderFactory factory
- = SSHAccRegWizzActivator.getSSHProtocolProviderFactory();
-
- return this.installAccount( factory,
- userName);
- }
-
- /**
- * Creates an account for the given Account ID, Identity File and Known
- * Hosts File
- *
- * @param providerFactory the ProtocolProviderFactory which will create
- * the account
- * @param user the user identifier
- * @return the <tt>ProtocolProviderService</tt> for the new account.
- */
- public ProtocolProviderService installAccount(
- ProtocolProviderFactory providerFactory,
- String user)
- throws OperationFailedException
- {
- Hashtable<String, String> accountProperties
- = new Hashtable<String, String>();
-
- accountProperties.put(ProtocolProviderFactory.ACCOUNT_ICON_PATH,
- "resources/images/protocol/ssh/ssh32x32.png");
-
- accountProperties.put(
- ProtocolProviderFactory.NO_PASSWORD_REQUIRED,
- new Boolean(true).toString());
-
- accountProperties.put(ProtocolProviderFactorySSHImpl.IDENTITY_FILE,
- registration.getIdentityFile());
-
- accountProperties.put(ProtocolProviderFactorySSHImpl.KNOWN_HOSTS_FILE,
- String.valueOf(registration.getKnownHostsFile()));
-
- try
- {
- AccountID accountID = providerFactory.installAccount(
- user, accountProperties);
-
- ServiceReference serRef = providerFactory
- .getProviderForAccount(accountID);
-
- protocolProvider = (ProtocolProviderService)
- SSHAccRegWizzActivator.bundleContext
- .getService(serRef);
- }
- catch (IllegalStateException exc)
- {
- logger.warn(exc.getMessage());
-
- throw new OperationFailedException(
- "Account already exists.",
- OperationFailedException.IDENTIFICATION_CONFLICT);
- }
- catch (Exception exc)
- {
- logger.warn(exc.getMessage());
-
- throw new OperationFailedException(
- "Failed to add account",
- OperationFailedException.GENERAL_ERROR);
- }
-
- return protocolProvider;
- }
-
- /**
- * Fills the UserID and Password fields in this panel with the data comming
- * from the given protocolProvider.
- * @param protocolProvider The <tt>ProtocolProviderService</tt> to load the
- * data from.
- */
- @Override
- public void loadAccount(ProtocolProviderService protocolProvider)
- {
- this.protocolProvider = protocolProvider;
-
- this.firstWizardPage.loadAccount(protocolProvider);
-
- setModification(true);
- }
-
- /**
- * Returns the size of this wizard.
- * @return the size of this wizard
- */
- @Override
- public Dimension getSize()
- {
- return new Dimension(600, 500);
- }
-
- /**
- * Returns the identifier of the first account registration wizard page.
- * This method is meant to be used by the wizard container to determine,
- * which is the first page to show to the user.
- *
- * @return the identifier of the first account registration wizard page
- */
- @Override
- public Object getFirstPageIdentifier()
- {
- return firstWizardPage.getIdentifier();
- }
-
- @Override
- public Object getLastPageIdentifier()
- {
- return firstWizardPage.getIdentifier();
- }
-
- /**
- * Returns an example string, which should indicate to the user how the
- * user name should look like.
- * @return an example string, which should indicate to the user how the
- * user name should look like.
- */
- @Override
- public String getUserNameExample()
- {
- return null;
- }
-
- /**
- * Indicates whether this wizard enables the simple "sign in" form shown
- * when the user opens the application for the first time. The simple
- * "sign in" form allows user to configure her account in one click, just
- * specifying her username and password and leaving any other configuration
- * as by default.
- * @return <code>true</code> if the simple "Sign in" form is enabled or
- * <code>false</code> otherwise.
- */
- @Override
- public boolean isSimpleFormEnabled()
- {
- return false;
- }
-
- /**
- * Returns a simple account registration form that would be the first form
- * shown to the user. Only if the user needs more settings she'll choose
- * to open the advanced wizard, consisted by all pages.
- *
- * @param isCreateAccount indicates if the simple form should be opened as
- * a create account form or as a login form
- * @return a simple account registration form
- */
- @Override
- public Object getSimpleForm(boolean isCreateAccount)
- {
- firstWizardPage = new FirstWizardPage(registration, getWizardContainer());
- return firstWizardPage.getSimpleForm();
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/sshaccregwizz/sshaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/sshaccregwizz/sshaccregwizz.manifest.mf
deleted file mode 100644
index c48b853..0000000
--- a/src/net/java/sip/communicator/plugin/sshaccregwizz/sshaccregwizz.manifest.mf
+++ /dev/null
@@ -1,32 +0,0 @@
-Bundle-Activator: net.java.sip.communicator.plugin.sshaccregwizz.SSHAccRegWizzActivator
-Bundle-Name: SSH account registration wizard
-Bundle-Description: SSH account registration wizard.
-Bundle-Vendor: jitsi.org
-Bundle-Version: 0.0.1
-Bundle-SymbolicName: net.java.sip.communicator.plugin.sshaccregwizz
-Import-Package: org.osgi.framework,
- net.java.sip.communicator.service.browserlauncher,
- org.jitsi.service.configuration,
- net.java.sip.communicator.service.contactlist,
- net.java.sip.communicator.service.contactlist.event,
- net.java.sip.communicator.service.gui,
- net.java.sip.communicator.service.gui.event,
- net.java.sip.communicator.service.protocol,
- net.java.sip.communicator.service.protocol.event,
- org.jitsi.service.resources, net.java.sip.communicator.service.resources,
- net.java.sip.communicator.util,
- net.java.sip.communicator.plugin.desktoputil,
- javax.swing,
- javax.swing.event,
- javax.swing.table,
- javax.swing.text,
- javax.swing.text.html,
- javax.accessibility,
- javax.swing.plaf,
- javax.swing.plaf.metal,
- javax.swing.plaf.basic,
- javax.imageio,
- javax.swing.filechooser,
- javax.swing.tree,
- javax.swing.undo,
- javax.swing.border
diff --git a/src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdActivator.java b/src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdActivator.java
index 2a1bbe3..00c204e 100644
--- a/src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdActivator.java
+++ b/src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdActivator.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,170 +15,170 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.thunderbird;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.contactsource.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.configuration.*;
-import org.jitsi.service.resources.*;
-import org.osgi.framework.*;
-
-/**
- * Bundle-Activator for the Thunderbird address book contact source plug-in.
- *
- * @author Ingo Bauersachs
- */
-public class ThunderbirdActivator
- implements BundleActivator
-{
- /** OSGi context. */
- private static BundleContext bundleContext;
-
- /** Active address book registrations. */
- private static Map<ThunderbirdContactSourceService, ServiceRegistration>
- registrations;
-
- /**
- * The registered PhoneNumberI18nService.
- */
- private static PhoneNumberI18nService phoneNumberI18nService;
-
- /**
- * Gets the configuration service.
- * @return the configuration service.
- */
- static ConfigurationService getConfigService()
- {
- return ServiceUtils.getService(bundleContext,
- ConfigurationService.class);
- }
-
- /**
- * Gets the resource service.
- * @return the resource service.
- */
- static ResourceManagementService getResources()
- {
- return ServiceUtils.getService(bundleContext,
- ResourceManagementService.class);
- }
-
- /**
- * Gets all registered Thunderbird address book services.
- * @return all registered Thunderbird address book services.
- */
- static List<ThunderbirdContactSourceService> getActiveServices()
- {
- return new LinkedList<ThunderbirdContactSourceService>(
- registrations.keySet());
- }
-
- /**
- * Loads and registers an address book service.
- * @param config the name of the base property of the service to load.
- */
- static void add(String config)
- {
- ThunderbirdContactSourceService service
- = new ThunderbirdContactSourceService(config);
- registrations.put(service,
- bundleContext.registerService(
- ContactSourceService.class.getName(), service, null));
- }
-
- /**
- * Stops an address book service and deletes the corresponding configuration
- * data.
- *
- * @param service the address book instance to remove.
- */
- static void remove(ThunderbirdContactSourceService service)
- {
- registrations.get(service).unregister();
- registrations.remove(service);
- ConfigurationService config = getConfigService();
- config.removeProperty(service.getBaseConfigProperty());
- for (String prop : config.getPropertyNamesByPrefix(
- service.getBaseConfigProperty(), false))
- {
- config.removeProperty(prop);
- }
- }
-
- /**
- * Searches the configuration for Thunderbird address books and registers a
- * {@link ContactSourceService} for each found config.
- */
- public void start(BundleContext bundleContext) throws Exception
- {
- ThunderbirdActivator.bundleContext = bundleContext;
-
- ConfigurationService config = getConfigService();
- List<String> configs =
- config.getPropertyNamesByPrefix(
- ThunderbirdContactSourceService.PNAME_BASE_THUNDERBIRD_CONFIG,
- false);
-
- registrations = new HashMap
- <ThunderbirdContactSourceService, ServiceRegistration>();
- for (String cfg : configs)
- {
- String value = config.getString(cfg);
- if (value != null && cfg.endsWith(value))
- {
- add(cfg);
- }
- }
-
- /* registers the configuration form */
- Dictionary<String, String> properties
- = new Hashtable<String, String>();
- properties.put(
- ConfigurationForm.FORM_TYPE,
- ConfigurationForm.CONTACT_SOURCE_TYPE);
-
- bundleContext.registerService(
- ConfigurationForm.class.getName(),
- new LazyConfigurationForm(
- ThunderbirdConfigForm.class.getName(),
- getClass().getClassLoader(),
- null,
- "plugin.thunderbird.CONFIG_FORM_TITLE"),
- properties);
- }
-
- /**
- * Unregisters all {@link ContactSourceService}s that were registered by
- * this activator.
- */
- public void stop(BundleContext bundleContext) throws Exception
- {
- for (ServiceRegistration sr : registrations.values())
- {
- sr.unregister();
- }
-
- registrations = null;
- }
-
- /**
- * Returns the PhoneNumberI18nService.
- * @return returns the PhoneNumberI18nService.
- */
- public static PhoneNumberI18nService getPhoneNumberI18nService()
- {
- if(phoneNumberI18nService == null)
- {
- phoneNumberI18nService = ServiceUtils.getService(
- bundleContext,
- PhoneNumberI18nService.class);
- }
-
- return phoneNumberI18nService;
- }
-}
+package net.java.sip.communicator.plugin.thunderbird;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.configuration.*;
+import org.jitsi.service.resources.*;
+import org.osgi.framework.*;
+
+/**
+ * Bundle-Activator for the Thunderbird address book contact source plug-in.
+ *
+ * @author Ingo Bauersachs
+ */
+public class ThunderbirdActivator
+ implements BundleActivator
+{
+ /** OSGi context. */
+ private static BundleContext bundleContext;
+
+ /** Active address book registrations. */
+ private static Map<ThunderbirdContactSourceService, ServiceRegistration>
+ registrations;
+
+ /**
+ * The registered PhoneNumberI18nService.
+ */
+ private static PhoneNumberI18nService phoneNumberI18nService;
+
+ /**
+ * Gets the configuration service.
+ * @return the configuration service.
+ */
+ static ConfigurationService getConfigService()
+ {
+ return ServiceUtils.getService(bundleContext,
+ ConfigurationService.class);
+ }
+
+ /**
+ * Gets the resource service.
+ * @return the resource service.
+ */
+ static ResourceManagementService getResources()
+ {
+ return ServiceUtils.getService(bundleContext,
+ ResourceManagementService.class);
+ }
+
+ /**
+ * Gets all registered Thunderbird address book services.
+ * @return all registered Thunderbird address book services.
+ */
+ static List<ThunderbirdContactSourceService> getActiveServices()
+ {
+ return new LinkedList<ThunderbirdContactSourceService>(
+ registrations.keySet());
+ }
+
+ /**
+ * Loads and registers an address book service.
+ * @param config the name of the base property of the service to load.
+ */
+ static void add(String config)
+ {
+ ThunderbirdContactSourceService service
+ = new ThunderbirdContactSourceService(config);
+ registrations.put(service,
+ bundleContext.registerService(
+ ContactSourceService.class.getName(), service, null));
+ }
+
+ /**
+ * Stops an address book service and deletes the corresponding configuration
+ * data.
+ *
+ * @param service the address book instance to remove.
+ */
+ static void remove(ThunderbirdContactSourceService service)
+ {
+ registrations.get(service).unregister();
+ registrations.remove(service);
+ ConfigurationService config = getConfigService();
+ config.removeProperty(service.getBaseConfigProperty());
+ for (String prop : config.getPropertyNamesByPrefix(
+ service.getBaseConfigProperty(), false))
+ {
+ config.removeProperty(prop);
+ }
+ }
+
+ /**
+ * Searches the configuration for Thunderbird address books and registers a
+ * {@link ContactSourceService} for each found config.
+ */
+ public void start(BundleContext bundleContext) throws Exception
+ {
+ ThunderbirdActivator.bundleContext = bundleContext;
+
+ ConfigurationService config = getConfigService();
+ List<String> configs =
+ config.getPropertyNamesByPrefix(
+ ThunderbirdContactSourceService.PNAME_BASE_THUNDERBIRD_CONFIG,
+ false);
+
+ registrations = new HashMap
+ <ThunderbirdContactSourceService, ServiceRegistration>();
+ for (String cfg : configs)
+ {
+ String value = config.getString(cfg);
+ if (value != null && cfg.endsWith(value))
+ {
+ add(cfg);
+ }
+ }
+
+ /* registers the configuration form */
+ Dictionary<String, String> properties
+ = new Hashtable<String, String>();
+ properties.put(
+ ConfigurationForm.FORM_TYPE,
+ ConfigurationForm.CONTACT_SOURCE_TYPE);
+
+ bundleContext.registerService(
+ ConfigurationForm.class.getName(),
+ new LazyConfigurationForm(
+ ThunderbirdConfigForm.class.getName(),
+ getClass().getClassLoader(),
+ null,
+ "plugin.thunderbird.CONFIG_FORM_TITLE"),
+ properties);
+ }
+
+ /**
+ * Unregisters all {@link ContactSourceService}s that were registered by
+ * this activator.
+ */
+ public void stop(BundleContext bundleContext) throws Exception
+ {
+ for (ServiceRegistration sr : registrations.values())
+ {
+ sr.unregister();
+ }
+
+ registrations = null;
+ }
+
+ /**
+ * Returns the PhoneNumberI18nService.
+ * @return returns the PhoneNumberI18nService.
+ */
+ public static PhoneNumberI18nService getPhoneNumberI18nService()
+ {
+ if(phoneNumberI18nService == null)
+ {
+ phoneNumberI18nService = ServiceUtils.getService(
+ bundleContext,
+ PhoneNumberI18nService.class);
+ }
+
+ return phoneNumberI18nService;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdContactQuery.java b/src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdContactQuery.java
index 429ff6c..00488f9 100644
--- a/src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdContactQuery.java
+++ b/src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdContactQuery.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,267 +15,267 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.thunderbird;
-
-import java.io.*;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.regex.*;
-
-import org.jitsi.util.StringUtils;
-
-import mork.*;
-import net.java.sip.communicator.service.contactsource.*;
-import net.java.sip.communicator.service.contactsource.ContactDetail.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Queries a Thunderbird address book for contacts matching the given pattern.
- *
- * @author Ingo Bauersachs
- */
-public class ThunderbirdContactQuery
- extends AsyncContactQuery<ThunderbirdContactSourceService>
-{
- /** Class logger */
- private final static Logger logger = Logger
- .getLogger(ThunderbirdContactQuery.class);
-
- /**
- * Creates a new instance of this class.
- *
- * @param owner The contact source that created this query.
- * @param query The pattern to match against the contacts database.
- */
- public ThunderbirdContactQuery(ThunderbirdContactSourceService owner,
- Pattern query)
- {
- super(owner, query);
- }
-
- /**
- * Starts the query against the address book database.
- */
- @Override
- protected void run()
- {
- String filename = super.getContactSource().getFilename();
- File file = new File(filename);
- try
- {
- if (file.lastModified() > getContactSource().lastDatabaseFileChange)
- {
- // parse the Thunderbird Mork database
- InputStreamReader sr =
- new InputStreamReader(new FileInputStream(filename));
- MorkDocument md = new MorkDocument(sr);
- sr.close();
-
- // We now have rows in their tables and additional rows at
- // transaction level. Put the to a better format:
- // DB -> Tables -> Rows
- Map<String, Map<String, Row>> db =
- new HashMap<String, Map<String, Row>>();
- for (Table t : md.getTables())
- {
- String tableId = t.getTableId() + "/" + t.getScopeName();
- Map<String, Row> table = db.get(tableId);
- if (table == null)
- {
- table = new HashMap<String, Row>();
- db.put(tableId, table);
- }
-
- for (Row r : t.getRows())
- {
- String scope = r.getScopeName();
- if (scope == null)
- {
- scope = t.getScopeName();
- }
-
- table.put(r.getRowId() + "/" + scope, r);
- }
- }
-
- // The additional rows at the root-level update/replace the ones
- // in the tables. There's usually neither a table nor a scope
- // defined, so lets just use the default.
- String defaultScope = md.getDicts().get(0).dereference("^80");
- for (Row r : md.getRows())
- {
- String scope = r.getScopeName();
- if (scope == null)
- {
- scope = defaultScope;
- }
-
- String tableId = "1/" + scope;
- Map<String, Row> table = db.get(tableId);
- if (table == null)
- {
- table = new HashMap<String, Row>();
- db.put(tableId, table);
- }
-
- String rowId = r.getRowId() + "/" + scope;
- if (rowId.startsWith("-"))
- {
- rowId = rowId.substring(1);
- }
-
- table.put(rowId, r);
- }
-
- super.getContactSource().database = db;
- super.getContactSource().defaultScope = defaultScope;
- super.getContactSource().lastDatabaseFileChange =
- file.lastModified();
- }
-
- // okay, "transactions" are applied, now perform the search
- for (Entry<String, Map<String, Row>> table
- : super.getContactSource().database.entrySet())
- {
- for (Map.Entry<String, Row> e : table.getValue().entrySet())
- {
- if (e.getKey().endsWith(getContactSource().defaultScope))
- {
- readEntry(e.getValue());
- }
- }
- }
-
- super.stopped(true);
- }
- catch (FileNotFoundException e)
- {
- logger.warn("Could not open address book", e);
- }
- catch (Exception e)
- {
- logger.warn("Could not parse " + file, e);
- }
- }
-
- /**
- * Processes a database row by matching it against the query and adding it
- * to the result set if it matched.
- *
- * @param r The database row representing a contact.
- */
- private void readEntry(Row r)
- {
- // match the pattern against this contact
- boolean hadMatch = false;
- for (Alias value : r.getAliases().values())
- {
- if (value != null
- && (super.query.matcher(value.getValue()).find() || super
- .phoneNumberMatches(value.getValue())))
- {
- hadMatch = true;
- break;
- }
- }
-
- // nope, didn't match, ignore
- if (!hadMatch)
- {
- return;
- }
-
- List<ContactDetail> details = new LinkedList<ContactDetail>();
-
- // e-mail(s)
- for (String email : getPropertySet(r, "PrimaryEmail", "SecondEmail",
- "DefaultEmail"))
- {
- ContactDetail detail = new ContactDetail(email, Category.Email);
- detail.addSupportedOpSet(OperationSetPersistentPresence.class);
- details.add(detail);
- }
-
- // phone number(s)
- this.addPhoneDetail(details, r, "HomePhone", SubCategory.Home);
- this.addPhoneDetail(details, r, "WorkPhone", SubCategory.Work);
- this.addPhoneDetail(details, r, "CellularNumber", SubCategory.Mobile);
-
- // and the dispaly name
- String displayName = r.getValue("DisplayName");
- if (StringUtils.isNullOrEmpty(displayName, true))
- {
- displayName = r.getValue("LastName");
- if (displayName != null)
- {
- displayName = displayName.trim();
- }
-
- String firstName = r.getValue("FirstName");
- if (!StringUtils.isNullOrEmpty(firstName, true))
- {
- displayName = firstName + " " + displayName;
- }
- }
-
- // create the contact and add it to the results
- GenericSourceContact sc =
- new GenericSourceContact(super.getContactSource(), displayName,
- details);
- addQueryResult(sc);
- }
-
- /**
- * Adds a "Phone" {@link ContactDetail} to a query contact.
- *
- * @param details The {@link List} of {@link ContactDetail}s to which the
- * details is added.
- * @param r The source database row of the contact.
- * @param property The source database property name to add as a detail.
- * @param category The Phone-{@link SubCategory} for the phone number to
- * add.
- */
- private void addPhoneDetail(List<ContactDetail> details, Row r,
- String property, SubCategory category)
- {
- String phone = r.getValue(property);
- if (StringUtils.isNullOrEmpty(phone, true))
- {
- return;
- }
-
- phone
- = ThunderbirdActivator.getPhoneNumberI18nService().normalize(phone);
- ContactDetail detail =
- new ContactDetail(phone, ContactDetail.Category.Phone,
- new ContactDetail.SubCategory[]
- { category });
-
- detail.addSupportedOpSet(OperationSetBasicTelephony.class);
- detail.addSupportedOpSet(OperationSetPersistentPresence.class);
- details.add(detail);
- }
-
- /**
- * Gets a set of non-empty properties from the source database row.
- *
- * @param r The source database row to process.
- * @param properties The property-names to extract.
- * @return A set of non-empty properties from the source database row.
- */
- private Set<String> getPropertySet(Row r, String... properties)
- {
- Set<String> validValues = new HashSet<String>(properties.length);
- for (String prop : properties)
- {
- String value = r.getValue(prop);
- if (!StringUtils.isNullOrEmpty(value, true))
- {
- validValues.add(value);
- }
- }
-
- return validValues;
- }
-}
+package net.java.sip.communicator.plugin.thunderbird;
+
+import java.io.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.regex.*;
+
+import org.jitsi.util.StringUtils;
+
+import mork.*;
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.contactsource.ContactDetail.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Queries a Thunderbird address book for contacts matching the given pattern.
+ *
+ * @author Ingo Bauersachs
+ */
+public class ThunderbirdContactQuery
+ extends AsyncContactQuery<ThunderbirdContactSourceService>
+{
+ /** Class logger */
+ private final static Logger logger = Logger
+ .getLogger(ThunderbirdContactQuery.class);
+
+ /**
+ * Creates a new instance of this class.
+ *
+ * @param owner The contact source that created this query.
+ * @param query The pattern to match against the contacts database.
+ */
+ public ThunderbirdContactQuery(ThunderbirdContactSourceService owner,
+ Pattern query)
+ {
+ super(owner, query);
+ }
+
+ /**
+ * Starts the query against the address book database.
+ */
+ @Override
+ protected void run()
+ {
+ String filename = super.getContactSource().getFilename();
+ File file = new File(filename);
+ try
+ {
+ if (file.lastModified() > getContactSource().lastDatabaseFileChange)
+ {
+ // parse the Thunderbird Mork database
+ InputStreamReader sr =
+ new InputStreamReader(new FileInputStream(filename));
+ MorkDocument md = new MorkDocument(sr);
+ sr.close();
+
+ // We now have rows in their tables and additional rows at
+ // transaction level. Put the to a better format:
+ // DB -> Tables -> Rows
+ Map<String, Map<String, Row>> db =
+ new HashMap<String, Map<String, Row>>();
+ for (Table t : md.getTables())
+ {
+ String tableId = t.getTableId() + "/" + t.getScopeName();
+ Map<String, Row> table = db.get(tableId);
+ if (table == null)
+ {
+ table = new HashMap<String, Row>();
+ db.put(tableId, table);
+ }
+
+ for (Row r : t.getRows())
+ {
+ String scope = r.getScopeName();
+ if (scope == null)
+ {
+ scope = t.getScopeName();
+ }
+
+ table.put(r.getRowId() + "/" + scope, r);
+ }
+ }
+
+ // The additional rows at the root-level update/replace the ones
+ // in the tables. There's usually neither a table nor a scope
+ // defined, so lets just use the default.
+ String defaultScope = md.getDicts().get(0).dereference("^80");
+ for (Row r : md.getRows())
+ {
+ String scope = r.getScopeName();
+ if (scope == null)
+ {
+ scope = defaultScope;
+ }
+
+ String tableId = "1/" + scope;
+ Map<String, Row> table = db.get(tableId);
+ if (table == null)
+ {
+ table = new HashMap<String, Row>();
+ db.put(tableId, table);
+ }
+
+ String rowId = r.getRowId() + "/" + scope;
+ if (rowId.startsWith("-"))
+ {
+ rowId = rowId.substring(1);
+ }
+
+ table.put(rowId, r);
+ }
+
+ super.getContactSource().database = db;
+ super.getContactSource().defaultScope = defaultScope;
+ super.getContactSource().lastDatabaseFileChange =
+ file.lastModified();
+ }
+
+ // okay, "transactions" are applied, now perform the search
+ for (Entry<String, Map<String, Row>> table
+ : super.getContactSource().database.entrySet())
+ {
+ for (Map.Entry<String, Row> e : table.getValue().entrySet())
+ {
+ if (e.getKey().endsWith(getContactSource().defaultScope))
+ {
+ readEntry(e.getValue());
+ }
+ }
+ }
+
+ super.stopped(true);
+ }
+ catch (FileNotFoundException e)
+ {
+ logger.warn("Could not open address book", e);
+ }
+ catch (Exception e)
+ {
+ logger.warn("Could not parse " + file, e);
+ }
+ }
+
+ /**
+ * Processes a database row by matching it against the query and adding it
+ * to the result set if it matched.
+ *
+ * @param r The database row representing a contact.
+ */
+ private void readEntry(Row r)
+ {
+ // match the pattern against this contact
+ boolean hadMatch = false;
+ for (Alias value : r.getAliases().values())
+ {
+ if (value != null
+ && (super.query.matcher(value.getValue()).find() || super
+ .phoneNumberMatches(value.getValue())))
+ {
+ hadMatch = true;
+ break;
+ }
+ }
+
+ // nope, didn't match, ignore
+ if (!hadMatch)
+ {
+ return;
+ }
+
+ List<ContactDetail> details = new LinkedList<ContactDetail>();
+
+ // e-mail(s)
+ for (String email : getPropertySet(r, "PrimaryEmail", "SecondEmail",
+ "DefaultEmail"))
+ {
+ ContactDetail detail = new ContactDetail(email, Category.Email);
+ detail.addSupportedOpSet(OperationSetPersistentPresence.class);
+ details.add(detail);
+ }
+
+ // phone number(s)
+ this.addPhoneDetail(details, r, "HomePhone", SubCategory.Home);
+ this.addPhoneDetail(details, r, "WorkPhone", SubCategory.Work);
+ this.addPhoneDetail(details, r, "CellularNumber", SubCategory.Mobile);
+
+ // and the dispaly name
+ String displayName = r.getValue("DisplayName");
+ if (StringUtils.isNullOrEmpty(displayName, true))
+ {
+ displayName = r.getValue("LastName");
+ if (displayName != null)
+ {
+ displayName = displayName.trim();
+ }
+
+ String firstName = r.getValue("FirstName");
+ if (!StringUtils.isNullOrEmpty(firstName, true))
+ {
+ displayName = firstName + " " + displayName;
+ }
+ }
+
+ // create the contact and add it to the results
+ GenericSourceContact sc =
+ new GenericSourceContact(super.getContactSource(), displayName,
+ details);
+ addQueryResult(sc);
+ }
+
+ /**
+ * Adds a "Phone" {@link ContactDetail} to a query contact.
+ *
+ * @param details The {@link List} of {@link ContactDetail}s to which the
+ * details is added.
+ * @param r The source database row of the contact.
+ * @param property The source database property name to add as a detail.
+ * @param category The Phone-{@link SubCategory} for the phone number to
+ * add.
+ */
+ private void addPhoneDetail(List<ContactDetail> details, Row r,
+ String property, SubCategory category)
+ {
+ String phone = r.getValue(property);
+ if (StringUtils.isNullOrEmpty(phone, true))
+ {
+ return;
+ }
+
+ phone
+ = ThunderbirdActivator.getPhoneNumberI18nService().normalize(phone);
+ ContactDetail detail =
+ new ContactDetail(phone, ContactDetail.Category.Phone,
+ new ContactDetail.SubCategory[]
+ { category });
+
+ detail.addSupportedOpSet(OperationSetBasicTelephony.class);
+ detail.addSupportedOpSet(OperationSetPersistentPresence.class);
+ details.add(detail);
+ }
+
+ /**
+ * Gets a set of non-empty properties from the source database row.
+ *
+ * @param r The source database row to process.
+ * @param properties The property-names to extract.
+ * @return A set of non-empty properties from the source database row.
+ */
+ private Set<String> getPropertySet(Row r, String... properties)
+ {
+ Set<String> validValues = new HashSet<String>(properties.length);
+ for (String prop : properties)
+ {
+ String value = r.getValue(prop);
+ if (!StringUtils.isNullOrEmpty(value, true))
+ {
+ validValues.add(value);
+ }
+ }
+
+ return validValues;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/update/CheckForUpdatesMenuItemComponent.java b/src/net/java/sip/communicator/plugin/update/CheckForUpdatesMenuItemComponent.java
index 20f85b8..9c61233 100644
--- a/src/net/java/sip/communicator/plugin/update/CheckForUpdatesMenuItemComponent.java
+++ b/src/net/java/sip/communicator/plugin/update/CheckForUpdatesMenuItemComponent.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,77 +15,77 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.update;
-
-import java.awt.event.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.service.gui.*;
-
-/**
- * Implements <tt>PluginComponent</tt> for the "Check for Updates" menu
- * item.
- *
- * @author Damian Minkov
- * @author Lyubomir Marinov
- */
-public class CheckForUpdatesMenuItemComponent
- extends AbstractPluginComponent
-{
- /**
- * The "Check for Updates" menu item.
- */
- private JMenuItem checkForUpdatesMenuItem;
-
- /**
- * Initializes a new "Check for Updates" menu item.
- *
- * @param container the container of the update menu component
- */
- public CheckForUpdatesMenuItemComponent(Container container,
- PluginComponentFactory parentFactory)
- {
- super(container, parentFactory);
- }
-
- /**
- * Gets the UI <tt>Component</tt> of this <tt>PluginComponent</tt>.
- *
- * @return the UI <tt>Component</tt> of this <tt>PluginComponent</tt>
- * @see PluginComponent#getComponent()
- */
- public JMenuItem getComponent()
- {
- if(checkForUpdatesMenuItem == null)
- {
- checkForUpdatesMenuItem
- = new JMenuItem(
- Resources.getResources().getI18NString(
- "plugin.updatechecker.UPDATE_MENU_ENTRY"));
- checkForUpdatesMenuItem.addActionListener(
- new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- UpdateActivator.getUpdateService().checkForUpdates(
- true);
- }
- });
- }
- return checkForUpdatesMenuItem;
- }
-
- /**
- * Gets the name of this <tt>PluginComponent</tt>.
- *
- * @return the name of this <tt>PluginComponent</tt>
- * @see PluginComponent#getName()
- */
- public String getName()
- {
- return
- Resources.getResources().getI18NString(
- "plugin.updatechecker.UPDATE_MENU_ENTRY");
- }
-}
+package net.java.sip.communicator.plugin.update;
+
+import java.awt.event.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.service.gui.*;
+
+/**
+ * Implements <tt>PluginComponent</tt> for the "Check for Updates" menu
+ * item.
+ *
+ * @author Damian Minkov
+ * @author Lyubomir Marinov
+ */
+public class CheckForUpdatesMenuItemComponent
+ extends AbstractPluginComponent
+{
+ /**
+ * The "Check for Updates" menu item.
+ */
+ private JMenuItem checkForUpdatesMenuItem;
+
+ /**
+ * Initializes a new "Check for Updates" menu item.
+ *
+ * @param container the container of the update menu component
+ */
+ public CheckForUpdatesMenuItemComponent(Container container,
+ PluginComponentFactory parentFactory)
+ {
+ super(container, parentFactory);
+ }
+
+ /**
+ * Gets the UI <tt>Component</tt> of this <tt>PluginComponent</tt>.
+ *
+ * @return the UI <tt>Component</tt> of this <tt>PluginComponent</tt>
+ * @see PluginComponent#getComponent()
+ */
+ public JMenuItem getComponent()
+ {
+ if(checkForUpdatesMenuItem == null)
+ {
+ checkForUpdatesMenuItem
+ = new JMenuItem(
+ Resources.getResources().getI18NString(
+ "plugin.updatechecker.UPDATE_MENU_ENTRY"));
+ checkForUpdatesMenuItem.addActionListener(
+ new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ UpdateActivator.getUpdateService().checkForUpdates(
+ true);
+ }
+ });
+ }
+ return checkForUpdatesMenuItem;
+ }
+
+ /**
+ * Gets the name of this <tt>PluginComponent</tt>.
+ *
+ * @return the name of this <tt>PluginComponent</tt>
+ * @see PluginComponent#getName()
+ */
+ public String getName()
+ {
+ return
+ Resources.getResources().getI18NString(
+ "plugin.updatechecker.UPDATE_MENU_ENTRY");
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/update/UpdateActivator.java b/src/net/java/sip/communicator/plugin/update/UpdateActivator.java
index 8155117..251ac7a 100644
--- a/src/net/java/sip/communicator/plugin/update/UpdateActivator.java
+++ b/src/net/java/sip/communicator/plugin/update/UpdateActivator.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,306 +15,306 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.plugin.update;
-
-import java.util.*;
-import java.util.concurrent.*;
-
-import net.java.sip.communicator.service.browserlauncher.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.shutdown.*;
-import net.java.sip.communicator.service.update.*;
-import net.java.sip.communicator.util.*;
-import net.java.sip.communicator.util.Logger;
-
-import org.jitsi.service.configuration.*;
-import org.jitsi.util.*;
-import org.osgi.framework.*;
-
-/**
- * Implements <tt>BundleActivator</tt> for the update plug-in.
- *
- * @author Damian Minkov
- * @author Lyubomir Marinov
- */
-public class UpdateActivator
- extends AbstractServiceDependentActivator
-{
- /**
- * The <tt>Logger</tt> used by the <tt>UpdateActivator</tt> class and its
- * instances for logging output.
- */
- private static final Logger logger
- = Logger.getLogger(UpdateActivator.class);
-
- /**
- * The name of the configuration property which indicates whether the
- * checking for updates on application startup is enabled.
- */
- private static final String UPDATE_ENABLED
- = "net.java.sip.communicator.plugin.updatechecker.ENABLED";
-
- /**
- * The name of the configuration property which indicates whether the
- * "checking for updates" menu entry is disabled.
- */
- private static final String CHECK_FOR_UPDATES_MENU_DISABLED_PROP
- = "net.java.sip.communicator.plugin.update.checkforupdatesmenu.DISABLED";
-
- /**
- * The name of the configuration property which indicates whether the client
- * should automatically check for updates each day or not.
- */
- private static final String CHECK_FOR_UPDATES_DAILY_ENABLED_PROP =
- "net.java.sip.communicator.plugin.update.checkforupdatesmenu.daily.ENABLED";
-
- /**
- * The name of the configuration property which indicates the hour that
- * the client should check for updates (if daily update checking is enabled)
- */
- private static final String CHECK_FOR_UPDATES_DAILY_TIME_PROP =
- "net.java.sip.communicator.plugin.update.checkforupdatesmenu.daily.HOUR";
-
- /**
- * Reference to the <tt>BrowserLauncherService</tt>.
- */
- private static BrowserLauncherService browserLauncher;
-
- /**
- * The <tt>BundleContext</tt> in which the one and only
- * <tt>UpdateActivator</tt> instance of the update plug-in has been started.
- */
- static BundleContext bundleContext;
-
- /**
- * Reference to the <tt>ConfigurationService</tt>.
- */
- private static ConfigurationService configuration;
-
- /**
- * Reference to the <tt>UIService</tt>.
- */
- private static UIService uiService;
-
- /**
- * The update service.
- */
- private static UpdateService updateService;
-
- /**
- * A scheduler to check for updates once a day
- */
- private ScheduledExecutorService mUpdateExecutor = null;
-
- /**
- * Returns the <tt>BrowserLauncherService</tt> obtained from the bundle
- * context.
- * @return the <tt>BrowserLauncherService</tt> obtained from the bundle
- * context
- */
- static BrowserLauncherService getBrowserLauncher()
- {
- if (browserLauncher == null)
- {
- browserLauncher
- = ServiceUtils.getService(
- bundleContext,
- BrowserLauncherService.class);
- }
- return browserLauncher;
- }
-
- /**
- * Returns the <tt>ConfigurationService</tt> obtained from the bundle
- * context.
- *
- * @return the <tt>ConfigurationService</tt> obtained from the bundle
- * context
- */
- static ConfigurationService getConfiguration()
- {
- if (configuration == null)
- {
- configuration
- = ServiceUtils.getService(
- bundleContext,
- ConfigurationService.class);
- }
- return configuration;
- }
-
- /**
- * Gets a reference to a <code>ShutdownService</code> implementation
- * currently registered in the bundle context of the active
- * <code>UpdateCheckActivator</code> instance.
- * <p>
- * The returned reference to <code>ShutdownService</code> is not being
- * cached.
- * </p>
- *
- * @return reference to a <code>ShutdownService</code> implementation
- * currently registered in the bundle context of the active
- * <code>UpdateCheckActivator</code> instance
- */
- static ShutdownService getShutdownService()
- {
- return ServiceUtils.getService(bundleContext, ShutdownService.class);
- }
-
- /**
- * Returns a reference to the UIService implementation currently registered
- * in the bundle context or null if no such implementation was found.
- *
- * @return a reference to a UIService implementation currently registered
- * in the bundle context or null if no such implementation was found.
- */
- static UIService getUIService()
- {
- if(uiService == null)
- uiService = ServiceUtils.getService(bundleContext, UIService.class);
- return uiService;
- }
-
- /**
- * The dependent service is available and the bundle will start.
- * @param dependentService the UIService this activator is waiting.
- */
- @Override
- public void start(Object dependentService)
- {
- if (logger.isDebugEnabled())
- logger.debug("Update checker [STARTED]");
-
- ConfigurationService cfg = getConfiguration();
-
- if (OSUtils.IS_WINDOWS)
- {
- updateService = new UpdateServiceImpl();
-
- bundleContext.registerService(
- UpdateService.class.getName(),
- updateService,
- null);
-
- // Register the "Check for Updates" menu item if
- // the "Check for Updates" property isn't disabled.
- if(!cfg.getBoolean(CHECK_FOR_UPDATES_MENU_DISABLED_PROP, false))
- {
- // Register the "Check for Updates" menu item.
-
- Hashtable<String, String> toolsMenuFilter
- = new Hashtable<String, String>();
- toolsMenuFilter.put(
- Container.CONTAINER_ID,
- Container.CONTAINER_HELP_MENU.getID());
-
- bundleContext.registerService(
- PluginComponentFactory.class.getName(),
- new PluginComponentFactory(Container.CONTAINER_HELP_MENU)
- {
- @Override
- protected PluginComponent getPluginInstance()
- {
- return new CheckForUpdatesMenuItemComponent(
- getContainer(), this);
- }
- },
- toolsMenuFilter);
- }
-
- // Check for software update upon startup if enabled.
- if(cfg.getBoolean(UPDATE_ENABLED, true))
- updateService.checkForUpdates(false);
- }
-
- if (cfg.getBoolean(CHECK_FOR_UPDATES_DAILY_ENABLED_PROP,
- false))
- {
- logger.info("Scheduled update checking enabled");
-
- // Schedule a "check for updates" task that will run once a day
- int hoursToWait = calcHoursToWait();
- Runnable updateRunnable = new Runnable()
- {
- public void run()
- {
- logger.debug("Performing scheduled update check");
- getUpdateService().checkForUpdates(false);
- }
- };
-
- mUpdateExecutor = Executors.newSingleThreadScheduledExecutor();
- mUpdateExecutor.scheduleAtFixedRate(updateRunnable,
- hoursToWait,
- 24*60*60,
- TimeUnit.SECONDS);
- }
-
- if (logger.isDebugEnabled())
- logger.debug("Update checker [REGISTERED]");
- }
-
- /**
- * This activator depends on UIService.
- * @return the class name of uiService.
- */
- @Override
- public Class<?> getDependentServiceClass()
- {
- return UIService.class;
- }
-
- /**
- * Setting context to the activator, as soon as we have one.
- *
- * @param context the context to set.
- */
- @Override
- public void setBundleContext(BundleContext context)
- {
- bundleContext = context;
- }
-
- /**
- * Calculate the number of hour to wait until the first scheduled update
- * check. This will only be called if daily checking for config updates
- * is enabled
- *
- * @return The number of hours to wait
- */
- private int calcHoursToWait()
- {
- // The hours to wait is the number of hours until midnight tonight (24
- // minus the current hour) plus the hour that the config says updates
- // should be
- return 24 - Calendar.getInstance().get(Calendar.HOUR_OF_DAY) +
- configuration.getInt(CHECK_FOR_UPDATES_DAILY_TIME_PROP, 0);
- }
-
- /**
- * Stop the bundle. Nothing to stop for now.
- * @param bundleContext <tt>BundleContext</tt> provided by OSGi framework
- * @throws Exception if something goes wrong during stop
- */
- public void stop(BundleContext bundleContext) throws Exception
- {
- if (logger.isDebugEnabled())
- logger.debug("Update checker [STOPPED]");
-
- if (mUpdateExecutor != null)
- {
- mUpdateExecutor.shutdown();
- mUpdateExecutor = null;
- }
- }
-
- /**
- * Returns the update service instance.
- *
- * @return the update service instance
- */
- static UpdateService getUpdateService()
- {
- return updateService;
- }
-}
+package net.java.sip.communicator.plugin.update;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+import net.java.sip.communicator.service.browserlauncher.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.shutdown.*;
+import net.java.sip.communicator.service.update.*;
+import net.java.sip.communicator.util.*;
+import net.java.sip.communicator.util.Logger;
+
+import org.jitsi.service.configuration.*;
+import org.jitsi.util.*;
+import org.osgi.framework.*;
+
+/**
+ * Implements <tt>BundleActivator</tt> for the update plug-in.
+ *
+ * @author Damian Minkov
+ * @author Lyubomir Marinov
+ */
+public class UpdateActivator
+ extends AbstractServiceDependentActivator
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>UpdateActivator</tt> class and its
+ * instances for logging output.
+ */
+ private static final Logger logger
+ = Logger.getLogger(UpdateActivator.class);
+
+ /**
+ * The name of the configuration property which indicates whether the
+ * checking for updates on application startup is enabled.
+ */
+ private static final String UPDATE_ENABLED
+ = "net.java.sip.communicator.plugin.updatechecker.ENABLED";
+
+ /**
+ * The name of the configuration property which indicates whether the
+ * "checking for updates" menu entry is disabled.
+ */
+ private static final String CHECK_FOR_UPDATES_MENU_DISABLED_PROP
+ = "net.java.sip.communicator.plugin.update.checkforupdatesmenu.DISABLED";
+
+ /**
+ * The name of the configuration property which indicates whether the client
+ * should automatically check for updates each day or not.
+ */
+ private static final String CHECK_FOR_UPDATES_DAILY_ENABLED_PROP =
+ "net.java.sip.communicator.plugin.update.checkforupdatesmenu.daily.ENABLED";
+
+ /**
+ * The name of the configuration property which indicates the hour that
+ * the client should check for updates (if daily update checking is enabled)
+ */
+ private static final String CHECK_FOR_UPDATES_DAILY_TIME_PROP =
+ "net.java.sip.communicator.plugin.update.checkforupdatesmenu.daily.HOUR";
+
+ /**
+ * Reference to the <tt>BrowserLauncherService</tt>.
+ */
+ private static BrowserLauncherService browserLauncher;
+
+ /**
+ * The <tt>BundleContext</tt> in which the one and only
+ * <tt>UpdateActivator</tt> instance of the update plug-in has been started.
+ */
+ static BundleContext bundleContext;
+
+ /**
+ * Reference to the <tt>ConfigurationService</tt>.
+ */
+ private static ConfigurationService configuration;
+
+ /**
+ * Reference to the <tt>UIService</tt>.
+ */
+ private static UIService uiService;
+
+ /**
+ * The update service.
+ */
+ private static UpdateService updateService;
+
+ /**
+ * A scheduler to check for updates once a day
+ */
+ private ScheduledExecutorService mUpdateExecutor = null;
+
+ /**
+ * Returns the <tt>BrowserLauncherService</tt> obtained from the bundle
+ * context.
+ * @return the <tt>BrowserLauncherService</tt> obtained from the bundle
+ * context
+ */
+ static BrowserLauncherService getBrowserLauncher()
+ {
+ if (browserLauncher == null)
+ {
+ browserLauncher
+ = ServiceUtils.getService(
+ bundleContext,
+ BrowserLauncherService.class);
+ }
+ return browserLauncher;
+ }
+
+ /**
+ * Returns the <tt>ConfigurationService</tt> obtained from the bundle
+ * context.
+ *
+ * @return the <tt>ConfigurationService</tt> obtained from the bundle
+ * context
+ */
+ static ConfigurationService getConfiguration()
+ {
+ if (configuration == null)
+ {
+ configuration
+ = ServiceUtils.getService(
+ bundleContext,
+ ConfigurationService.class);
+ }
+ return configuration;
+ }
+
+ /**
+ * Gets a reference to a <code>ShutdownService</code> implementation
+ * currently registered in the bundle context of the active
+ * <code>UpdateCheckActivator</code> instance.
+ * <p>
+ * The returned reference to <code>ShutdownService</code> is not being
+ * cached.
+ * </p>
+ *
+ * @return reference to a <code>ShutdownService</code> implementation
+ * currently registered in the bundle context of the active
+ * <code>UpdateCheckActivator</code> instance
+ */
+ static ShutdownService getShutdownService()
+ {
+ return ServiceUtils.getService(bundleContext, ShutdownService.class);
+ }
+
+ /**
+ * Returns a reference to the UIService implementation currently registered
+ * in the bundle context or null if no such implementation was found.
+ *
+ * @return a reference to a UIService implementation currently registered
+ * in the bundle context or null if no such implementation was found.
+ */
+ static UIService getUIService()
+ {
+ if(uiService == null)
+ uiService = ServiceUtils.getService(bundleContext, UIService.class);
+ return uiService;
+ }
+
+ /**
+ * The dependent service is available and the bundle will start.
+ * @param dependentService the UIService this activator is waiting.
+ */
+ @Override
+ public void start(Object dependentService)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Update checker [STARTED]");
+
+ ConfigurationService cfg = getConfiguration();
+
+ if (OSUtils.IS_WINDOWS)
+ {
+ updateService = new UpdateServiceImpl();
+
+ bundleContext.registerService(
+ UpdateService.class.getName(),
+ updateService,
+ null);
+
+ // Register the "Check for Updates" menu item if
+ // the "Check for Updates" property isn't disabled.
+ if(!cfg.getBoolean(CHECK_FOR_UPDATES_MENU_DISABLED_PROP, false))
+ {
+ // Register the "Check for Updates" menu item.
+
+ Hashtable<String, String> toolsMenuFilter
+ = new Hashtable<String, String>();
+ toolsMenuFilter.put(
+ Container.CONTAINER_ID,
+ Container.CONTAINER_HELP_MENU.getID());
+
+ bundleContext.registerService(
+ PluginComponentFactory.class.getName(),
+ new PluginComponentFactory(Container.CONTAINER_HELP_MENU)
+ {
+ @Override
+ protected PluginComponent getPluginInstance()
+ {
+ return new CheckForUpdatesMenuItemComponent(
+ getContainer(), this);
+ }
+ },
+ toolsMenuFilter);
+ }
+
+ // Check for software update upon startup if enabled.
+ if(cfg.getBoolean(UPDATE_ENABLED, true))
+ updateService.checkForUpdates(false);
+ }
+
+ if (cfg.getBoolean(CHECK_FOR_UPDATES_DAILY_ENABLED_PROP,
+ false))
+ {
+ logger.info("Scheduled update checking enabled");
+
+ // Schedule a "check for updates" task that will run once a day
+ int hoursToWait = calcHoursToWait();
+ Runnable updateRunnable = new Runnable()
+ {
+ public void run()
+ {
+ logger.debug("Performing scheduled update check");
+ getUpdateService().checkForUpdates(false);
+ }
+ };
+
+ mUpdateExecutor = Executors.newSingleThreadScheduledExecutor();
+ mUpdateExecutor.scheduleAtFixedRate(updateRunnable,
+ hoursToWait,
+ 24*60*60,
+ TimeUnit.SECONDS);
+ }
+
+ if (logger.isDebugEnabled())
+ logger.debug("Update checker [REGISTERED]");
+ }
+
+ /**
+ * This activator depends on UIService.
+ * @return the class name of uiService.
+ */
+ @Override
+ public Class<?> getDependentServiceClass()
+ {
+ return UIService.class;
+ }
+
+ /**
+ * Setting context to the activator, as soon as we have one.
+ *
+ * @param context the context to set.
+ */
+ @Override
+ public void setBundleContext(BundleContext context)
+ {
+ bundleContext = context;
+ }
+
+ /**
+ * Calculate the number of hour to wait until the first scheduled update
+ * check. This will only be called if daily checking for config updates
+ * is enabled
+ *
+ * @return The number of hours to wait
+ */
+ private int calcHoursToWait()
+ {
+ // The hours to wait is the number of hours until midnight tonight (24
+ // minus the current hour) plus the hour that the config says updates
+ // should be
+ return 24 - Calendar.getInstance().get(Calendar.HOUR_OF_DAY) +
+ configuration.getInt(CHECK_FOR_UPDATES_DAILY_TIME_PROP, 0);
+ }
+
+ /**
+ * Stop the bundle. Nothing to stop for now.
+ * @param bundleContext <tt>BundleContext</tt> provided by OSGi framework
+ * @throws Exception if something goes wrong during stop
+ */
+ public void stop(BundleContext bundleContext) throws Exception
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Update checker [STOPPED]");
+
+ if (mUpdateExecutor != null)
+ {
+ mUpdateExecutor.shutdown();
+ mUpdateExecutor = null;
+ }
+ }
+
+ /**
+ * Returns the update service instance.
+ *
+ * @return the update service instance
+ */
+ static UpdateService getUpdateService()
+ {
+ return updateService;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/update/UpdateServiceImpl.java b/src/net/java/sip/communicator/plugin/update/UpdateServiceImpl.java
index 53dde17..d0c908e 100644
--- a/src/net/java/sip/communicator/plugin/update/UpdateServiceImpl.java
+++ b/src/net/java/sip/communicator/plugin/update/UpdateServiceImpl.java
@@ -545,24 +545,22 @@ public class UpdateServiceImpl
if(notifyAboutNewestVersion)
{
SwingUtilities.invokeLater(
- new Runnable()
+ new Runnable()
+ {
+ public void run()
{
- public void run()
- {
- UIService ui = UpdateActivator.getUIService();
- ResourceManagementService r
- = Resources.getResources();
-
- ui.getPopupDialog().showMessagePopupDialog(
- r.getI18NString(
- "plugin.updatechecker."
- + "DIALOG_NOUPDATE"),
- r.getI18NString(
- "plugin.updatechecker."
- + "DIALOG_NOUPDATE_TITLE"),
- PopupDialog.INFORMATION_MESSAGE);
- }
- });
+ UIService ui = UpdateActivator.getUIService();
+ ResourceManagementService r
+ = Resources.getResources();
+
+ ui.getPopupDialog().showMessagePopupDialog(
+ r.getI18NString(
+ "plugin.updatechecker.DIALOG_NOUPDATE"),
+ r.getI18NString(
+ "plugin.updatechecker.DIALOG_NOUPDATE_TITLE"),
+ PopupDialog.INFORMATION_MESSAGE);
+ }
+ });
}
}
else
diff --git a/src/net/java/sip/communicator/plugin/yahooaccregwizz/FirstWizardPage.java b/src/net/java/sip/communicator/plugin/yahooaccregwizz/FirstWizardPage.java
deleted file mode 100644
index 27e32c6..0000000
--- a/src/net/java/sip/communicator/plugin/yahooaccregwizz/FirstWizardPage.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.yahooaccregwizz;
-
-import java.awt.*;
-
-import javax.swing.*;
-import javax.swing.event.*;
-
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
-
-/**
- * The <tt>FirstWizardPage</tt> is the page, where user could enter the uin
- * and the password of the account.
- *
- * @author Yana Stamcheva
- * @author Damian Minkov
- */
-public class FirstWizardPage
- extends TransparentPanel
- implements WizardPage,
- DocumentListener
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- public static final String FIRST_PAGE_IDENTIFIER = "FirstPageIdentifier";
-
- public static final String USER_NAME_EXAMPLE
- = "Ex: johnsmith@yahoo.com or johnsmith";
-
- private JPanel uinPassPanel = new TransparentPanel(new BorderLayout(10, 10));
-
- private JPanel labelsPanel = new TransparentPanel();
-
- private JPanel valuesPanel = new TransparentPanel();
-
- private JLabel uinLabel = new JLabel(
- Resources.getString("plugin.yahooaccregwizz.USERNAME"));
-
- private JLabel passLabel
- = new JLabel(Resources.getString("service.gui.PASSWORD"));
-
- private JPanel emptyPanel = new TransparentPanel();
-
- private JLabel uinExampleLabel = new JLabel(USER_NAME_EXAMPLE);
-
- private JTextField userIDField = new TrimTextField();
-
- private JPasswordField passField = new JPasswordField();
-
- private JCheckBox rememberPassBox =
- new SIPCommCheckBox(
- Resources.getString("service.gui.REMEMBER_PASSWORD"));
-
- private JPanel mainPanel = new TransparentPanel();
-
- private Object nextPageIdentifier = WizardPage.SUMMARY_PAGE_IDENTIFIER;
-
- private YahooAccountRegistrationWizard wizard;
-
- private boolean isCommitted = false;
-
- /**
- * Creates an instance of <tt>FirstWizardPage</tt>.
- *
- * @param wizard the parent wizard
- */
- public FirstWizardPage(YahooAccountRegistrationWizard wizard)
- {
-
- super(new BorderLayout());
-
- this.wizard = wizard;
-
- mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
-
- this.init();
-
- this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
-
- this.labelsPanel
- .setLayout(new BoxLayout(labelsPanel, BoxLayout.Y_AXIS));
-
- this.valuesPanel
- .setLayout(new BoxLayout(valuesPanel, BoxLayout.Y_AXIS));
- }
-
- /**
- * Initializes all panels, buttons, etc.
- */
- private void init()
- {
- this.mainPanel.setOpaque(false);
- this.labelsPanel.setOpaque(false);
- this.valuesPanel.setOpaque(false);
- this.uinPassPanel.setOpaque(false);
- this.emptyPanel.setOpaque(false);
-
- this.userIDField.getDocument().addDocumentListener(this);
- this.rememberPassBox.setSelected(true);
-
- this.uinExampleLabel.setForeground(Color.GRAY);
- this.uinExampleLabel.setFont(uinExampleLabel.getFont().deriveFont(8));
- this.emptyPanel.setMaximumSize(new Dimension(40, 35));
- this.uinExampleLabel.setBorder(
- BorderFactory.createEmptyBorder(0, 0, 8, 0));
-
- labelsPanel.add(uinLabel);
- labelsPanel.add(emptyPanel);
- labelsPanel.add(passLabel);
-
- valuesPanel.add(userIDField);
- valuesPanel.add(uinExampleLabel);
- valuesPanel.add(passField);
-
- uinPassPanel.add(labelsPanel, BorderLayout.WEST);
- uinPassPanel.add(valuesPanel, BorderLayout.CENTER);
- uinPassPanel.add(rememberPassBox, BorderLayout.SOUTH);
-
- uinPassPanel.setBorder(BorderFactory.createTitledBorder(Resources
- .getString("plugin.yahooaccregwizz.USERID_AND_PASSWORD")));
-
- mainPanel.add(uinPassPanel);
- this.add(mainPanel, BorderLayout.NORTH);
- }
-
- /**
- * Implements the <code>WizardPage.getIdentifier</code> to return this
- * page identifier.
- */
- public Object getIdentifier()
- {
- return FIRST_PAGE_IDENTIFIER;
- }
-
- /**
- * Implements the <code>WizardPage.getNextPageIdentifier</code> to return
- * the next page identifier - the summary page.
- */
- public Object getNextPageIdentifier()
- {
- return nextPageIdentifier;
- }
-
- /**
- * Implements the <code>WizardPage.getBackPageIdentifier</code> to return
- * the back identifier. In this case it's null because this is the first
- * wizard page.
- * @return the identifier of the previous wizard page
- */
- public Object getBackPageIdentifier()
- {
- return null;
- }
-
- /**
- * Implements the <code>WizardPage.getWizardForm</code> to return this
- * panel.
- */
- public Object getWizardForm()
- {
- return this;
- }
-
- /**
- * Before this page is displayed enables or disables the "Next" wizard
- * button according to whether the UIN field is empty.
- */
- public void pageShowing()
- {
- this.setNextButtonAccordingToUIN();
- }
-
- /**
- * Saves the user input when the "Next" wizard buttons is clicked.
- */
- public void commitPage()
- {
- YahooAccountRegistration registration = wizard.getRegistration();
-
- String userID = userIDField.getText();
-
- if(userID == null || userID.trim().length() == 0)
- throw new IllegalStateException("No user ID provided.");
-
- registration.setUserID(userID);
- registration.setPassword(new String(passField.getPassword()));
- registration.setRememberPassword(rememberPassBox.isSelected());
-
- nextPageIdentifier = SUMMARY_PAGE_IDENTIFIER;
-
- isCommitted = true;
- }
-
- /**
- * Enables or disables the "Next" wizard button according to whether the UIN
- * field is empty.
- */
- private void setNextButtonAccordingToUIN()
- {
- if (userIDField.getText() == null || userIDField.getText().equals(""))
- {
- wizard.getWizardContainer().setNextFinishButtonEnabled(false);
- }
- else
- {
- wizard.getWizardContainer().setNextFinishButtonEnabled(true);
- }
- }
-
- /**
- * Handles the <tt>DocumentEvent</tt> triggered when user types in the UIN
- * field. Enables or disables the "Next" wizard button according to whether
- * the UIN field is empty.
- */
- public void insertUpdate(DocumentEvent e)
- {
- this.setNextButtonAccordingToUIN();
- }
-
- /**
- * Handles the <tt>DocumentEvent</tt> triggered when user deletes letters
- * from the UIN field. Enables or disables the "Next" wizard button
- * according to whether the UIN field is empty.
- */
- public void removeUpdate(DocumentEvent e)
- {
- this.setNextButtonAccordingToUIN();
- }
-
- public void changedUpdate(DocumentEvent e)
- {
- }
-
- public void pageHiding()
- {
- }
-
- public void pageShown()
- {
- }
-
- public void pageBack()
- {
- }
-
- /**
- * Fills the UIN and Password fields in this panel with the data coming
- * from the given protocolProvider.
- *
- * @param protocolProvider The <tt>ProtocolProviderService</tt> to load
- * the data from.
- */
- public void loadAccount(ProtocolProviderService protocolProvider)
- {
- AccountID accountID = protocolProvider.getAccountID();
- String password = YahooAccRegWizzActivator
- .getYahooProtocolProviderFactory().loadPassword(accountID);
-
- this.userIDField.setEnabled(false);
- this.userIDField.setText(accountID.getUserID());
-
- if (password != null)
- {
- this.passField.setText(password);
- this.rememberPassBox.setSelected(true);
- }
- }
-
- public Object getSimpleForm()
- {
- return uinPassPanel;
- }
-
- public boolean isCommitted()
- {
- return isCommitted;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/yahooaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/yahooaccregwizz/Resources.java
deleted file mode 100644
index c41a72f..0000000
--- a/src/net/java/sip/communicator/plugin/yahooaccregwizz/Resources.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.yahooaccregwizz;
-
-import net.java.sip.communicator.service.resources.*;
-
-import org.jitsi.service.resources.*;
-
-/**
- * The <tt>Resources</tt> class manages the access to the internationalization
- * properties files and the image resources used in this plugin.
- *
- * @author Yana Stamcheva
- */
-public class Resources
-{
- private static ResourceManagementService resourcesService;
-
- public static ImageID YAHOO_LOGO
- = new ImageID("service.protocol.yahoo.YAHOO_16x16");
-
- public static ImageID PAGE_IMAGE
- = new ImageID("service.protocol.yahoo.YAHOO_64x64");
-
- /**
- * Returns an internationalized string corresponding to the given key.
- * @param key The key of the string.
- * @return An internationalized string corresponding to the given key.
- */
- public static String getString(String key)
- {
- return getResources().getI18NString(key);
- }
-
- /**
- * Loads an image from a given image identifier.
- * @param imageID The identifier of the image.
- * @return The image for the given identifier.
- */
- public static byte[] getImage(ImageID imageID)
- {
- return getResources().getImageInBytes(imageID.getId());
- }
-
- /**
- * Returns the <tt>ResourceManagementService</tt>.
- *
- * @return the <tt>ResourceManagementService</tt>.
- */
- public static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- resourcesService =
- ResourceManagementServiceUtils
- .getService(YahooAccRegWizzActivator.bundleContext);
- return resourcesService;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/yahooaccregwizz/YahooAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/yahooaccregwizz/YahooAccRegWizzActivator.java
deleted file mode 100644
index cd526a9..0000000
--- a/src/net/java/sip/communicator/plugin/yahooaccregwizz/YahooAccRegWizzActivator.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.yahooaccregwizz;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.browserlauncher.*;
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * Registers the <tt>YahooAccountRegistrationWizard</tt> in the UI Service.
- *
- * @author Yana Stamcheva
- */
-public class YahooAccRegWizzActivator
- extends AbstractServiceDependentActivator
-{
- /**
- * OSGi bundle context.
- */
- public static BundleContext bundleContext;
-
- private static final Logger logger =
- Logger.getLogger(YahooAccRegWizzActivator.class);
-
- private static BrowserLauncherService browserLauncherService;
-
- private static WizardContainer wizardContainer;
-
- private static YahooAccountRegistrationWizard yahooWizard;
-
- private static UIService uiService;
-
- /**
- * Starts this bundle.
- */
- @Override
- public void start(Object dependentService)
- {
- uiService = (UIService)dependentService;
-
- wizardContainer = uiService.getAccountRegWizardContainer();
-
- yahooWizard = new YahooAccountRegistrationWizard(wizardContainer);
-
- Hashtable<String, String> containerFilter
- = new Hashtable<String, String>();
-
- containerFilter.put(
- ProtocolProviderFactory.PROTOCOL,
- ProtocolNames.YAHOO);
-
- bundleContext.registerService(
- AccountRegistrationWizard.class.getName(),
- yahooWizard,
- containerFilter);
- }
-
- /**
- * The dependent class. We are waiting for the ui service.
- * @return the ui service class.
- */
- @Override
- public Class<?> getDependentServiceClass()
- {
- return UIService.class;
- }
-
- /**
- * The bundle context to use.
- * @param context the context to set.
- */
- @Override
- public void setBundleContext(BundleContext context)
- {
- bundleContext = context;
- }
-
- public void stop(BundleContext bundleContext) throws Exception
- {
- }
-
- /**
- * Returns the <tt>ProtocolProviderFactory</tt> for the Yahoo protocol.
- * @return the <tt>ProtocolProviderFactory</tt> for the Yahoo protocol
- */
- public static ProtocolProviderFactory getYahooProtocolProviderFactory()
- {
- ServiceReference[] serRefs = null;
- String osgiFilter
- = "("
- + ProtocolProviderFactory.PROTOCOL
- + "="
- + ProtocolNames.YAHOO
- + ")";
-
- try {
- serRefs
- = bundleContext.getServiceReferences(
- ProtocolProviderFactory.class.getName(),
- osgiFilter);
- }
- catch (InvalidSyntaxException ex){
- logger.error("YahooAccRegWizzActivator : " + ex);
- }
-
- return
- (serRefs == null)
- ? null
- : (ProtocolProviderFactory)
- bundleContext.getService(serRefs[0]);
- }
-
- /**
- * Returns the <tt>UIService</tt>.
- *
- * @return the <tt>UIService</tt>
- */
- public static UIService getUIService()
- {
- return uiService;
- }
-
- /**
- * Returns the <tt>BrowserLauncherService</tt> obtained from the bundle
- * context.
- * @return the <tt>BrowserLauncherService</tt> obtained from the bundle
- * context
- */
- public static BrowserLauncherService getBrowserLauncher() {
- if (browserLauncherService == null) {
- ServiceReference serviceReference = bundleContext
- .getServiceReference(BrowserLauncherService.class.getName());
-
- browserLauncherService = (BrowserLauncherService) bundleContext
- .getService(serviceReference);
- }
-
- return browserLauncherService;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/yahooaccregwizz/YahooAccountRegistration.java b/src/net/java/sip/communicator/plugin/yahooaccregwizz/YahooAccountRegistration.java
deleted file mode 100644
index 6cf7759..0000000
--- a/src/net/java/sip/communicator/plugin/yahooaccregwizz/YahooAccountRegistration.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.yahooaccregwizz;
-
-/**
- * The <tt>YahooAccountRegistration</tt> is used to store all user input data
- * through the <tt>YahooAccountRegistrationWizard</tt>.
- *
- * @author Yana Stamcheva
- */
-public class YahooAccountRegistration {
-
- private String uin;
-
- private String password;
-
- private boolean rememberPassword = true;
-
- /**
- * Returns the password of the yahoo registration account.
- * @return the password of the yahoo registration account.
- */
- public String getPassword() {
- return password;
- }
-
- /**
- * Sets the password of the yahoo registration account.
- * @param password the password of the yahoo registration account.
- */
- public void setPassword(String password) {
- this.password = password;
- }
-
- /**
- * Returns TRUE if password has to remembered, FALSE otherwise.
- * @return TRUE if password has to remembered, FALSE otherwise
- */
- public boolean isRememberPassword() {
- return rememberPassword;
- }
-
- /**
- * Sets the rememberPassword value of this yahoo account registration.
- * @param rememberPassword TRUE if password has to remembered, FALSE
- * otherwise
- */
- public void setRememberPassword(boolean rememberPassword) {
- this.rememberPassword = rememberPassword;
- }
-
- /**
- * Returns the UIN of the yahoo registration account.
- * @return the UIN of the yahoo registration account.
- */
- public String getUin() {
- return uin;
- }
-
- /**
- * Sets the UIN of the yahoo registration account.
- * @param uin the UIN of the yahoo registration account.
- */
- public void setUserID(String uin) {
- this.uin = uin;
- }
-
-}
diff --git a/src/net/java/sip/communicator/plugin/yahooaccregwizz/YahooAccountRegistrationWizard.java b/src/net/java/sip/communicator/plugin/yahooaccregwizz/YahooAccountRegistrationWizard.java
deleted file mode 100644
index 033f409..0000000
--- a/src/net/java/sip/communicator/plugin/yahooaccregwizz/YahooAccountRegistrationWizard.java
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.yahooaccregwizz;
-
-import java.awt.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * The <tt>YahooAccountRegistrationWizard</tt> is an implementation of the
- * <tt>AccountRegistrationWizard</tt> for the Yahoo protocol. It should allow
- * the user to create and configure a new Yahoo account.
- *
- * @author Yana Stamcheva
- */
-public class YahooAccountRegistrationWizard
- extends DesktopAccountRegistrationWizard
-{
- private final Logger logger
- = Logger.getLogger(YahooAccountRegistrationWizard.class);
-
- private FirstWizardPage firstWizardPage;
-
- private YahooAccountRegistration registration =
- new YahooAccountRegistration();
-
- private ProtocolProviderService protocolProvider;
-
- /**
- * Creates an instance of <tt>YahooAccountRegistrationWizard</tt>.
- *
- * @param wizardContainer the wizard container, where this wizard is added
- */
- public YahooAccountRegistrationWizard(WizardContainer wizardContainer)
- {
- setWizardContainer(wizardContainer);
-
- wizardContainer
- .setFinishButtonText(Resources.getString("service.gui.SIGN_IN"));
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getIcon</code> method.
- * Returns the icon to be used for this wizard.
- *
- * @return byte[]
- */
- @Override
- public byte[] getIcon()
- {
- return Resources.getImage(Resources.YAHOO_LOGO);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getPageImage</code>
- * method. Returns the image used to decorate the wizard page
- *
- * @return byte[] the image used to decorate the wizard page
- */
- @Override
- public byte[] getPageImage()
- {
- return Resources.getImage(Resources.PAGE_IMAGE);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getProtocolName</code>
- * method. Returns the protocol name for this wizard.
- *
- * @return String
- */
- @Override
- public String getProtocolName()
- {
- return Resources.getString("plugin.yahooaccregwizz.PROTOCOL_NAME");
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getProtocolDescription
- * </code>
- * method. Returns the description of the protocol for this wizard.
- *
- * @return String
- */
- @Override
- public String getProtocolDescription()
- {
- return Resources
- .getString("plugin.yahooaccregwizz.PROTOCOL_DESCRIPTION");
- }
-
- /**
- * Returns the set of pages contained in this wizard.
- *
- * @return Iterator
- */
- @Override
- public Iterator<WizardPage> getPages()
- {
- java.util.List<WizardPage> pages = new ArrayList<WizardPage>();
- firstWizardPage = new FirstWizardPage(this);
-
- pages.add(firstWizardPage);
-
- return pages.iterator();
- }
-
- /**
- * Returns the set of data that user has entered through this wizard.
- *
- * @return Iterator
- */
- @Override
- public Iterator<Map.Entry<String, String>> getSummary()
- {
- Hashtable<String, String> summaryTable
- = new Hashtable<String, String>();
-
- summaryTable.put(
- Resources.getString("plugin.yahooaccregwizz.USERNAME"),
- registration.getUin());
- summaryTable.put(
- Resources.getString("service.gui.REMEMBER_PASSWORD"),
- Boolean.toString(registration.isRememberPassword()));
-
- return summaryTable.entrySet().iterator();
- }
-
- /**
- * Defines the operations that will be executed when the user clicks on
- * the wizard "Signin" button.
- *
- * @return the created <tt>ProtocolProviderService</tt> corresponding to the
- * new account
- * @throws OperationFailedException if the operation didn't succeed
- */
- @Override
- public ProtocolProviderService signin()
- throws OperationFailedException
- {
- firstWizardPage.commitPage();
-
- return signin( registration.getUin(),
- registration.getPassword());
- }
-
- /**
- * Defines the operations that will be executed when the user clicks on
- * the wizard "Signin" button.
- *
- * @param userName the user name to sign in with
- * @param password the password to sign in with
- * @return the created <tt>ProtocolProviderService</tt> corresponding to the
- * new account
- * @throws OperationFailedException if the operation didn't succeed
- */
- @Override
- public ProtocolProviderService signin(String userName, String password)
- throws OperationFailedException
- {
- ProtocolProviderFactory factory =
- YahooAccRegWizzActivator.getYahooProtocolProviderFactory();
-
- return this.installAccount( factory,
- userName,
- password);
- }
-
- /**
- * Creates an account for the given user and password.
- *
- * @param providerFactory the ProtocolProviderFactory which will create the
- * account
- * @param user the user identifier
- * @param passwd the password
- * @return the <tt>ProtocolProviderService</tt> for the new account.
- */
- public ProtocolProviderService installAccount(
- ProtocolProviderFactory providerFactory, String user, String passwd)
- throws OperationFailedException
- {
- Hashtable<String, String> accountProperties
- = new Hashtable<String, String>();
-
- accountProperties.put(ProtocolProviderFactory.ACCOUNT_ICON_PATH,
- "resources/images/protocol/yahoo/yahoo32x32.png");
-
- if (registration.isRememberPassword())
- {
- accountProperties.put(ProtocolProviderFactory.PASSWORD, passwd);
- }
-
- if (isModification())
- {
- providerFactory.modifyAccount( protocolProvider,
- accountProperties);
-
- setModification(false);
-
- return protocolProvider;
- }
-
- try
- {
- AccountID accountID =
- providerFactory.installAccount(user, accountProperties);
-
- ServiceReference serRef =
- providerFactory.getProviderForAccount(accountID);
-
- protocolProvider =
- (ProtocolProviderService) YahooAccRegWizzActivator
- .bundleContext.getService(serRef);
- }
- catch (IllegalStateException exc)
- {
- logger.warn(exc.getMessage());
-
- throw new OperationFailedException(
- "Account already exists.",
- OperationFailedException.IDENTIFICATION_CONFLICT);
- }
- catch (Exception exc)
- {
- logger.warn(exc.getMessage());
-
- throw new OperationFailedException(
- "Failed to add account",
- OperationFailedException.GENERAL_ERROR);
- }
-
- return protocolProvider;
- }
-
- /**
- * Fills the UIN and Password fields in this panel with the data coming
- * from the given protocolProvider.
- *
- * @param protocolProvider The <tt>ProtocolProviderService</tt> to load
- * the data from.
- */
- @Override
- public void loadAccount(ProtocolProviderService protocolProvider)
- {
- setModification(true);
-
- this.protocolProvider = protocolProvider;
-
- this.registration = new YahooAccountRegistration();
-
- this.firstWizardPage.loadAccount(protocolProvider);
- }
-
- /**
- * Returns the registration object, which will store all the data through
- * the wizard.
- *
- * @return the registration object, which will store all the data through
- * the wizard
- */
- public YahooAccountRegistration getRegistration()
- {
- return registration;
- }
-
- /**
- * Returns the size of this wizard.
- * @return the size of this wizard
- */
- @Override
- public Dimension getSize()
- {
- return new Dimension(600, 500);
- }
-
- /**
- * Returns the identifier of the page to show first in the wizard.
- * @return the identifier of the page to show first in the wizard.
- */
- @Override
- public Object getFirstPageIdentifier()
- {
- return firstWizardPage.getIdentifier();
- }
-
- /**
- * Returns the identifier of the page to show last in the wizard.
- * @return the identifier of the page to show last in the wizard.
- */
- @Override
- public Object getLastPageIdentifier()
- {
- return firstWizardPage.getIdentifier();
- }
-
- /**
- * Returns an example string, which should indicate to the user how the
- * user name should look like.
- * @return an example string, which should indicate to the user how the
- * user name should look like.
- */
- @Override
- public String getUserNameExample()
- {
- return FirstWizardPage.USER_NAME_EXAMPLE;
- }
-
- /**
- * Defines the operation that will be executed when user clicks on the
- * "Sign up" link.
- * @throws UnsupportedOperationException if the web sign up operation is
- * not supported by the current implementation.
- */
- @Override
- public void webSignup()
- {
- YahooAccRegWizzActivator.getBrowserLauncher()
- .openURL("https://edit.yahoo.com/registration");
- }
-
- /**
- * Returns <code>true</code> if the web sign up is supported by the current
- * implementation, <code>false</code> - otherwise.
- * @return <code>true</code> if the web sign up is supported by the current
- * implementation, <code>false</code> - otherwise
- */
- @Override
- public boolean isWebSignupSupported()
- {
- return true;
- }
-
- /**
- * Returns a simple account registration form that would be the first form
- * shown to the user. Only if the user needs more settings she'll choose
- * to open the advanced wizard, consisted by all pages.
- *
- * @param isCreateAccount indicates if the simple form should be opened as
- * a create account form or as a login form
- * @return a simple account registration form
- */
- @Override
- public Object getSimpleForm(boolean isCreateAccount)
- {
- firstWizardPage = new FirstWizardPage(this);
-
- return firstWizardPage.getSimpleForm();
- }
-
- /**
- * Whether the advanced configuration is enabled. Gives an option
- * to disable/hide advanced config button.
- * @return whether the advanced configuration is enabled.
- */
- public boolean isAdvancedConfigurationEnabled()
- {
- return false;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/yahooaccregwizz/yahooaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/yahooaccregwizz/yahooaccregwizz.manifest.mf
deleted file mode 100644
index a975e2e..0000000
--- a/src/net/java/sip/communicator/plugin/yahooaccregwizz/yahooaccregwizz.manifest.mf
+++ /dev/null
@@ -1,33 +0,0 @@
-Bundle-Activator: net.java.sip.communicator.plugin.yahooaccregwizz.YahooAccRegWizzActivator
-Bundle-Name: Yahoo account registration wizard
-Bundle-Description: Yahoo account registration wizard.
-Bundle-Vendor: jitsi.org
-Bundle-Version: 0.0.1
-Bundle-SymbolicName: net.java.sip.communicator.plugin.yahooaccregwizz
-Import-Package: org.osgi.framework,
- net.java.sip.communicator.service.browserlauncher,
- org.jitsi.service.configuration,
- net.java.sip.communicator.service.contactlist,
- net.java.sip.communicator.service.contactlist.event,
- net.java.sip.communicator.service.gui,
- net.java.sip.communicator.service.gui.event,
- net.java.sip.communicator.service.protocol,
- net.java.sip.communicator.service.protocol.event,
- net.java.sip.communicator.service.protocol.icqconstants,
- org.jitsi.service.resources, net.java.sip.communicator.service.resources,
- net.java.sip.communicator.util,
- net.java.sip.communicator.plugin.desktoputil,
- javax.swing,
- javax.swing.event,
- javax.swing.table,
- javax.swing.text,
- javax.swing.text.html,
- javax.accessibility,
- javax.swing.plaf,
- javax.swing.plaf.metal,
- javax.swing.plaf.basic,
- javax.imageio,
- javax.swing.filechooser,
- javax.swing.tree,
- javax.swing.undo,
- javax.swing.border
diff --git a/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/FirstWizardPage.java b/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/FirstWizardPage.java
deleted file mode 100644
index 0f8815c..0000000
--- a/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/FirstWizardPage.java
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.zeroconfaccregwizz;
-
-import java.awt.*;
-
-import javax.swing.*;
-import javax.swing.event.*;
-
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
-
-/**
- * The <tt>FirstWizardPage</tt> is the page, where user could enter the user ID
- * and the password of the account.
- *
- * @author Christian Vincenot
- * @author Maxime Catelin
- */
-public class FirstWizardPage
- extends TransparentPanel
- implements WizardPage,
- DocumentListener
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- public static final String FIRST_PAGE_IDENTIFIER = "FirstPageIdentifier";
-
- private JPanel userPassPanel = new TransparentPanel(new BorderLayout(10, 10));
-
- private JPanel labelsPanel = new TransparentPanel();
-
- private JPanel valuesPanel = new TransparentPanel();
-
- private JLabel userID = new JLabel(
- Resources.getString("plugin.zeroaccregwizz.USERID"));
-
- /* TEMPORARY : HARD CODED !! Should be added to Resource */
- private JLabel firstLabel
- = new JLabel(Resources.getString("plugin.zeroaccregwizz.FIRST_NAME"));
- private JLabel lastLabel
- = new JLabel(Resources.getString("plugin.zeroaccregwizz.LAST_NAME"));
- private JLabel mailLabel
- = new JLabel(Resources.getString("plugin.zeroaccregwizz.EMAIL"));
-
- private JPanel emptyPanel = new TransparentPanel();
- private JPanel emptyPanel2 = new TransparentPanel();
- private JPanel emptyPanel3 = new TransparentPanel();
- private JPanel emptyPanel4 = new TransparentPanel();
-
- private JLabel userIDExampleLabel = new JLabel("Ex: Bill@microsoft");
- private JLabel firstExampleLabel = new JLabel("Ex: Bill");
- private JLabel lastExampleLabel = new JLabel("Ex: Gates");
- private JLabel mailExampleLabel = new JLabel("Ex: Bill@microsoft.com");
-
- private JTextField userIDField = new TrimTextField();
- private JTextField firstField = new JTextField();
- private JTextField lastField = new JTextField();
- private JTextField mailField = new JTextField();
-
- private JCheckBox rememberContacts =
- new SIPCommCheckBox(Resources.getString(
- "plugin.zeroaccregwizz.REMEMBER_CONTACTS"));
-
- private JPanel mainPanel = new TransparentPanel();
-
- private Object nextPageIdentifier = WizardPage.SUMMARY_PAGE_IDENTIFIER;
-
- private ZeroconfAccountRegistrationWizard wizard;
-
- private boolean isCommitted = false;
-
- /**
- * Creates an instance of <tt>FirstWizardPage</tt>.
- *
- * @param wizard the parent wizard
- */
- public FirstWizardPage(ZeroconfAccountRegistrationWizard wizard)
- {
-
- super(new BorderLayout());
-
- this.wizard = wizard;
-
- mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
-
- this.init();
-
- this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
-
- this.labelsPanel.setLayout(
- new BoxLayout(labelsPanel, BoxLayout.Y_AXIS));
-
- this.valuesPanel.setLayout(
- new BoxLayout(valuesPanel, BoxLayout.Y_AXIS));
- }
-
- /**
- * Initializes all panels, buttons, etc.
- */
- private void init()
- {
- this.userIDField.getDocument().addDocumentListener(this);
- this.firstField.getDocument().addDocumentListener(this);
- this.rememberContacts.setSelected(false);
-
- // not used so disable it for the moment
- this.rememberContacts.setEnabled(false);
-
- this.userIDExampleLabel.setForeground(Color.GRAY);
- this.userIDExampleLabel.setFont(
- userIDExampleLabel.getFont().deriveFont(8));
- this.emptyPanel.setMaximumSize(new Dimension(40, 35));
- this.userIDExampleLabel.setBorder(
- BorderFactory.createEmptyBorder(0, 0, 8,0));
-
- this.firstExampleLabel.setForeground(Color.GRAY);
- this.firstExampleLabel.setFont(
- firstExampleLabel.getFont().deriveFont(8));
- this.emptyPanel2.setMaximumSize(new Dimension(40, 35));
- this.firstExampleLabel.setBorder(
- BorderFactory.createEmptyBorder(0, 0, 8,0));
-
- this.lastExampleLabel.setForeground(Color.GRAY);
- this.lastExampleLabel.setFont(
- lastExampleLabel.getFont().deriveFont(8));
- this.emptyPanel3.setMaximumSize(new Dimension(40, 35));
- this.lastExampleLabel.setBorder(
- BorderFactory.createEmptyBorder(0, 0, 8,0));
-
- this.mailExampleLabel.setForeground(Color.GRAY);
- this.mailExampleLabel.setFont(
- mailExampleLabel.getFont().deriveFont(8));
- this.emptyPanel4.setMaximumSize(new Dimension(40, 35));
- this.mailExampleLabel.setBorder(
- BorderFactory.createEmptyBorder(0, 0, 8,0));
-
- labelsPanel.add(userID);
- labelsPanel.add(emptyPanel);
- labelsPanel.add(firstLabel);
- labelsPanel.add(emptyPanel2);
- labelsPanel.add(lastLabel);
- labelsPanel.add(emptyPanel3);
- labelsPanel.add(mailLabel);
-
- valuesPanel.add(userIDField);
- valuesPanel.add(userIDExampleLabel);
- valuesPanel.add(firstField);
- valuesPanel.add(firstExampleLabel);
- valuesPanel.add(lastField);
- valuesPanel.add(lastExampleLabel);
- valuesPanel.add(mailField);
- valuesPanel.add(mailExampleLabel);
-
- userPassPanel.add(labelsPanel, BorderLayout.WEST);
- userPassPanel.add(valuesPanel, BorderLayout.CENTER);
- userPassPanel.add(rememberContacts, BorderLayout.SOUTH);
-
- userPassPanel.setBorder(BorderFactory.createTitledBorder(
- Resources.getString("plugin.zeroaccregwizz.USERID_AND_PASSWORD")));
-
- this.add(userPassPanel, BorderLayout.NORTH);
- }
-
- /**
- * Implements the <code>WizardPage.getIdentifier</code> to return
- * this page identifier.
- *
- * @return the Identifier of the first page in this wizard.
- */
- public Object getIdentifier()
- {
- return FIRST_PAGE_IDENTIFIER;
- }
-
- /**
- * Implements the <code>WizardPage.getNextPageIdentifier</code> to return
- * the next page identifier - the summary page.
- *
- * @return the identifier of the page following this one.
- */
- public Object getNextPageIdentifier()
- {
- return nextPageIdentifier;
- }
-
- /**
- * Implements the <code>WizardPage.getBackPageIdentifier</code> to return
- * the back identifier. In this case it's null because this is the first
- * wizard page.
- *
- * @return the identifier of the previous wizard page
- */
- public Object getBackPageIdentifier()
- {
- return null;
- }
-
- /**
- * Implements the <code>WizardPage.getWizardForm</code> to return
- * this panel.
- *
- * @return the component to be displayed in this wizard page.
- */
- public Object getWizardForm()
- {
- return this;
- }
-
- /**
- * Before this page is displayed enables or disables the "Next" wizard
- * button according to whether the UserID field is empty.
- */
- public void pageShowing()
- {
- this.setNextButtonAccordingToUserID();
- }
-
- /**
- * Saves the user input when the "Next" wizard buttons is clicked.
- */
- public void commitPage()
- {
- ZeroconfAccountRegistration registration
- = wizard.getRegistration();
-
- String userID = userIDField.getText();
-
- if(userID == null || userID.trim().length() == 0)
- throw new IllegalStateException("No user ID provided.");
-
- registration.setUserID(userID);
- registration.setFirst(firstField.getText());
- registration.setLast(lastField.getText());
- registration.setMail(mailField.getText());
-
- registration.setRememberContacts(rememberContacts.isSelected());
-
- nextPageIdentifier = SUMMARY_PAGE_IDENTIFIER;
-
- isCommitted = true;
- }
-
- /**
- * Enables or disables the "Next" wizard button according to whether the
- * User ID field is empty.
- */
- private void setNextButtonAccordingToUserID()
- {
- if (userIDField.getText() == null || userIDField.getText().equals(""))
- {
- wizard.getWizardContainer().setNextFinishButtonEnabled(false);
- }
- else
- {
- wizard.getWizardContainer().setNextFinishButtonEnabled(true);
- }
- }
-
- /**
- * Handles the <tt>DocumentEvent</tt> triggered when user types in the
- * User ID field. Enables or disables the "Next" wizard button according to
- * whether the User ID field is empty.
- *
- * @param event the event containing the update.
- */
- public void insertUpdate(DocumentEvent event)
- {
- this.setNextButtonAccordingToUserID();
- }
-
- /**
- * Handles the <tt>DocumentEvent</tt> triggered when user deletes letters
- * from the UserID field. Enables or disables the "Next" wizard button
- * according to whether the UserID field is empty.
- *
- * @param event the event containing the update.
- */
- public void removeUpdate(DocumentEvent event)
- {
- this.setNextButtonAccordingToUserID();
- }
-
- /**
- * Implemented from Wizard interface
- * @param event Event that happened
- */
- public void changedUpdate(DocumentEvent event)
- {
- }
-
- /**
- * Created to
- */
- public void pageHiding()
- {
- }
-
- /**
- * Implemented from Wizard interface
- */
- public void pageShown()
- {
- }
-
- /**
- * Implemented from Wizard interface
- */
- public void pageBack()
- {
- }
-
- /**
- * Fills the UserID field in this panel with the data comming
- * from the given protocolProvider.
- * @param protocolProvider The <tt>ProtocolProviderService</tt> to load the
- * data from.
- */
- public void loadAccount(ProtocolProviderService protocolProvider)
- {
- AccountID accountID = protocolProvider.getAccountID();
-
- this.userIDField.setEnabled(false);
- this.userIDField.setText(accountID.getUserID());
- this.firstField.setText(accountID.getAccountPropertyString("first"));
- this.lastField.setText(accountID.getAccountPropertyString("last"));
- this.mailField.setText(accountID.getAccountPropertyString("mail"));
-
- boolean remember = accountID
- .getAccountPropertyBoolean("rememberContacts", true);
- if (remember)
- this.rememberContacts.setSelected(true);
- }
-
- public Object getSimpleForm()
- {
- JPanel simplePanel = new TransparentPanel(new BorderLayout(10, 10));
-
- simplePanel.add(userID, BorderLayout.WEST);
- simplePanel.add(userIDField, BorderLayout.CENTER);
-
- return simplePanel;
- }
-
- public boolean isCommitted()
- {
- return isCommitted;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/Resources.java
deleted file mode 100644
index 83b6131..0000000
--- a/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/Resources.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.zeroconfaccregwizz;
-
-import net.java.sip.communicator.service.resources.*;
-
-import org.jitsi.service.resources.*;
-
-/**
- * The Resources class manages the access to the internationalization
- * properties files and the images properties file.
- *
- * @author Christian Vincenot
- * @author Maxime Catelin
- */
-public class Resources
-{
- private static ResourceManagementService resourcesService;
-
- public static ImageID ZEROCONF_LOGO
- = new ImageID("service.protocol.zeroconf.ZEROCONF_16x16");
-
- public static ImageID PAGE_IMAGE
- = new ImageID("service.protocol.zeroconf.ZEROCONF_64x64");
-
- /**
- * Returns an internationalized string corresponding to the given key.
- * @param key The key of the string.
- * @return An internationalized string corresponding to the given key.
- */
- public static String getString(String key)
- {
- return getResources().getI18NString(key);
- }
-
- /**
- * Loads an image from a given image identifier.
- * @param imageID The identifier of the image.
- * @return The image for the given identifier.
- */
- public static byte[] getImage(ImageID imageID)
- {
- return getResources().getImageInBytes(imageID.getId());
- }
-
- /**
- * Returns the <tt>ResourceManagementService</tt>.
- *
- * @return the <tt>ResourceManagementService</tt>.
- */
- public static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- resourcesService =
- ResourceManagementServiceUtils
- .getService(ZeroconfAccRegWizzActivator.bundleContext);
- return resourcesService;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/ZeroconfAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/ZeroconfAccRegWizzActivator.java
deleted file mode 100644
index 352796b..0000000
--- a/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/ZeroconfAccRegWizzActivator.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.zeroconfaccregwizz;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * Registers the <tt>ZeroconfAccountRegistrationWizard</tt> in the UI Service.
- *
- * @author Christian Vincenot
- * @author Maxime Catelin
- */
-public class ZeroconfAccRegWizzActivator
- implements BundleActivator
-{
- private static final Logger logger =
- Logger.getLogger(ZeroconfAccRegWizzActivator.class);
-
- /**
- * A currently valid bundle context.
- */
- public static BundleContext bundleContext;
-
- private static UIService uiService;
-
- /**
- * Starts this bundle.
- * @param bc the currently valid <tt>BundleContext</tt>.
- */
- public void start(BundleContext bc)
- {
- if (logger.isInfoEnabled())
- logger.info("Loading zeroconf account wizard.");
-
- bundleContext = bc;
-
- ServiceReference uiServiceRef = bundleContext
- .getServiceReference(UIService.class.getName());
-
- uiService = (UIService) bundleContext.getService(uiServiceRef);
-
- WizardContainer wizardContainer
- = uiService.getAccountRegWizardContainer();
-
- ZeroconfAccountRegistrationWizard zeroconfWizard
- = new ZeroconfAccountRegistrationWizard(wizardContainer);
-
- Hashtable<String, String> containerFilter
- = new Hashtable<String, String>();
-
- containerFilter.put(
- ProtocolProviderFactory.PROTOCOL,
- ProtocolNames.ZEROCONF);
-
- bundleContext.registerService(
- AccountRegistrationWizard.class.getName(),
- zeroconfWizard,
- containerFilter);
-
- if (logger.isInfoEnabled())
- logger.info("Zeroconf account registration wizard [STARTED].");
- }
-
- /**
- * Called when this bundle is stopped so the Framework can perform the
- * bundle-specific activities necessary to stop the bundle.
- *
- * @param context The execution context of the bundle being stopped.
- */
- public void stop(BundleContext context)
- {
-
- }
-
- /**
- * Returns the <tt>ProtocolProviderFactory</tt> for the Zeroconf protocol.
- * @return the <tt>ProtocolProviderFactory</tt> for the Zeroconf protocol
- */
- public static ProtocolProviderFactory getZeroconfProtocolProviderFactory()
- {
- ServiceReference[] serRefs = null;
- String osgiFilter
- = "("
- + ProtocolProviderFactory.PROTOCOL
- + "="
- + ProtocolNames.ZEROCONF
- + ")";
-
- try
- {
- serRefs
- = bundleContext.getServiceReferences(
- ProtocolProviderFactory.class.getName(),
- osgiFilter);
- }
- catch (InvalidSyntaxException ex)
- {
- logger.error(ex);
- }
-
- return
- (serRefs == null)
- ? null
- : (ProtocolProviderFactory)
- bundleContext.getService(serRefs[0]);
- }
-
- /**
- * Returns the bundleContext that we received when we were started.
- * @return a currently valid instance of a bundleContext.
- */
- public BundleContext getBundleContext()
- {
- return bundleContext;
- }
-
- /**
- * Returns the <tt>UIService</tt>.
- *
- * @return the <tt>UIService</tt>
- */
- public static UIService getUIService()
- {
- return uiService;
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/ZeroconfAccountRegistration.java b/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/ZeroconfAccountRegistration.java
deleted file mode 100644
index df4f6f5..0000000
--- a/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/ZeroconfAccountRegistration.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.zeroconfaccregwizz;
-
-/**
- * The <tt>ZeroconfAccountRegistration</tt> is used to store
- * all user input data
- * through the <tt>ZeroconfAccountRegistrationWizard</tt>.
- *
- * @author Christian Vincenot
- * @author Maxime Catelin
- */
-public class ZeroconfAccountRegistration
-{
- private String userID;
- private String first;
- private String last;
- private String mail;
- private boolean rememberContacts;
-
- /**
- * Returns the User ID of the zeroconf registration account.
- * @return the User ID of the zeroconf registration account.
- */
- public String getUserID()
- {
- return userID;
- }
-
- /**
- * Sets the user ID of the zeroconf registration account.
- * @param userID the userID of the zeroconf registration account.
- */
- public void setUserID(String userID)
- {
- this.userID = userID;
- }
-
- /**
- * Returns the password of the Zeroconf registration account.
- * @return the password of the Zeroconf registration account.
- */
- public String getFirst()
- {
- return first;
- }
-
- /**
- * Sets the password of the Zeroconf registration account.
- * @param first first name
- */
- public void setFirst(String first)
- {
- this.first = first;
- }
-
- /**
- * Returns <tt>true</tt> if password has to remembered, <tt>false</tt>
- * otherwise.
- * @return <tt>true</tt> if password has to remembered, <tt>false</tt>
- * otherwise.
- */
- public boolean isRememberContacts()
- {
- return rememberContacts;
- }
-
- /**
- * Sets the rememberPassword value of this Zeroconf account registration.
- * @param rememberContacts true if we want to remember the
- * contacts we meet, false otherwise
- */
- public void setRememberContacts(boolean rememberContacts)
- {
- this.rememberContacts = rememberContacts;
- }
-
- /**
- * Returns the last name
- * @return last name
- */
- public String getLast()
- {
- return last;
- }
-
- /**
- * Sets the last name
- * @param last last name
- */
- public void setLast(String last)
- {
- this.last = last;
- }
-
- /**
- * Returns the mail address
- * @return mail address
- */
- public String getMail()
- {
- return mail;
- }
-
- /**
- * Sets the mail address
- * @param mail mail address
- */
- public void setMail(String mail)
- {
- this.mail = mail;
- }
-
-
-}
diff --git a/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/ZeroconfAccountRegistrationWizard.java b/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/ZeroconfAccountRegistrationWizard.java
deleted file mode 100644
index 79f085f..0000000
--- a/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/ZeroconfAccountRegistrationWizard.java
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.plugin.zeroconfaccregwizz;
-
-import java.awt.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.gui.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * The <tt>ZeroconfAccountRegistrationWizard</tt> is an implementation of the
- * <tt>AccountRegistrationWizard</tt> for the Zeroconf protocol. It allows
- * the user to create and configure a new Zeroconf account.
- *
- * @author Christian Vincenot
- * @author Maxime Catelin
- */
-public class ZeroconfAccountRegistrationWizard
- extends DesktopAccountRegistrationWizard
-{
- private Logger logger
- = Logger.getLogger(ZeroconfAccountRegistrationWizard.class);
-
- /**
- * The first page of the zeroconf account registration wizard.
- */
- private FirstWizardPage firstWizardPage;
-
- /**
- * The object that we use to store details on an account that we will be
- * creating.
- */
- private ZeroconfAccountRegistration registration
- = new ZeroconfAccountRegistration();
-
- private ProtocolProviderService protocolProvider;
-
- /**
- * Creates an instance of <tt>ZeroconfAccountRegistrationWizard</tt>.
- * @param wizardContainer the wizard container, where this wizard
- * is added
- */
- public ZeroconfAccountRegistrationWizard(WizardContainer wizardContainer)
- {
- setWizardContainer(wizardContainer);
-
- wizardContainer
- .setFinishButtonText(Resources.getString("service.gui.SIGN_IN"));
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getIcon</code> method.
- * Returns the icon to be used for this wizard.
- * @return byte[]
- */
- @Override
- public byte[] getIcon()
- {
- return Resources.getImage(Resources.ZEROCONF_LOGO);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getPageImage</code> method.
- * Returns the image used to decorate the wizard page
- *
- * @return byte[] the image used to decorate the wizard page
- */
- @Override
- public byte[] getPageImage()
- {
- return Resources.getImage(Resources.PAGE_IMAGE);
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getProtocolName</code>
- * method. Returns the protocol name for this wizard.
- * @return String
- */
- @Override
- public String getProtocolName()
- {
- return Resources.getString("plugin.zeroaccregwizz.PROTOCOL_NAME");
- }
-
- /**
- * Implements the <code>AccountRegistrationWizard.getProtocolDescription
- * </code> method. Returns the description of the protocol for this wizard.
- * @return String
- */
- @Override
- public String getProtocolDescription()
- {
- return Resources.getString("plugin.zeroaccregwizz.PROTOCOL_DESCRIPTION");
- }
-
- /**
- * Returns the set of pages contained in this wizard.
- * @return Iterator
- */
- @Override
- public Iterator<WizardPage> getPages()
- {
- java.util.List<WizardPage> pages = new ArrayList<WizardPage>();
-
- // create new registration, our container needs the pages
- // this means this is a new wizard and we must reset all data
- // it will be invoked and when the wizard cleans and unregister
- // our pages, but this fix don't hurt in this situation.
- this.registration = new ZeroconfAccountRegistration();
-
- firstWizardPage = new FirstWizardPage(this);
-
- pages.add(firstWizardPage);
-
- return pages.iterator();
- }
-
- /**
- * Returns the set of data that user has entered through this wizard.
- * @return Iterator
- */
- @Override
- public Iterator<Map.Entry<String, String>> getSummary()
- {
- Hashtable<String, String> summaryTable = new Hashtable<String, String>();
-
- summaryTable.put("User ID", registration.getUserID());
- summaryTable.put("First Name", registration.getFirst());
- summaryTable.put("Last Name", registration.getLast());
- summaryTable.put("Mail Address", registration.getMail());
- summaryTable.put("Remember Bonjour contacts?",
- Boolean.toString(registration.isRememberContacts()));
-
- return summaryTable.entrySet().iterator();
- }
-
- /**
- * Defines the operations that will be executed when the user clicks on
- * the wizard "Signin" button.
- *
- * @return the created <tt>ProtocolProviderService</tt> corresponding to the
- * new account
- * @throws OperationFailedException if the operation didn't succeed
- */
- @Override
- public ProtocolProviderService signin()
- throws OperationFailedException
- {
- firstWizardPage.commitPage();
-
- return signin(registration.getUserID(), null);
- }
-
- /**
- * Defines the operations that will be executed when the user clicks on
- * the wizard "Signin" button.
- *
- * @param userName the user name to sign in with
- * @param password the password to sign in with
- * @return the created <tt>ProtocolProviderService</tt> corresponding to the
- * new account
- * @throws OperationFailedException if the operation didn't succeed
- */
- @Override
- public ProtocolProviderService signin(String userName, String password)
- throws OperationFailedException
- {
- ProtocolProviderFactory factory
- = ZeroconfAccRegWizzActivator.getZeroconfProtocolProviderFactory();
-
- return this.installAccount(factory,
- userName);
- }
-
- /**
- * Creates an account for the given user and password.
- *
- * @return the <tt>ProtocolProviderService</tt> for the new account.
- * @param providerFactory the ProtocolProviderFactory which will create
- * the account
- * @param user the user identifier
- */
- public ProtocolProviderService installAccount(
- ProtocolProviderFactory providerFactory,
- String user)
- throws OperationFailedException
- {
- Hashtable<String, String> accountProperties
- = new Hashtable<String, String>();
-
- accountProperties.put(ProtocolProviderFactory.ACCOUNT_ICON_PATH,
- "resources/images/protocol/zeroconf/zeroconf32x32.png");
-
- accountProperties.put("first", registration.getFirst());
- accountProperties.put("last", registration.getLast());
- accountProperties.put("mail", registration.getMail());
-
- accountProperties.put(
- ProtocolProviderFactory.NO_PASSWORD_REQUIRED,
- new Boolean(true).toString());
-
- accountProperties.put("rememberContacts",
- new Boolean(registration.isRememberContacts()).toString());
-
- if (isModification())
- {
- providerFactory.uninstallAccount(protocolProvider.getAccountID());
- this.protocolProvider = null;
- setModification(false);
- }
-
- try
- {
- AccountID accountID = providerFactory.installAccount(
- user, accountProperties);
-
- ServiceReference serRef = providerFactory
- .getProviderForAccount(accountID);
-
- protocolProvider = (ProtocolProviderService)
- ZeroconfAccRegWizzActivator.bundleContext
- .getService(serRef);
- }
- catch (IllegalStateException exc)
- {
- logger.warn(exc.getMessage());
-
- throw new OperationFailedException(
- "Account already exists.",
- OperationFailedException.IDENTIFICATION_CONFLICT);
- }
- catch (Exception exc)
- {
- logger.warn(exc.getMessage());
-
- throw new OperationFailedException(
- "Failed to add account",
- OperationFailedException.GENERAL_ERROR);
- }
-
-
- return protocolProvider;
- }
-
- /**
- * Fills the UserID and Password fields in this panel with the data coming
- * from the given protocolProvider.
- * @param protocolProvider The <tt>ProtocolProviderService</tt> to load the
- * data from.
- */
- @Override
- public void loadAccount(ProtocolProviderService protocolProvider)
- {
- setModification(true);
-
- this.protocolProvider = protocolProvider;
-
- this.registration = new ZeroconfAccountRegistration();
-
- this.firstWizardPage.loadAccount(protocolProvider);
- }
-
- /**
- * Returns the registration object, which will store all the data through
- * the wizard.
- *
- * @return the registration object, which will store all the data through
- * the wizard
- */
- public ZeroconfAccountRegistration getRegistration()
- {
- return registration;
- }
-
- /**
- * Returns the size of this wizard.
- * @return the size of this wizard
- */
- @Override
- public Dimension getSize()
- {
- return new Dimension(600, 500);
- }
-
- /**
- * Returns the identifier of the page to show first in the wizard.
- * @return the identifier of the page to show first in the wizard.
- */
- @Override
- public Object getFirstPageIdentifier()
- {
- return firstWizardPage.getIdentifier();
- }
-
- /**
- * Returns the identifier of the page to show last in the wizard.
- * @return the identifier of the page to show last in the wizard.
- */
- @Override
- public Object getLastPageIdentifier()
- {
- return firstWizardPage.getIdentifier();
- }
-
- /**
- * Returns the password label for the simplified account registration form.
- * @return the password label for the simplified account registration form.
- */
- public String getPasswordLabel()
- {
- return Resources.getString("service.gui.PASSWORD");
- }
-
- /**
- * Returns the user name label for the simplified account registration
- * form.
- *
- * @return the user name label for the simplified account registration
- * form.
- */
- public String getUserNameLabel()
- {
- return Resources.getString("userID");
- }
-
- /**
- * Returns an example string, which should indicate to the user how the
- * user name should look like.
- * @return an example string, which should indicate to the user how the
- * user name should look like.
- */
- @Override
- public String getUserNameExample()
- {
- return null;
- }
-
- /**
- * Indicates whether this wizard enables the simple "sign in" form shown
- * when the user opens the application for the first time. The simple
- * "sign in" form allows user to configure her account in one click, just
- * specifying her username and password and leaving any other configuration
- * as by default.
- * @return <code>true</code> if the simple "Sign in" form is enabled or
- * <code>false</code> otherwise.
- */
- @Override
- public boolean isSimpleFormEnabled()
- {
- return false;
- }
-
- /**
- * Returns a simple account registration form that would be the first form
- * shown to the user. Only if the user needs more settings she'll choose
- * to open the advanced wizard, consisted by all pages.
- *
- * @param isCreateAccount indicates if the simple form should be opened as
- * a create account form or as a login form
- * @return a simple account registration form
- */
- @Override
- public Object getSimpleForm(boolean isCreateAccount)
- {
- // when creating first wizard page, create and new
- // AccountRegistration to avoid reusing old instances and
- // data left from old registrations
- this.registration = new ZeroconfAccountRegistration();
-
- firstWizardPage = new FirstWizardPage(this);
- return firstWizardPage.getSimpleForm();
- }
-}
diff --git a/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/zeroconfaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/zeroconfaccregwizz.manifest.mf
deleted file mode 100644
index 57a863b..0000000
--- a/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/zeroconfaccregwizz.manifest.mf
+++ /dev/null
@@ -1,32 +0,0 @@
-Bundle-Activator: net.java.sip.communicator.plugin.zeroconfaccregwizz.ZeroconfAccRegWizzActivator
-Bundle-Name: Zeroconf account registration wizard
-Bundle-Description: Zeroconf account registration wizard.
-Bundle-Vendor: jitsi.org
-Bundle-Version: 0.0.1
-Bundle-SymbolicName: net.java.sip.communicator.plugin.zeroconfaccregwizz
-Import-Package: org.osgi.framework,
- net.java.sip.communicator.service.browserlauncher,
- org.jitsi.service.configuration,
- net.java.sip.communicator.service.contactlist,
- net.java.sip.communicator.service.contactlist.event,
- net.java.sip.communicator.service.gui,
- net.java.sip.communicator.service.gui.event,
- net.java.sip.communicator.service.protocol,
- net.java.sip.communicator.service.protocol.event,
- org.jitsi.service.resources, net.java.sip.communicator.service.resources,
- net.java.sip.communicator.util,
- net.java.sip.communicator.plugin.desktoputil,
- javax.swing,
- javax.swing.event,
- javax.swing.table,
- javax.swing.text,
- javax.swing.text.html,
- javax.accessibility,
- javax.swing.plaf,
- javax.swing.plaf.metal,
- javax.swing.plaf.basic,
- javax.imageio,
- javax.swing.filechooser,
- javax.swing.tree,
- javax.swing.undo,
- javax.swing.border
diff --git a/src/net/java/sip/communicator/service/certificate/CertificateConfigEntry.java b/src/net/java/sip/communicator/service/certificate/CertificateConfigEntry.java
index 4cbcd96..ff03b26 100644
--- a/src/net/java/sip/communicator/service/certificate/CertificateConfigEntry.java
+++ b/src/net/java/sip/communicator/service/certificate/CertificateConfigEntry.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,172 +15,172 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.certificate;
-
-/**
- * Data object for client certificate configuration entries.
- *
- * @author Ingo Bauersachs
- */
-public class CertificateConfigEntry
-{
- // ------------------------------------------------------------------------
- // Fields
- // ------------------------------------------------------------------------
- private KeyStoreType keyStoreType;
- private String keyStorePassword;
- private String displayName;
- private String alias;
- private String id;
- private String keyStore;
- private boolean savePassword;
-
- // ------------------------------------------------------------------------
- // Properties
- // ------------------------------------------------------------------------
- /**
- * Sets the key store type.
- *
- * @param keyStoreType the new key store type
- */
- public void setKeyStoreType(KeyStoreType keyStoreType)
- {
- this.keyStoreType = keyStoreType;
- }
-
- /**
- * Gets the key store type.
- *
- * @return the key store type
- */
- public KeyStoreType getKeyStoreType()
- {
- return keyStoreType;
- }
-
- /**
- * Sets the key store password.
- *
- * @param keyStorePassword the new key store password
- */
- public void setKeyStorePassword(String keyStorePassword)
- {
- this.keyStorePassword = keyStorePassword;
- }
-
- /**
- * Gets the key store password.
- *
- * @return the key store password
- */
- public String getKeyStorePassword()
- {
- return keyStorePassword;
- }
-
- /**
- * Sets the display name.
- *
- * @param displayName the new display name
- */
- public void setDisplayName(String displayName)
- {
- this.displayName = displayName;
- }
-
- /**
- * Gets the display name.
- *
- * @return the display name
- */
- public String getDisplayName()
- {
- return displayName;
- }
-
- /**
- * Sets the alias.
- *
- * @param alias the new alias
- */
- public void setAlias(String alias)
- {
- this.alias = alias;
- }
-
- /**
- * Gets the alias.
- *
- * @return the alias
- */
- public String getAlias()
- {
- return alias;
- }
-
- /**
- * Sets the id.
- *
- * @param id the new id
- */
- public void setId(String id)
- {
- this.id = id;
- }
-
- /**
- * Gets the id.
- *
- * @return the id
- */
- public String getId()
- {
- return id;
- }
-
- /**
- * Sets the key store.
- *
- * @param keyStore the new key store
- */
- public void setKeyStore(String keyStore)
- {
- this.keyStore = keyStore;
- }
-
- /**
- * Gets the key store.
- *
- * @return the key store
- */
- public String getKeyStore()
- {
- return keyStore;
- }
-
- /**
- * Sets the save password.
- *
- * @param savePassword the new save password
- */
- public void setSavePassword(boolean savePassword)
- {
- this.savePassword = savePassword;
- }
-
- /**
- * Checks if is save password.
- *
- * @return true, if is save password
- */
- public boolean isSavePassword()
- {
- return savePassword;
- }
-
- @Override
- public String toString()
- {
- return displayName;
- }
-}
+package net.java.sip.communicator.service.certificate;
+
+/**
+ * Data object for client certificate configuration entries.
+ *
+ * @author Ingo Bauersachs
+ */
+public class CertificateConfigEntry
+{
+ // ------------------------------------------------------------------------
+ // Fields
+ // ------------------------------------------------------------------------
+ private KeyStoreType keyStoreType;
+ private String keyStorePassword;
+ private String displayName;
+ private String alias;
+ private String id;
+ private String keyStore;
+ private boolean savePassword;
+
+ // ------------------------------------------------------------------------
+ // Properties
+ // ------------------------------------------------------------------------
+ /**
+ * Sets the key store type.
+ *
+ * @param keyStoreType the new key store type
+ */
+ public void setKeyStoreType(KeyStoreType keyStoreType)
+ {
+ this.keyStoreType = keyStoreType;
+ }
+
+ /**
+ * Gets the key store type.
+ *
+ * @return the key store type
+ */
+ public KeyStoreType getKeyStoreType()
+ {
+ return keyStoreType;
+ }
+
+ /**
+ * Sets the key store password.
+ *
+ * @param keyStorePassword the new key store password
+ */
+ public void setKeyStorePassword(String keyStorePassword)
+ {
+ this.keyStorePassword = keyStorePassword;
+ }
+
+ /**
+ * Gets the key store password.
+ *
+ * @return the key store password
+ */
+ public String getKeyStorePassword()
+ {
+ return keyStorePassword;
+ }
+
+ /**
+ * Sets the display name.
+ *
+ * @param displayName the new display name
+ */
+ public void setDisplayName(String displayName)
+ {
+ this.displayName = displayName;
+ }
+
+ /**
+ * Gets the display name.
+ *
+ * @return the display name
+ */
+ public String getDisplayName()
+ {
+ return displayName;
+ }
+
+ /**
+ * Sets the alias.
+ *
+ * @param alias the new alias
+ */
+ public void setAlias(String alias)
+ {
+ this.alias = alias;
+ }
+
+ /**
+ * Gets the alias.
+ *
+ * @return the alias
+ */
+ public String getAlias()
+ {
+ return alias;
+ }
+
+ /**
+ * Sets the id.
+ *
+ * @param id the new id
+ */
+ public void setId(String id)
+ {
+ this.id = id;
+ }
+
+ /**
+ * Gets the id.
+ *
+ * @return the id
+ */
+ public String getId()
+ {
+ return id;
+ }
+
+ /**
+ * Sets the key store.
+ *
+ * @param keyStore the new key store
+ */
+ public void setKeyStore(String keyStore)
+ {
+ this.keyStore = keyStore;
+ }
+
+ /**
+ * Gets the key store.
+ *
+ * @return the key store
+ */
+ public String getKeyStore()
+ {
+ return keyStore;
+ }
+
+ /**
+ * Sets the save password.
+ *
+ * @param savePassword the new save password
+ */
+ public void setSavePassword(boolean savePassword)
+ {
+ this.savePassword = savePassword;
+ }
+
+ /**
+ * Checks if is save password.
+ *
+ * @return true, if is save password
+ */
+ public boolean isSavePassword()
+ {
+ return savePassword;
+ }
+
+ @Override
+ public String toString()
+ {
+ return displayName;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/certificate/CertificateMatcher.java b/src/net/java/sip/communicator/service/certificate/CertificateMatcher.java
index 365d9a9..a3baf8e 100644
--- a/src/net/java/sip/communicator/service/certificate/CertificateMatcher.java
+++ b/src/net/java/sip/communicator/service/certificate/CertificateMatcher.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,24 +15,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.certificate;
-
-import java.security.cert.*;
-
-/**
- * Interface to verify X.509 certificate
- */
-public interface CertificateMatcher
-{
- /**
- * Implementations check whether one of the supplied identities is
- * contained in the certificate.
- *
- * @param identitiesToTest The that are compared against the certificate.
- * @param cert The X.509 certificate that was supplied by the server or
- * client.
- * @throws CertificateException When any certificate parsing fails.
- */
- public void verify(Iterable<String> identitiesToTest, X509Certificate cert)
- throws CertificateException;
-}
+package net.java.sip.communicator.service.certificate;
+
+import java.security.cert.*;
+
+/**
+ * Interface to verify X.509 certificate
+ */
+public interface CertificateMatcher
+{
+ /**
+ * Implementations check whether one of the supplied identities is
+ * contained in the certificate.
+ *
+ * @param identitiesToTest The that are compared against the certificate.
+ * @param cert The X.509 certificate that was supplied by the server or
+ * client.
+ * @throws CertificateException When any certificate parsing fails.
+ */
+ public void verify(Iterable<String> identitiesToTest, X509Certificate cert)
+ throws CertificateException;
+}
diff --git a/src/net/java/sip/communicator/service/certificate/CertificateService.java b/src/net/java/sip/communicator/service/certificate/CertificateService.java
index f77a3cc..bbe265b 100644
--- a/src/net/java/sip/communicator/service/certificate/CertificateService.java
+++ b/src/net/java/sip/communicator/service/certificate/CertificateService.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,266 +15,266 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.certificate;
-
-import java.security.*;
-import java.security.cert.*;
-import java.security.cert.Certificate;
-import java.util.*;
-
-import javax.net.ssl.*;
-
-/**
- * A service which implementors will ask the user for permission for the
- * certificates which are for some reason not valid and not globally trusted.
- *
- * @author Damian Minkov
- * @author Ingo Bauersachs
- */
-public interface CertificateService
-{
- // ------------------------------------------------------------------------
- // Configuration property names
- // ------------------------------------------------------------------------
- /**
- * Property for always trust mode. When enabled certificate check is
- * skipped.
- */
- public final static String PNAME_ALWAYS_TRUST =
- "net.java.sip.communicator.service.gui.ALWAYS_TRUST_MODE_ENABLED";
-
- /**
- * When set to true, the certificate check is performed. If the check fails
- * the user is not asked and the error is directly reported to the calling
- * service.
- */
- public final static String PNAME_NO_USER_INTERACTION =
- "net.java.sip.communicator.service.tls.NO_USER_INTERACTION";
-
- /**
- * The property name prefix of all client authentication configurations.
- */
- public static final String PNAME_CLIENTAUTH_CERTCONFIG_BASE =
- "net.java.sip.communicator.service.cert.clientauth";
-
- /**
- * Property that is being applied to the system property
- * <tt>javax.net.ssl.trustStoreType</tt>
- */
- public static final String PNAME_TRUSTSTORE_TYPE =
- "net.java.sip.communicator.service.cert.truststore.type";
-
- /**
- * Property that is being applied to the system property
- * <tt>javax.net.ssl.trustStore</tt>
- */
- public static final String PNAME_TRUSTSTORE_FILE =
- "net.java.sip.communicator.service.cert.truststore.file";
-
- /**
- * Property that is being applied to the system property
- * <tt>javax.net.ssl.trustStorePassword</tt>
- */
- public static final String PNAME_TRUSTSTORE_PASSWORD =
- "net.java.sip.communicator.service.cert.truststore.password";
-
- /**
- * Property that is being applied to the system properties
- * <tt>com.sun.net.ssl.checkRevocation</tt> and
- * <tt>com.sun.security.enableCRLDP</tt>
- */
- public static final String PNAME_REVOCATION_CHECK_ENABLED =
- "net.java.sip.communicator.service.cert.revocation.enabled";
-
- /**
- * Property that is being applied to the Security property
- * <tt>ocsp.enable</tt>
- */
- public static final String PNAME_OCSP_ENABLED =
- "net.java.sip.communicator.service.cert.ocsp.enabled";
-
- // ------------------------------------------------------------------------
- // constants
- // ------------------------------------------------------------------------
- /**
- * Result of user interaction. User does not trust this certificate.
- */
- public final static int DO_NOT_TRUST = 0;
-
- /**
- * Result of user interaction. User will always trust this certificate.
- */
- public final static int TRUST_ALWAYS = 1;
-
- /**
- * Result of user interaction. User will trust this certificate
- * only for the current session.
- */
- public final static int TRUST_THIS_SESSION_ONLY = 2;
-
- // ------------------------------------------------------------------------
- // Client authentication configuration
- // ------------------------------------------------------------------------
- /**
- * Returns all saved {@link CertificateConfigEntry}s.
- *
- * @return List of the saved authentication configurations.
- */
- public List<CertificateConfigEntry> getClientAuthCertificateConfigs();
-
- /**
- * Deletes a saved {@link CertificateConfigEntry}.
- *
- * @param id The ID ({@link CertificateConfigEntry#getId()}) of the entry to
- * delete.
- */
- public void removeClientAuthCertificateConfig(String id);
-
- /**
- * Saves or updates the passed {@link CertificateConfigEntry} to the config.
- * If {@link CertificateConfigEntry#getId()} returns null, a new entry is
- * created.
- *
- * @param entry The @see CertificateConfigEntry to save or update.
- */
- public void setClientAuthCertificateConfig(CertificateConfigEntry entry);
-
- /**
- * Gets a list of all supported KeyStore types.
- *
- * @return a list of all supported KeyStore types.
- */
- public List<KeyStoreType> getSupportedKeyStoreTypes();
-
- // ------------------------------------------------------------------------
- // Certificate trust handling
- // ------------------------------------------------------------------------
- /**
- * Get an SSL Context that validates certificates based on the JRE default
- * check and asks the user when the JRE check fails.
- *
- * CAUTION: Only the certificate itself is validated, no check is performed
- * whether it is valid for a specific server or client.
- *
- * @return An SSL context based on a user confirming trust manager.
- * @throws GeneralSecurityException
- */
- public SSLContext getSSLContext() throws GeneralSecurityException;
-
- /**
- * Get an SSL Context with the specified trustmanager.
- *
- * @param trustManager The trustmanager that will be used by the created
- * SSLContext
- * @return An SSL context based on the supplied trust manager.
- * @throws GeneralSecurityException
- */
- public SSLContext getSSLContext(X509TrustManager trustManager)
- throws GeneralSecurityException;
-
- /**
- * Get an SSL Context with the specified trustmanager.
- *
- * @param clientCertConfig The ID of a client certificate configuration
- * entry that is to be used when the server asks for a client TLS
- * certificate
- * @param trustManager The trustmanager that will be used by the created
- * SSLContext
- * @return An SSL context based on the supplied trust manager.
- * @throws GeneralSecurityException
- */
- public SSLContext getSSLContext(String clientCertConfig,
- X509TrustManager trustManager)
- throws GeneralSecurityException;
-
- /**
- * Get an SSL Context with the specified trustmanager.
- *
- * @param keyManagers The key manager(s) to be used for client
- * authentication
- * @param trustManager The trustmanager that will be used by the created
- * SSLContext
- * @return An SSL context based on the supplied trust manager.
- * @throws GeneralSecurityException
- */
- public SSLContext getSSLContext(KeyManager[] keyManagers,
- X509TrustManager trustManager)
- throws GeneralSecurityException;
-
- /**
- * Creates a trustmanager that validates the certificate based on the JRE
- * default check and asks the user when the JRE check fails. When
- * <tt>null</tt> is passed as the <tt>identityToTest</tt> then no check is
- * performed whether the certificate is valid for a specific server or
- * client. The passed identities are checked by applying a behavior similar
- * to the on regular browsers use.
- *
- * @param identitiesToTest when not <tt>null</tt>, the values are assumed
- * to be hostnames for invocations of checkServerTrusted and
- * e-mail addresses for invocations of checkClientTrusted
- * @return TrustManager to use in an SSLContext
- * @throws GeneralSecurityException
- */
- public X509TrustManager getTrustManager(Iterable<String> identitiesToTest)
- throws GeneralSecurityException;
-
- /**
- * @see #getTrustManager(Iterable)
- *
- * @param identityToTest when not <tt>null</tt>, the value is assumed to
- * be a hostname for invocations of checkServerTrusted and an
- * e-mail address for invocations of checkClientTrusted
- * @return TrustManager to use in an SSLContext
- * @throws GeneralSecurityException
- */
- public X509TrustManager getTrustManager(String identityToTest)
- throws GeneralSecurityException;
-
- /**
- * @see #getTrustManager(Iterable, CertificateMatcher, CertificateMatcher)
- *
- * @param identityToTest The identity to match against the supplied
- * verifiers.
- * @param clientVerifier The verifier to use in calls to checkClientTrusted
- * @param serverVerifier The verifier to use in calls to checkServerTrusted
- * @return TrustManager to use in an SSLContext
- * @throws GeneralSecurityException
- */
- public X509TrustManager getTrustManager(
- final String identityToTest,
- final CertificateMatcher clientVerifier,
- final CertificateMatcher serverVerifier)
- throws GeneralSecurityException;
-
- /**
- * Creates a trustmanager that validates the certificate based on the JRE
- * default check and asks the user when the JRE check fails. When
- * <tt>null</tt> is passed as the <tt>identityToTest</tt> then no check is
- * performed whether the certificate is valid for a specific server or
- * client.
- *
- * @param identitiesToTest The identities to match against the supplied
- * verifiers.
- * @param clientVerifier The verifier to use in calls to checkClientTrusted
- * @param serverVerifier The verifier to use in calls to checkServerTrusted
- * @return TrustManager to use in an SSLContext
- * @throws GeneralSecurityException
- */
- public X509TrustManager getTrustManager(
- final Iterable<String> identitiesToTest,
- final CertificateMatcher clientVerifier,
- final CertificateMatcher serverVerifier)
- throws GeneralSecurityException;
-
- /**
- * Adds a certificate to the local trust store.
- *
- * @param cert The certificate to add to the trust store.
- * @param trustFor
- * @param trustMode Whether to trust the certificate permanently or only
- * for the current session.
- * @throws CertificateException when the thumbprint could not be calculated
- */
- public void addCertificateToTrust(Certificate cert, String trustFor,
- int trustMode) throws CertificateException;
+package net.java.sip.communicator.service.certificate;
+
+import java.security.*;
+import java.security.cert.*;
+import java.security.cert.Certificate;
+import java.util.*;
+
+import javax.net.ssl.*;
+
+/**
+ * A service which implementors will ask the user for permission for the
+ * certificates which are for some reason not valid and not globally trusted.
+ *
+ * @author Damian Minkov
+ * @author Ingo Bauersachs
+ */
+public interface CertificateService
+{
+ // ------------------------------------------------------------------------
+ // Configuration property names
+ // ------------------------------------------------------------------------
+ /**
+ * Property for always trust mode. When enabled certificate check is
+ * skipped.
+ */
+ public final static String PNAME_ALWAYS_TRUST =
+ "net.java.sip.communicator.service.gui.ALWAYS_TRUST_MODE_ENABLED";
+
+ /**
+ * When set to true, the certificate check is performed. If the check fails
+ * the user is not asked and the error is directly reported to the calling
+ * service.
+ */
+ public final static String PNAME_NO_USER_INTERACTION =
+ "net.java.sip.communicator.service.tls.NO_USER_INTERACTION";
+
+ /**
+ * The property name prefix of all client authentication configurations.
+ */
+ public static final String PNAME_CLIENTAUTH_CERTCONFIG_BASE =
+ "net.java.sip.communicator.service.cert.clientauth";
+
+ /**
+ * Property that is being applied to the system property
+ * <tt>javax.net.ssl.trustStoreType</tt>
+ */
+ public static final String PNAME_TRUSTSTORE_TYPE =
+ "net.java.sip.communicator.service.cert.truststore.type";
+
+ /**
+ * Property that is being applied to the system property
+ * <tt>javax.net.ssl.trustStore</tt>
+ */
+ public static final String PNAME_TRUSTSTORE_FILE =
+ "net.java.sip.communicator.service.cert.truststore.file";
+
+ /**
+ * Property that is being applied to the system property
+ * <tt>javax.net.ssl.trustStorePassword</tt>
+ */
+ public static final String PNAME_TRUSTSTORE_PASSWORD =
+ "net.java.sip.communicator.service.cert.truststore.password";
+
+ /**
+ * Property that is being applied to the system properties
+ * <tt>com.sun.net.ssl.checkRevocation</tt> and
+ * <tt>com.sun.security.enableCRLDP</tt>
+ */
+ public static final String PNAME_REVOCATION_CHECK_ENABLED =
+ "net.java.sip.communicator.service.cert.revocation.enabled";
+
+ /**
+ * Property that is being applied to the Security property
+ * <tt>ocsp.enable</tt>
+ */
+ public static final String PNAME_OCSP_ENABLED =
+ "net.java.sip.communicator.service.cert.ocsp.enabled";
+
+ // ------------------------------------------------------------------------
+ // constants
+ // ------------------------------------------------------------------------
+ /**
+ * Result of user interaction. User does not trust this certificate.
+ */
+ public final static int DO_NOT_TRUST = 0;
+
+ /**
+ * Result of user interaction. User will always trust this certificate.
+ */
+ public final static int TRUST_ALWAYS = 1;
+
+ /**
+ * Result of user interaction. User will trust this certificate
+ * only for the current session.
+ */
+ public final static int TRUST_THIS_SESSION_ONLY = 2;
+
+ // ------------------------------------------------------------------------
+ // Client authentication configuration
+ // ------------------------------------------------------------------------
+ /**
+ * Returns all saved {@link CertificateConfigEntry}s.
+ *
+ * @return List of the saved authentication configurations.
+ */
+ public List<CertificateConfigEntry> getClientAuthCertificateConfigs();
+
+ /**
+ * Deletes a saved {@link CertificateConfigEntry}.
+ *
+ * @param id The ID ({@link CertificateConfigEntry#getId()}) of the entry to
+ * delete.
+ */
+ public void removeClientAuthCertificateConfig(String id);
+
+ /**
+ * Saves or updates the passed {@link CertificateConfigEntry} to the config.
+ * If {@link CertificateConfigEntry#getId()} returns null, a new entry is
+ * created.
+ *
+ * @param entry The @see CertificateConfigEntry to save or update.
+ */
+ public void setClientAuthCertificateConfig(CertificateConfigEntry entry);
+
+ /**
+ * Gets a list of all supported KeyStore types.
+ *
+ * @return a list of all supported KeyStore types.
+ */
+ public List<KeyStoreType> getSupportedKeyStoreTypes();
+
+ // ------------------------------------------------------------------------
+ // Certificate trust handling
+ // ------------------------------------------------------------------------
+ /**
+ * Get an SSL Context that validates certificates based on the JRE default
+ * check and asks the user when the JRE check fails.
+ *
+ * CAUTION: Only the certificate itself is validated, no check is performed
+ * whether it is valid for a specific server or client.
+ *
+ * @return An SSL context based on a user confirming trust manager.
+ * @throws GeneralSecurityException
+ */
+ public SSLContext getSSLContext() throws GeneralSecurityException;
+
+ /**
+ * Get an SSL Context with the specified trustmanager.
+ *
+ * @param trustManager The trustmanager that will be used by the created
+ * SSLContext
+ * @return An SSL context based on the supplied trust manager.
+ * @throws GeneralSecurityException
+ */
+ public SSLContext getSSLContext(X509TrustManager trustManager)
+ throws GeneralSecurityException;
+
+ /**
+ * Get an SSL Context with the specified trustmanager.
+ *
+ * @param clientCertConfig The ID of a client certificate configuration
+ * entry that is to be used when the server asks for a client TLS
+ * certificate
+ * @param trustManager The trustmanager that will be used by the created
+ * SSLContext
+ * @return An SSL context based on the supplied trust manager.
+ * @throws GeneralSecurityException
+ */
+ public SSLContext getSSLContext(String clientCertConfig,
+ X509TrustManager trustManager)
+ throws GeneralSecurityException;
+
+ /**
+ * Get an SSL Context with the specified trustmanager.
+ *
+ * @param keyManagers The key manager(s) to be used for client
+ * authentication
+ * @param trustManager The trustmanager that will be used by the created
+ * SSLContext
+ * @return An SSL context based on the supplied trust manager.
+ * @throws GeneralSecurityException
+ */
+ public SSLContext getSSLContext(KeyManager[] keyManagers,
+ X509TrustManager trustManager)
+ throws GeneralSecurityException;
+
+ /**
+ * Creates a trustmanager that validates the certificate based on the JRE
+ * default check and asks the user when the JRE check fails. When
+ * <tt>null</tt> is passed as the <tt>identityToTest</tt> then no check is
+ * performed whether the certificate is valid for a specific server or
+ * client. The passed identities are checked by applying a behavior similar
+ * to the on regular browsers use.
+ *
+ * @param identitiesToTest when not <tt>null</tt>, the values are assumed
+ * to be hostnames for invocations of checkServerTrusted and
+ * e-mail addresses for invocations of checkClientTrusted
+ * @return TrustManager to use in an SSLContext
+ * @throws GeneralSecurityException
+ */
+ public X509TrustManager getTrustManager(Iterable<String> identitiesToTest)
+ throws GeneralSecurityException;
+
+ /**
+ * @see #getTrustManager(Iterable)
+ *
+ * @param identityToTest when not <tt>null</tt>, the value is assumed to
+ * be a hostname for invocations of checkServerTrusted and an
+ * e-mail address for invocations of checkClientTrusted
+ * @return TrustManager to use in an SSLContext
+ * @throws GeneralSecurityException
+ */
+ public X509TrustManager getTrustManager(String identityToTest)
+ throws GeneralSecurityException;
+
+ /**
+ * @see #getTrustManager(Iterable, CertificateMatcher, CertificateMatcher)
+ *
+ * @param identityToTest The identity to match against the supplied
+ * verifiers.
+ * @param clientVerifier The verifier to use in calls to checkClientTrusted
+ * @param serverVerifier The verifier to use in calls to checkServerTrusted
+ * @return TrustManager to use in an SSLContext
+ * @throws GeneralSecurityException
+ */
+ public X509TrustManager getTrustManager(
+ final String identityToTest,
+ final CertificateMatcher clientVerifier,
+ final CertificateMatcher serverVerifier)
+ throws GeneralSecurityException;
+
+ /**
+ * Creates a trustmanager that validates the certificate based on the JRE
+ * default check and asks the user when the JRE check fails. When
+ * <tt>null</tt> is passed as the <tt>identityToTest</tt> then no check is
+ * performed whether the certificate is valid for a specific server or
+ * client.
+ *
+ * @param identitiesToTest The identities to match against the supplied
+ * verifiers.
+ * @param clientVerifier The verifier to use in calls to checkClientTrusted
+ * @param serverVerifier The verifier to use in calls to checkServerTrusted
+ * @return TrustManager to use in an SSLContext
+ * @throws GeneralSecurityException
+ */
+ public X509TrustManager getTrustManager(
+ final Iterable<String> identitiesToTest,
+ final CertificateMatcher clientVerifier,
+ final CertificateMatcher serverVerifier)
+ throws GeneralSecurityException;
+
+ /**
+ * Adds a certificate to the local trust store.
+ *
+ * @param cert The certificate to add to the trust store.
+ * @param trustFor
+ * @param trustMode Whether to trust the certificate permanently or only
+ * for the current session.
+ * @throws CertificateException when the thumbprint could not be calculated
+ */
+ public void addCertificateToTrust(Certificate cert, String trustFor,
+ int trustMode) throws CertificateException;
}
diff --git a/src/net/java/sip/communicator/service/certificate/KeyStoreType.java b/src/net/java/sip/communicator/service/certificate/KeyStoreType.java
index ba1fd72..16927d8 100644
--- a/src/net/java/sip/communicator/service/certificate/KeyStoreType.java
+++ b/src/net/java/sip/communicator/service/certificate/KeyStoreType.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,65 +15,65 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.certificate;
-
-/**
- * Data object for KeyStore configurations. Primarily used during adding/
- * editing client certificate configurations.
- *
- * @author Ingo Bauersachs
- */
-public class KeyStoreType
-{
- private String name;
- private String[] fileExtensions;
- private boolean hasKeyStorePassword;
-
- /**
- * Creates a new instance of this class.
- * @param name the display name of the keystore type.
- * @param fileExtensions known file name extensions (including the dot)
- * @param hasKeyStorePassword
- */
- public KeyStoreType(String name, String[] fileExtensions,
- boolean hasKeyStorePassword)
- {
- this.name = name;
- this.fileExtensions = fileExtensions;
- this.hasKeyStorePassword = hasKeyStorePassword;
- }
-
- @Override
- public String toString()
- {
- return name;
- }
-
- /**
- * Gets the display name.
- * @return the display name.
- */
- public String getName()
- {
- return name;
- }
-
- /**
- * Gets the known file name extensions.
- * @return Known file name extensions (including the dot).
- */
- public String[] getFileExtensions()
- {
- return fileExtensions;
- }
-
- /**
- * Flag that indicates if the keystore supports passwords.
- * @return <tt>true</tt> if the keystore supports passwords, <tt>false</tt>
- * otherwise.
- */
- public boolean hasKeyStorePassword()
- {
- return hasKeyStorePassword;
- }
+package net.java.sip.communicator.service.certificate;
+
+/**
+ * Data object for KeyStore configurations. Primarily used during adding/
+ * editing client certificate configurations.
+ *
+ * @author Ingo Bauersachs
+ */
+public class KeyStoreType
+{
+ private String name;
+ private String[] fileExtensions;
+ private boolean hasKeyStorePassword;
+
+ /**
+ * Creates a new instance of this class.
+ * @param name the display name of the keystore type.
+ * @param fileExtensions known file name extensions (including the dot)
+ * @param hasKeyStorePassword
+ */
+ public KeyStoreType(String name, String[] fileExtensions,
+ boolean hasKeyStorePassword)
+ {
+ this.name = name;
+ this.fileExtensions = fileExtensions;
+ this.hasKeyStorePassword = hasKeyStorePassword;
+ }
+
+ @Override
+ public String toString()
+ {
+ return name;
+ }
+
+ /**
+ * Gets the display name.
+ * @return the display name.
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Gets the known file name extensions.
+ * @return Known file name extensions (including the dot).
+ */
+ public String[] getFileExtensions()
+ {
+ return fileExtensions;
+ }
+
+ /**
+ * Flag that indicates if the keystore supports passwords.
+ * @return <tt>true</tt> if the keystore supports passwords, <tt>false</tt>
+ * otherwise.
+ */
+ public boolean hasKeyStorePassword()
+ {
+ return hasKeyStorePassword;
+ }
}
diff --git a/src/net/java/sip/communicator/service/contactsource/AbstractContactQuery.java b/src/net/java/sip/communicator/service/contactsource/AbstractContactQuery.java
index 2c14e52..be9de8a 100644
--- a/src/net/java/sip/communicator/service/contactsource/AbstractContactQuery.java
+++ b/src/net/java/sip/communicator/service/contactsource/AbstractContactQuery.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,286 +15,286 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.contactsource;
-
-import java.util.*;
-
-/**
- * Provides an abstract implementation of the basic functionality of
- * <tt>ContactQuery</tt> and allows extenders to focus on the specifics of their
- * implementation.
- *
- * @author Lyubomir Marinov
- * @param <T> the very type of <tt>ContactSourceService</tt> which performs the
- * <tt>ContactQuery</tt>
- */
-public abstract class AbstractContactQuery<T extends ContactSourceService>
- implements ContactQuery
-{
- /**
- * The <tt>ContactSourceService</tt> which is performing this
- * <tt>ContactQuery</tt>.
- */
- private final T contactSource;
-
- /**
- * The <tt>List</tt> of <tt>ContactQueryListener</tt>s which are to be
- * notified by this <tt>ContactQuery</tt> about changes in its status, the
- * receipt of new <tt>ContactSource</tt>s via this <tt>ContactQuery</tt>,
- * etc.
- */
- private final List<ContactQueryListener> listeners
- = new LinkedList<ContactQueryListener>();
-
- /**
- * The status of this <tt>ContactQuery</tt> which is one of the
- * <tt>QUERY_XXX</tt> constants defined by the <tt>ContactQuery</tt> class.
- */
- private int status = QUERY_IN_PROGRESS;
-
- /**
- * Initializes a new <tt>AbstractContactQuery</tt> which is to be performed
- * by a specific <tt>ContactSourceService</tt>. The status of the new
- * instance is {@link ContactQuery#QUERY_IN_PROGRESS}.
- *
- * @param contactSource the <tt>ContactSourceService</tt> which is to
- * perform the new <tt>AbstractContactQuery</tt>
- */
- protected AbstractContactQuery(T contactSource)
- {
- this.contactSource = contactSource;
- }
-
- /**
- * Adds a <tt>ContactQueryListener</tt> to the list of listeners interested
- * in notifications about this <tt>ContactQuery</tt> changing its status,
- * the receipt of new <tt>SourceContact</tt>s via this
- * <tt>ContactQuery</tt>, etc.
- *
- * @param l the <tt>ContactQueryListener</tt> to be added to the list of
- * listeners interested in the notifications raised by this
- * <tt>ContactQuery</tt>
- * @see ContactQuery#addContactQueryListener(ContactQueryListener)
- */
- public void addContactQueryListener(ContactQueryListener l)
- {
- if (l == null)
- throw new NullPointerException("l");
- else
- {
- synchronized (listeners)
- {
- if (!listeners.contains(l))
- listeners.add(l);
- }
- }
- }
-
- /**
- * Cancels this <tt>ContactQuery</tt>.
- *
- * @see ContactQuery#cancel()
- */
- public void cancel()
- {
- if (getStatus() == QUERY_IN_PROGRESS)
- setStatus(QUERY_CANCELED);
- }
-
- /**
- * Notifies the <tt>ContactQueryListener</tt>s registered with this
- * <tt>ContactQuery</tt> that a new <tt>SourceContact</tt> has been
- * received.
- *
- * @param contact the <tt>SourceContact</tt> which has been received and
- * which the registered <tt>ContactQueryListener</tt>s are to be notified
- * about
- * @param showMoreEnabled indicates whether show more label should be shown
- * or not.
- */
- protected void fireContactReceived(SourceContact contact,
- boolean showMoreEnabled)
- {
- ContactQueryListener[] ls;
-
- synchronized (listeners)
- {
- ls = listeners.toArray(new ContactQueryListener[listeners.size()]);
- }
-
- ContactReceivedEvent ev
- = new ContactReceivedEvent(this, contact, showMoreEnabled);
-
- for (ContactQueryListener l : ls)
- {
- l.contactReceived(ev);
- }
- }
-
- /**
- * Notifies the <tt>ContactQueryListener</tt>s registered with this
- * <tt>ContactQuery</tt> that a new <tt>SourceContact</tt> has been
- * received.
- *
- * @param contact the <tt>SourceContact</tt> which has been received and
- * which the registered <tt>ContactQueryListener</tt>s are to be notified
- * about
- */
- protected void fireContactReceived(SourceContact contact)
- {
- fireContactReceived(contact, true);
- }
-
- /**
- * Notifies the <tt>ContactQueryListener</tt>s registered with this
- * <tt>ContactQuery</tt> that a <tt>SourceContact</tt> has been
- * removed.
- *
- * @param contact the <tt>SourceContact</tt> which has been removed and
- * which the registered <tt>ContactQueryListener</tt>s are to be notified
- * about
- */
- protected void fireContactRemoved(SourceContact contact)
- {
- ContactQueryListener[] ls;
-
- synchronized (listeners)
- {
- ls = listeners.toArray(new ContactQueryListener[listeners.size()]);
- }
-
- ContactRemovedEvent ev = new ContactRemovedEvent(this, contact);
-
- for (ContactQueryListener l : ls)
- l.contactRemoved(ev);
- }
-
- /**
- * Notifies the <tt>ContactQueryListener</tt>s registered with this
- * <tt>ContactQuery</tt> that a <tt>SourceContact</tt> has been
- * changed.
- *
- * @param contact the <tt>SourceContact</tt> which has been changed and
- * which the registered <tt>ContactQueryListener</tt>s are to be notified
- * about
- */
- protected void fireContactChanged(SourceContact contact)
- {
- ContactQueryListener[] ls;
-
- synchronized (listeners)
- {
- ls = listeners.toArray(new ContactQueryListener[listeners.size()]);
- }
-
- ContactChangedEvent ev = new ContactChangedEvent(this, contact);
-
- for (ContactQueryListener l : ls)
- l.contactChanged(ev);
- }
-
- /**
- * Notifies the <tt>ContactQueryListener</tt>s registered with this
- * <tt>ContactQuery</tt> that its state has changed.
- *
- * @param eventType the type of the <tt>ContactQueryStatusEvent</tt> to be
- * fired which can be one of the <tt>QUERY_XXX</tt> constants defined by
- * <tt>ContactQueryStatusEvent</tt>
- */
- protected void fireQueryStatusChanged(int eventType)
- {
- ContactQueryListener[] ls;
-
- synchronized (listeners)
- {
- ls = listeners.toArray(new ContactQueryListener[listeners.size()]);
- }
-
- ContactQueryStatusEvent ev
- = new ContactQueryStatusEvent(this, eventType);
-
- for (ContactQueryListener l : ls)
- l.queryStatusChanged(ev);
- }
-
- /**
- * Gets the <tt>ContactSourceService</tt> which is performing this
- * <tt>ContactQuery</tt>.
- *
- * @return the <tt>ContactSourceService</tt> which is performing this
- * <tt>ContactQuery</tt>
- * @see ContactQuery#getContactSource()
- */
- public T getContactSource()
- {
- return contactSource;
- }
-
- /**
- * Gets the status of this <tt>ContactQuery</tt> which can be one of the
- * <tt>QUERY_XXX</tt> constants defined by <tt>ContactQuery</tt>.
- *
- * @return the status of this <tt>ContactQuery</tt> which can be one of the
- * <tt>QUERY_XXX</tt> constants defined by <tt>ContactQuery</tt>
- * @see ContactQuery#getStatus()
- */
- public int getStatus()
- {
- return status;
- }
-
- /**
- * Removes a <tt>ContactQueryListener</tt> from the list of listeners
- * interested in notifications about this <tt>ContactQuery</tt> changing its
- * status, the receipt of new <tt>SourceContact</tt>s via this
- * <tt>ContactQuery</tt>, etc.
- *
- * @param l the <tt>ContactQueryListener</tt> to be removed from the list of
- * listeners interested in notifications raised by this <tt>ContactQuery</tt>
- * @see ContactQuery#removeContactQueryListener(ContactQueryListener)
- */
- public void removeContactQueryListener(ContactQueryListener l)
- {
- if (l != null)
- {
- synchronized (listeners)
- {
- listeners.remove(l);
- }
- }
- }
-
- /**
- * Sets the status of this <tt>ContactQuery</tt>.
- *
- * @param status {@link ContactQuery#QUERY_CANCELED},
- * {@link ContactQuery#QUERY_COMPLETED}, or
- * {@link ContactQuery#QUERY_ERROR}
- */
- public void setStatus(int status)
- {
- if (this.status != status)
- {
- int eventType;
-
- switch (status)
- {
- case QUERY_CANCELED:
- eventType = ContactQueryStatusEvent.QUERY_CANCELED;
- break;
- case QUERY_COMPLETED:
- eventType = ContactQueryStatusEvent.QUERY_COMPLETED;
- break;
- case QUERY_ERROR:
- eventType = ContactQueryStatusEvent.QUERY_ERROR;
- break;
- case QUERY_IN_PROGRESS:
- default:
- throw new IllegalArgumentException("status");
- }
-
- this.status = status;
- fireQueryStatusChanged(eventType);
- }
- }
-}
+package net.java.sip.communicator.service.contactsource;
+
+import java.util.*;
+
+/**
+ * Provides an abstract implementation of the basic functionality of
+ * <tt>ContactQuery</tt> and allows extenders to focus on the specifics of their
+ * implementation.
+ *
+ * @author Lyubomir Marinov
+ * @param <T> the very type of <tt>ContactSourceService</tt> which performs the
+ * <tt>ContactQuery</tt>
+ */
+public abstract class AbstractContactQuery<T extends ContactSourceService>
+ implements ContactQuery
+{
+ /**
+ * The <tt>ContactSourceService</tt> which is performing this
+ * <tt>ContactQuery</tt>.
+ */
+ private final T contactSource;
+
+ /**
+ * The <tt>List</tt> of <tt>ContactQueryListener</tt>s which are to be
+ * notified by this <tt>ContactQuery</tt> about changes in its status, the
+ * receipt of new <tt>ContactSource</tt>s via this <tt>ContactQuery</tt>,
+ * etc.
+ */
+ private final List<ContactQueryListener> listeners
+ = new LinkedList<ContactQueryListener>();
+
+ /**
+ * The status of this <tt>ContactQuery</tt> which is one of the
+ * <tt>QUERY_XXX</tt> constants defined by the <tt>ContactQuery</tt> class.
+ */
+ private int status = QUERY_IN_PROGRESS;
+
+ /**
+ * Initializes a new <tt>AbstractContactQuery</tt> which is to be performed
+ * by a specific <tt>ContactSourceService</tt>. The status of the new
+ * instance is {@link ContactQuery#QUERY_IN_PROGRESS}.
+ *
+ * @param contactSource the <tt>ContactSourceService</tt> which is to
+ * perform the new <tt>AbstractContactQuery</tt>
+ */
+ protected AbstractContactQuery(T contactSource)
+ {
+ this.contactSource = contactSource;
+ }
+
+ /**
+ * Adds a <tt>ContactQueryListener</tt> to the list of listeners interested
+ * in notifications about this <tt>ContactQuery</tt> changing its status,
+ * the receipt of new <tt>SourceContact</tt>s via this
+ * <tt>ContactQuery</tt>, etc.
+ *
+ * @param l the <tt>ContactQueryListener</tt> to be added to the list of
+ * listeners interested in the notifications raised by this
+ * <tt>ContactQuery</tt>
+ * @see ContactQuery#addContactQueryListener(ContactQueryListener)
+ */
+ public void addContactQueryListener(ContactQueryListener l)
+ {
+ if (l == null)
+ throw new NullPointerException("l");
+ else
+ {
+ synchronized (listeners)
+ {
+ if (!listeners.contains(l))
+ listeners.add(l);
+ }
+ }
+ }
+
+ /**
+ * Cancels this <tt>ContactQuery</tt>.
+ *
+ * @see ContactQuery#cancel()
+ */
+ public void cancel()
+ {
+ if (getStatus() == QUERY_IN_PROGRESS)
+ setStatus(QUERY_CANCELED);
+ }
+
+ /**
+ * Notifies the <tt>ContactQueryListener</tt>s registered with this
+ * <tt>ContactQuery</tt> that a new <tt>SourceContact</tt> has been
+ * received.
+ *
+ * @param contact the <tt>SourceContact</tt> which has been received and
+ * which the registered <tt>ContactQueryListener</tt>s are to be notified
+ * about
+ * @param showMoreEnabled indicates whether show more label should be shown
+ * or not.
+ */
+ protected void fireContactReceived(SourceContact contact,
+ boolean showMoreEnabled)
+ {
+ ContactQueryListener[] ls;
+
+ synchronized (listeners)
+ {
+ ls = listeners.toArray(new ContactQueryListener[listeners.size()]);
+ }
+
+ ContactReceivedEvent ev
+ = new ContactReceivedEvent(this, contact, showMoreEnabled);
+
+ for (ContactQueryListener l : ls)
+ {
+ l.contactReceived(ev);
+ }
+ }
+
+ /**
+ * Notifies the <tt>ContactQueryListener</tt>s registered with this
+ * <tt>ContactQuery</tt> that a new <tt>SourceContact</tt> has been
+ * received.
+ *
+ * @param contact the <tt>SourceContact</tt> which has been received and
+ * which the registered <tt>ContactQueryListener</tt>s are to be notified
+ * about
+ */
+ protected void fireContactReceived(SourceContact contact)
+ {
+ fireContactReceived(contact, true);
+ }
+
+ /**
+ * Notifies the <tt>ContactQueryListener</tt>s registered with this
+ * <tt>ContactQuery</tt> that a <tt>SourceContact</tt> has been
+ * removed.
+ *
+ * @param contact the <tt>SourceContact</tt> which has been removed and
+ * which the registered <tt>ContactQueryListener</tt>s are to be notified
+ * about
+ */
+ protected void fireContactRemoved(SourceContact contact)
+ {
+ ContactQueryListener[] ls;
+
+ synchronized (listeners)
+ {
+ ls = listeners.toArray(new ContactQueryListener[listeners.size()]);
+ }
+
+ ContactRemovedEvent ev = new ContactRemovedEvent(this, contact);
+
+ for (ContactQueryListener l : ls)
+ l.contactRemoved(ev);
+ }
+
+ /**
+ * Notifies the <tt>ContactQueryListener</tt>s registered with this
+ * <tt>ContactQuery</tt> that a <tt>SourceContact</tt> has been
+ * changed.
+ *
+ * @param contact the <tt>SourceContact</tt> which has been changed and
+ * which the registered <tt>ContactQueryListener</tt>s are to be notified
+ * about
+ */
+ protected void fireContactChanged(SourceContact contact)
+ {
+ ContactQueryListener[] ls;
+
+ synchronized (listeners)
+ {
+ ls = listeners.toArray(new ContactQueryListener[listeners.size()]);
+ }
+
+ ContactChangedEvent ev = new ContactChangedEvent(this, contact);
+
+ for (ContactQueryListener l : ls)
+ l.contactChanged(ev);
+ }
+
+ /**
+ * Notifies the <tt>ContactQueryListener</tt>s registered with this
+ * <tt>ContactQuery</tt> that its state has changed.
+ *
+ * @param eventType the type of the <tt>ContactQueryStatusEvent</tt> to be
+ * fired which can be one of the <tt>QUERY_XXX</tt> constants defined by
+ * <tt>ContactQueryStatusEvent</tt>
+ */
+ protected void fireQueryStatusChanged(int eventType)
+ {
+ ContactQueryListener[] ls;
+
+ synchronized (listeners)
+ {
+ ls = listeners.toArray(new ContactQueryListener[listeners.size()]);
+ }
+
+ ContactQueryStatusEvent ev
+ = new ContactQueryStatusEvent(this, eventType);
+
+ for (ContactQueryListener l : ls)
+ l.queryStatusChanged(ev);
+ }
+
+ /**
+ * Gets the <tt>ContactSourceService</tt> which is performing this
+ * <tt>ContactQuery</tt>.
+ *
+ * @return the <tt>ContactSourceService</tt> which is performing this
+ * <tt>ContactQuery</tt>
+ * @see ContactQuery#getContactSource()
+ */
+ public T getContactSource()
+ {
+ return contactSource;
+ }
+
+ /**
+ * Gets the status of this <tt>ContactQuery</tt> which can be one of the
+ * <tt>QUERY_XXX</tt> constants defined by <tt>ContactQuery</tt>.
+ *
+ * @return the status of this <tt>ContactQuery</tt> which can be one of the
+ * <tt>QUERY_XXX</tt> constants defined by <tt>ContactQuery</tt>
+ * @see ContactQuery#getStatus()
+ */
+ public int getStatus()
+ {
+ return status;
+ }
+
+ /**
+ * Removes a <tt>ContactQueryListener</tt> from the list of listeners
+ * interested in notifications about this <tt>ContactQuery</tt> changing its
+ * status, the receipt of new <tt>SourceContact</tt>s via this
+ * <tt>ContactQuery</tt>, etc.
+ *
+ * @param l the <tt>ContactQueryListener</tt> to be removed from the list of
+ * listeners interested in notifications raised by this <tt>ContactQuery</tt>
+ * @see ContactQuery#removeContactQueryListener(ContactQueryListener)
+ */
+ public void removeContactQueryListener(ContactQueryListener l)
+ {
+ if (l != null)
+ {
+ synchronized (listeners)
+ {
+ listeners.remove(l);
+ }
+ }
+ }
+
+ /**
+ * Sets the status of this <tt>ContactQuery</tt>.
+ *
+ * @param status {@link ContactQuery#QUERY_CANCELED},
+ * {@link ContactQuery#QUERY_COMPLETED}, or
+ * {@link ContactQuery#QUERY_ERROR}
+ */
+ public void setStatus(int status)
+ {
+ if (this.status != status)
+ {
+ int eventType;
+
+ switch (status)
+ {
+ case QUERY_CANCELED:
+ eventType = ContactQueryStatusEvent.QUERY_CANCELED;
+ break;
+ case QUERY_COMPLETED:
+ eventType = ContactQueryStatusEvent.QUERY_COMPLETED;
+ break;
+ case QUERY_ERROR:
+ eventType = ContactQueryStatusEvent.QUERY_ERROR;
+ break;
+ case QUERY_IN_PROGRESS:
+ default:
+ throw new IllegalArgumentException("status");
+ }
+
+ this.status = status;
+ fireQueryStatusChanged(eventType);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/service/contactsource/AsyncContactQuery.java b/src/net/java/sip/communicator/service/contactsource/AsyncContactQuery.java
index 1eb38f8..9570dad 100644
--- a/src/net/java/sip/communicator/service/contactsource/AsyncContactQuery.java
+++ b/src/net/java/sip/communicator/service/contactsource/AsyncContactQuery.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,410 +15,410 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.contactsource;
-
-import java.util.*;
-import java.util.regex.*;
-
-/**
- * Provides an abstract implementation of a <tt>ContactQuery</tt> which runs in
- * a separate <tt>Thread</tt>.
- *
- * @author Lyubomir Marinov
- * @param <T> the very type of <tt>ContactSourceService</tt> which performs the
- * <tt>ContactQuery</tt>
- */
-public abstract class AsyncContactQuery<T extends ContactSourceService>
- extends AbstractContactQuery<T>
-{
- /**
- * The {@link #query} in the form of a <tt>String</tt> telephone number if
- * such parsing, formatting and validation is possible; otherwise,
- * <tt>null</tt>.
- */
- private String phoneNumberQuery;
-
- /**
- * The <tt>Pattern</tt> for which the associated
- * <tt>ContactSourceService</tt> is being queried.
- */
- protected final Pattern query;
-
- /**
- * The indicator which determines whether there has been an attempt to
- * convert {@link #query} to {@link #phoneNumberQuery}. If the conversion has
- * been successful, <tt>phoneNumberQuery</tt> will be non-<tt>null</tt>.
- */
- private boolean queryIsConvertedToPhoneNumber;
-
- /**
- * The <tt>SourceContact</tt>s which match {@link #query}.
- */
- private Collection<SourceContact> queryResults
- = new LinkedList<SourceContact>();
-
- /**
- * The <tt>Thread</tt> in which this <tt>AsyncContactQuery</tt> is
- * performing {@link #query}.
- */
- private Thread thread;
-
- /**
- * Initializes a new <tt>AsyncContactQuery</tt> instance which is to perform
- * a specific <tt>query</tt> on behalf of a specific <tt>contactSource</tt>.
- *
- * @param contactSource the <tt>ContactSourceService</tt> which is to
- * perform the new <tt>ContactQuery</tt> instance
- * @param query the <tt>Pattern</tt> for which <tt>contactSource</tt> is
- * being queried
- * @param isSorted indicates if the results of this query should be sorted
- */
- protected AsyncContactQuery(T contactSource,
- Pattern query,
- boolean isSorted)
- {
- super(contactSource);
-
- this.query = query;
-
- if (isSorted)
- queryResults = new TreeSet<SourceContact>();
- }
-
- /**
- * Initializes a new <tt>AsyncContactQuery</tt> instance which is to perform
- * a specific <tt>query</tt> on behalf of a specific <tt>contactSource</tt>.
- *
- * @param contactSource the <tt>ContactSourceService</tt> which is to
- * perform the new <tt>ContactQuery</tt> instance
- * @param query the <tt>Pattern</tt> for which <tt>contactSource</tt> is
- * being queried
- */
- protected AsyncContactQuery(T contactSource, Pattern query)
- {
- super(contactSource);
-
- this.query = query;
- }
-
- /**
- * Adds a specific <tt>SourceContact</tt> to the list of
- * <tt>SourceContact</tt>s to be returned by this <tt>ContactQuery</tt> in
- * response to {@link #getQueryResults()}.
- *
- * @param sourceContact the <tt>SourceContact</tt> to be added to the
- * <tt>queryResults</tt> of this <tt>ContactQuery</tt>
- * @param showMoreEnabled indicates whether show more label should be shown
- * or not.
- * @return <tt>true</tt> if the <tt>queryResults</tt> of this
- * <tt>ContactQuery</tt> has changed in response to the call
- */
- protected boolean addQueryResult(SourceContact sourceContact,
- boolean showMoreEnabled)
- {
- boolean changed;
-
- synchronized (queryResults)
- {
- changed = queryResults.add(sourceContact);
- }
- if (changed)
- fireContactReceived(sourceContact, showMoreEnabled);
-
- return changed;
- }
-
- /**
- * Adds a specific <tt>SourceContact</tt> to the list of
- * <tt>SourceContact</tt>s to be returned by this <tt>ContactQuery</tt> in
- * response to {@link #getQueryResults()}.
- *
- * @param sourceContact the <tt>SourceContact</tt> to be added to the
- * <tt>queryResults</tt> of this <tt>ContactQuery</tt>
- * @return <tt>true</tt> if the <tt>queryResults</tt> of this
- * <tt>ContactQuery</tt> has changed in response to the call
- */
- protected boolean addQueryResult(SourceContact sourceContact)
- {
- boolean changed;
-
- synchronized (queryResults)
- {
- changed = queryResults.add(sourceContact);
- }
- if (changed)
- fireContactReceived(sourceContact);
-
- return changed;
- }
-
- /**
- * Removes a specific <tt>SourceContact</tt> from the list of
- * <tt>SourceContact</tt>s.
- *
- * @param sourceContact the <tt>SourceContact</tt> to be removed from the
- * <tt>queryResults</tt> of this <tt>ContactQuery</tt>
- * @return <tt>true</tt> if the <tt>queryResults</tt> of this
- * <tt>ContactQuery</tt> has changed in response to the call
- */
- protected boolean removeQueryResult(SourceContact sourceContact)
- {
- boolean changed;
-
- synchronized (queryResults)
- {
- changed = queryResults.remove(sourceContact);
- }
- if (changed)
- fireContactRemoved(sourceContact);
-
- return changed;
- }
-
- /**
- * Adds a set of <tt>SourceContact</tt> instances to the list of
- * <tt>SourceContact</tt>s to be returned by this <tt>ContactQuery</tt> in
- * response to {@link #getQueryResults()}.
- *
- * @param sourceContacts the set of <tt>SourceContact</tt> to be added to
- * the <tt>queryResults</tt> of this <tt>ContactQuery</tt>
- * @return <tt>true</tt> if the <tt>queryResults</tt> of this
- * <tt>ContactQuery</tt> has changed in response to the call
- */
- protected boolean addQueryResults(
- final Set<? extends SourceContact> sourceContacts)
- {
- final boolean changed;
-
- synchronized (queryResults)
- {
- changed = queryResults.addAll(sourceContacts);
- }
-
- if (changed)
- {
- // TODO Need something to fire one event for multiple contacts.
- for (SourceContact contact : sourceContacts)
- {
- fireContactReceived(contact, false);
- }
- }
-
- return changed;
- }
-
-
- /**
- * Gets the {@link #query} of this <tt>AsyncContactQuery</tt> as a
- * <tt>String</tt> which represents a phone number (if possible).
- *
- * @return a <tt>String</tt> which represents the <tt>query</tt> of this
- * <tt>AsyncContactQuery</tt> as a phone number if such parsing, formatting
- * and validation is possible; otherwise, <tt>null</tt>
- */
- protected String getPhoneNumberQuery()
- {
- if ((phoneNumberQuery == null) && !queryIsConvertedToPhoneNumber)
- {
- try
- {
- String pattern = query.pattern();
-
- if (pattern != null)
- {
- int patternLength = pattern.length();
-
- if ((patternLength > 2)
- && (pattern.charAt(0) == '^')
- && (pattern.charAt(patternLength - 1) == '$'))
- {
- phoneNumberQuery
- = pattern.substring(1, patternLength - 1);
- }
- else if ((patternLength > 4)
- && (pattern.charAt(0) == '\\')
- && (pattern.charAt(1) == 'Q')
- && (pattern.charAt(patternLength - 2) == '\\')
- && (pattern.charAt(patternLength - 1) == 'E'))
- {
- phoneNumberQuery
- = pattern.substring(2, patternLength - 2);
- }
-
- }
- }
- finally
- {
- queryIsConvertedToPhoneNumber = true;
- }
- }
- return phoneNumberQuery;
- }
-
- /**
- * Gets the number of <tt>SourceContact</tt>s which match this
- * <tt>ContactQuery</tt>.
- *
- * @return the number of <tt>SourceContact</tt> which match this
- * <tt>ContactQuery</tt>
- */
- public int getQueryResultCount()
- {
- synchronized (queryResults)
- {
- return queryResults.size();
- }
- }
-
- /**
- * Gets the <tt>List</tt> of <tt>SourceContact</tt>s which match this
- * <tt>ContactQuery</tt>.
- *
- * @return the <tt>List</tt> of <tt>SourceContact</tt>s which match this
- * <tt>ContactQuery</tt>
- * @see ContactQuery#getQueryResults()
- */
- public List<SourceContact> getQueryResults()
- {
- List<SourceContact> qr;
-
- synchronized (queryResults)
- {
- qr = new ArrayList<SourceContact>(queryResults.size());
- qr.addAll(queryResults);
- }
- return qr;
- }
-
- /**
- * Returns the query string, this query was created for.
- *
- * @return the query string, this query was created for
- */
- public String getQueryString()
- {
- return query.toString();
- }
-
- /**
- * Performs this <tt>ContactQuery</tt> in a background <tt>Thread</tt>.
- */
- protected abstract void run();
-
- /**
- * Starts this <tt>AsyncContactQuery</tt>.
- */
- public synchronized void start()
- {
- if (thread == null)
- {
- thread
- = new Thread()
- {
- @Override
- public void run()
- {
- boolean completed = false;
-
- try
- {
- AsyncContactQuery.this.run();
- completed = true;
- }
- finally
- {
- synchronized (AsyncContactQuery.this)
- {
- if (thread == Thread.currentThread())
- stopped(completed);
- }
- }
- }
- };
- thread.setDaemon(true);
- thread.start();
- }
- else
- throw new IllegalStateException("thread");
- }
-
- /**
- * Notifies this <tt>AsyncContactQuery</tt> that it has stopped performing
- * in the associated background <tt>Thread</tt>.
- *
- * @param completed <tt>true</tt> if this <tt>ContactQuery</tt> has
- * successfully completed, <tt>false</tt> if an error has been encountered
- * during its execution
- */
- protected void stopped(boolean completed)
- {
- if (getStatus() == QUERY_IN_PROGRESS)
- setStatus(completed ? QUERY_COMPLETED : QUERY_ERROR);
- }
-
- /**
- * Determines whether a specific <tt>String</tt> phone number matches the
- * {@link #query} of this <tt>AsyncContactQuery</tt>.
- *
- * @param phoneNumber the <tt>String</tt> which represents the phone number
- * to match to the <tt>query</tt> of this <tt>AsyncContactQuery</tt>
- * @return <tt>true</tt> if the specified <tt>phoneNumber</tt> matches the
- * <tt>query</tt> of this <tt>AsyncContactQuery</tt>; otherwise,
- * <tt>false</tt>
- */
- protected boolean phoneNumberMatches(String phoneNumber)
- {
- /*
- * PhoneNumberI18nService implements functionality to aid the parsing,
- * formatting and validation of international phone numbers so attempt
- * to use it to determine whether the specified phoneNumber matches the
- * query. For example, check whether the normalized phoneNumber matches
- * the query.
- */
-
- boolean phoneNumberMatches = false;
-
- if (query
- .matcher(ContactSourceActivator.getPhoneNumberI18nService()
- .normalize(phoneNumber)).find())
- {
- phoneNumberMatches = true;
- }
- else
- {
- /*
- * The fact that the normalized form of the phoneNumber doesn't
- * match the query doesn't mean that, for example, it doesn't
- * match the normalized form of the query. The latter, though,
- * requires the query to look like a phone number as well. In
- * order to not accidentally start matching all queries to phone
- * numbers, it seems justified to normalize the query only when
- * it is a phone number, not whenever it looks like a piece of a
- * phone number.
- */
-
- String phoneNumberQuery = getPhoneNumberQuery();
-
- if ((phoneNumberQuery != null)
- && (phoneNumberQuery.length() != 0))
- {
- try
- {
- phoneNumberMatches
- = ContactSourceActivator.getPhoneNumberI18nService()
- .phoneNumbersMatch(
- phoneNumberQuery,
- phoneNumber);
- }
- catch (IllegalArgumentException iaex)
- {
- /*
- * Ignore it, phoneNumberMatches will remain equal to
- * false.
- */
- }
- }
- }
- return phoneNumberMatches;
- }
-}
+package net.java.sip.communicator.service.contactsource;
+
+import java.util.*;
+import java.util.regex.*;
+
+/**
+ * Provides an abstract implementation of a <tt>ContactQuery</tt> which runs in
+ * a separate <tt>Thread</tt>.
+ *
+ * @author Lyubomir Marinov
+ * @param <T> the very type of <tt>ContactSourceService</tt> which performs the
+ * <tt>ContactQuery</tt>
+ */
+public abstract class AsyncContactQuery<T extends ContactSourceService>
+ extends AbstractContactQuery<T>
+{
+ /**
+ * The {@link #query} in the form of a <tt>String</tt> telephone number if
+ * such parsing, formatting and validation is possible; otherwise,
+ * <tt>null</tt>.
+ */
+ private String phoneNumberQuery;
+
+ /**
+ * The <tt>Pattern</tt> for which the associated
+ * <tt>ContactSourceService</tt> is being queried.
+ */
+ protected final Pattern query;
+
+ /**
+ * The indicator which determines whether there has been an attempt to
+ * convert {@link #query} to {@link #phoneNumberQuery}. If the conversion has
+ * been successful, <tt>phoneNumberQuery</tt> will be non-<tt>null</tt>.
+ */
+ private boolean queryIsConvertedToPhoneNumber;
+
+ /**
+ * The <tt>SourceContact</tt>s which match {@link #query}.
+ */
+ private Collection<SourceContact> queryResults
+ = new LinkedList<SourceContact>();
+
+ /**
+ * The <tt>Thread</tt> in which this <tt>AsyncContactQuery</tt> is
+ * performing {@link #query}.
+ */
+ private Thread thread;
+
+ /**
+ * Initializes a new <tt>AsyncContactQuery</tt> instance which is to perform
+ * a specific <tt>query</tt> on behalf of a specific <tt>contactSource</tt>.
+ *
+ * @param contactSource the <tt>ContactSourceService</tt> which is to
+ * perform the new <tt>ContactQuery</tt> instance
+ * @param query the <tt>Pattern</tt> for which <tt>contactSource</tt> is
+ * being queried
+ * @param isSorted indicates if the results of this query should be sorted
+ */
+ protected AsyncContactQuery(T contactSource,
+ Pattern query,
+ boolean isSorted)
+ {
+ super(contactSource);
+
+ this.query = query;
+
+ if (isSorted)
+ queryResults = new TreeSet<SourceContact>();
+ }
+
+ /**
+ * Initializes a new <tt>AsyncContactQuery</tt> instance which is to perform
+ * a specific <tt>query</tt> on behalf of a specific <tt>contactSource</tt>.
+ *
+ * @param contactSource the <tt>ContactSourceService</tt> which is to
+ * perform the new <tt>ContactQuery</tt> instance
+ * @param query the <tt>Pattern</tt> for which <tt>contactSource</tt> is
+ * being queried
+ */
+ protected AsyncContactQuery(T contactSource, Pattern query)
+ {
+ super(contactSource);
+
+ this.query = query;
+ }
+
+ /**
+ * Adds a specific <tt>SourceContact</tt> to the list of
+ * <tt>SourceContact</tt>s to be returned by this <tt>ContactQuery</tt> in
+ * response to {@link #getQueryResults()}.
+ *
+ * @param sourceContact the <tt>SourceContact</tt> to be added to the
+ * <tt>queryResults</tt> of this <tt>ContactQuery</tt>
+ * @param showMoreEnabled indicates whether show more label should be shown
+ * or not.
+ * @return <tt>true</tt> if the <tt>queryResults</tt> of this
+ * <tt>ContactQuery</tt> has changed in response to the call
+ */
+ protected boolean addQueryResult(SourceContact sourceContact,
+ boolean showMoreEnabled)
+ {
+ boolean changed;
+
+ synchronized (queryResults)
+ {
+ changed = queryResults.add(sourceContact);
+ }
+ if (changed)
+ fireContactReceived(sourceContact, showMoreEnabled);
+
+ return changed;
+ }
+
+ /**
+ * Adds a specific <tt>SourceContact</tt> to the list of
+ * <tt>SourceContact</tt>s to be returned by this <tt>ContactQuery</tt> in
+ * response to {@link #getQueryResults()}.
+ *
+ * @param sourceContact the <tt>SourceContact</tt> to be added to the
+ * <tt>queryResults</tt> of this <tt>ContactQuery</tt>
+ * @return <tt>true</tt> if the <tt>queryResults</tt> of this
+ * <tt>ContactQuery</tt> has changed in response to the call
+ */
+ protected boolean addQueryResult(SourceContact sourceContact)
+ {
+ boolean changed;
+
+ synchronized (queryResults)
+ {
+ changed = queryResults.add(sourceContact);
+ }
+ if (changed)
+ fireContactReceived(sourceContact);
+
+ return changed;
+ }
+
+ /**
+ * Removes a specific <tt>SourceContact</tt> from the list of
+ * <tt>SourceContact</tt>s.
+ *
+ * @param sourceContact the <tt>SourceContact</tt> to be removed from the
+ * <tt>queryResults</tt> of this <tt>ContactQuery</tt>
+ * @return <tt>true</tt> if the <tt>queryResults</tt> of this
+ * <tt>ContactQuery</tt> has changed in response to the call
+ */
+ protected boolean removeQueryResult(SourceContact sourceContact)
+ {
+ boolean changed;
+
+ synchronized (queryResults)
+ {
+ changed = queryResults.remove(sourceContact);
+ }
+ if (changed)
+ fireContactRemoved(sourceContact);
+
+ return changed;
+ }
+
+ /**
+ * Adds a set of <tt>SourceContact</tt> instances to the list of
+ * <tt>SourceContact</tt>s to be returned by this <tt>ContactQuery</tt> in
+ * response to {@link #getQueryResults()}.
+ *
+ * @param sourceContacts the set of <tt>SourceContact</tt> to be added to
+ * the <tt>queryResults</tt> of this <tt>ContactQuery</tt>
+ * @return <tt>true</tt> if the <tt>queryResults</tt> of this
+ * <tt>ContactQuery</tt> has changed in response to the call
+ */
+ protected boolean addQueryResults(
+ final Set<? extends SourceContact> sourceContacts)
+ {
+ final boolean changed;
+
+ synchronized (queryResults)
+ {
+ changed = queryResults.addAll(sourceContacts);
+ }
+
+ if (changed)
+ {
+ // TODO Need something to fire one event for multiple contacts.
+ for (SourceContact contact : sourceContacts)
+ {
+ fireContactReceived(contact, false);
+ }
+ }
+
+ return changed;
+ }
+
+
+ /**
+ * Gets the {@link #query} of this <tt>AsyncContactQuery</tt> as a
+ * <tt>String</tt> which represents a phone number (if possible).
+ *
+ * @return a <tt>String</tt> which represents the <tt>query</tt> of this
+ * <tt>AsyncContactQuery</tt> as a phone number if such parsing, formatting
+ * and validation is possible; otherwise, <tt>null</tt>
+ */
+ protected String getPhoneNumberQuery()
+ {
+ if ((phoneNumberQuery == null) && !queryIsConvertedToPhoneNumber)
+ {
+ try
+ {
+ String pattern = query.pattern();
+
+ if (pattern != null)
+ {
+ int patternLength = pattern.length();
+
+ if ((patternLength > 2)
+ && (pattern.charAt(0) == '^')
+ && (pattern.charAt(patternLength - 1) == '$'))
+ {
+ phoneNumberQuery
+ = pattern.substring(1, patternLength - 1);
+ }
+ else if ((patternLength > 4)
+ && (pattern.charAt(0) == '\\')
+ && (pattern.charAt(1) == 'Q')
+ && (pattern.charAt(patternLength - 2) == '\\')
+ && (pattern.charAt(patternLength - 1) == 'E'))
+ {
+ phoneNumberQuery
+ = pattern.substring(2, patternLength - 2);
+ }
+
+ }
+ }
+ finally
+ {
+ queryIsConvertedToPhoneNumber = true;
+ }
+ }
+ return phoneNumberQuery;
+ }
+
+ /**
+ * Gets the number of <tt>SourceContact</tt>s which match this
+ * <tt>ContactQuery</tt>.
+ *
+ * @return the number of <tt>SourceContact</tt> which match this
+ * <tt>ContactQuery</tt>
+ */
+ public int getQueryResultCount()
+ {
+ synchronized (queryResults)
+ {
+ return queryResults.size();
+ }
+ }
+
+ /**
+ * Gets the <tt>List</tt> of <tt>SourceContact</tt>s which match this
+ * <tt>ContactQuery</tt>.
+ *
+ * @return the <tt>List</tt> of <tt>SourceContact</tt>s which match this
+ * <tt>ContactQuery</tt>
+ * @see ContactQuery#getQueryResults()
+ */
+ public List<SourceContact> getQueryResults()
+ {
+ List<SourceContact> qr;
+
+ synchronized (queryResults)
+ {
+ qr = new ArrayList<SourceContact>(queryResults.size());
+ qr.addAll(queryResults);
+ }
+ return qr;
+ }
+
+ /**
+ * Returns the query string, this query was created for.
+ *
+ * @return the query string, this query was created for
+ */
+ public String getQueryString()
+ {
+ return query.toString();
+ }
+
+ /**
+ * Performs this <tt>ContactQuery</tt> in a background <tt>Thread</tt>.
+ */
+ protected abstract void run();
+
+ /**
+ * Starts this <tt>AsyncContactQuery</tt>.
+ */
+ public synchronized void start()
+ {
+ if (thread == null)
+ {
+ thread
+ = new Thread()
+ {
+ @Override
+ public void run()
+ {
+ boolean completed = false;
+
+ try
+ {
+ AsyncContactQuery.this.run();
+ completed = true;
+ }
+ finally
+ {
+ synchronized (AsyncContactQuery.this)
+ {
+ if (thread == Thread.currentThread())
+ stopped(completed);
+ }
+ }
+ }
+ };
+ thread.setDaemon(true);
+ thread.start();
+ }
+ else
+ throw new IllegalStateException("thread");
+ }
+
+ /**
+ * Notifies this <tt>AsyncContactQuery</tt> that it has stopped performing
+ * in the associated background <tt>Thread</tt>.
+ *
+ * @param completed <tt>true</tt> if this <tt>ContactQuery</tt> has
+ * successfully completed, <tt>false</tt> if an error has been encountered
+ * during its execution
+ */
+ protected void stopped(boolean completed)
+ {
+ if (getStatus() == QUERY_IN_PROGRESS)
+ setStatus(completed ? QUERY_COMPLETED : QUERY_ERROR);
+ }
+
+ /**
+ * Determines whether a specific <tt>String</tt> phone number matches the
+ * {@link #query} of this <tt>AsyncContactQuery</tt>.
+ *
+ * @param phoneNumber the <tt>String</tt> which represents the phone number
+ * to match to the <tt>query</tt> of this <tt>AsyncContactQuery</tt>
+ * @return <tt>true</tt> if the specified <tt>phoneNumber</tt> matches the
+ * <tt>query</tt> of this <tt>AsyncContactQuery</tt>; otherwise,
+ * <tt>false</tt>
+ */
+ protected boolean phoneNumberMatches(String phoneNumber)
+ {
+ /*
+ * PhoneNumberI18nService implements functionality to aid the parsing,
+ * formatting and validation of international phone numbers so attempt
+ * to use it to determine whether the specified phoneNumber matches the
+ * query. For example, check whether the normalized phoneNumber matches
+ * the query.
+ */
+
+ boolean phoneNumberMatches = false;
+
+ if (query
+ .matcher(ContactSourceActivator.getPhoneNumberI18nService()
+ .normalize(phoneNumber)).find())
+ {
+ phoneNumberMatches = true;
+ }
+ else
+ {
+ /*
+ * The fact that the normalized form of the phoneNumber doesn't
+ * match the query doesn't mean that, for example, it doesn't
+ * match the normalized form of the query. The latter, though,
+ * requires the query to look like a phone number as well. In
+ * order to not accidentally start matching all queries to phone
+ * numbers, it seems justified to normalize the query only when
+ * it is a phone number, not whenever it looks like a piece of a
+ * phone number.
+ */
+
+ String phoneNumberQuery = getPhoneNumberQuery();
+
+ if ((phoneNumberQuery != null)
+ && (phoneNumberQuery.length() != 0))
+ {
+ try
+ {
+ phoneNumberMatches
+ = ContactSourceActivator.getPhoneNumberI18nService()
+ .phoneNumbersMatch(
+ phoneNumberQuery,
+ phoneNumber);
+ }
+ catch (IllegalArgumentException iaex)
+ {
+ /*
+ * Ignore it, phoneNumberMatches will remain equal to
+ * false.
+ */
+ }
+ }
+ }
+ return phoneNumberMatches;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/contactsource/AsyncContactSourceService.java b/src/net/java/sip/communicator/service/contactsource/AsyncContactSourceService.java
index 848a723..14d06a4 100644
--- a/src/net/java/sip/communicator/service/contactsource/AsyncContactSourceService.java
+++ b/src/net/java/sip/communicator/service/contactsource/AsyncContactSourceService.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,70 +15,70 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.contactsource;
-
-import java.util.regex.*;
-
-/**
- * Declares the interface of a <tt>ContactSourceService</tt> which performs
- * <tt>ContactQuery</tt>s in a separate <tt>Thread</tt>.
- *
- * @author Lyubomir Marinov
- */
-public abstract class AsyncContactSourceService
- implements ExtendedContactSourceService
-{
- /**
- * Creates query that searches for <tt>SourceContact</tt>s
- * which match a specific <tt>query</tt> <tt>String</tt>.
- *
- * @param query the <tt>String</tt> which this <tt>ContactSourceService</tt>
- * is being queried for
- * @return a <tt>ContactQuery</tt> which represents the query of this
- * <tt>ContactSourceService</tt> implementation for the specified
- * <tt>String</tt> and via which the matching <tt>SourceContact</tt>s (if
- * any) will be returned
- * @see ContactSourceService#queryContactSource(String)
- */
- public ContactQuery createContactQuery(String query)
- {
- return createContactQuery(
- Pattern.compile(query, Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
- }
-
- /**
- * Creates query that searches for <tt>SourceContact</tt>s
- * which match a specific <tt>query</tt> <tt>String</tt>.
- *
- * @param query the <tt>String</tt> which this <tt>ContactSourceService</tt>
- * is being queried for
- * @param contactCount the maximum count of result contacts
- * @return a <tt>ContactQuery</tt> which represents the query of this
- * <tt>ContactSourceService</tt> implementation for the specified
- * <tt>String</tt> and via which the matching <tt>SourceContact</tt>s (if
- * any) will be returned
- * @see ContactSourceService#queryContactSource(String)
- */
- public ContactQuery createContactQuery(String query, int contactCount)
- {
- return createContactQuery(
- Pattern.compile(query, Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
- }
-
- /**
- * Stops this <tt>ContactSourceService</tt>.
- */
- public abstract void stop();
-
- /**
- * Defines whether using this contact source service (Outlook or MacOSX
- * Contacs) can be used as result for the search field. This is
- * useful when an external plugin looks for result of this contact source
- * service, but want to display the search field result from its own (avoid
- * duplicate results).
- *
- * @return True if this contact source service can be used to perform search
- * for contacts. False otherwise.
- */
- public abstract boolean canBeUsedToSearchContacts();
-}
+package net.java.sip.communicator.service.contactsource;
+
+import java.util.regex.*;
+
+/**
+ * Declares the interface of a <tt>ContactSourceService</tt> which performs
+ * <tt>ContactQuery</tt>s in a separate <tt>Thread</tt>.
+ *
+ * @author Lyubomir Marinov
+ */
+public abstract class AsyncContactSourceService
+ implements ExtendedContactSourceService
+{
+ /**
+ * Creates query that searches for <tt>SourceContact</tt>s
+ * which match a specific <tt>query</tt> <tt>String</tt>.
+ *
+ * @param query the <tt>String</tt> which this <tt>ContactSourceService</tt>
+ * is being queried for
+ * @return a <tt>ContactQuery</tt> which represents the query of this
+ * <tt>ContactSourceService</tt> implementation for the specified
+ * <tt>String</tt> and via which the matching <tt>SourceContact</tt>s (if
+ * any) will be returned
+ * @see ContactSourceService#queryContactSource(String)
+ */
+ public ContactQuery createContactQuery(String query)
+ {
+ return createContactQuery(
+ Pattern.compile(query, Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+ }
+
+ /**
+ * Creates query that searches for <tt>SourceContact</tt>s
+ * which match a specific <tt>query</tt> <tt>String</tt>.
+ *
+ * @param query the <tt>String</tt> which this <tt>ContactSourceService</tt>
+ * is being queried for
+ * @param contactCount the maximum count of result contacts
+ * @return a <tt>ContactQuery</tt> which represents the query of this
+ * <tt>ContactSourceService</tt> implementation for the specified
+ * <tt>String</tt> and via which the matching <tt>SourceContact</tt>s (if
+ * any) will be returned
+ * @see ContactSourceService#queryContactSource(String)
+ */
+ public ContactQuery createContactQuery(String query, int contactCount)
+ {
+ return createContactQuery(
+ Pattern.compile(query, Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+ }
+
+ /**
+ * Stops this <tt>ContactSourceService</tt>.
+ */
+ public abstract void stop();
+
+ /**
+ * Defines whether using this contact source service (Outlook or MacOSX
+ * Contacs) can be used as result for the search field. This is
+ * useful when an external plugin looks for result of this contact source
+ * service, but want to display the search field result from its own (avoid
+ * duplicate results).
+ *
+ * @return True if this contact source service can be used to perform search
+ * for contacts. False otherwise.
+ */
+ public abstract boolean canBeUsedToSearchContacts();
+}
diff --git a/src/net/java/sip/communicator/service/contactsource/ContactDetail.java b/src/net/java/sip/communicator/service/contactsource/ContactDetail.java
index c062035..362faf4 100644
--- a/src/net/java/sip/communicator/service/contactsource/ContactDetail.java
+++ b/src/net/java/sip/communicator/service/contactsource/ContactDetail.java
@@ -210,11 +210,9 @@ public class ContactDetail
*/
AIM("AIM"),
ICQ("ICQ"),
- MSN("MSN"),
- Jabber("Jabber"),
+ Jabber("XMPP"),
Skype("Skype"),
Yahoo("Yahoo"),
- Facebook("Facebook"),
GoogleTalk("GoogleTalk"),
/**
@@ -438,9 +436,19 @@ public class ContactDetail
this.contactDetailValue = contactDetailValue;
if (!StringUtils.isNullOrEmpty(detailDisplayName))
+ {
this.detailDisplayName = detailDisplayName;
+ }
+ else if (category == Category.Phone)
+ {
+ this.detailDisplayName =
+ ContactSourceActivator.getPhoneNumberI18nService()
+ .formatForDisplay(contactDetailValue);
+ }
else
+ {
this.detailDisplayName = contactDetailValue;
+ }
// category & labels
this.category = category;
diff --git a/src/net/java/sip/communicator/service/contactsource/GenericSourceContact.java b/src/net/java/sip/communicator/service/contactsource/GenericSourceContact.java
index a77adee..0c0cb0d 100644
--- a/src/net/java/sip/communicator/service/contactsource/GenericSourceContact.java
+++ b/src/net/java/sip/communicator/service/contactsource/GenericSourceContact.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,295 +15,295 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.contactsource;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Implements a generic <tt>SourceContact</tt> for the purposes of the support
- * for the OS-specific Address Book.
- *
- * @author Lyubomir Marinov
- */
-public class GenericSourceContact
- extends DataObject
- implements SourceContact
-{
- /**
- * The <tt>ContactDetail</tt>s of this <tt>SourceContact</tt>.
- */
- protected final List<ContactDetail> contactDetails;
-
- /**
- * The <tt>ContactSourceService</tt> which has created this
- * <tt>SourceContact</tt>.
- */
- private final ContactSourceService contactSource;
-
- /**
- * The display name of this <tt>SourceContact</tt>.
- */
- private String displayName;
-
- /**
- * The display details of this contact.
- */
- private String displayDetails;
-
- /**
- * The presence status of this contact.
- */
- private PresenceStatus presenceStatus;
-
- /**
- * The image/avatar of this <tt>SourceContact</tt>
- */
- private byte[] image;
-
- /**
- * The address of the contact.
- */
- private String contactAddress = null;
-
- /**
- * Initializes a new <tt>AddrBookSourceContact</tt> instance.
- *
- * @param contactSource the <tt>ContactSourceService</tt> which is creating
- * the new instance
- * @param displayName the display name of the new instance
- * @param contactDetails the <tt>ContactDetail</tt>s of the new instance
- */
- public GenericSourceContact(
- ContactSourceService contactSource,
- String displayName,
- List<ContactDetail> contactDetails)
- {
- this.contactSource = contactSource;
- this.displayName = displayName;
- this.contactDetails = contactDetails;
- }
-
- /**
- * Returns the address of the contact.
- *
- * @return the contact address.
- */
- public String getContactAddress()
- {
- return contactAddress;
- }
-
- /**
- * Gets the <tt>ContactDetail</tt>s of this <tt>SourceContact</tt>.
- *
- * @return the <tt>ContactDetail</tt>s of this <tt>SourceContact</tt>
- * @see SourceContact#getContactDetails()
- */
- public List<ContactDetail> getContactDetails()
- {
- return Collections.unmodifiableList(contactDetails);
- }
-
- /**
- * Gets the <tt>ContactDetail</tt>s of this <tt>SourceContact</tt> which
- * support a specific <tt>OperationSet</tt>.
- *
- * @param operationSet the <tt>OperationSet</tt> the supporting
- * <tt>ContactDetail</tt>s of which are to be returned
- * @return the <tt>ContactDetail</tt>s of this <tt>SourceContact</tt> which
- * support the specified <tt>operationSet</tt>
- * @see SourceContact#getContactDetails(Class)
- */
- public List<ContactDetail> getContactDetails(
- Class<? extends OperationSet> operationSet)
- {
- List<ContactDetail> contactDetails = new LinkedList<ContactDetail>();
-
- for (ContactDetail contactDetail : getContactDetails())
- {
- List<Class<? extends OperationSet>> supportedOperationSets
- = contactDetail.getSupportedOperationSets();
-
- if ((supportedOperationSets != null)
- && supportedOperationSets.contains(operationSet))
- contactDetails.add(contactDetail);
- }
- return contactDetails;
- }
-
- /**
- * Returns a list of all <tt>ContactDetail</tt>s corresponding to the given
- * category.
- * @param category the <tt>OperationSet</tt> class we're looking for
- * @return a list of all <tt>ContactDetail</tt>s corresponding to the given
- * category
- */
- public List<ContactDetail> getContactDetails(
- ContactDetail.Category category)
- {
- List<ContactDetail> contactDetails = new LinkedList<ContactDetail>();
-
- for (ContactDetail contactDetail : getContactDetails())
- {
- if(contactDetail != null)
- {
- ContactDetail.Category detailCategory
- = contactDetail.getCategory();
- if (detailCategory != null && detailCategory.equals(category))
- contactDetails.add(contactDetail);
- }
- }
- return contactDetails;
- }
-
- /**
- * Gets the <tt>ContactSourceService</tt> which has created this
- * <tt>SourceContact</tt>.
- *
- * @return the <tt>ContactSourceService</tt> which has created this
- * <tt>SourceContact</tt>
- * @see SourceContact#getContactSource()
- */
- public ContactSourceService getContactSource()
- {
- return contactSource;
- }
-
- /**
- * Gets the display details of this <tt>SourceContact</tt>.
- *
- * @return the display details of this <tt>SourceContact</tt>
- * @see SourceContact#getDisplayDetails()
- */
- public String getDisplayDetails()
- {
- return displayDetails;
- }
-
- /**
- * Sets the address of the contact.
- *
- * @param contactAddress the address to set.
- */
- public void setContactAddress(String contactAddress)
- {
- this.contactAddress = contactAddress;
- }
-
- /**
- * Sets the display details of this <tt>SourceContact</tt>.
- *
- * @param displayDetails the display details of this <tt>SourceContact</tt>
- */
- public String setDisplayDetails(String displayDetails)
- {
- return this.displayDetails = displayDetails;
- }
-
- /**
- * Gets the display name of this <tt>SourceContact</tt>.
- *
- * @return the display name of this <tt>SourceContact</tt>
- * @see SourceContact#getDisplayName()
- */
- public String getDisplayName()
- {
- return displayName;
- }
-
- /**
- * Sets the display name of this <tt>SourceContact</tt>.
- *
- * @param displayName The display name of this <tt>SourceContact</tt>
- */
- public void setDisplayName(String displayName)
- {
- this.displayName = displayName;
- }
-
- /**
- * Gets the image/avatar of this <tt>SourceContact</tt>.
- *
- * @return the image/avatar of this <tt>SourceContact</tt>
- * @see SourceContact#getImage()
- */
- public byte[] getImage()
- {
- return image;
- }
-
- /**
- * Gets the preferred <tt>ContactDetail</tt> for a specific
- * <tt>OperationSet</tt>.
- *
- * @param operationSet the <tt>OperationSet</tt> to get the preferred
- * <tt>ContactDetail</tt> for
- * @return the preferred <tt>ContactDetail</tt> for the specified
- * <tt>operationSet</tt>
- * @see SourceContact#getPreferredContactDetail(Class)
- */
- public ContactDetail getPreferredContactDetail(
- Class<? extends OperationSet> operationSet)
- {
- List<ContactDetail> contactDetails = getContactDetails(operationSet);
-
- return contactDetails.isEmpty() ? null : contactDetails.get(0);
- }
-
- /**
- * Sets the image/avatar of this <tt>SourceContact</tt>.
- *
- * @param image the image/avatar to be set on this <tt>SourceContact</tt>
- */
- public void setImage(byte[] image)
- {
- this.image = image;
- }
-
- /**
- * Whether the current image returned by @see #getImage() is the one
- * provided by the SourceContact by default, or is a one used and obtained
- * from external source.
- *
- * @return whether this is the default image for this SourceContact.
- */
- @Override
- public boolean isDefaultImage()
- {
- // in this SourceContact we always show an externally set image or null
- return false;
- }
-
- /**
- * Returns the status of the source contact. And null if such information
- * is not available.
- * @return the PresenceStatus representing the state of this source contact.
- */
- public PresenceStatus getPresenceStatus()
- {
- return presenceStatus;
- }
-
- /**
- * Sets the status of the source contact.
- *
- * @param presenceStatus the status of this contact
- */
- public void setPresenceStatus(PresenceStatus presenceStatus)
- {
- this.presenceStatus = presenceStatus;
- }
-
- /**
- * Returns the index of this source contact in its parent.
- *
- * @return the index of this source contact in its parent
- */
- public int getIndex()
- {
- return -1;
- }
-}
+package net.java.sip.communicator.service.contactsource;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Implements a generic <tt>SourceContact</tt> for the purposes of the support
+ * for the OS-specific Address Book.
+ *
+ * @author Lyubomir Marinov
+ */
+public class GenericSourceContact
+ extends DataObject
+ implements SourceContact
+{
+ /**
+ * The <tt>ContactDetail</tt>s of this <tt>SourceContact</tt>.
+ */
+ protected final List<ContactDetail> contactDetails;
+
+ /**
+ * The <tt>ContactSourceService</tt> which has created this
+ * <tt>SourceContact</tt>.
+ */
+ private final ContactSourceService contactSource;
+
+ /**
+ * The display name of this <tt>SourceContact</tt>.
+ */
+ private String displayName;
+
+ /**
+ * The display details of this contact.
+ */
+ private String displayDetails;
+
+ /**
+ * The presence status of this contact.
+ */
+ private PresenceStatus presenceStatus;
+
+ /**
+ * The image/avatar of this <tt>SourceContact</tt>
+ */
+ private byte[] image;
+
+ /**
+ * The address of the contact.
+ */
+ private String contactAddress = null;
+
+ /**
+ * Initializes a new <tt>AddrBookSourceContact</tt> instance.
+ *
+ * @param contactSource the <tt>ContactSourceService</tt> which is creating
+ * the new instance
+ * @param displayName the display name of the new instance
+ * @param contactDetails the <tt>ContactDetail</tt>s of the new instance
+ */
+ public GenericSourceContact(
+ ContactSourceService contactSource,
+ String displayName,
+ List<ContactDetail> contactDetails)
+ {
+ this.contactSource = contactSource;
+ this.displayName = displayName;
+ this.contactDetails = contactDetails;
+ }
+
+ /**
+ * Returns the address of the contact.
+ *
+ * @return the contact address.
+ */
+ public String getContactAddress()
+ {
+ return contactAddress;
+ }
+
+ /**
+ * Gets the <tt>ContactDetail</tt>s of this <tt>SourceContact</tt>.
+ *
+ * @return the <tt>ContactDetail</tt>s of this <tt>SourceContact</tt>
+ * @see SourceContact#getContactDetails()
+ */
+ public List<ContactDetail> getContactDetails()
+ {
+ return Collections.unmodifiableList(contactDetails);
+ }
+
+ /**
+ * Gets the <tt>ContactDetail</tt>s of this <tt>SourceContact</tt> which
+ * support a specific <tt>OperationSet</tt>.
+ *
+ * @param operationSet the <tt>OperationSet</tt> the supporting
+ * <tt>ContactDetail</tt>s of which are to be returned
+ * @return the <tt>ContactDetail</tt>s of this <tt>SourceContact</tt> which
+ * support the specified <tt>operationSet</tt>
+ * @see SourceContact#getContactDetails(Class)
+ */
+ public List<ContactDetail> getContactDetails(
+ Class<? extends OperationSet> operationSet)
+ {
+ List<ContactDetail> contactDetails = new LinkedList<ContactDetail>();
+
+ for (ContactDetail contactDetail : getContactDetails())
+ {
+ List<Class<? extends OperationSet>> supportedOperationSets
+ = contactDetail.getSupportedOperationSets();
+
+ if ((supportedOperationSets != null)
+ && supportedOperationSets.contains(operationSet))
+ contactDetails.add(contactDetail);
+ }
+ return contactDetails;
+ }
+
+ /**
+ * Returns a list of all <tt>ContactDetail</tt>s corresponding to the given
+ * category.
+ * @param category the <tt>OperationSet</tt> class we're looking for
+ * @return a list of all <tt>ContactDetail</tt>s corresponding to the given
+ * category
+ */
+ public List<ContactDetail> getContactDetails(
+ ContactDetail.Category category)
+ {
+ List<ContactDetail> contactDetails = new LinkedList<ContactDetail>();
+
+ for (ContactDetail contactDetail : getContactDetails())
+ {
+ if(contactDetail != null)
+ {
+ ContactDetail.Category detailCategory
+ = contactDetail.getCategory();
+ if (detailCategory != null && detailCategory.equals(category))
+ contactDetails.add(contactDetail);
+ }
+ }
+ return contactDetails;
+ }
+
+ /**
+ * Gets the <tt>ContactSourceService</tt> which has created this
+ * <tt>SourceContact</tt>.
+ *
+ * @return the <tt>ContactSourceService</tt> which has created this
+ * <tt>SourceContact</tt>
+ * @see SourceContact#getContactSource()
+ */
+ public ContactSourceService getContactSource()
+ {
+ return contactSource;
+ }
+
+ /**
+ * Gets the display details of this <tt>SourceContact</tt>.
+ *
+ * @return the display details of this <tt>SourceContact</tt>
+ * @see SourceContact#getDisplayDetails()
+ */
+ public String getDisplayDetails()
+ {
+ return displayDetails;
+ }
+
+ /**
+ * Sets the address of the contact.
+ *
+ * @param contactAddress the address to set.
+ */
+ public void setContactAddress(String contactAddress)
+ {
+ this.contactAddress = contactAddress;
+ }
+
+ /**
+ * Sets the display details of this <tt>SourceContact</tt>.
+ *
+ * @param displayDetails the display details of this <tt>SourceContact</tt>
+ */
+ public String setDisplayDetails(String displayDetails)
+ {
+ return this.displayDetails = displayDetails;
+ }
+
+ /**
+ * Gets the display name of this <tt>SourceContact</tt>.
+ *
+ * @return the display name of this <tt>SourceContact</tt>
+ * @see SourceContact#getDisplayName()
+ */
+ public String getDisplayName()
+ {
+ return displayName;
+ }
+
+ /**
+ * Sets the display name of this <tt>SourceContact</tt>.
+ *
+ * @param displayName The display name of this <tt>SourceContact</tt>
+ */
+ public void setDisplayName(String displayName)
+ {
+ this.displayName = displayName;
+ }
+
+ /**
+ * Gets the image/avatar of this <tt>SourceContact</tt>.
+ *
+ * @return the image/avatar of this <tt>SourceContact</tt>
+ * @see SourceContact#getImage()
+ */
+ public byte[] getImage()
+ {
+ return image;
+ }
+
+ /**
+ * Gets the preferred <tt>ContactDetail</tt> for a specific
+ * <tt>OperationSet</tt>.
+ *
+ * @param operationSet the <tt>OperationSet</tt> to get the preferred
+ * <tt>ContactDetail</tt> for
+ * @return the preferred <tt>ContactDetail</tt> for the specified
+ * <tt>operationSet</tt>
+ * @see SourceContact#getPreferredContactDetail(Class)
+ */
+ public ContactDetail getPreferredContactDetail(
+ Class<? extends OperationSet> operationSet)
+ {
+ List<ContactDetail> contactDetails = getContactDetails(operationSet);
+
+ return contactDetails.isEmpty() ? null : contactDetails.get(0);
+ }
+
+ /**
+ * Sets the image/avatar of this <tt>SourceContact</tt>.
+ *
+ * @param image the image/avatar to be set on this <tt>SourceContact</tt>
+ */
+ public void setImage(byte[] image)
+ {
+ this.image = image;
+ }
+
+ /**
+ * Whether the current image returned by @see #getImage() is the one
+ * provided by the SourceContact by default, or is a one used and obtained
+ * from external source.
+ *
+ * @return whether this is the default image for this SourceContact.
+ */
+ @Override
+ public boolean isDefaultImage()
+ {
+ // in this SourceContact we always show an externally set image or null
+ return false;
+ }
+
+ /**
+ * Returns the status of the source contact. And null if such information
+ * is not available.
+ * @return the PresenceStatus representing the state of this source contact.
+ */
+ public PresenceStatus getPresenceStatus()
+ {
+ return presenceStatus;
+ }
+
+ /**
+ * Sets the status of the source contact.
+ *
+ * @param presenceStatus the status of this contact
+ */
+ public void setPresenceStatus(PresenceStatus presenceStatus)
+ {
+ this.presenceStatus = presenceStatus;
+ }
+
+ /**
+ * Returns the index of this source contact in its parent.
+ *
+ * @return the index of this source contact in its parent
+ */
+ public int getIndex()
+ {
+ return -1;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/dns/DnssecException.java b/src/net/java/sip/communicator/service/dns/DnssecException.java
index bc91146..dc4923e 100644
--- a/src/net/java/sip/communicator/service/dns/DnssecException.java
+++ b/src/net/java/sip/communicator/service/dns/DnssecException.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,27 +15,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.dns;
-
-/**
- * Checked DNSSEC exception for code that knows how to deal with it.
- *
- * @author Ingo Bauersachs
- */
-public class DnssecException
- extends Exception
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * Creates a new instance of this class.
- * @param e the DNSSEC runtime exception to encapsulate.
- */
- public DnssecException(DnssecRuntimeException e)
- {
- super(e);
- }
-}
+package net.java.sip.communicator.service.dns;
+
+/**
+ * Checked DNSSEC exception for code that knows how to deal with it.
+ *
+ * @author Ingo Bauersachs
+ */
+public class DnssecException
+ extends Exception
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * Creates a new instance of this class.
+ * @param e the DNSSEC runtime exception to encapsulate.
+ */
+ public DnssecException(DnssecRuntimeException e)
+ {
+ super(e);
+ }
+}
diff --git a/src/net/java/sip/communicator/service/dns/DnssecRuntimeException.java b/src/net/java/sip/communicator/service/dns/DnssecRuntimeException.java
index 192f9e4..cd948b4 100644
--- a/src/net/java/sip/communicator/service/dns/DnssecRuntimeException.java
+++ b/src/net/java/sip/communicator/service/dns/DnssecRuntimeException.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,32 +15,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.dns;
-
-import java.net.*;
-
-/**
- * Runtime exception that is thrown when a DNSSEC validation failure occurred.
- * This is not a checked exception or a derivative of
- * {@link UnknownHostException} so that existing code does not retry the lookup
- * (potentially in a loop).
- *
- * @author Ingo Bauersachs
- */
-public class DnssecRuntimeException
- extends RuntimeException
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * Creates a new instance of this class.
- * @param message The reason why this exception is thrown.
- */
- public DnssecRuntimeException(String message)
- {
- super(message);
- }
-}
+package net.java.sip.communicator.service.dns;
+
+import java.net.*;
+
+/**
+ * Runtime exception that is thrown when a DNSSEC validation failure occurred.
+ * This is not a checked exception or a derivative of
+ * {@link UnknownHostException} so that existing code does not retry the lookup
+ * (potentially in a loop).
+ *
+ * @author Ingo Bauersachs
+ */
+public class DnssecRuntimeException
+ extends RuntimeException
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * Creates a new instance of this class.
+ * @param message The reason why this exception is thrown.
+ */
+ public DnssecRuntimeException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/src/net/java/sip/communicator/service/googlecontacts/GoogleContactsEntry.java b/src/net/java/sip/communicator/service/googlecontacts/GoogleContactsEntry.java
index 0e89162..e72fe67 100644
--- a/src/net/java/sip/communicator/service/googlecontacts/GoogleContactsEntry.java
+++ b/src/net/java/sip/communicator/service/googlecontacts/GoogleContactsEntry.java
@@ -37,21 +37,11 @@ public interface GoogleContactsEntry
GOOGLETALK,
/**
- * Yahoo protocol.
- */
- YAHOO,
-
- /**
* AIM protocol.
*/
AIM,
/**
- * MSN protocol.
- */
- MSN,
-
- /**
* ICQ protocol.
*/
ICQ,
@@ -62,6 +52,11 @@ public interface GoogleContactsEntry
JABBER,
/**
+ * Skype protocol.
+ */
+ SKYPE,
+
+ /**
* Other protocol (i.e. not supported).
*/
OTHER,
diff --git a/src/net/java/sip/communicator/service/gui/AlertUIService.java b/src/net/java/sip/communicator/service/gui/AlertUIService.java
index 2843d60..a6055c4 100644
--- a/src/net/java/sip/communicator/service/gui/AlertUIService.java
+++ b/src/net/java/sip/communicator/service/gui/AlertUIService.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,125 +15,125 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.gui;
-
-/**
- * The <tt>AlertUIService</tt> is a service that allows to show error messages
- * and warnings.
- *
- * @author Yana Stamcheva
- */
-public interface AlertUIService
-{
- /**
- * Indicates that the OK button is pressed.
- */
- public static final int OK_RETURN_CODE = 0;
-
- /**
- * Indicates that the Cancel button is pressed.
- */
- public static final int CANCEL_RETURN_CODE = 1;
-
- /**
- * Indicates that the OK button is pressed and the Don't ask check box is
- * checked.
- */
- public static final int OK_DONT_ASK_CODE = 2;
-
- /**
- * The type of the alert dialog, which displays a warning instead of an
- * error.
- */
- public static final int WARNING = 1;
-
- /**
- * The type of alert dialog which displays a warning instead of an error.
- */
- public static final int ERROR = 0;
-
- /**
- * Shows an alert dialog with the given title and message.
- *
- * @param title the title of the dialog
- * @param message the message to be displayed
- */
- public void showAlertDialog(String title,
- String message);
-
- /**
- * Shows an alert dialog with the given title message and exception
- * corresponding to the error.
- *
- * @param title the title of the dialog
- * @param message the message to be displayed
- * @param e the exception corresponding to the error
- */
- public void showAlertDialog(String title,
- String message,
- Throwable e);
-
- /**
- * Shows an alert dialog with the given title, message and type of message.
- *
- * @param title the title of the error dialog
- * @param message the message to be displayed
- * @param type the dialog type (warning or error)
- */
- public void showAlertDialog(String title,
- String message,
- int type);
-
- /**
- * Shows an notification pop-up which can be clicked. An error dialog is
- * shown when the notification is clicked.
- *
- * @param title the title of the error dialog and the notification pop-up
- * @param message the message to be displayed in the error dialog and the
- * pop-up
- */
- public void showAlertPopup(String title, String message);
-
- /**
- * Shows an notification pop-up which can be clicked. An error dialog is
- * shown when the notification is clicked.
- *
- * @param title the title of the error dialog and the notification pop-up
- * @param message the message to be displayed in the error dialog and the
- * pop-up
- * @param e the exception that can be shown in the error dialog
- */
- public void showAlertPopup(String title, String message,
- Throwable e);
-
- /**
- * Shows an notification pop-up which can be clicked. An error dialog is
- * shown when the notification is clicked.
- *
- * @param title the title of the notification pop-up
- * @param message the message of the pop-up
- * @param errorDialogTitle the title of the error dialog
- * @param errorDialogMessage the message of the error dialog
- */
- public void showAlertPopup(String title, String message,
- String errorDialogTitle, String errorDialogMessage);
-
- /**
- * Shows an notification pop-up which can be clicked. An error dialog is
- * shown when the notification is clicked.
- *
- * @param title the title of the notification pop-up
- * @param message the message of the pop-up
- * @param errorDialogTitle the title of the error dialog
- * @param errorDialogMessage the message of the error dialog
- * @param e the exception that can be shown in the error dialog
- */
- public void showAlertPopup(String title, String message,
- String errorDialogTitle, String errorDialogMessage, Throwable e);
-
- /**
- * Releases the resources acquired by this instance throughout its lifetime
- * and removes the listeners.
- */
- public void dispose();
-}
+package net.java.sip.communicator.service.gui;
+
+/**
+ * The <tt>AlertUIService</tt> is a service that allows to show error messages
+ * and warnings.
+ *
+ * @author Yana Stamcheva
+ */
+public interface AlertUIService
+{
+ /**
+ * Indicates that the OK button is pressed.
+ */
+ public static final int OK_RETURN_CODE = 0;
+
+ /**
+ * Indicates that the Cancel button is pressed.
+ */
+ public static final int CANCEL_RETURN_CODE = 1;
+
+ /**
+ * Indicates that the OK button is pressed and the Don't ask check box is
+ * checked.
+ */
+ public static final int OK_DONT_ASK_CODE = 2;
+
+ /**
+ * The type of the alert dialog, which displays a warning instead of an
+ * error.
+ */
+ public static final int WARNING = 1;
+
+ /**
+ * The type of alert dialog which displays a warning instead of an error.
+ */
+ public static final int ERROR = 0;
+
+ /**
+ * Shows an alert dialog with the given title and message.
+ *
+ * @param title the title of the dialog
+ * @param message the message to be displayed
+ */
+ public void showAlertDialog(String title,
+ String message);
+
+ /**
+ * Shows an alert dialog with the given title message and exception
+ * corresponding to the error.
+ *
+ * @param title the title of the dialog
+ * @param message the message to be displayed
+ * @param e the exception corresponding to the error
+ */
+ public void showAlertDialog(String title,
+ String message,
+ Throwable e);
+
+ /**
+ * Shows an alert dialog with the given title, message and type of message.
+ *
+ * @param title the title of the error dialog
+ * @param message the message to be displayed
+ * @param type the dialog type (warning or error)
+ */
+ public void showAlertDialog(String title,
+ String message,
+ int type);
+
+ /**
+ * Shows an notification pop-up which can be clicked. An error dialog is
+ * shown when the notification is clicked.
+ *
+ * @param title the title of the error dialog and the notification pop-up
+ * @param message the message to be displayed in the error dialog and the
+ * pop-up
+ */
+ public void showAlertPopup(String title, String message);
+
+ /**
+ * Shows an notification pop-up which can be clicked. An error dialog is
+ * shown when the notification is clicked.
+ *
+ * @param title the title of the error dialog and the notification pop-up
+ * @param message the message to be displayed in the error dialog and the
+ * pop-up
+ * @param e the exception that can be shown in the error dialog
+ */
+ public void showAlertPopup(String title, String message,
+ Throwable e);
+
+ /**
+ * Shows an notification pop-up which can be clicked. An error dialog is
+ * shown when the notification is clicked.
+ *
+ * @param title the title of the notification pop-up
+ * @param message the message of the pop-up
+ * @param errorDialogTitle the title of the error dialog
+ * @param errorDialogMessage the message of the error dialog
+ */
+ public void showAlertPopup(String title, String message,
+ String errorDialogTitle, String errorDialogMessage);
+
+ /**
+ * Shows an notification pop-up which can be clicked. An error dialog is
+ * shown when the notification is clicked.
+ *
+ * @param title the title of the notification pop-up
+ * @param message the message of the pop-up
+ * @param errorDialogTitle the title of the error dialog
+ * @param errorDialogMessage the message of the error dialog
+ * @param e the exception that can be shown in the error dialog
+ */
+ public void showAlertPopup(String title, String message,
+ String errorDialogTitle, String errorDialogMessage, Throwable e);
+
+ /**
+ * Releases the resources acquired by this instance throughout its lifetime
+ * and removes the listeners.
+ */
+ public void dispose();
+}
diff --git a/src/net/java/sip/communicator/service/gui/ChatLinkClickedListener.java b/src/net/java/sip/communicator/service/gui/ChatLinkClickedListener.java
index 5d64489..cf7468f 100644
--- a/src/net/java/sip/communicator/service/gui/ChatLinkClickedListener.java
+++ b/src/net/java/sip/communicator/service/gui/ChatLinkClickedListener.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,21 +15,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.gui;
-
-import java.net.*;
-
-/**
- * Event-callback for clicks on links.
- *
- * @author Daniel Perren
- */
-public interface ChatLinkClickedListener
-{
- /**
- * Callback that is executed when a link was clicked.
- *
- * @param url The URI of the link that was clicked.
- */
- public void chatLinkClicked(URI url);
-}
+package net.java.sip.communicator.service.gui;
+
+import java.net.*;
+
+/**
+ * Event-callback for clicks on links.
+ *
+ * @author Daniel Perren
+ */
+public interface ChatLinkClickedListener
+{
+ /**
+ * Callback that is executed when a link was clicked.
+ *
+ * @param url The URI of the link that was clicked.
+ */
+ public void chatLinkClicked(URI url);
+}
diff --git a/src/net/java/sip/communicator/service/gui/Container.java b/src/net/java/sip/communicator/service/gui/Container.java
index 1b5e144..d0fcab7 100644
--- a/src/net/java/sip/communicator/service/gui/Container.java
+++ b/src/net/java/sip/communicator/service/gui/Container.java
@@ -257,4 +257,10 @@ public class Container
else
return false;
}
+
+ @Override
+ public int hashCode()
+ {
+ return containerName.hashCode();
+ }
}
diff --git a/src/net/java/sip/communicator/service/gui/LazyConfigurationForm.java b/src/net/java/sip/communicator/service/gui/LazyConfigurationForm.java
index f5db9fa..fe4a66e 100644
--- a/src/net/java/sip/communicator/service/gui/LazyConfigurationForm.java
+++ b/src/net/java/sip/communicator/service/gui/LazyConfigurationForm.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,220 +15,220 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.gui;
-
-import java.lang.reflect.*;
-
-import net.java.sip.communicator.service.gui.internal.*;
-import net.java.sip.communicator.service.resources.*;
-
-import org.jitsi.service.resources.*;
-
-/**
- * @author Lubomir Marinov
- * @author Yana Stamcheva
- */
-public class LazyConfigurationForm
- implements ConfigurationForm
-{
- /**
- * The <tt>ResourceManagementService</tt> used to obtain any resources.
- */
- private static ResourceManagementService resources;
-
- /**
- * Returns an instance of the <tt>ResourceManagementService</tt>, which
- * could be used to obtain any resources.
- * @return an instance of the <tt>ResourceManagementService</tt>
- */
- private static ResourceManagementService getResources()
- {
- if (resources == null)
- resources =
- ResourceManagementServiceUtils.getService(GuiServiceActivator
- .getBundleContext());
- return resources;
- }
-
- /**
- * The form class loader.
- */
- private final ClassLoader formClassLoader;
-
- /**
- * The class name of the form.
- */
- private final String formClassName;
-
- /**
- * The identifier of the icon.
- */
- private final String iconID;
-
- /**
- * The index of the form in the parent container.
- */
- private final int index;
-
- /**
- * The title identifier.
- */
- private final String titleID;
-
- /**
- * Indicates if this form is advanced.
- */
- private final boolean isAdvanced;
-
- /**
- * Creates an instance of <tt>LazyConfigurationForm</tt>.
- * @param formClassName the class name of the configuration form
- * @param formClassLoader the class loader
- * @param iconID the identifier of the form icon
- * @param titleID the identifier of the form title
- */
- public LazyConfigurationForm(String formClassName,
- ClassLoader formClassLoader, String iconID, String titleID)
- {
- this(formClassName, formClassLoader, iconID, titleID, -1, false);
- }
-
- /**
- * Creates an instance of <tt>LazyConfigurationForm</tt>.
- * @param formClassName the class name of the configuration form
- * @param formClassLoader the class loader
- * @param iconID the identifier of the form icon
- * @param titleID the identifier of the form title
- * @param index the index of the form in the parent container
- */
- public LazyConfigurationForm(String formClassName,
- ClassLoader formClassLoader, String iconID, String titleID, int index)
- {
- this(formClassName, formClassLoader, iconID, titleID, index, false);
- }
-
- /**
- * Creates an instance of <tt>LazyConfigurationForm</tt>.
- * @param formClassName the class name of the configuration form
- * @param formClassLoader the class loader
- * @param iconID the identifier of the form icon
- * @param titleID the identifier of the form title
- * @param index the index of the form in the parent container
- * @param isAdvanced indicates if the form is advanced configuration form
- */
- public LazyConfigurationForm(String formClassName,
- ClassLoader formClassLoader,
- String iconID,
- String titleID,
- int index,
- boolean isAdvanced)
- {
- this.formClassName = formClassName;
- this.formClassLoader = formClassLoader;
- this.iconID = iconID;
- this.titleID = titleID;
- this.index = index;
- this.isAdvanced = isAdvanced;
- }
-
- /**
- * Returns the form component.
- * @return the form component
- */
- public Object getForm()
- {
- Exception exception;
- try
- {
- return Class
- .forName(getFormClassName(), true, getFormClassLoader())
- .newInstance();
- }
- catch (ClassNotFoundException ex)
- {
- exception = ex;
- }
- catch (IllegalAccessException ex)
- {
- exception = ex;
- }
- catch (InstantiationException ex)
- {
- exception = ex;
- }
- throw new UndeclaredThrowableException(exception);
- }
-
- /**
- * Returns the form class loader.
- * @return the form class loader
- */
- protected ClassLoader getFormClassLoader()
- {
- return formClassLoader;
- }
-
- /**
- * Returns the form class name.
- * @return the form class name
- */
- public String getFormClassName()
- {
- return formClassName;
- }
-
- /**
- * Returns the icon of the form.
- * @return a byte array containing the icon of the form
- */
- public byte[] getIcon()
- {
- return getResources().getImageInBytes(getIconID());
- }
-
- /**
- * Returns the identifier of the icon.
- * @return the identifier of the icon
- */
- protected String getIconID()
- {
- return iconID;
- }
-
- /**
- * Returns the index of the form in its parent container.
- * @return the index of the form in its parent container
- */
- public int getIndex()
- {
- return index;
- }
-
- /**
- * Returns the title of the form.
- * @return the title of the form
- */
- public String getTitle()
- {
- return getResources().getI18NString(getTitleID());
- }
-
- /**
- * Returns the identifier of the title of the form.
- * @return the identifier of the title of the form
- */
- protected String getTitleID()
- {
- return titleID;
- }
-
- /**
- * Indicates if the form is an advanced form.
- * @return <tt>true</tt> to indicate that this is an advanced form,
- * otherwise returns <tt>false</tt>
- */
- public boolean isAdvanced()
- {
- return isAdvanced;
- }
-}
+package net.java.sip.communicator.service.gui;
+
+import java.lang.reflect.*;
+
+import net.java.sip.communicator.service.gui.internal.*;
+import net.java.sip.communicator.service.resources.*;
+
+import org.jitsi.service.resources.*;
+
+/**
+ * @author Lubomir Marinov
+ * @author Yana Stamcheva
+ */
+public class LazyConfigurationForm
+ implements ConfigurationForm
+{
+ /**
+ * The <tt>ResourceManagementService</tt> used to obtain any resources.
+ */
+ private static ResourceManagementService resources;
+
+ /**
+ * Returns an instance of the <tt>ResourceManagementService</tt>, which
+ * could be used to obtain any resources.
+ * @return an instance of the <tt>ResourceManagementService</tt>
+ */
+ private static ResourceManagementService getResources()
+ {
+ if (resources == null)
+ resources =
+ ResourceManagementServiceUtils.getService(GuiServiceActivator
+ .getBundleContext());
+ return resources;
+ }
+
+ /**
+ * The form class loader.
+ */
+ private final ClassLoader formClassLoader;
+
+ /**
+ * The class name of the form.
+ */
+ private final String formClassName;
+
+ /**
+ * The identifier of the icon.
+ */
+ private final String iconID;
+
+ /**
+ * The index of the form in the parent container.
+ */
+ private final int index;
+
+ /**
+ * The title identifier.
+ */
+ private final String titleID;
+
+ /**
+ * Indicates if this form is advanced.
+ */
+ private final boolean isAdvanced;
+
+ /**
+ * Creates an instance of <tt>LazyConfigurationForm</tt>.
+ * @param formClassName the class name of the configuration form
+ * @param formClassLoader the class loader
+ * @param iconID the identifier of the form icon
+ * @param titleID the identifier of the form title
+ */
+ public LazyConfigurationForm(String formClassName,
+ ClassLoader formClassLoader, String iconID, String titleID)
+ {
+ this(formClassName, formClassLoader, iconID, titleID, -1, false);
+ }
+
+ /**
+ * Creates an instance of <tt>LazyConfigurationForm</tt>.
+ * @param formClassName the class name of the configuration form
+ * @param formClassLoader the class loader
+ * @param iconID the identifier of the form icon
+ * @param titleID the identifier of the form title
+ * @param index the index of the form in the parent container
+ */
+ public LazyConfigurationForm(String formClassName,
+ ClassLoader formClassLoader, String iconID, String titleID, int index)
+ {
+ this(formClassName, formClassLoader, iconID, titleID, index, false);
+ }
+
+ /**
+ * Creates an instance of <tt>LazyConfigurationForm</tt>.
+ * @param formClassName the class name of the configuration form
+ * @param formClassLoader the class loader
+ * @param iconID the identifier of the form icon
+ * @param titleID the identifier of the form title
+ * @param index the index of the form in the parent container
+ * @param isAdvanced indicates if the form is advanced configuration form
+ */
+ public LazyConfigurationForm(String formClassName,
+ ClassLoader formClassLoader,
+ String iconID,
+ String titleID,
+ int index,
+ boolean isAdvanced)
+ {
+ this.formClassName = formClassName;
+ this.formClassLoader = formClassLoader;
+ this.iconID = iconID;
+ this.titleID = titleID;
+ this.index = index;
+ this.isAdvanced = isAdvanced;
+ }
+
+ /**
+ * Returns the form component.
+ * @return the form component
+ */
+ public Object getForm()
+ {
+ Exception exception;
+ try
+ {
+ return Class
+ .forName(getFormClassName(), true, getFormClassLoader())
+ .newInstance();
+ }
+ catch (ClassNotFoundException ex)
+ {
+ exception = ex;
+ }
+ catch (IllegalAccessException ex)
+ {
+ exception = ex;
+ }
+ catch (InstantiationException ex)
+ {
+ exception = ex;
+ }
+ throw new UndeclaredThrowableException(exception);
+ }
+
+ /**
+ * Returns the form class loader.
+ * @return the form class loader
+ */
+ protected ClassLoader getFormClassLoader()
+ {
+ return formClassLoader;
+ }
+
+ /**
+ * Returns the form class name.
+ * @return the form class name
+ */
+ public String getFormClassName()
+ {
+ return formClassName;
+ }
+
+ /**
+ * Returns the icon of the form.
+ * @return a byte array containing the icon of the form
+ */
+ public byte[] getIcon()
+ {
+ return getResources().getImageInBytes(getIconID());
+ }
+
+ /**
+ * Returns the identifier of the icon.
+ * @return the identifier of the icon
+ */
+ protected String getIconID()
+ {
+ return iconID;
+ }
+
+ /**
+ * Returns the index of the form in its parent container.
+ * @return the index of the form in its parent container
+ */
+ public int getIndex()
+ {
+ return index;
+ }
+
+ /**
+ * Returns the title of the form.
+ * @return the title of the form
+ */
+ public String getTitle()
+ {
+ return getResources().getI18NString(getTitleID());
+ }
+
+ /**
+ * Returns the identifier of the title of the form.
+ * @return the identifier of the title of the form
+ */
+ protected String getTitleID()
+ {
+ return titleID;
+ }
+
+ /**
+ * Indicates if the form is an advanced form.
+ * @return <tt>true</tt> to indicate that this is an advanced form,
+ * otherwise returns <tt>false</tt>
+ */
+ public boolean isAdvanced()
+ {
+ return isAdvanced;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/gui/UIService.java b/src/net/java/sip/communicator/service/gui/UIService.java
index 33219d8..48994d4 100644
--- a/src/net/java/sip/communicator/service/gui/UIService.java
+++ b/src/net/java/sip/communicator/service/gui/UIService.java
@@ -157,26 +157,14 @@ public interface UIService
public void bringToFront();
/**
- * Sets the exitOnClose property. When TRUE, the user could exit the
- * application by simply closing the main application window (by clicking
- * the X button or pressing Alt-F4). When set to FALSE the main application
- * window will be only hidden.
- *
- * @param exitOnClose When TRUE, the user could exit the application by
- * simply closing the main application window (by clicking the X
- * button or pressing Alt-F4). When set to FALSE the main
- * application window will be only hidden.
- */
- public void setExitOnMainWindowClose(boolean exitOnClose);
-
- /**
- * Returns TRUE if the application could be exited by closing the main
- * application window, otherwise returns FALSE.
- *
- * @return Returns TRUE if the application could be exited by closing the
- * main application window, otherwise returns FALSE
+ * Called from the systray service when a tray has been initialized and
+ * hiding (instead of minimizing or exiting) is possible). If hiding is
+ * possible and the option to minimize is not selected, the application
+ * gets hidden on clicking 'X'.
+ *
+ * @param true if a tray icon was loaded.
*/
- public boolean getExitOnMainWindowClose();
+ public void setMainWindowCanHide(boolean exitOnClose);
/**
* Returns an exported window given by the <tt>WindowID</tt>. This could be
diff --git a/src/net/java/sip/communicator/service/gui/internal/GuiServiceActivator.java b/src/net/java/sip/communicator/service/gui/internal/GuiServiceActivator.java
index 7dfbc37..abfc1bd 100644
--- a/src/net/java/sip/communicator/service/gui/internal/GuiServiceActivator.java
+++ b/src/net/java/sip/communicator/service/gui/internal/GuiServiceActivator.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,78 +15,78 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.gui.internal;
-
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.resources.*;
-import org.osgi.framework.*;
-
-/**
- * @author Lubomir Marinov
- * @author Yana Stamcheva
- */
-public class GuiServiceActivator
- implements BundleActivator
-{
- /**
- * The <tt>BundleContext</tt> of the service.
- */
- private static BundleContext bundleContext;
-
- /**
- * The <tt>ResourceManagementService</tt>, which gives access to application
- * resources.
- */
- private static ResourceManagementService resourceService;
-
- /**
- * Returns the <tt>BundleContext</tt>.
- *
- * @return bundle context
- */
- public static BundleContext getBundleContext()
- {
- return bundleContext;
- }
-
- /**
- * Initialize and start GUI service
- *
- * @param bundleContext the <tt>BundleContext</tt>
- */
- public void start(BundleContext bundleContext)
- {
- GuiServiceActivator.bundleContext = bundleContext;
- }
-
- /**
- * Stops this bundle.
- *
- * @param bundleContext the <tt>BundleContext</tt>
- */
- public void stop(BundleContext bundleContext)
- {
- if (GuiServiceActivator.bundleContext == bundleContext)
- GuiServiceActivator.bundleContext = null;
- }
-
- /**
- * Returns the <tt>ResourceManagementService</tt>, through which we will
- * access all resources.
- *
- * @return the <tt>ResourceManagementService</tt>, through which we will
- * access all resources.
- */
- public static ResourceManagementService getResources()
- {
- if (resourceService == null)
- {
- resourceService
- = ServiceUtils.getService(
- bundleContext,
- ResourceManagementService.class);
- }
- return resourceService;
- }
-}
+package net.java.sip.communicator.service.gui.internal;
+
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.resources.*;
+import org.osgi.framework.*;
+
+/**
+ * @author Lubomir Marinov
+ * @author Yana Stamcheva
+ */
+public class GuiServiceActivator
+ implements BundleActivator
+{
+ /**
+ * The <tt>BundleContext</tt> of the service.
+ */
+ private static BundleContext bundleContext;
+
+ /**
+ * The <tt>ResourceManagementService</tt>, which gives access to application
+ * resources.
+ */
+ private static ResourceManagementService resourceService;
+
+ /**
+ * Returns the <tt>BundleContext</tt>.
+ *
+ * @return bundle context
+ */
+ public static BundleContext getBundleContext()
+ {
+ return bundleContext;
+ }
+
+ /**
+ * Initialize and start GUI service
+ *
+ * @param bundleContext the <tt>BundleContext</tt>
+ */
+ public void start(BundleContext bundleContext)
+ {
+ GuiServiceActivator.bundleContext = bundleContext;
+ }
+
+ /**
+ * Stops this bundle.
+ *
+ * @param bundleContext the <tt>BundleContext</tt>
+ */
+ public void stop(BundleContext bundleContext)
+ {
+ if (GuiServiceActivator.bundleContext == bundleContext)
+ GuiServiceActivator.bundleContext = null;
+ }
+
+ /**
+ * Returns the <tt>ResourceManagementService</tt>, through which we will
+ * access all resources.
+ *
+ * @return the <tt>ResourceManagementService</tt>, through which we will
+ * access all resources.
+ */
+ public static ResourceManagementService getResources()
+ {
+ if (resourceService == null)
+ {
+ resourceService
+ = ServiceUtils.getService(
+ bundleContext,
+ ResourceManagementService.class);
+ }
+ return resourceService;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/muc/ChatRoomPresenceStatus.java b/src/net/java/sip/communicator/service/muc/ChatRoomPresenceStatus.java
index fa9d244..b0d81a8 100644
--- a/src/net/java/sip/communicator/service/muc/ChatRoomPresenceStatus.java
+++ b/src/net/java/sip/communicator/service/muc/ChatRoomPresenceStatus.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,72 +15,72 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.muc;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * The chat room statuses.
- *
- * @author Hristo Terezov
- */
-public class ChatRoomPresenceStatus extends PresenceStatus
-{
- /**
- * An integer above which all values of the status coefficient indicate
- * eagerness to communicate
- */
- public static final int CHAT_ROOM_ONLINE_THRESHOLD = 86;
-
- /**
- * An integer above which all values of the status coefficient indicate
- * eagerness to communicate
- */
- public static final int CHAT_ROOM_OFFLINE_THRESHOLD = 87;
-
- /**
- * Indicates that the user is connected and ready to communicate.
- */
- public static final String ONLINE_STATUS = "Online";
-
- /**
- * Indicates that the user is disconnected.
- */
- public static final String OFFLINE_STATUS = "Offline";
-
- /**
- * The Online status. Indicate that the user is able and willing to
- * communicate in the chat room.
- */
- public static final ChatRoomPresenceStatus CHAT_ROOM_ONLINE
- = new ChatRoomPresenceStatus(
- 86,
- ONLINE_STATUS);
-
- /**
- * The Offline status. Indicates the user does not seem to be connected
- * to the chat room.
- */
- public static final ChatRoomPresenceStatus CHAT_ROOM_OFFLINE
- = new ChatRoomPresenceStatus(
- 87,
- OFFLINE_STATUS);
-
- /**
- * Creates a status with the specified connectivity coeff and name for the
- * chat rooms.
- * @param status the connectivity coefficient for the specified status
- * @param statusName String
- */
- protected ChatRoomPresenceStatus(int status, String statusName)
- {
- super(status, statusName);
- }
-
- @Override
- public boolean isOnline()
- {
- return getStatus() == CHAT_ROOM_ONLINE_THRESHOLD;
- }
-
-}
+package net.java.sip.communicator.service.muc;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The chat room statuses.
+ *
+ * @author Hristo Terezov
+ */
+public class ChatRoomPresenceStatus extends PresenceStatus
+{
+ /**
+ * An integer above which all values of the status coefficient indicate
+ * eagerness to communicate
+ */
+ public static final int CHAT_ROOM_ONLINE_THRESHOLD = 86;
+
+ /**
+ * An integer above which all values of the status coefficient indicate
+ * eagerness to communicate
+ */
+ public static final int CHAT_ROOM_OFFLINE_THRESHOLD = 87;
+
+ /**
+ * Indicates that the user is connected and ready to communicate.
+ */
+ public static final String ONLINE_STATUS = "Online";
+
+ /**
+ * Indicates that the user is disconnected.
+ */
+ public static final String OFFLINE_STATUS = "Offline";
+
+ /**
+ * The Online status. Indicate that the user is able and willing to
+ * communicate in the chat room.
+ */
+ public static final ChatRoomPresenceStatus CHAT_ROOM_ONLINE
+ = new ChatRoomPresenceStatus(
+ 86,
+ ONLINE_STATUS);
+
+ /**
+ * The Offline status. Indicates the user does not seem to be connected
+ * to the chat room.
+ */
+ public static final ChatRoomPresenceStatus CHAT_ROOM_OFFLINE
+ = new ChatRoomPresenceStatus(
+ 87,
+ OFFLINE_STATUS);
+
+ /**
+ * Creates a status with the specified connectivity coeff and name for the
+ * chat rooms.
+ * @param status the connectivity coefficient for the specified status
+ * @param statusName String
+ */
+ protected ChatRoomPresenceStatus(int status, String statusName)
+ {
+ super(status, statusName);
+ }
+
+ @Override
+ public boolean isOnline()
+ {
+ return getStatus() == CHAT_ROOM_ONLINE_THRESHOLD;
+ }
+
+}
diff --git a/src/net/java/sip/communicator/service/muc/ChatRoomProviderWrapperListener.java b/src/net/java/sip/communicator/service/muc/ChatRoomProviderWrapperListener.java
index 261f2d7..dab910b 100644
--- a/src/net/java/sip/communicator/service/muc/ChatRoomProviderWrapperListener.java
+++ b/src/net/java/sip/communicator/service/muc/ChatRoomProviderWrapperListener.java
@@ -1,40 +1,40 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.service.muc;
-
-/**
- * Listener which registers for provider add/remove changes.
- */
-public interface ChatRoomProviderWrapperListener
-{
- /**
- * When a provider wrapper is added this method is called to inform
- * listeners.
- * @param provider which was added.
- */
- public void chatRoomProviderWrapperAdded(
- ChatRoomProviderWrapper provider);
-
- /**
- * When a provider wrapper is removed this method is called to inform
- * listeners.
- * @param provider which was removed.
- */
- public void chatRoomProviderWrapperRemoved(
- ChatRoomProviderWrapper provider);
-}
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.service.muc;
+
+/**
+ * Listener which registers for provider add/remove changes.
+ */
+public interface ChatRoomProviderWrapperListener
+{
+ /**
+ * When a provider wrapper is added this method is called to inform
+ * listeners.
+ * @param provider which was added.
+ */
+ public void chatRoomProviderWrapperAdded(
+ ChatRoomProviderWrapper provider);
+
+ /**
+ * When a provider wrapper is removed this method is called to inform
+ * listeners.
+ * @param provider which was removed.
+ */
+ public void chatRoomProviderWrapperRemoved(
+ ChatRoomProviderWrapper provider);
+}
diff --git a/src/net/java/sip/communicator/service/muc/MUCService.java b/src/net/java/sip/communicator/service/muc/MUCService.java
index 856d122..15d57a3 100644
--- a/src/net/java/sip/communicator/service/muc/MUCService.java
+++ b/src/net/java/sip/communicator/service/muc/MUCService.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,398 +15,398 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.muc;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.contactsource.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * The MUC service provides interface for the chat rooms. It connects the GUI
- * with the protcol.
- *
- * @author Hristo Terezov
- */
-public abstract class MUCService
-{
- /**
- * The configuration property to disable
- */
- public static final String DISABLED_PROPERTY
- = "net.java.sip.communicator.impl.muc.MUC_SERVICE_DISABLED";
-
- /**
- * Key for auto-open configuration entry.
- */
- private static String AUTO_OPEN_CONFIG_KEY = "openAutomatically";
-
- /**
- * The value for chat room configuration property to open automatically on
- * activity
- */
- public static String OPEN_ON_ACTIVITY = "on_activity";
-
- /**
- * The value for chat room configuration property to open automatically on
- * message
- */
- public static String OPEN_ON_MESSAGE = "on_message";
-
- /**
- * The value for chat room configuration property to open automatically on
- * important messages.
- */
- public static String OPEN_ON_IMPORTANT_MESSAGE = "on_important_message";
-
- /**
- * The default for chat room auto-open behaviour.
- */
- public static String DEFAULT_AUTO_OPEN_BEHAVIOUR = OPEN_ON_MESSAGE;
-
- /**
- * Map for the auto open configuration values and their text representation
- */
- public static Map<String, String> autoOpenConfigValuesTexts
- = new HashMap<String, String>();
-
- static
- {
- autoOpenConfigValuesTexts.put(OPEN_ON_ACTIVITY,
- "service.gui.OPEN_ON_ACTIVITY");
- autoOpenConfigValuesTexts.put(OPEN_ON_MESSAGE,
- "service.gui.OPEN_ON_MESSAGE");
- autoOpenConfigValuesTexts.put(OPEN_ON_IMPORTANT_MESSAGE,
- "service.gui.OPEN_ON_IMPORTANT_MESSAGE");
- }
-
- /**
- * Sets chat room open automatically property
- * @param pps the provider
- * @param chatRoomId the chat room id
- * @param value the new value for the property
- */
- public static void setChatRoomAutoOpenOption(
- ProtocolProviderService pps,
- String chatRoomId,
- String value)
- {
- ConfigurationUtils.updateChatRoomProperty(
- pps,
- chatRoomId, AUTO_OPEN_CONFIG_KEY, value);
- }
-
- /**
- * Returns the value of the chat room open automatically property
- * @param pps the provider
- * @param chatRoomId the chat room id
- * @return the value of the chat room open automatically property
- */
- public static String getChatRoomAutoOpenOption(
- ProtocolProviderService pps,
- String chatRoomId)
- {
- return ConfigurationUtils.getChatRoomProperty(
- pps,
- chatRoomId, AUTO_OPEN_CONFIG_KEY);
- }
-
- /**
- * Fires a <tt>ChatRoomListChangedEvent</tt> event.
- *
- * @param chatRoomWrapper the chat room.
- * @param eventID the id of the event.
- */
- public abstract void fireChatRoomListChangedEvent(
- ChatRoomWrapper chatRoomWrapper, int eventID);
-
- /**
- * Joins the given chat room with the given password and manages all the
- * exceptions that could occur during the join process.
- *
- * @param chatRoomWrapper the chat room to join.
- * @param nickName the nickname we choose for the given chat room.
- * @param password the password.
- * @param subject the subject which will be set to the room after the user
- * join successful.
- */
- public abstract void joinChatRoom( ChatRoomWrapper chatRoomWrapper,
- String nickName, byte[] password, String subject);
-
- /**
- * Creates a chat room, by specifying the chat room name, the parent
- * protocol provider and eventually, the contacts invited to participate in
- * this chat room.
- *
- * @param roomName the name of the room
- * @param protocolProvider the parent protocol provider.
- * @param contacts the contacts invited when creating the chat room.
- * @param reason
- * @param persistent is the room persistent
- * @return the <tt>ChatRoomWrapper</tt> corresponding to the created room
- */
- public abstract ChatRoomWrapper createChatRoom(String roomName,
- ProtocolProviderService protocolProvider, Collection<String> contacts,
- String reason, boolean persistent);
-
-
-
- /**
- * Creates a private chat room, by specifying the parent
- * protocol provider and eventually, the contacts invited to participate in
- * this chat room.
- *
- * @param protocolProvider the parent protocol provider.
- * @param contacts the contacts invited when creating the chat room.
- * @param reason
- * @param persistent is the room persistent
- * @return the <tt>ChatRoomWrapper</tt> corresponding to the created room
- */
- public abstract ChatRoomWrapper createPrivateChatRoom(
- ProtocolProviderService protocolProvider, Collection<String> contacts,
- String reason, boolean persistent);
-
-
- /**
- * Creates a chat room, by specifying the chat room name, the parent
- * protocol provider and eventually, the contacts invited to participate in
- * this chat room.
- *
- * @param roomName the name of the room
- * @param protocolProvider the parent protocol provider.
- * @param contacts the contacts invited when creating the chat room.
- * @param reason
- * @param join whether we should join the room after creating it.
- * @param persistent whether the newly created room will be persistent.
- * @param isPrivate whether the room will be private or public.
- * @return the <tt>ChatRoomWrapper</tt> corresponding to the created room or
- * <tt>null</tt> if the protocol failed to create the chat room
- */
- public abstract ChatRoomWrapper createChatRoom(String roomName,
- ProtocolProviderService protocolProvider, Collection<String> contacts,
- String reason, boolean join, boolean persistent, boolean isPrivate);
-
- /**
- * Joins the room with the given name though the given chat room provider.
- *
- * @param chatRoomName the name of the room to join.
- * @param chatRoomProvider the chat room provider to join through.
- */
- public abstract void joinChatRoom( String chatRoomName,
- ChatRoomProviderWrapper chatRoomProvider);
-
- /**
- * Returns existing chat rooms for the given <tt>chatRoomProvider</tt>.
- * @param chatRoomProvider the <tt>ChatRoomProviderWrapper</tt>, which
- * chat rooms we're looking for
- * @return existing chat rooms for the given <tt>chatRoomProvider</tt>
- */
- public abstract List<String> getExistingChatRooms(
- ChatRoomProviderWrapper chatRoomProvider);
-
-
- /**
- * Called to accept an incoming invitation. Adds the invitation chat room
- * to the list of chat rooms and joins it.
- *
- * @param invitation the invitation to accept.
- */
- public abstract void acceptInvitation(ChatRoomInvitation invitation);
-
- /**
- * Rejects the given invitation with the specified reason.
- *
- * @param multiUserChatOpSet the operation set to use for rejecting the
- * invitation
- * @param invitation the invitation to reject
- * @param reason the reason for the rejection
- */
- public abstract void rejectInvitation( OperationSetMultiUserChat multiUserChatOpSet,
- ChatRoomInvitation invitation,
- String reason);
-
- /**
- * Determines whether a specific <code>ChatRoom</code> is private i.e.
- * represents a one-to-one conversation which is not a channel. Since the
- * interface {@link ChatRoom} does not expose the private property, an
- * heuristic is used as a workaround: (1) a system <code>ChatRoom</code> is
- * obviously not private and (2) a <code>ChatRoom</code> is private if it
- * has only one <code>ChatRoomMember</code> who is not the local user.
- *
- * @param chatRoom
- * the <code>ChatRoom</code> to be determined as private or not
- * @return <tt>true</tt> if the specified <code>ChatRoom</code> is private;
- * otherwise, <tt>false</tt>
- */
- public static boolean isPrivate(ChatRoom chatRoom)
- {
- if (!chatRoom.isSystem()
- && chatRoom.isJoined()
- && (chatRoom.getMembersCount() == 1))
- {
- String nickname = chatRoom.getUserNickname();
-
- if (nickname != null)
- {
- for (ChatRoomMember member : chatRoom.getMembers())
- if (nickname.equals(member.getName()))
- return false;
- return true;
- }
- }
- return false;
- }
-
- /**
- * Leaves the given chat room.
- *
- * @param chatRoomWrapper the chat room to leave.
- * @return <tt>ChatRoomWrapper</tt> instance associated with the chat room.
- */
- public abstract ChatRoomWrapper leaveChatRoom(ChatRoomWrapper chatRoomWrapper);
-
- /**
- * Finds <tt>ChatRoomWrapper</tt> instance associated with the given source
- * contact.
- * @param contact the contact.
- * @return <tt>ChatRoomWrapper</tt> instance associated with the given
- * source contact.
- */
- public abstract ChatRoomWrapper findChatRoomWrapperFromSourceContact(
- SourceContact contact);
-
- /**
- * Searches for chat room wrapper in chat room list by chat room.
- *
- * @param chatRoom the chat room.
- * @param create if <tt>true</tt> and the chat room wrapper is not found new
- * chatRoomWrapper is created.
- * @return found chat room wrapper or the created chat room wrapper.
- */
- public abstract ChatRoomWrapper getChatRoomWrapperByChatRoom(
- ChatRoom chatRoom, boolean create);
-
- /**
- * Returns the multi user chat operation set for the given protocol provider.
- *
- * @param protocolProvider The protocol provider for which the multi user
- * chat operation set is about.
- * @return OperationSetMultiUserChat The telephony operation
- * set for the given protocol provider.
- */
- public static OperationSetMultiUserChat getMultiUserChatOpSet(
- ProtocolProviderService protocolProvider)
- {
- OperationSet opSet
- = protocolProvider.getOperationSet(OperationSetMultiUserChat.class);
-
- return (opSet instanceof OperationSetMultiUserChat)
- ? (OperationSetMultiUserChat) opSet
- : null;
- }
-
- /**
- * Finds the <tt>ChatRoomWrapper</tt> instance associated with the
- * chat room.
- * @param chatRoomID the id of the chat room.
- * @param pps the provider of the chat room.
- * @return the <tt>ChatRoomWrapper</tt> instance.
- */
- public abstract ChatRoomWrapper findChatRoomWrapperFromChatRoomID(
- String chatRoomID,
- ProtocolProviderService pps);
-
- /**
- * Goes through the locally stored chat rooms list and for each
- * {@link ChatRoomWrapper} tries to find the corresponding server stored
- * {@link ChatRoom} in the specified operation set. Joins automatically all
- * found chat rooms.
- *
- * @param protocolProvider the protocol provider for the account to
- * synchronize
- * @param opSet the multi user chat operation set, which give us access to
- * chat room server
- */
- public abstract void synchronizeOpSetWithLocalContactList(
- ProtocolProviderService protocolProvider,
- final OperationSetMultiUserChat opSet);
-
- /**
- * Returns an iterator to the list of chat room providers.
- *
- * @return an iterator to the list of chat room providers.
- */
- public abstract Iterator<ChatRoomProviderWrapper> getChatRoomProviders();
-
- /**
- * Removes the given <tt>ChatRoom</tt> from the list of all chat rooms.
- *
- * @param chatRoomWrapper the <tt>ChatRoomWrapper</tt> to remove
- */
- public abstract void removeChatRoom(ChatRoomWrapper chatRoomWrapper);
-
- /**
- * Adds a ChatRoomProviderWrapperListener to the listener list.
- *
- * @param listener the ChatRoomProviderWrapperListener to be added
- */
- public abstract void addChatRoomProviderWrapperListener(
- ChatRoomProviderWrapperListener listener);
-
- /**
- * Removes the ChatRoomProviderWrapperListener to the listener list.
- *
- * @param listener the ChatRoomProviderWrapperListener to be removed
- */
- public abstract void removeChatRoomProviderWrapperListener(
- ChatRoomProviderWrapperListener listener);
-
- /**
- * Returns the <tt>ChatRoomProviderWrapper</tt> that correspond to the
- * given <tt>ProtocolProviderService</tt>. If the list doesn't contain a
- * corresponding wrapper - returns null.
- *
- * @param protocolProvider the protocol provider that we're looking for
- * @return the <tt>ChatRoomProvider</tt> object corresponding to
- * the given <tt>ProtocolProviderService</tt>
- */
- public abstract ChatRoomProviderWrapper findServerWrapperFromProvider(
- ProtocolProviderService protocolProvider);
-
- /**
- * Returns the <tt>ChatRoomWrapper</tt> that correspond to the given
- * <tt>ChatRoom</tt>. If the list of chat rooms doesn't contain a
- * corresponding wrapper - returns null.
- *
- * @param chatRoom the <tt>ChatRoom</tt> that we're looking for
- * @return the <tt>ChatRoomWrapper</tt> object corresponding to the given
- * <tt>ChatRoom</tt>
- */
- public abstract ChatRoomWrapper findChatRoomWrapperFromChatRoom(
- ChatRoom chatRoom);
-
- /**
- * Opens a chat window for the chat room.
- *
- * @param room the chat room.
- */
- public abstract void openChatRoom(ChatRoomWrapper room);
-
- /**
- * Returns instance of the <tt>ServerChatRoomContactSourceService</tt>
- * contact source.
- * @return instance of the <tt>ServerChatRoomContactSourceService</tt>
- * contact source.
- */
- public abstract ContactSourceService
- getServerChatRoomsContactSourceForProvider(ChatRoomProviderWrapper pps);
-
- /**
- * Returns <tt>true</tt> if the contact is <tt>ChatRoomSourceContact</tt>
- *
- * @param contact the contact
- * @return <tt>true</tt> if the contact is <tt>ChatRoomSourceContact</tt>
- */
- public abstract boolean isMUCSourceContact(SourceContact contact);
-}
+package net.java.sip.communicator.service.muc;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * The MUC service provides interface for the chat rooms. It connects the GUI
+ * with the protcol.
+ *
+ * @author Hristo Terezov
+ */
+public abstract class MUCService
+{
+ /**
+ * The configuration property to disable
+ */
+ public static final String DISABLED_PROPERTY
+ = "net.java.sip.communicator.impl.muc.MUC_SERVICE_DISABLED";
+
+ /**
+ * Key for auto-open configuration entry.
+ */
+ private static String AUTO_OPEN_CONFIG_KEY = "openAutomatically";
+
+ /**
+ * The value for chat room configuration property to open automatically on
+ * activity
+ */
+ public static String OPEN_ON_ACTIVITY = "on_activity";
+
+ /**
+ * The value for chat room configuration property to open automatically on
+ * message
+ */
+ public static String OPEN_ON_MESSAGE = "on_message";
+
+ /**
+ * The value for chat room configuration property to open automatically on
+ * important messages.
+ */
+ public static String OPEN_ON_IMPORTANT_MESSAGE = "on_important_message";
+
+ /**
+ * The default for chat room auto-open behaviour.
+ */
+ public static String DEFAULT_AUTO_OPEN_BEHAVIOUR = OPEN_ON_MESSAGE;
+
+ /**
+ * Map for the auto open configuration values and their text representation
+ */
+ public static Map<String, String> autoOpenConfigValuesTexts
+ = new HashMap<String, String>();
+
+ static
+ {
+ autoOpenConfigValuesTexts.put(OPEN_ON_ACTIVITY,
+ "service.gui.OPEN_ON_ACTIVITY");
+ autoOpenConfigValuesTexts.put(OPEN_ON_MESSAGE,
+ "service.gui.OPEN_ON_MESSAGE");
+ autoOpenConfigValuesTexts.put(OPEN_ON_IMPORTANT_MESSAGE,
+ "service.gui.OPEN_ON_IMPORTANT_MESSAGE");
+ }
+
+ /**
+ * Sets chat room open automatically property
+ * @param pps the provider
+ * @param chatRoomId the chat room id
+ * @param value the new value for the property
+ */
+ public static void setChatRoomAutoOpenOption(
+ ProtocolProviderService pps,
+ String chatRoomId,
+ String value)
+ {
+ ConfigurationUtils.updateChatRoomProperty(
+ pps,
+ chatRoomId, AUTO_OPEN_CONFIG_KEY, value);
+ }
+
+ /**
+ * Returns the value of the chat room open automatically property
+ * @param pps the provider
+ * @param chatRoomId the chat room id
+ * @return the value of the chat room open automatically property
+ */
+ public static String getChatRoomAutoOpenOption(
+ ProtocolProviderService pps,
+ String chatRoomId)
+ {
+ return ConfigurationUtils.getChatRoomProperty(
+ pps,
+ chatRoomId, AUTO_OPEN_CONFIG_KEY);
+ }
+
+ /**
+ * Fires a <tt>ChatRoomListChangedEvent</tt> event.
+ *
+ * @param chatRoomWrapper the chat room.
+ * @param eventID the id of the event.
+ */
+ public abstract void fireChatRoomListChangedEvent(
+ ChatRoomWrapper chatRoomWrapper, int eventID);
+
+ /**
+ * Joins the given chat room with the given password and manages all the
+ * exceptions that could occur during the join process.
+ *
+ * @param chatRoomWrapper the chat room to join.
+ * @param nickName the nickname we choose for the given chat room.
+ * @param password the password.
+ * @param subject the subject which will be set to the room after the user
+ * join successful.
+ */
+ public abstract void joinChatRoom( ChatRoomWrapper chatRoomWrapper,
+ String nickName, byte[] password, String subject);
+
+ /**
+ * Creates a chat room, by specifying the chat room name, the parent
+ * protocol provider and eventually, the contacts invited to participate in
+ * this chat room.
+ *
+ * @param roomName the name of the room
+ * @param protocolProvider the parent protocol provider.
+ * @param contacts the contacts invited when creating the chat room.
+ * @param reason
+ * @param persistent is the room persistent
+ * @return the <tt>ChatRoomWrapper</tt> corresponding to the created room
+ */
+ public abstract ChatRoomWrapper createChatRoom(String roomName,
+ ProtocolProviderService protocolProvider, Collection<String> contacts,
+ String reason, boolean persistent);
+
+
+
+ /**
+ * Creates a private chat room, by specifying the parent
+ * protocol provider and eventually, the contacts invited to participate in
+ * this chat room.
+ *
+ * @param protocolProvider the parent protocol provider.
+ * @param contacts the contacts invited when creating the chat room.
+ * @param reason
+ * @param persistent is the room persistent
+ * @return the <tt>ChatRoomWrapper</tt> corresponding to the created room
+ */
+ public abstract ChatRoomWrapper createPrivateChatRoom(
+ ProtocolProviderService protocolProvider, Collection<String> contacts,
+ String reason, boolean persistent);
+
+
+ /**
+ * Creates a chat room, by specifying the chat room name, the parent
+ * protocol provider and eventually, the contacts invited to participate in
+ * this chat room.
+ *
+ * @param roomName the name of the room
+ * @param protocolProvider the parent protocol provider.
+ * @param contacts the contacts invited when creating the chat room.
+ * @param reason
+ * @param join whether we should join the room after creating it.
+ * @param persistent whether the newly created room will be persistent.
+ * @param isPrivate whether the room will be private or public.
+ * @return the <tt>ChatRoomWrapper</tt> corresponding to the created room or
+ * <tt>null</tt> if the protocol failed to create the chat room
+ */
+ public abstract ChatRoomWrapper createChatRoom(String roomName,
+ ProtocolProviderService protocolProvider, Collection<String> contacts,
+ String reason, boolean join, boolean persistent, boolean isPrivate);
+
+ /**
+ * Joins the room with the given name though the given chat room provider.
+ *
+ * @param chatRoomName the name of the room to join.
+ * @param chatRoomProvider the chat room provider to join through.
+ */
+ public abstract void joinChatRoom( String chatRoomName,
+ ChatRoomProviderWrapper chatRoomProvider);
+
+ /**
+ * Returns existing chat rooms for the given <tt>chatRoomProvider</tt>.
+ * @param chatRoomProvider the <tt>ChatRoomProviderWrapper</tt>, which
+ * chat rooms we're looking for
+ * @return existing chat rooms for the given <tt>chatRoomProvider</tt>
+ */
+ public abstract List<String> getExistingChatRooms(
+ ChatRoomProviderWrapper chatRoomProvider);
+
+
+ /**
+ * Called to accept an incoming invitation. Adds the invitation chat room
+ * to the list of chat rooms and joins it.
+ *
+ * @param invitation the invitation to accept.
+ */
+ public abstract void acceptInvitation(ChatRoomInvitation invitation);
+
+ /**
+ * Rejects the given invitation with the specified reason.
+ *
+ * @param multiUserChatOpSet the operation set to use for rejecting the
+ * invitation
+ * @param invitation the invitation to reject
+ * @param reason the reason for the rejection
+ */
+ public abstract void rejectInvitation( OperationSetMultiUserChat multiUserChatOpSet,
+ ChatRoomInvitation invitation,
+ String reason);
+
+ /**
+ * Determines whether a specific <code>ChatRoom</code> is private i.e.
+ * represents a one-to-one conversation which is not a channel. Since the
+ * interface {@link ChatRoom} does not expose the private property, an
+ * heuristic is used as a workaround: (1) a system <code>ChatRoom</code> is
+ * obviously not private and (2) a <code>ChatRoom</code> is private if it
+ * has only one <code>ChatRoomMember</code> who is not the local user.
+ *
+ * @param chatRoom
+ * the <code>ChatRoom</code> to be determined as private or not
+ * @return <tt>true</tt> if the specified <code>ChatRoom</code> is private;
+ * otherwise, <tt>false</tt>
+ */
+ public static boolean isPrivate(ChatRoom chatRoom)
+ {
+ if (!chatRoom.isSystem()
+ && chatRoom.isJoined()
+ && (chatRoom.getMembersCount() == 1))
+ {
+ String nickname = chatRoom.getUserNickname();
+
+ if (nickname != null)
+ {
+ for (ChatRoomMember member : chatRoom.getMembers())
+ if (nickname.equals(member.getName()))
+ return false;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Leaves the given chat room.
+ *
+ * @param chatRoomWrapper the chat room to leave.
+ * @return <tt>ChatRoomWrapper</tt> instance associated with the chat room.
+ */
+ public abstract ChatRoomWrapper leaveChatRoom(ChatRoomWrapper chatRoomWrapper);
+
+ /**
+ * Finds <tt>ChatRoomWrapper</tt> instance associated with the given source
+ * contact.
+ * @param contact the contact.
+ * @return <tt>ChatRoomWrapper</tt> instance associated with the given
+ * source contact.
+ */
+ public abstract ChatRoomWrapper findChatRoomWrapperFromSourceContact(
+ SourceContact contact);
+
+ /**
+ * Searches for chat room wrapper in chat room list by chat room.
+ *
+ * @param chatRoom the chat room.
+ * @param create if <tt>true</tt> and the chat room wrapper is not found new
+ * chatRoomWrapper is created.
+ * @return found chat room wrapper or the created chat room wrapper.
+ */
+ public abstract ChatRoomWrapper getChatRoomWrapperByChatRoom(
+ ChatRoom chatRoom, boolean create);
+
+ /**
+ * Returns the multi user chat operation set for the given protocol provider.
+ *
+ * @param protocolProvider The protocol provider for which the multi user
+ * chat operation set is about.
+ * @return OperationSetMultiUserChat The telephony operation
+ * set for the given protocol provider.
+ */
+ public static OperationSetMultiUserChat getMultiUserChatOpSet(
+ ProtocolProviderService protocolProvider)
+ {
+ OperationSet opSet
+ = protocolProvider.getOperationSet(OperationSetMultiUserChat.class);
+
+ return (opSet instanceof OperationSetMultiUserChat)
+ ? (OperationSetMultiUserChat) opSet
+ : null;
+ }
+
+ /**
+ * Finds the <tt>ChatRoomWrapper</tt> instance associated with the
+ * chat room.
+ * @param chatRoomID the id of the chat room.
+ * @param pps the provider of the chat room.
+ * @return the <tt>ChatRoomWrapper</tt> instance.
+ */
+ public abstract ChatRoomWrapper findChatRoomWrapperFromChatRoomID(
+ String chatRoomID,
+ ProtocolProviderService pps);
+
+ /**
+ * Goes through the locally stored chat rooms list and for each
+ * {@link ChatRoomWrapper} tries to find the corresponding server stored
+ * {@link ChatRoom} in the specified operation set. Joins automatically all
+ * found chat rooms.
+ *
+ * @param protocolProvider the protocol provider for the account to
+ * synchronize
+ * @param opSet the multi user chat operation set, which give us access to
+ * chat room server
+ */
+ public abstract void synchronizeOpSetWithLocalContactList(
+ ProtocolProviderService protocolProvider,
+ final OperationSetMultiUserChat opSet);
+
+ /**
+ * Returns an iterator to the list of chat room providers.
+ *
+ * @return an iterator to the list of chat room providers.
+ */
+ public abstract Iterator<ChatRoomProviderWrapper> getChatRoomProviders();
+
+ /**
+ * Removes the given <tt>ChatRoom</tt> from the list of all chat rooms.
+ *
+ * @param chatRoomWrapper the <tt>ChatRoomWrapper</tt> to remove
+ */
+ public abstract void removeChatRoom(ChatRoomWrapper chatRoomWrapper);
+
+ /**
+ * Adds a ChatRoomProviderWrapperListener to the listener list.
+ *
+ * @param listener the ChatRoomProviderWrapperListener to be added
+ */
+ public abstract void addChatRoomProviderWrapperListener(
+ ChatRoomProviderWrapperListener listener);
+
+ /**
+ * Removes the ChatRoomProviderWrapperListener to the listener list.
+ *
+ * @param listener the ChatRoomProviderWrapperListener to be removed
+ */
+ public abstract void removeChatRoomProviderWrapperListener(
+ ChatRoomProviderWrapperListener listener);
+
+ /**
+ * Returns the <tt>ChatRoomProviderWrapper</tt> that correspond to the
+ * given <tt>ProtocolProviderService</tt>. If the list doesn't contain a
+ * corresponding wrapper - returns null.
+ *
+ * @param protocolProvider the protocol provider that we're looking for
+ * @return the <tt>ChatRoomProvider</tt> object corresponding to
+ * the given <tt>ProtocolProviderService</tt>
+ */
+ public abstract ChatRoomProviderWrapper findServerWrapperFromProvider(
+ ProtocolProviderService protocolProvider);
+
+ /**
+ * Returns the <tt>ChatRoomWrapper</tt> that correspond to the given
+ * <tt>ChatRoom</tt>. If the list of chat rooms doesn't contain a
+ * corresponding wrapper - returns null.
+ *
+ * @param chatRoom the <tt>ChatRoom</tt> that we're looking for
+ * @return the <tt>ChatRoomWrapper</tt> object corresponding to the given
+ * <tt>ChatRoom</tt>
+ */
+ public abstract ChatRoomWrapper findChatRoomWrapperFromChatRoom(
+ ChatRoom chatRoom);
+
+ /**
+ * Opens a chat window for the chat room.
+ *
+ * @param room the chat room.
+ */
+ public abstract void openChatRoom(ChatRoomWrapper room);
+
+ /**
+ * Returns instance of the <tt>ServerChatRoomContactSourceService</tt>
+ * contact source.
+ * @return instance of the <tt>ServerChatRoomContactSourceService</tt>
+ * contact source.
+ */
+ public abstract ContactSourceService
+ getServerChatRoomsContactSourceForProvider(ChatRoomProviderWrapper pps);
+
+ /**
+ * Returns <tt>true</tt> if the contact is <tt>ChatRoomSourceContact</tt>
+ *
+ * @param contact the contact
+ * @return <tt>true</tt> if the contact is <tt>ChatRoomSourceContact</tt>
+ */
+ public abstract boolean isMUCSourceContact(SourceContact contact);
+}
diff --git a/src/net/java/sip/communicator/service/notification/CommandNotificationAction.java b/src/net/java/sip/communicator/service/notification/CommandNotificationAction.java
index ffe8d10..dd502e4 100644
--- a/src/net/java/sip/communicator/service/notification/CommandNotificationAction.java
+++ b/src/net/java/sip/communicator/service/notification/CommandNotificationAction.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,39 +15,39 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.notification;
-
-/**
- * An implementation of the <tt>CommandNotificationHandler</tt> interface.
- *
- * @author Yana Stamcheva
- */
-public class CommandNotificationAction
- extends NotificationAction
-{
- private String commandDescriptor;
-
- /**
- * Creates an instance of <tt>CommandNotification</tt> by
- * specifying the <tt>commandDescriptor</tt>, which will point us to the
- * command to execute.
- *
- * @param commandDescriptor a String that should point us to the command to
- * execute
- */
- public CommandNotificationAction(String commandDescriptor)
- {
- super(NotificationAction.ACTION_COMMAND);
- this.commandDescriptor = commandDescriptor;
- }
-
- /**
- * Returns the command descriptor.
- *
- * @return the command descriptor
- */
- public String getDescriptor()
- {
- return commandDescriptor;
- }
-}
+package net.java.sip.communicator.service.notification;
+
+/**
+ * An implementation of the <tt>CommandNotificationHandler</tt> interface.
+ *
+ * @author Yana Stamcheva
+ */
+public class CommandNotificationAction
+ extends NotificationAction
+{
+ private String commandDescriptor;
+
+ /**
+ * Creates an instance of <tt>CommandNotification</tt> by
+ * specifying the <tt>commandDescriptor</tt>, which will point us to the
+ * command to execute.
+ *
+ * @param commandDescriptor a String that should point us to the command to
+ * execute
+ */
+ public CommandNotificationAction(String commandDescriptor)
+ {
+ super(NotificationAction.ACTION_COMMAND);
+ this.commandDescriptor = commandDescriptor;
+ }
+
+ /**
+ * Returns the command descriptor.
+ *
+ * @return the command descriptor
+ */
+ public String getDescriptor()
+ {
+ return commandDescriptor;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/notification/NotificationAction.java b/src/net/java/sip/communicator/service/notification/NotificationAction.java
index bb8b156..73b285f 100644
--- a/src/net/java/sip/communicator/service/notification/NotificationAction.java
+++ b/src/net/java/sip/communicator/service/notification/NotificationAction.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,98 +15,98 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.notification;
-
-/**
- * Base class for actions of a notification.
- *
- * @author Ingo Bauersachs
- */
-public abstract class NotificationAction
-{
- /**
- * The sound action type indicates that a sound would be played, when a
- * notification is fired.
- */
- public static final String ACTION_SOUND = "SoundAction";
-
- /**
- * The popup message action type indicates that a window (or a systray
- * popup), containing the corresponding notification message would be poped
- * up, when a notification is fired.
- */
- public static final String ACTION_POPUP_MESSAGE = "PopupMessageAction";
-
- /**
- * The log message action type indicates that a message would be logged,
- * when a notification is fired.
- */
- public static final String ACTION_LOG_MESSAGE = "LogMessageAction";
-
- /**
- * The command action type indicates that a command would be executed,
- * when a notification is fired.
- */
- public static final String ACTION_COMMAND = "CommandAction";
-
- /**
- * The vibrate action type indicates that the device will vibrate,
- * when a notification is fired.
- */
- public static final String ACTION_VIBRATE = "VibrateAction";
-
- /**
- * Indicates if this handler is enabled.
- */
- private boolean isEnabled = true;
-
- /**
- * The action type name.
- */
- private String actionType;
-
- /**
- * Creates a new instance of this class.
- * @param actionType The action type name.
- */
- protected NotificationAction(String actionType)
- {
- this.actionType = actionType;
- }
-
- /**
- * Return the action type name.
- * @return the action type name.
- */
- public String getActionType()
- {
- return actionType;
- }
-
- /**
- * Returns TRUE if this notification action handler is enabled and FALSE
- * otherwise. While the notification handler for the sound action type is
- * disabled no sounds will be played when the <tt>fireNotification</tt>
- * method is called.
- *
- * @return TRUE if this notification action handler is enabled and FALSE
- * otherwise
- */
- public boolean isEnabled()
- {
- return isEnabled;
- }
-
- /**
- * Enables or disables this notification handler. While the notification
- * handler for the sound action type is disabled no sounds will be played
- * when the <tt>fireNotification</tt> method is called.
- *
- * @param isEnabled TRUE to enable this notification handler, FALSE to
- * disable it.
- */
- public void setEnabled(boolean isEnabled)
- {
- this.isEnabled = isEnabled;
- }
-}
+package net.java.sip.communicator.service.notification;
+
+/**
+ * Base class for actions of a notification.
+ *
+ * @author Ingo Bauersachs
+ */
+public abstract class NotificationAction
+{
+ /**
+ * The sound action type indicates that a sound would be played, when a
+ * notification is fired.
+ */
+ public static final String ACTION_SOUND = "SoundAction";
+
+ /**
+ * The popup message action type indicates that a window (or a systray
+ * popup), containing the corresponding notification message would be poped
+ * up, when a notification is fired.
+ */
+ public static final String ACTION_POPUP_MESSAGE = "PopupMessageAction";
+
+ /**
+ * The log message action type indicates that a message would be logged,
+ * when a notification is fired.
+ */
+ public static final String ACTION_LOG_MESSAGE = "LogMessageAction";
+
+ /**
+ * The command action type indicates that a command would be executed,
+ * when a notification is fired.
+ */
+ public static final String ACTION_COMMAND = "CommandAction";
+
+ /**
+ * The vibrate action type indicates that the device will vibrate,
+ * when a notification is fired.
+ */
+ public static final String ACTION_VIBRATE = "VibrateAction";
+
+ /**
+ * Indicates if this handler is enabled.
+ */
+ private boolean isEnabled = true;
+
+ /**
+ * The action type name.
+ */
+ private String actionType;
+
+ /**
+ * Creates a new instance of this class.
+ * @param actionType The action type name.
+ */
+ protected NotificationAction(String actionType)
+ {
+ this.actionType = actionType;
+ }
+
+ /**
+ * Return the action type name.
+ * @return the action type name.
+ */
+ public String getActionType()
+ {
+ return actionType;
+ }
+
+ /**
+ * Returns TRUE if this notification action handler is enabled and FALSE
+ * otherwise. While the notification handler for the sound action type is
+ * disabled no sounds will be played when the <tt>fireNotification</tt>
+ * method is called.
+ *
+ * @return TRUE if this notification action handler is enabled and FALSE
+ * otherwise
+ */
+ public boolean isEnabled()
+ {
+ return isEnabled;
+ }
+
+ /**
+ * Enables or disables this notification handler. While the notification
+ * handler for the sound action type is disabled no sounds will be played
+ * when the <tt>fireNotification</tt> method is called.
+ *
+ * @param isEnabled TRUE to enable this notification handler, FALSE to
+ * disable it.
+ */
+ public void setEnabled(boolean isEnabled)
+ {
+ this.isEnabled = isEnabled;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/notification/NotificationData.java b/src/net/java/sip/communicator/service/notification/NotificationData.java
index 21c8fba..dd2bc8f 100644
--- a/src/net/java/sip/communicator/service/notification/NotificationData.java
+++ b/src/net/java/sip/communicator/service/notification/NotificationData.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,151 +15,151 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.notification;
-
-import java.util.*;
-
-/**
- * Object to cache fired notifications before all handler implementations are
- * ready registered.
- *
- * @author Ingo Bauersachs
- */
-public class NotificationData
-{
- /**
- * The name/key of the <tt>NotificationData</tt> extra which is provided to
- * {@link CommandNotificationHandler#execute(CommandNotificationAction,
- * Map)} i.e. a <tt>Map&lt;String,String&gt;</tt> which is known by the
- * (argument) name <tt>cmdargs</tt>.
- */
- public static final String COMMAND_NOTIFICATION_HANDLER_CMDARGS_EXTRA
- = "CommandNotificationHandler.cmdargs";
-
- /**
- * The name/key of the <tt>NotificationData</tt> extra which is provided to
- * {@link PopupMessageNotificationHandler#popupMessage(
- * PopupMessageNotificationAction, String, String, byte[], Object)} i.e. an
- * <tt>Object</tt> which is known by the (argument) name <tt>tag</tt>.
- */
- public static final String POPUP_MESSAGE_HANDLER_TAG_EXTRA
- = "PopupMessageNotificationHandler.tag";
-
- /**
- * The name/key of the <tt>NotificationData</tt> extra which is provided to
- * {@link SoundNotificationHandler} i.e. a <tt>Callable&lt;Boolean&gt;</tt>
- * which is known as the condition which determines whether looping sounds
- * are to continue playing.
- */
- public static final String SOUND_NOTIFICATION_HANDLER_LOOP_CONDITION_EXTRA
- = "SoundNotificationHandler.loopCondition";
-
- private final String eventType;
-
- /**
- * The {@link NotificationHandler}-specific extras provided to this
- * instance. The keys are among the <tt>XXX_EXTRA</tt> constants defined by
- * the <tt>NotificationData</tt> class.
- */
- private final Map<String, Object> extras;
-
- private final byte[] icon;
- private final String message;
- private final String title;
-
- /**
- * Creates a new instance of this class.
- *
- * @param eventType the type of the event that we'd like to fire a
- * notification for.
- * @param title the title of the given message
- * @param message the message to use if and where appropriate (e.g. with
- * systray or log notification.)
- * @param icon the icon to show in the notification if and where appropriate
- * @param extras additional/extra {@link NotificationHandler}-specific data
- * to be provided by the new instance to the various
- * <tt>NotificationHandler</tt>s
- */
- NotificationData(
- String eventType,
- String title,
- String message,
- byte[] icon,
- Map<String, Object> extras)
- {
- this.eventType = eventType;
- this.title = title;
- this.message = message;
- this.icon = icon;
- this.extras = extras;
- }
-
- /**
- * Gets the type of the event that we'd like to fire a notification for
- *
- * @return the eventType
- */
- public String getEventType()
- {
- return eventType;
- }
-
- /**
- * Gets the {@link NotificationHandler}-specific extras provided to this
- * instance.
- *
- * @return the <tt>NotificationHandler</tt>-specific extras provided to this
- * instance. The keys are among the <tt>XXX_EXTRA</tt> constants defined by
- * the <tt>NotificationData</tt> class
- */
- Map<String, Object> getExtras()
- {
- return Collections.unmodifiableMap(extras);
- }
-
- /**
- * Gets the {@link NotificationHandler}-specific extra provided to this
- * instance associated with a specific key.
- *
- * @param key the key whose associated <tt>NotificationHandler</tt>-specific
- * extra is to be returned. Well known keys are defined by the
- * <tt>NotificationData</tt> class as the <tt>XXX_EXTRA</tt> constants.
- * @return the <tt>NotificationHandler</tt>-specific extra provided to this
- * instance associated with the specified <tt>key</tt>
- */
- public Object getExtra(String key)
- {
- return (extras == null) ? null : extras.get(key);
- }
-
- /**
- * Gets the icon to show in the notification if and where appropriate.
- *
- * @return the icon
- */
- byte[] getIcon()
- {
- return icon;
- }
-
- /**
- * Gets the message to use if and where appropriate (e.g. with systray or
- * log notification).
- *
- * @return the message
- */
- String getMessage()
- {
- return message;
- }
-
- /**
- * Gets the title of the given message.
- *
- * @return the title
- */
- String getTitle()
- {
- return title;
- }
-}
+package net.java.sip.communicator.service.notification;
+
+import java.util.*;
+
+/**
+ * Object to cache fired notifications before all handler implementations are
+ * ready registered.
+ *
+ * @author Ingo Bauersachs
+ */
+public class NotificationData
+{
+ /**
+ * The name/key of the <tt>NotificationData</tt> extra which is provided to
+ * {@link CommandNotificationHandler#execute(CommandNotificationAction,
+ * Map)} i.e. a <tt>Map&lt;String,String&gt;</tt> which is known by the
+ * (argument) name <tt>cmdargs</tt>.
+ */
+ public static final String COMMAND_NOTIFICATION_HANDLER_CMDARGS_EXTRA
+ = "CommandNotificationHandler.cmdargs";
+
+ /**
+ * The name/key of the <tt>NotificationData</tt> extra which is provided to
+ * {@link PopupMessageNotificationHandler#popupMessage(
+ * PopupMessageNotificationAction, String, String, byte[], Object)} i.e. an
+ * <tt>Object</tt> which is known by the (argument) name <tt>tag</tt>.
+ */
+ public static final String POPUP_MESSAGE_HANDLER_TAG_EXTRA
+ = "PopupMessageNotificationHandler.tag";
+
+ /**
+ * The name/key of the <tt>NotificationData</tt> extra which is provided to
+ * {@link SoundNotificationHandler} i.e. a <tt>Callable&lt;Boolean&gt;</tt>
+ * which is known as the condition which determines whether looping sounds
+ * are to continue playing.
+ */
+ public static final String SOUND_NOTIFICATION_HANDLER_LOOP_CONDITION_EXTRA
+ = "SoundNotificationHandler.loopCondition";
+
+ private final String eventType;
+
+ /**
+ * The {@link NotificationHandler}-specific extras provided to this
+ * instance. The keys are among the <tt>XXX_EXTRA</tt> constants defined by
+ * the <tt>NotificationData</tt> class.
+ */
+ private final Map<String, Object> extras;
+
+ private final byte[] icon;
+ private final String message;
+ private final String title;
+
+ /**
+ * Creates a new instance of this class.
+ *
+ * @param eventType the type of the event that we'd like to fire a
+ * notification for.
+ * @param title the title of the given message
+ * @param message the message to use if and where appropriate (e.g. with
+ * systray or log notification.)
+ * @param icon the icon to show in the notification if and where appropriate
+ * @param extras additional/extra {@link NotificationHandler}-specific data
+ * to be provided by the new instance to the various
+ * <tt>NotificationHandler</tt>s
+ */
+ NotificationData(
+ String eventType,
+ String title,
+ String message,
+ byte[] icon,
+ Map<String, Object> extras)
+ {
+ this.eventType = eventType;
+ this.title = title;
+ this.message = message;
+ this.icon = icon;
+ this.extras = extras;
+ }
+
+ /**
+ * Gets the type of the event that we'd like to fire a notification for
+ *
+ * @return the eventType
+ */
+ public String getEventType()
+ {
+ return eventType;
+ }
+
+ /**
+ * Gets the {@link NotificationHandler}-specific extras provided to this
+ * instance.
+ *
+ * @return the <tt>NotificationHandler</tt>-specific extras provided to this
+ * instance. The keys are among the <tt>XXX_EXTRA</tt> constants defined by
+ * the <tt>NotificationData</tt> class
+ */
+ Map<String, Object> getExtras()
+ {
+ return Collections.unmodifiableMap(extras);
+ }
+
+ /**
+ * Gets the {@link NotificationHandler}-specific extra provided to this
+ * instance associated with a specific key.
+ *
+ * @param key the key whose associated <tt>NotificationHandler</tt>-specific
+ * extra is to be returned. Well known keys are defined by the
+ * <tt>NotificationData</tt> class as the <tt>XXX_EXTRA</tt> constants.
+ * @return the <tt>NotificationHandler</tt>-specific extra provided to this
+ * instance associated with the specified <tt>key</tt>
+ */
+ public Object getExtra(String key)
+ {
+ return (extras == null) ? null : extras.get(key);
+ }
+
+ /**
+ * Gets the icon to show in the notification if and where appropriate.
+ *
+ * @return the icon
+ */
+ byte[] getIcon()
+ {
+ return icon;
+ }
+
+ /**
+ * Gets the message to use if and where appropriate (e.g. with systray or
+ * log notification).
+ *
+ * @return the message
+ */
+ String getMessage()
+ {
+ return message;
+ }
+
+ /**
+ * Gets the title of the given message.
+ *
+ * @return the title
+ */
+ String getTitle()
+ {
+ return title;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/notification/PopupMessageNotificationAction.java b/src/net/java/sip/communicator/service/notification/PopupMessageNotificationAction.java
index 244945f..395249c 100644
--- a/src/net/java/sip/communicator/service/notification/PopupMessageNotificationAction.java
+++ b/src/net/java/sip/communicator/service/notification/PopupMessageNotificationAction.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,108 +15,108 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.notification;
-
-/**
- * An implementation of the <tt>PopupMessageNotificationHandler</tt> interface.
- *
- * @author Yana Stamcheva
- */
-public class PopupMessageNotificationAction
- extends NotificationAction
-{
- private String defaultMessage;
-
- /**
- * Suggested timeout in ms for hiding the popup if not clicked by the user.
- */
- private long timeout = -1;
-
- /**
- * Group name used to group notifications on Android.
- */
- private String groupName;
-
- /**
- * Creates an instance of <tt>PopupMessageNotificationHandlerImpl</tt> by
- * specifying the default message to use if no message is specified.
- *
- * @param defaultMessage the default message to use if no message is
- * specified
- */
- public PopupMessageNotificationAction(String defaultMessage)
- {
- super(NotificationAction.ACTION_POPUP_MESSAGE);
- this.defaultMessage = defaultMessage;
- }
-
- /**
- * Creates an instance of <tt>PopupMessageNotificationHandlerImpl</tt> by
- * specifying the default message to use if no message is specified.
- *
- * @param defaultMessage the default message to use if no message is
- * specified
- * @param timeout suggested timeout in ms for hiding the popup if not
- * clicked by the user, -1 for infinity
- */
- public PopupMessageNotificationAction(String defaultMessage, long timeout)
- {
- this(defaultMessage);
- this.timeout = timeout;
- }
-
- /**
- * Creates an instance of <tt>PopupMessageNotificationHandlerImpl</tt> by
- * specifying the default message to use if no message is specified.
- *
- * @param defaultMessage the default message to use if no message is
- * specified
- * @param timeout suggested timeout in ms for hiding the popup if not
- * clicked by the user, -1 for infinity
- * @param groupName name of the group that will be used for merging popups
- */
- public PopupMessageNotificationAction(String defaultMessage, long timeout,
- String groupName)
- {
- this(defaultMessage, timeout);
- this.groupName = groupName;
- }
-
- /**
- * Return the default message to use if no message is specified.
- *
- * @return the default message to use if no message is specified.
- */
- public String getDefaultMessage()
- {
- return defaultMessage;
- }
-
- /**
- * Returns suggested timeout value in ms for hiding the popup if not clicked
- * by the user.
- * @return timeout value in ms for hiding the popup, -1 for infinity.
- */
- public long getTimeout()
- {
- return timeout;
- }
-
- /**
- * Sets the name of the group that will be used for merging popups.
- * @param groupName name of popup group to set.
- */
- public void setGroupName(String groupName)
- {
- this.groupName = groupName;
- }
-
- /**
- * Returns name of popup group that will be used for merging notifications.
- * @return name of popup group that will be used for merging notifications.
- */
- public String getGroupName()
- {
- return groupName;
- }
-}
+package net.java.sip.communicator.service.notification;
+
+/**
+ * An implementation of the <tt>PopupMessageNotificationHandler</tt> interface.
+ *
+ * @author Yana Stamcheva
+ */
+public class PopupMessageNotificationAction
+ extends NotificationAction
+{
+ private String defaultMessage;
+
+ /**
+ * Suggested timeout in ms for hiding the popup if not clicked by the user.
+ */
+ private long timeout = -1;
+
+ /**
+ * Group name used to group notifications on Android.
+ */
+ private String groupName;
+
+ /**
+ * Creates an instance of <tt>PopupMessageNotificationHandlerImpl</tt> by
+ * specifying the default message to use if no message is specified.
+ *
+ * @param defaultMessage the default message to use if no message is
+ * specified
+ */
+ public PopupMessageNotificationAction(String defaultMessage)
+ {
+ super(NotificationAction.ACTION_POPUP_MESSAGE);
+ this.defaultMessage = defaultMessage;
+ }
+
+ /**
+ * Creates an instance of <tt>PopupMessageNotificationHandlerImpl</tt> by
+ * specifying the default message to use if no message is specified.
+ *
+ * @param defaultMessage the default message to use if no message is
+ * specified
+ * @param timeout suggested timeout in ms for hiding the popup if not
+ * clicked by the user, -1 for infinity
+ */
+ public PopupMessageNotificationAction(String defaultMessage, long timeout)
+ {
+ this(defaultMessage);
+ this.timeout = timeout;
+ }
+
+ /**
+ * Creates an instance of <tt>PopupMessageNotificationHandlerImpl</tt> by
+ * specifying the default message to use if no message is specified.
+ *
+ * @param defaultMessage the default message to use if no message is
+ * specified
+ * @param timeout suggested timeout in ms for hiding the popup if not
+ * clicked by the user, -1 for infinity
+ * @param groupName name of the group that will be used for merging popups
+ */
+ public PopupMessageNotificationAction(String defaultMessage, long timeout,
+ String groupName)
+ {
+ this(defaultMessage, timeout);
+ this.groupName = groupName;
+ }
+
+ /**
+ * Return the default message to use if no message is specified.
+ *
+ * @return the default message to use if no message is specified.
+ */
+ public String getDefaultMessage()
+ {
+ return defaultMessage;
+ }
+
+ /**
+ * Returns suggested timeout value in ms for hiding the popup if not clicked
+ * by the user.
+ * @return timeout value in ms for hiding the popup, -1 for infinity.
+ */
+ public long getTimeout()
+ {
+ return timeout;
+ }
+
+ /**
+ * Sets the name of the group that will be used for merging popups.
+ * @param groupName name of popup group to set.
+ */
+ public void setGroupName(String groupName)
+ {
+ this.groupName = groupName;
+ }
+
+ /**
+ * Returns name of popup group that will be used for merging notifications.
+ * @return name of popup group that will be used for merging notifications.
+ */
+ public String getGroupName()
+ {
+ return groupName;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/notification/SoundNotificationAction.java b/src/net/java/sip/communicator/service/notification/SoundNotificationAction.java
index b633fb3..159b15c 100644
--- a/src/net/java/sip/communicator/service/notification/SoundNotificationAction.java
+++ b/src/net/java/sip/communicator/service/notification/SoundNotificationAction.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,180 +15,180 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.notification;
-
-/**
- * An implementation of the <tt>SoundNotificationHandlerImpl</tt> interface.
- *
- * @author Yana Stamcheva
- */
-public class SoundNotificationAction
- extends NotificationAction
-{
- /**
- * Interval of milliseconds to wait before repeating the sound. -1 means no
- * repetition.
- */
- private int loopInterval;
-
- /**
- * the descriptor pointing to the sound to be played.
- */
- private String soundFileDescriptor;
-
- /**
- * The boolean telling if this sound is to be played on notification device.
- */
- private boolean isSoundNotificationEnabled;
-
- /**
- * Is sound to be played on playback device.
- */
- private boolean isSoundPlaybackEnabled;
-
- /**
- * Is sound to be played on pc speaker device.
- */
- private boolean isSoundPCSpeakerEnabled;
-
- /**
- * Creates an instance of <tt>SoundNotification</tt> by
- * specifying the sound file descriptor and the loop interval.
- * By default is enabling simulation output to notification and
- * playback device.
- *
- * @param soundDescriptor the sound file descriptor
- * @param loopInterval the loop interval
- */
- public SoundNotificationAction( String soundDescriptor,
- int loopInterval)
- {
- this(soundDescriptor, loopInterval,
- false,
- false,
- false);
- }
-
- /**
- * Creates an instance of <tt>SoundNotification</tt> by
- * specifying the sound file descriptor and the loop interval.
- *
- * @param soundDescriptor the sound file descriptor
- * @param loopInterval the loop interval
- * @param isSoundNotificationEnabled True if this sound is activated. False Otherwise.
- * @param isSoundPlaybackEnabled True if this sound is activated. False Otherwise.
- * @param isSoundPCSpeakerEnabled True if this sound is activated. False Otherwise.
- */
- public SoundNotificationAction( String soundDescriptor,
- int loopInterval,
- boolean isSoundNotificationEnabled,
- boolean isSoundPlaybackEnabled,
- boolean isSoundPCSpeakerEnabled)
- {
- super(NotificationAction.ACTION_SOUND);
- this.soundFileDescriptor = soundDescriptor;
- this.loopInterval = loopInterval;
- this.isSoundNotificationEnabled = isSoundNotificationEnabled;
- this.isSoundPlaybackEnabled = isSoundPlaybackEnabled;
- this.isSoundPCSpeakerEnabled = isSoundPCSpeakerEnabled;
- }
-
- /**
- * Returns the loop interval. This is the interval of milliseconds to wait
- * before repeating the sound, when playing a sound in loop. By default this
- * method returns -1.
- *
- * @return the loop interval
- */
- public int getLoopInterval()
- {
- return loopInterval;
- }
-
- /**
- * Changes the loop interval. This is the interval of milliseconds to wait
- * before repeating the sound, when playing a sound in loop.
- *
- * @return the loop interval
- */
- public void setLoopInterval(int loopInterval)
- {
- this.loopInterval = loopInterval;
- }
-
- /**
- * Returns the descriptor pointing to the sound to be played.
- *
- * @return the descriptor pointing to the sound to be played.
- */
- public String getDescriptor()
- {
- return soundFileDescriptor;
- }
-
- /**
- * Returns if this sound is to be played on notification device.
- *
- * @return True if this sound is played on notification device.
- * False Otherwise.
- */
- public boolean isSoundNotificationEnabled()
- {
- return isSoundNotificationEnabled;
- }
-
- /**
- * Returns if this sound is to be played on playback device.
- *
- * @return True if this sound is played on playback device.
- * False Otherwise.
- */
- public boolean isSoundPlaybackEnabled()
- {
- return isSoundPlaybackEnabled;
- }
-
- /**
- * Returns if this sound is to be played on pc speaker device.
- *
- * @return True if this sound is played on pc speaker device.
- * False Otherwise.
- */
- public boolean isSoundPCSpeakerEnabled()
- {
- return isSoundPCSpeakerEnabled;
- }
-
- /**
- * Enables or disables this sound for notification device.
- *
- * @param isSoundEnabled True if this sound is played on notification
- * device. False Otherwise.
- */
- public void setSoundNotificationEnabled(boolean isSoundEnabled)
- {
- this.isSoundNotificationEnabled = isSoundEnabled;
- }
-
- /**
- * Enables or disables this sound for playback device.
- *
- * @param isSoundEnabled True if this sound is played on playback
- * device. False Otherwise.
- */
- public void setSoundPlaybackEnabled(boolean isSoundEnabled)
- {
- this.isSoundPlaybackEnabled = isSoundEnabled;
- }
-
- /**
- * Enables or disables this sound for pc speaker device.
- *
- * @param isSoundEnabled True if this sound is played on speaker
- * device. False Otherwise.
- */
- public void setSoundPCSpeakerEnabled(boolean isSoundEnabled)
- {
- this.isSoundPCSpeakerEnabled = isSoundEnabled;
- }
-}
+package net.java.sip.communicator.service.notification;
+
+/**
+ * An implementation of the <tt>SoundNotificationHandlerImpl</tt> interface.
+ *
+ * @author Yana Stamcheva
+ */
+public class SoundNotificationAction
+ extends NotificationAction
+{
+ /**
+ * Interval of milliseconds to wait before repeating the sound. -1 means no
+ * repetition.
+ */
+ private int loopInterval;
+
+ /**
+ * the descriptor pointing to the sound to be played.
+ */
+ private String soundFileDescriptor;
+
+ /**
+ * The boolean telling if this sound is to be played on notification device.
+ */
+ private boolean isSoundNotificationEnabled;
+
+ /**
+ * Is sound to be played on playback device.
+ */
+ private boolean isSoundPlaybackEnabled;
+
+ /**
+ * Is sound to be played on pc speaker device.
+ */
+ private boolean isSoundPCSpeakerEnabled;
+
+ /**
+ * Creates an instance of <tt>SoundNotification</tt> by
+ * specifying the sound file descriptor and the loop interval.
+ * By default is enabling simulation output to notification and
+ * playback device.
+ *
+ * @param soundDescriptor the sound file descriptor
+ * @param loopInterval the loop interval
+ */
+ public SoundNotificationAction( String soundDescriptor,
+ int loopInterval)
+ {
+ this(soundDescriptor, loopInterval,
+ false,
+ false,
+ false);
+ }
+
+ /**
+ * Creates an instance of <tt>SoundNotification</tt> by
+ * specifying the sound file descriptor and the loop interval.
+ *
+ * @param soundDescriptor the sound file descriptor
+ * @param loopInterval the loop interval
+ * @param isSoundNotificationEnabled True if this sound is activated. False Otherwise.
+ * @param isSoundPlaybackEnabled True if this sound is activated. False Otherwise.
+ * @param isSoundPCSpeakerEnabled True if this sound is activated. False Otherwise.
+ */
+ public SoundNotificationAction( String soundDescriptor,
+ int loopInterval,
+ boolean isSoundNotificationEnabled,
+ boolean isSoundPlaybackEnabled,
+ boolean isSoundPCSpeakerEnabled)
+ {
+ super(NotificationAction.ACTION_SOUND);
+ this.soundFileDescriptor = soundDescriptor;
+ this.loopInterval = loopInterval;
+ this.isSoundNotificationEnabled = isSoundNotificationEnabled;
+ this.isSoundPlaybackEnabled = isSoundPlaybackEnabled;
+ this.isSoundPCSpeakerEnabled = isSoundPCSpeakerEnabled;
+ }
+
+ /**
+ * Returns the loop interval. This is the interval of milliseconds to wait
+ * before repeating the sound, when playing a sound in loop. By default this
+ * method returns -1.
+ *
+ * @return the loop interval
+ */
+ public int getLoopInterval()
+ {
+ return loopInterval;
+ }
+
+ /**
+ * Changes the loop interval. This is the interval of milliseconds to wait
+ * before repeating the sound, when playing a sound in loop.
+ *
+ * @return the loop interval
+ */
+ public void setLoopInterval(int loopInterval)
+ {
+ this.loopInterval = loopInterval;
+ }
+
+ /**
+ * Returns the descriptor pointing to the sound to be played.
+ *
+ * @return the descriptor pointing to the sound to be played.
+ */
+ public String getDescriptor()
+ {
+ return soundFileDescriptor;
+ }
+
+ /**
+ * Returns if this sound is to be played on notification device.
+ *
+ * @return True if this sound is played on notification device.
+ * False Otherwise.
+ */
+ public boolean isSoundNotificationEnabled()
+ {
+ return isSoundNotificationEnabled;
+ }
+
+ /**
+ * Returns if this sound is to be played on playback device.
+ *
+ * @return True if this sound is played on playback device.
+ * False Otherwise.
+ */
+ public boolean isSoundPlaybackEnabled()
+ {
+ return isSoundPlaybackEnabled;
+ }
+
+ /**
+ * Returns if this sound is to be played on pc speaker device.
+ *
+ * @return True if this sound is played on pc speaker device.
+ * False Otherwise.
+ */
+ public boolean isSoundPCSpeakerEnabled()
+ {
+ return isSoundPCSpeakerEnabled;
+ }
+
+ /**
+ * Enables or disables this sound for notification device.
+ *
+ * @param isSoundEnabled True if this sound is played on notification
+ * device. False Otherwise.
+ */
+ public void setSoundNotificationEnabled(boolean isSoundEnabled)
+ {
+ this.isSoundNotificationEnabled = isSoundEnabled;
+ }
+
+ /**
+ * Enables or disables this sound for playback device.
+ *
+ * @param isSoundEnabled True if this sound is played on playback
+ * device. False Otherwise.
+ */
+ public void setSoundPlaybackEnabled(boolean isSoundEnabled)
+ {
+ this.isSoundPlaybackEnabled = isSoundEnabled;
+ }
+
+ /**
+ * Enables or disables this sound for pc speaker device.
+ *
+ * @param isSoundEnabled True if this sound is played on speaker
+ * device. False Otherwise.
+ */
+ public void setSoundPCSpeakerEnabled(boolean isSoundEnabled)
+ {
+ this.isSoundPCSpeakerEnabled = isSoundEnabled;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java b/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java
index 4270a78..6f038b5 100644
--- a/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java
+++ b/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java
@@ -137,14 +137,6 @@ public abstract class AbstractOperationSetBasicInstantMessaging
return createMessage(messageText);
}
- /**
- * {@inheritDoc}
- */
- public Message createMessageWithUID(String messageText, String messageUID)
- {
- return createMessage(messageText);
- }
-
public abstract Message createMessage(
String content, String contentType, String encoding, String subject);
diff --git a/src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java b/src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java
index 9a78eec..897b74b 100644
--- a/src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java
+++ b/src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java
@@ -245,6 +245,19 @@ public abstract class AbstractProtocolProviderService
}
/**
+ * Default implementation that always returns true.
+ *
+ * @param contactId ignored.
+ * @param result ignored
+ * @return true
+ */
+ @Override
+ public boolean validateContactAddress(String contactId, List<String> result)
+ {
+ return true;
+ }
+
+ /**
* Returns an array containing all operation sets supported by the current
* implementation. When querying this method users must be prepared to
* receive any subset of the OperationSet-s defined by this service. They
diff --git a/src/net/java/sip/communicator/service/protocol/AccountManager.java b/src/net/java/sip/communicator/service/protocol/AccountManager.java
index c608092..3ce85dc 100644
--- a/src/net/java/sip/communicator/service/protocol/AccountManager.java
+++ b/src/net/java/sip/communicator/service/protocol/AccountManager.java
@@ -1,1083 +1,1083 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.service.protocol;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.credentialsstorage.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-import net.java.sip.communicator.util.Base64; //disambiguate from java.util.Base64
-
-import org.jitsi.service.configuration.*;
-import org.osgi.framework.*;
-
-/**
- * Represents an implementation of <tt>AccountManager</tt> which loads the
- * accounts in a separate thread.
- *
- * @author Lyubomir Marinov
- * @author Yana Stamcheva
- */
-public class AccountManager
-{
- /**
- * The delay in milliseconds the background <tt>Thread</tt> loading the
- * stored accounts should wait before dying so that it doesn't get recreated
- * for each <tt>ProtocolProviderFactory</tt> registration.
- */
- private static final long LOAD_STORED_ACCOUNTS_TIMEOUT = 30000;
-
- /**
- * The <tt>BundleContext</tt> this service is registered in.
- */
- private final BundleContext bundleContext;
-
- /**
- * The <tt>AccountManagerListener</tt>s currently interested in the
- * events fired by this manager.
- */
- private final List<AccountManagerListener> listeners =
- new LinkedList<AccountManagerListener>();
-
- /**
- * The queue of <tt>ProtocolProviderFactory</tt> services awaiting their
- * stored accounts to be loaded.
- */
- private final Queue<ProtocolProviderFactory> loadStoredAccountsQueue =
- new LinkedList<ProtocolProviderFactory>();
-
- /**
- * The <tt>Thread</tt> loading the stored accounts of the
- * <tt>ProtocolProviderFactory</tt> services waiting in
- * {@link #loadStoredAccountsQueue}.
- */
- private Thread loadStoredAccountsThread;
-
- /**
- * The <tt>Logger</tt> used by this <tt>AccountManagerImpl</tt> instance for
- * logging output.
- */
- private final Logger logger = Logger.getLogger(AccountManager.class);
-
- /**
- * The list of <tt>AccountID</tt>s, corresponding to all stored accounts.
- */
- private final Vector<AccountID> storedAccounts = new Vector<AccountID>();
-
- /**
- * The prefix of the account unique identifier.
- */
- private static final String ACCOUNT_UID_PREFIX = "acc";
-
- /**
- * Initializes a new <tt>AccountManagerImpl</tt> instance loaded in a
- * specific <tt>BundleContext</tt> (in which the caller will usually
- * later register it).
- *
- * @param bundleContext the <tt>BundleContext</tt> in which the new
- * instance is loaded (and in which the caller will usually later
- * register it as a service)
- */
- public AccountManager(BundleContext bundleContext)
- {
- this.bundleContext = bundleContext;
-
- this.bundleContext.addServiceListener(new ServiceListener()
- {
- public void serviceChanged(ServiceEvent serviceEvent)
- {
- AccountManager.this.serviceChanged(serviceEvent);
- }
- });
- }
-
- /**
- * Implements AccountManager#addListener(AccountManagerListener).
- * @param listener the <tt>AccountManagerListener</tt> to add
- */
- public void addListener(AccountManagerListener listener)
- {
- synchronized (listeners)
- {
- if (!listeners.contains(listener))
- listeners.add(listener);
- }
- }
-
- /**
- * Loads the accounts stored for a specific
- * <tt>ProtocolProviderFactory</tt>.
- *
- * @param factory the <tt>ProtocolProviderFactory</tt> to load the
- * stored accounts of
- */
- private void doLoadStoredAccounts(ProtocolProviderFactory factory)
- {
- ConfigurationService configService
- = ProtocolProviderActivator.getConfigurationService();
- String factoryPackage = getFactoryImplPackageName(factory);
- List<String> accounts
- = configService.getPropertyNamesByPrefix(factoryPackage, true);
-
- if (logger.isDebugEnabled())
- logger.debug("Discovered " + accounts.size() + " stored "
- + factoryPackage + " accounts");
-
- for (Iterator<String> storedAccountIter = accounts.iterator();
- storedAccountIter.hasNext();)
- {
- String storedAccount = storedAccountIter.next();
-
- // If the property is not related to an account we skip it.
- int dotIndex = storedAccount.lastIndexOf(".");
- if (!storedAccount.substring(dotIndex + 1)
- .startsWith(ACCOUNT_UID_PREFIX))
- continue;
-
- if (logger.isDebugEnabled())
- logger.debug("Loading account " + storedAccount);
-
- List<String> storedAccountProperties =
- configService.getPropertyNamesByPrefix(storedAccount, false);
- Map<String, String> accountProperties =
- new Hashtable<String, String>();
- boolean disabled = false;
- CredentialsStorageService credentialsStorage
- = ServiceUtils.getService(
- bundleContext,
- CredentialsStorageService.class);
-
- int prefLen = storedAccount.length() + 1;
- for (Iterator<String> storedAccountPropertyIter
- = storedAccountProperties.iterator();
- storedAccountPropertyIter.hasNext();)
- {
- String property = storedAccountPropertyIter.next();
- String value = configService.getString(property);
-
- //strip the package prefix
- if(prefLen > property.length())
- continue;
-
- property = property.substring(prefLen);
-
- if (ProtocolProviderFactory.IS_ACCOUNT_DISABLED.equals(property))
- disabled = Boolean.parseBoolean(value);
- // Decode passwords.
- else if (ProtocolProviderFactory.PASSWORD.equals(property)
- && !credentialsStorage.isStoredEncrypted(storedAccount))
- {
- if ((value != null) && value.length() != 0)
- {
-
- /*
- * TODO Converting byte[] to String using the platform's
- * default charset may result in an invalid password.
- */
- value = new String(Base64.decode(value));
- }
- }
-
- if (value != null)
- accountProperties.put(property, value);
- }
-
- try
- {
- AccountID accountID = factory.createAccount(accountProperties);
-
- // If for some reason the account id is not created we move to
- // the next account.
- if (accountID == null)
- continue;
-
- synchronized (storedAccounts)
- {
- storedAccounts.add(accountID);
- }
- if (!disabled)
- factory.loadAccount(accountID);
- }
- catch (Exception ex)
- {
- /*
- * Swallow the exception in order to prevent a single account
- * from halting the loading of subsequent accounts.
- */
- logger.error("Failed to load account " + accountProperties, ex);
- }
- catch (ExceptionInInitializerError ex)
- {
- // In case we fail to instantiate the ProtocolProviderService.
- logger.error(
- "Failed to create account service instance for account "
- + accountProperties, ex);
- }
- }
- }
-
- /**
- * Notifies the registered {@link #listeners} that the stored accounts of a
- * specific <tt>ProtocolProviderFactory</tt> have just been loaded.
- *
- * @param factory the <tt>ProtocolProviderFactory</tt> which had its
- * stored accounts just loaded
- */
- private void fireStoredAccountsLoaded(ProtocolProviderFactory factory)
- {
- AccountManagerListener[] listeners;
- synchronized (this.listeners)
- {
- listeners =
- this.listeners
- .toArray(new AccountManagerListener[this.listeners.size()]);
- }
-
- int listenerCount = listeners.length;
- if (listenerCount > 0)
- {
- AccountManagerEvent event =
- new AccountManagerEvent(this,
- AccountManagerEvent.STORED_ACCOUNTS_LOADED, factory);
-
- for (int listenerIndex = 0;
- listenerIndex < listenerCount; listenerIndex++)
- {
- listeners[listenerIndex].handleAccountManagerEvent(event);
- }
- }
- }
-
- /**
- * Returns the package name of the <tt>factory</tt>.
- * @param factory the factory which package will be returned.
- * @return the package name of the <tt>factory</tt>.
- */
- public String getFactoryImplPackageName(ProtocolProviderFactory factory)
- {
- String className = factory.getClass().getName();
-
- return className.substring(0, className.lastIndexOf('.'));
- }
-
- /**
- * Check for stored accounts for the supplied <tt>protocolName</tt>.
- * @param protocolName the protocol name to check for
- * @param includeHidden whether to include hidden providers
- * @return <tt>true</tt> if there is any account stored in configuration
- * service with <tt>protocolName</tt>, <tt>false</tt> otherwise.
- */
- public boolean hasStoredAccounts(String protocolName, boolean includeHidden)
- {
- return hasStoredAccount(protocolName, includeHidden, null);
- }
-
- /**
- * Checks whether a stored account with <tt>userID</tt> is stored
- * in configuration.
- *
- * @param protocolName the protocol name
- * @param includeHidden whether to check hidden providers
- * @param userID the user id to check.
- * @return <tt>true</tt> if there is any account stored in configuration
- * service with <tt>protocolName</tt> and <tt>userID</tt>,
- * <tt>false</tt> otherwise.
- */
- public boolean hasStoredAccount(String protocolName,
- boolean includeHidden,
- String userID)
- {
- Collection<ServiceReference<ProtocolProviderFactory>> factoryRefs
- = ServiceUtils.getServiceReferences(
- bundleContext,
- ProtocolProviderFactory.class);
- boolean hasStoredAccounts = false;
-
- if (!factoryRefs.isEmpty())
- {
- ConfigurationService configService
- = ProtocolProviderActivator.getConfigurationService();
-
- for (ServiceReference<ProtocolProviderFactory> factoryRef
- : factoryRefs)
- {
- ProtocolProviderFactory factory
- = bundleContext.getService(factoryRef);
-
- if ((protocolName != null)
- && !protocolName.equals(factory.getProtocolName()))
- {
- continue;
- }
-
- String factoryPackage = getFactoryImplPackageName(factory);
- List<String> storedAccounts
- = configService
- .getPropertyNamesByPrefix(factoryPackage + ".acc",
- false);
-
- /* Ignore the hidden accounts. */
- for (Iterator<String> storedAccountIter =
- storedAccounts.iterator(); storedAccountIter.hasNext();)
- {
- String storedAccount = storedAccountIter.next();
- List<String> storedAccountProperties =
- configService.getPropertyNamesByPrefix(storedAccount,
- true);
- boolean hidden = false;
- String accountUserID = null;
-
- if (!includeHidden || userID != null)
- {
- for (Iterator<String> storedAccountPropertyIter =
- storedAccountProperties.iterator();
- storedAccountPropertyIter.hasNext();)
- {
- String property = storedAccountPropertyIter.next();
- String value = configService.getString(property);
-
- property = stripPackagePrefix(property);
-
- if (ProtocolProviderFactory.IS_PROTOCOL_HIDDEN
- .equals(property))
- {
- hidden = (value != null);
- }
- else if (ProtocolProviderFactory.USER_ID
- .equals(property))
- {
- accountUserID = value;
- }
- }
- }
-
- if (includeHidden || !hidden)
- {
- if(accountUserID != null
- && userID != null
- && userID.equals(accountUserID))
- {
- hasStoredAccounts = true;
- break;
- }
- else if(userID == null)
- {
- hasStoredAccounts = true;
- break;
- }
- }
- }
-
- if (hasStoredAccounts || (protocolName != null))
- {
- break;
- }
- }
- }
- return hasStoredAccounts;
- }
-
- /**
- * Searches for stored account with <tt>uid</tt> in stored
- * configuration. The <tt>uid</tt> is the one generated when creating
- * accounts with prefix <tt>ACCOUNT_UID_PREFIX</tt>.
- *
- * @return <tt>AccountID</tt> if there is any account stored in configuration
- * service with <tt>uid</tt>,
- * <tt>null</tt> otherwise.
- */
- public AccountID findAccountID(String uid)
- {
- Collection<ServiceReference<ProtocolProviderFactory>> factoryRefs
- = ServiceUtils.getServiceReferences(
- bundleContext,
- ProtocolProviderFactory.class);
-
- if (!factoryRefs.isEmpty())
- {
- ConfigurationService configService
- = ProtocolProviderActivator.getConfigurationService();
-
- for (ServiceReference<ProtocolProviderFactory> factoryRef
- : factoryRefs)
- {
- ProtocolProviderFactory factory
- = bundleContext.getService(factoryRef);
-
- String factoryPackage = getFactoryImplPackageName(factory);
- List<String> storedAccountsProps
- = configService
- .getPropertyNamesByPrefix(factoryPackage, true);
-
- for (Iterator<String> storedAccountIter =
- storedAccountsProps.iterator();
- storedAccountIter.hasNext();)
- {
- String storedAccount = storedAccountIter.next();
-
- if(!storedAccount.endsWith(uid))
- continue;
-
- String accountUID = configService.getString(
- storedAccount //node id
- + "." + ProtocolProviderFactory.ACCOUNT_UID);// propname
-
- for(AccountID acc : storedAccounts)
- {
- if(acc.getAccountUniqueID().equals(accountUID))
- return acc;
- }
- }
- }
- }
- return null;
- }
-
- /**
- * Loads the accounts stored for a specific
- * <tt>ProtocolProviderFactory</tt> and notifies the registered
- * {@link #listeners} that the stored accounts of the specified
- * <tt>factory</tt> have just been loaded
- *
- * @param factory the <tt>ProtocolProviderFactory</tt> to load the
- * stored accounts of
- */
- private void loadStoredAccounts(ProtocolProviderFactory factory)
- {
- doLoadStoredAccounts(factory);
-
- fireStoredAccountsLoaded(factory);
- }
-
- /**
- * Notifies this manager that a specific
- * <tt>ProtocolProviderFactory</tt> has been registered as a service.
- * The current implementation queues the specified <tt>factory</tt> to
- * have its stored accounts as soon as possible.
- *
- * @param factory the <tt>ProtocolProviderFactory</tt> which has been
- * registered as a service.
- */
- private void protocolProviderFactoryRegistered(
- ProtocolProviderFactory factory)
- {
- queueLoadStoredAccounts(factory);
- }
-
- /**
- * Queues a specific <tt>ProtocolProviderFactory</tt> to have its stored
- * accounts loaded as soon as possible.
- *
- * @param factory the <tt>ProtocolProviderFactory</tt> to be queued for
- * loading its stored accounts as soon as possible
- */
- private void queueLoadStoredAccounts(ProtocolProviderFactory factory)
- {
- synchronized (loadStoredAccountsQueue)
- {
- loadStoredAccountsQueue.add(factory);
- loadStoredAccountsQueue.notifyAll();
-
- if (loadStoredAccountsThread == null)
- {
- loadStoredAccountsThread = new Thread()
- {
- @Override
- public void run()
- {
- runInLoadStoredAccountsThread();
- }
- };
- loadStoredAccountsThread.setDaemon(true);
- loadStoredAccountsThread.setName(
- "AccountManager.loadStoredAccounts");
- loadStoredAccountsThread.start();
- }
- }
- }
-
- /**
- * Implements AccountManager#removeListener(AccountManagerListener).
- * @param listener the <tt>AccountManagerListener</tt> to remove
- */
- public void removeListener(AccountManagerListener listener)
- {
- synchronized (listeners)
- {
- listeners.remove(listener);
- }
- }
-
- /**
- * Running in {@link #loadStoredAccountsThread}, loads the stored accounts
- * of the <tt>ProtocolProviderFactory</tt> services waiting in
- * {@link #loadStoredAccountsQueue}
- */
- private void runInLoadStoredAccountsThread()
- {
- boolean interrupted = false;
- while (!interrupted)
- {
- try
- {
- ProtocolProviderFactory factory;
-
- synchronized (loadStoredAccountsQueue)
- {
- factory = loadStoredAccountsQueue.poll();
- if (factory == null)
- {
- /*
- * Technically, we should be handing spurious wakeups.
- * However, we cannot check the condition in a queue.
- * Anyway, we just want to keep this Thread alive long
- * enough to allow it to not be re-created multiple
- * times and not handing a spurious wakeup will just
- * cause such an inconvenience.
- */
- try
- {
- loadStoredAccountsQueue
- .wait(LOAD_STORED_ACCOUNTS_TIMEOUT);
- }
- catch (InterruptedException ex)
- {
- logger
- .warn(
- "The loading of the stored accounts has"
- + " been interrupted",
- ex);
- interrupted = true;
- break;
- }
- factory = loadStoredAccountsQueue.poll();
- }
- if (factory != null)
- loadStoredAccountsQueue.notifyAll();
- }
-
- if (factory != null)
- {
- try
- {
- loadStoredAccounts(factory);
- }
- catch (Exception ex)
- {
-
- /*
- * Swallow the exception in order to prevent a single
- * factory from halting the loading of subsequent
- * factories.
- */
- logger.error("Failed to load accounts for " + factory,
- ex);
- }
- }
- }
- finally
- {
- synchronized (loadStoredAccountsQueue)
- {
- if (!interrupted && (loadStoredAccountsQueue.size() <= 0))
- {
- if (loadStoredAccountsThread == Thread.currentThread())
- {
- loadStoredAccountsThread = null;
- loadStoredAccountsQueue.notifyAll();
- }
- break;
- }
- }
- }
- }
- }
-
- /**
- * Notifies this manager that an OSGi service has changed. The current
- * implementation tracks the registrations of
- * <tt>ProtocolProviderFactory</tt> services in order to queue them for
- * loading their stored accounts.
- *
- * @param serviceEvent the <tt>ServiceEvent</tt> containing the event
- * data
- */
- private void serviceChanged(ServiceEvent serviceEvent)
- {
- switch (serviceEvent.getType())
- {
- case ServiceEvent.REGISTERED:
- Object service
- = bundleContext.getService(serviceEvent.getServiceReference());
-
- if (service instanceof ProtocolProviderFactory)
- {
- protocolProviderFactoryRegistered(
- (ProtocolProviderFactory) service);
- }
- break;
- default:
- break;
- }
- }
-
- /**
- * Stores an account represented in the form of an <tt>AccountID</tt>
- * created by a specific <tt>ProtocolProviderFactory</tt>.
- *
- * @param factory the <tt>ProtocolProviderFactory</tt> which created the
- * account to be stored
- * @param accountID the account in the form of <tt>AccountID</tt> to be
- * stored
- * @throws OperationFailedException if anything goes wrong while storing the
- * account
- */
- public void storeAccount(
- ProtocolProviderFactory factory,
- AccountID accountID)
- throws OperationFailedException
- {
- synchronized (storedAccounts)
- {
- if (!storedAccounts.contains(accountID))
- storedAccounts.add(accountID);
- }
-
- ConfigurationService configurationService
- = ProtocolProviderActivator.getConfigurationService();
- String factoryPackage = getFactoryImplPackageName(factory);
-
- String accountNodeName
- = getAccountNodeName( factory,
- accountID.getAccountUniqueID() );
-
- Map<String, Object> configurationProperties
- = new HashMap<String, Object>();
-
- // Create a unique node name of the properties node that will contain
- // this account's properties.
- if (accountNodeName == null)
- {
- accountNodeName
- = ACCOUNT_UID_PREFIX + Long.toString(System.currentTimeMillis());
-
- // set a value for the persistent node so that we could later
- // retrieve it as a property
- configurationProperties.put(
- factoryPackage /* prefix */ + "." + accountNodeName,
- accountNodeName);
-
- // register the account in the configuration service.
- // we register all the properties in the following hierarchy
- //net.java.sip.communicator.impl.protocol.PROTO_NAME.ACC_ID.PROP_NAME
- configurationProperties.put(factoryPackage// prefix
- + "." + accountNodeName // node name for the account id
- + "." + ProtocolProviderFactory.ACCOUNT_UID, // propname
- accountID.getAccountUniqueID()); // value
- }
-
- // store the rest of the properties
- Map<String, String> accountProperties = accountID.getAccountProperties();
-
- for (Map.Entry<String, String> entry : accountProperties.entrySet())
- {
- String property = entry.getKey();
- String value = entry.getValue();
- String secureStorePrefix = null;
-
- // If the property is a password, store it securely.
- if (property.equals(ProtocolProviderFactory.PASSWORD))
- {
- String accountPrefix = factoryPackage + "." + accountNodeName;
- secureStorePrefix = accountPrefix;
- }
- else if(property.endsWith("." + ProtocolProviderFactory.PASSWORD))
- {
- secureStorePrefix = factoryPackage + "." + accountNodeName +
- "." + property.substring(0, property.lastIndexOf("."));
- }
-
- if(secureStorePrefix != null)
- {
- CredentialsStorageService credentialsStorage
- = ServiceUtils.getService(
- bundleContext,
- CredentialsStorageService.class);
-
- // encrypt and store
- if ((value != null)
- && (value.length() != 0)
- && !credentialsStorage.storePassword(
- secureStorePrefix,
- value))
- {
- throw
- new OperationFailedException(
- "CredentialsStorageService failed to"
- + " storePassword",
- OperationFailedException.GENERAL_ERROR);
- }
- }
- else
- {
- configurationProperties.put(
- factoryPackage // prefix
- + "." + accountNodeName // a unique node name for the account id
- + "." + property, // propname
- value); // value
- }
- }
-
- // clear the password if missing property, modification can request
- // password delete
- if(!accountProperties.containsKey(ProtocolProviderFactory.PASSWORD)
- && // And only if it's not stored already in encrypted form.
- // Account registration object clears also this property
- // in order to forget the password
- !configurationProperties.containsKey(
- factoryPackage+"."+accountNodeName+".ENCRYPTED_PASSWORD"))
- {
- CredentialsStorageService credentialsStorage
- = ServiceUtils.getService(
- bundleContext,
- CredentialsStorageService.class);
- credentialsStorage.removePassword(
- factoryPackage + "." + accountNodeName);
- }
-
- if (configurationProperties.size() > 0)
- configurationService.setProperties(configurationProperties);
-
- if (logger.isDebugEnabled())
- logger.debug("Stored account for id " + accountID.getAccountUniqueID()
- + " for package " + factoryPackage);
- }
-
- /**
- * Gets account node name under which account configuration properties are
- * stored.
- *
- * @param factory account's protocol provider factory
- * @param accountUID account for which the prefix will be returned
- * @return configuration prefix for given <tt>accountID</tt> if exists or
- * <tt>null</tt> otherwise
- */
- public String getAccountNodeName( ProtocolProviderFactory factory,
- String accountUID )
- {
- ConfigurationService configurationService
- = ProtocolProviderActivator.getConfigurationService();
- String factoryPackage = getFactoryImplPackageName(factory);
-
- // First check if such accountID already exists in the configuration.
- List<String> storedAccounts =
- configurationService.getPropertyNamesByPrefix(factoryPackage, true);
- String accountNodeName = null;
-
- for (Iterator<String> storedAccountIter = storedAccounts.iterator();
- storedAccountIter.hasNext();)
- {
- String storedAccount = storedAccountIter.next();
-
- // If the property is not related to an account we skip it.
- int dotIndex = storedAccount.lastIndexOf(".");
- if (!storedAccount.substring(dotIndex + 1)
- .startsWith(ACCOUNT_UID_PREFIX))
- continue;
-
- String storedAccountUID
- = configurationService.getString(
- storedAccount + "." + ProtocolProviderFactory.ACCOUNT_UID);
-
- if(storedAccountUID == null)
- continue;
-
- if (storedAccountUID.equals(accountUID))
- accountNodeName = configurationService.getString(storedAccount);
- }
- return accountNodeName;
- }
-
- /**
- * Removes the account with <tt>accountID</tt> from the set of accounts
- * that are persistently stored inside the configuration service.
- *
- * @param factory the <tt>ProtocolProviderFactory</tt> which created the
- * account to be stored
- * @param accountID the AccountID of the account to remove.
- * @return true if an account has been removed and false otherwise.
- */
- public boolean removeStoredAccount(ProtocolProviderFactory factory,
- AccountID accountID)
- {
- synchronized (storedAccounts)
- {
- if (storedAccounts.contains(accountID))
- storedAccounts.remove(accountID);
- }
-
- /*
- * We're already doing it in #unloadAccount(AccountID) - we're figuring
- * out the ProtocolProviderFactory by the AccountID.
- */
- if (factory == null)
- {
- factory
- = ProtocolProviderActivator.getProtocolProviderFactory(
- accountID.getProtocolName());
- }
-
- String factoryPackage = getFactoryImplPackageName(factory);
-
- // remove the stored password explicitly using credentials service
- CredentialsStorageService credentialsStorage
- = ServiceUtils.getService(
- bundleContext,
- CredentialsStorageService.class);
- String accountPrefix =
- ProtocolProviderFactory.findAccountPrefix(bundleContext, accountID,
- factoryPackage);
-
- credentialsStorage.removePassword(accountPrefix);
-
- ConfigurationService configurationService
- = ServiceUtils.getService(
- bundleContext,
- ConfigurationService.class);
- //first retrieve all accounts that we've registered
- List<String> storedAccounts
- = configurationService.getPropertyNamesByPrefix(
- factoryPackage, true);
-
- //find an account with the corresponding id.
- for (String accountRootPropertyName : storedAccounts)
- {
- //unregister the account in the configuration service.
- //all the properties must have been registered in the following
- //hierarchy:
- //net.java.sip.communicator.impl.protocol.PROTO_NAME.ACC_ID.PROP_NAME
- String accountUID = configurationService.getString(
- accountRootPropertyName //node id
- + "." + ProtocolProviderFactory.ACCOUNT_UID); // propname
-
- if (accountID.getAccountUniqueID().equals(accountUID))
- {
- //retrieve the names of all properties registered for the
- //current account.
- List<String> accountPropertyNames
- = configurationService.getPropertyNamesByPrefix(
- accountRootPropertyName, false);
-
- //set all account properties to null in order to remove them.
- for (String propName : accountPropertyNames)
- configurationService.setProperty(propName, null);
-
- //and now remove the parent too.
- configurationService.setProperty(accountRootPropertyName, null);
- return true;
- }
- }
- return false;
- }
-
- /**
- * Removes all accounts which have been persistently stored.
- *
- * @see #removeStoredAccount(ProtocolProviderFactory, AccountID)
- */
- public void removeStoredAccounts()
- {
- synchronized (loadStoredAccountsQueue)
- {
- /*
- * Wait for the Thread which loads the stored account to complete so
- * that we can be sure later on that it will not load a stored
- * account while we are deleting it or another one for that matter.
- */
- boolean interrupted = false;
-
- while (loadStoredAccountsThread != null)
- try
- {
- loadStoredAccountsQueue.wait(LOAD_STORED_ACCOUNTS_TIMEOUT);
- }
- catch (InterruptedException ie)
- {
- interrupted = true;
- }
- if (interrupted)
- Thread.currentThread().interrupt();
-
- synchronized (this.storedAccounts)
- {
- AccountID[] storedAccounts
- = this.storedAccounts.toArray(
- new AccountID[this.storedAccounts.size()]);
-
- for (AccountID storedAccount : storedAccounts)
- {
- ProtocolProviderFactory ppf
- = ProtocolProviderActivator.getProtocolProviderFactory(
- storedAccount.getProtocolName());
-
- if (ppf != null)
- ppf.uninstallAccount(storedAccount);
- }
- }
- }
- }
-
- /**
- * Returns an <tt>Iterator</tt> over a list of all stored
- * <tt>AccountID</tt>s. The list of stored accounts include all registered
- * accounts and all disabled accounts. In other words in this list we could
- * find accounts that aren't loaded.
- * <p>
- * In order to check if an account is already loaded please use the
- * #isAccountLoaded(AccountID accountID) method. To load an account use the
- * #loadAccount(AccountID accountID) method.
- *
- * @return an <tt>Iterator</tt> over a list of all stored
- * <tt>AccountID</tt>s
- */
- public Collection<AccountID> getStoredAccounts()
- {
- synchronized (storedAccounts)
- {
- return new Vector<AccountID>(storedAccounts);
- }
- }
-
- /**
- * Loads the account corresponding to the given <tt>AccountID</tt>. An
- * account is loaded when its <tt>ProtocolProviderService</tt> is registered
- * in the bundle context. This method is meant to load the account through
- * the corresponding <tt>ProtocolProviderFactory</tt>.
- *
- * @param accountID the identifier of the account to load
- * @throws OperationFailedException if anything goes wrong while loading the
- * account corresponding to the specified <tt>accountID</tt>
- */
- public void loadAccount(AccountID accountID)
- throws OperationFailedException
- {
- // If the account with the given id is already loaded we have nothing
- // to do here.
- if (isAccountLoaded(accountID))
- return;
-
- ProtocolProviderFactory providerFactory
- = ProtocolProviderActivator.getProtocolProviderFactory(
- accountID.getProtocolName());
-
- if(providerFactory.loadAccount(accountID))
- {
- accountID.putAccountProperty(
- ProtocolProviderFactory.IS_ACCOUNT_DISABLED,
- String.valueOf(false));
- // Finally store the modified properties.
- storeAccount(providerFactory, accountID);
- }
- }
-
- /**
- * Unloads the account corresponding to the given <tt>AccountID</tt>. An
- * account is unloaded when its <tt>ProtocolProviderService</tt> is
- * unregistered in the bundle context. This method is meant to unload the
- * account through the corresponding <tt>ProtocolProviderFactory</tt>.
- *
- * @param accountID the identifier of the account to load
- * @throws OperationFailedException if anything goes wrong while unloading
- * the account corresponding to the specified <tt>accountID</tt>
- */
- public void unloadAccount(AccountID accountID)
- throws OperationFailedException
- {
- // If the account with the given id is already unloaded we have nothing
- // to do here.
- if (!isAccountLoaded(accountID))
- return;
-
- ProtocolProviderFactory providerFactory
- = ProtocolProviderActivator.getProtocolProviderFactory(
- accountID.getProtocolName());
-
- // Obtain the protocol provider.
- ServiceReference<ProtocolProviderService> serRef
- = providerFactory.getProviderForAccount(accountID);
-
- // If there's no such provider we have nothing to do here.
- if (serRef == null)
- return;
-
- ProtocolProviderService protocolProvider
- = bundleContext.getService(serRef);
-
- // Set the account icon path for unloaded accounts.
- String iconPathProperty = accountID.getAccountPropertyString(
- ProtocolProviderFactory.ACCOUNT_ICON_PATH);
-
- if (iconPathProperty == null)
- {
- accountID.putAccountProperty(
- ProtocolProviderFactory.ACCOUNT_ICON_PATH,
- protocolProvider.getProtocolIcon()
- .getIconPath(ProtocolIcon.ICON_SIZE_32x32));
- }
-
- accountID.putAccountProperty(
- ProtocolProviderFactory.IS_ACCOUNT_DISABLED,
- String.valueOf(true));
-
- if (!providerFactory.unloadAccount(accountID))
- {
- accountID.putAccountProperty(
- ProtocolProviderFactory.IS_ACCOUNT_DISABLED,
- String.valueOf(false));
- }
- // Finally store the modified properties.
- storeAccount(providerFactory, accountID);
- }
-
- /**
- * Checks if the account corresponding to the given <tt>accountID</tt> is
- * loaded. An account is loaded if its <tt>ProtocolProviderService</tt> is
- * registered in the bundle context. By default all accounts are loaded.
- * However the user could manually unload an account, which would be
- * unregistered from the bundle context, but would remain in the
- * configuration file.
- *
- * @param accountID the identifier of the account to load
- * @return <tt>true</tt> to indicate that the account with the given
- * <tt>accountID</tt> is loaded, <tt>false</tt> - otherwise
- */
- public boolean isAccountLoaded(AccountID accountID)
- {
- return storedAccounts.contains(accountID) && accountID.isEnabled();
- }
-
- private String stripPackagePrefix(String property)
- {
- int packageEndIndex = property.lastIndexOf('.');
-
- if (packageEndIndex != -1)
- property = property.substring(packageEndIndex + 1);
- return property;
- }
-}
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.service.protocol;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.credentialsstorage.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.util.*;
+import net.java.sip.communicator.util.Base64; //disambiguate from java.util.Base64
+
+import org.jitsi.service.configuration.*;
+import org.osgi.framework.*;
+
+/**
+ * Represents an implementation of <tt>AccountManager</tt> which loads the
+ * accounts in a separate thread.
+ *
+ * @author Lyubomir Marinov
+ * @author Yana Stamcheva
+ */
+public class AccountManager
+{
+ /**
+ * The delay in milliseconds the background <tt>Thread</tt> loading the
+ * stored accounts should wait before dying so that it doesn't get recreated
+ * for each <tt>ProtocolProviderFactory</tt> registration.
+ */
+ private static final long LOAD_STORED_ACCOUNTS_TIMEOUT = 30000;
+
+ /**
+ * The <tt>BundleContext</tt> this service is registered in.
+ */
+ private final BundleContext bundleContext;
+
+ /**
+ * The <tt>AccountManagerListener</tt>s currently interested in the
+ * events fired by this manager.
+ */
+ private final List<AccountManagerListener> listeners =
+ new LinkedList<AccountManagerListener>();
+
+ /**
+ * The queue of <tt>ProtocolProviderFactory</tt> services awaiting their
+ * stored accounts to be loaded.
+ */
+ private final Queue<ProtocolProviderFactory> loadStoredAccountsQueue =
+ new LinkedList<ProtocolProviderFactory>();
+
+ /**
+ * The <tt>Thread</tt> loading the stored accounts of the
+ * <tt>ProtocolProviderFactory</tt> services waiting in
+ * {@link #loadStoredAccountsQueue}.
+ */
+ private Thread loadStoredAccountsThread;
+
+ /**
+ * The <tt>Logger</tt> used by this <tt>AccountManagerImpl</tt> instance for
+ * logging output.
+ */
+ private final Logger logger = Logger.getLogger(AccountManager.class);
+
+ /**
+ * The list of <tt>AccountID</tt>s, corresponding to all stored accounts.
+ */
+ private final Vector<AccountID> storedAccounts = new Vector<AccountID>();
+
+ /**
+ * The prefix of the account unique identifier.
+ */
+ private static final String ACCOUNT_UID_PREFIX = "acc";
+
+ /**
+ * Initializes a new <tt>AccountManagerImpl</tt> instance loaded in a
+ * specific <tt>BundleContext</tt> (in which the caller will usually
+ * later register it).
+ *
+ * @param bundleContext the <tt>BundleContext</tt> in which the new
+ * instance is loaded (and in which the caller will usually later
+ * register it as a service)
+ */
+ public AccountManager(BundleContext bundleContext)
+ {
+ this.bundleContext = bundleContext;
+
+ this.bundleContext.addServiceListener(new ServiceListener()
+ {
+ public void serviceChanged(ServiceEvent serviceEvent)
+ {
+ AccountManager.this.serviceChanged(serviceEvent);
+ }
+ });
+ }
+
+ /**
+ * Implements AccountManager#addListener(AccountManagerListener).
+ * @param listener the <tt>AccountManagerListener</tt> to add
+ */
+ public void addListener(AccountManagerListener listener)
+ {
+ synchronized (listeners)
+ {
+ if (!listeners.contains(listener))
+ listeners.add(listener);
+ }
+ }
+
+ /**
+ * Loads the accounts stored for a specific
+ * <tt>ProtocolProviderFactory</tt>.
+ *
+ * @param factory the <tt>ProtocolProviderFactory</tt> to load the
+ * stored accounts of
+ */
+ private void doLoadStoredAccounts(ProtocolProviderFactory factory)
+ {
+ ConfigurationService configService
+ = ProtocolProviderActivator.getConfigurationService();
+ String factoryPackage = getFactoryImplPackageName(factory);
+ List<String> accounts
+ = configService.getPropertyNamesByPrefix(factoryPackage, true);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Discovered " + accounts.size() + " stored "
+ + factoryPackage + " accounts");
+
+ for (Iterator<String> storedAccountIter = accounts.iterator();
+ storedAccountIter.hasNext();)
+ {
+ String storedAccount = storedAccountIter.next();
+
+ // If the property is not related to an account we skip it.
+ int dotIndex = storedAccount.lastIndexOf(".");
+ if (!storedAccount.substring(dotIndex + 1)
+ .startsWith(ACCOUNT_UID_PREFIX))
+ continue;
+
+ if (logger.isDebugEnabled())
+ logger.debug("Loading account " + storedAccount);
+
+ List<String> storedAccountProperties =
+ configService.getPropertyNamesByPrefix(storedAccount, false);
+ Map<String, String> accountProperties =
+ new Hashtable<String, String>();
+ boolean disabled = false;
+ CredentialsStorageService credentialsStorage
+ = ServiceUtils.getService(
+ bundleContext,
+ CredentialsStorageService.class);
+
+ int prefLen = storedAccount.length() + 1;
+ for (Iterator<String> storedAccountPropertyIter
+ = storedAccountProperties.iterator();
+ storedAccountPropertyIter.hasNext();)
+ {
+ String property = storedAccountPropertyIter.next();
+ String value = configService.getString(property);
+
+ //strip the package prefix
+ if(prefLen > property.length())
+ continue;
+
+ property = property.substring(prefLen);
+
+ if (ProtocolProviderFactory.IS_ACCOUNT_DISABLED.equals(property))
+ disabled = Boolean.parseBoolean(value);
+ // Decode passwords.
+ else if (ProtocolProviderFactory.PASSWORD.equals(property)
+ && !credentialsStorage.isStoredEncrypted(storedAccount))
+ {
+ if ((value != null) && value.length() != 0)
+ {
+
+ /*
+ * TODO Converting byte[] to String using the platform's
+ * default charset may result in an invalid password.
+ */
+ value = new String(Base64.decode(value));
+ }
+ }
+
+ if (value != null)
+ accountProperties.put(property, value);
+ }
+
+ try
+ {
+ AccountID accountID = factory.createAccount(accountProperties);
+
+ // If for some reason the account id is not created we move to
+ // the next account.
+ if (accountID == null)
+ continue;
+
+ synchronized (storedAccounts)
+ {
+ storedAccounts.add(accountID);
+ }
+ if (!disabled)
+ factory.loadAccount(accountID);
+ }
+ catch (Exception ex)
+ {
+ /*
+ * Swallow the exception in order to prevent a single account
+ * from halting the loading of subsequent accounts.
+ */
+ logger.error("Failed to load account " + accountProperties, ex);
+ }
+ catch (ExceptionInInitializerError ex)
+ {
+ // In case we fail to instantiate the ProtocolProviderService.
+ logger.error(
+ "Failed to create account service instance for account "
+ + accountProperties, ex);
+ }
+ }
+ }
+
+ /**
+ * Notifies the registered {@link #listeners} that the stored accounts of a
+ * specific <tt>ProtocolProviderFactory</tt> have just been loaded.
+ *
+ * @param factory the <tt>ProtocolProviderFactory</tt> which had its
+ * stored accounts just loaded
+ */
+ private void fireStoredAccountsLoaded(ProtocolProviderFactory factory)
+ {
+ AccountManagerListener[] listeners;
+ synchronized (this.listeners)
+ {
+ listeners =
+ this.listeners
+ .toArray(new AccountManagerListener[this.listeners.size()]);
+ }
+
+ int listenerCount = listeners.length;
+ if (listenerCount > 0)
+ {
+ AccountManagerEvent event =
+ new AccountManagerEvent(this,
+ AccountManagerEvent.STORED_ACCOUNTS_LOADED, factory);
+
+ for (int listenerIndex = 0;
+ listenerIndex < listenerCount; listenerIndex++)
+ {
+ listeners[listenerIndex].handleAccountManagerEvent(event);
+ }
+ }
+ }
+
+ /**
+ * Returns the package name of the <tt>factory</tt>.
+ * @param factory the factory which package will be returned.
+ * @return the package name of the <tt>factory</tt>.
+ */
+ public String getFactoryImplPackageName(ProtocolProviderFactory factory)
+ {
+ String className = factory.getClass().getName();
+
+ return className.substring(0, className.lastIndexOf('.'));
+ }
+
+ /**
+ * Check for stored accounts for the supplied <tt>protocolName</tt>.
+ * @param protocolName the protocol name to check for
+ * @param includeHidden whether to include hidden providers
+ * @return <tt>true</tt> if there is any account stored in configuration
+ * service with <tt>protocolName</tt>, <tt>false</tt> otherwise.
+ */
+ public boolean hasStoredAccounts(String protocolName, boolean includeHidden)
+ {
+ return hasStoredAccount(protocolName, includeHidden, null);
+ }
+
+ /**
+ * Checks whether a stored account with <tt>userID</tt> is stored
+ * in configuration.
+ *
+ * @param protocolName the protocol name
+ * @param includeHidden whether to check hidden providers
+ * @param userID the user id to check.
+ * @return <tt>true</tt> if there is any account stored in configuration
+ * service with <tt>protocolName</tt> and <tt>userID</tt>,
+ * <tt>false</tt> otherwise.
+ */
+ public boolean hasStoredAccount(String protocolName,
+ boolean includeHidden,
+ String userID)
+ {
+ Collection<ServiceReference<ProtocolProviderFactory>> factoryRefs
+ = ServiceUtils.getServiceReferences(
+ bundleContext,
+ ProtocolProviderFactory.class);
+ boolean hasStoredAccounts = false;
+
+ if (!factoryRefs.isEmpty())
+ {
+ ConfigurationService configService
+ = ProtocolProviderActivator.getConfigurationService();
+
+ for (ServiceReference<ProtocolProviderFactory> factoryRef
+ : factoryRefs)
+ {
+ ProtocolProviderFactory factory
+ = bundleContext.getService(factoryRef);
+
+ if ((protocolName != null)
+ && !protocolName.equals(factory.getProtocolName()))
+ {
+ continue;
+ }
+
+ String factoryPackage = getFactoryImplPackageName(factory);
+ List<String> storedAccounts
+ = configService
+ .getPropertyNamesByPrefix(factoryPackage + ".acc",
+ false);
+
+ /* Ignore the hidden accounts. */
+ for (Iterator<String> storedAccountIter =
+ storedAccounts.iterator(); storedAccountIter.hasNext();)
+ {
+ String storedAccount = storedAccountIter.next();
+ List<String> storedAccountProperties =
+ configService.getPropertyNamesByPrefix(storedAccount,
+ true);
+ boolean hidden = false;
+ String accountUserID = null;
+
+ if (!includeHidden || userID != null)
+ {
+ for (Iterator<String> storedAccountPropertyIter =
+ storedAccountProperties.iterator();
+ storedAccountPropertyIter.hasNext();)
+ {
+ String property = storedAccountPropertyIter.next();
+ String value = configService.getString(property);
+
+ property = stripPackagePrefix(property);
+
+ if (ProtocolProviderFactory.IS_PROTOCOL_HIDDEN
+ .equals(property))
+ {
+ hidden = (value != null);
+ }
+ else if (ProtocolProviderFactory.USER_ID
+ .equals(property))
+ {
+ accountUserID = value;
+ }
+ }
+ }
+
+ if (includeHidden || !hidden)
+ {
+ if(accountUserID != null
+ && userID != null
+ && userID.equals(accountUserID))
+ {
+ hasStoredAccounts = true;
+ break;
+ }
+ else if(userID == null)
+ {
+ hasStoredAccounts = true;
+ break;
+ }
+ }
+ }
+
+ if (hasStoredAccounts || (protocolName != null))
+ {
+ break;
+ }
+ }
+ }
+ return hasStoredAccounts;
+ }
+
+ /**
+ * Searches for stored account with <tt>uid</tt> in stored
+ * configuration. The <tt>uid</tt> is the one generated when creating
+ * accounts with prefix <tt>ACCOUNT_UID_PREFIX</tt>.
+ *
+ * @return <tt>AccountID</tt> if there is any account stored in configuration
+ * service with <tt>uid</tt>,
+ * <tt>null</tt> otherwise.
+ */
+ public AccountID findAccountID(String uid)
+ {
+ Collection<ServiceReference<ProtocolProviderFactory>> factoryRefs
+ = ServiceUtils.getServiceReferences(
+ bundleContext,
+ ProtocolProviderFactory.class);
+
+ if (!factoryRefs.isEmpty())
+ {
+ ConfigurationService configService
+ = ProtocolProviderActivator.getConfigurationService();
+
+ for (ServiceReference<ProtocolProviderFactory> factoryRef
+ : factoryRefs)
+ {
+ ProtocolProviderFactory factory
+ = bundleContext.getService(factoryRef);
+
+ String factoryPackage = getFactoryImplPackageName(factory);
+ List<String> storedAccountsProps
+ = configService
+ .getPropertyNamesByPrefix(factoryPackage, true);
+
+ for (Iterator<String> storedAccountIter =
+ storedAccountsProps.iterator();
+ storedAccountIter.hasNext();)
+ {
+ String storedAccount = storedAccountIter.next();
+
+ if(!storedAccount.endsWith(uid))
+ continue;
+
+ String accountUID = configService.getString(
+ storedAccount //node id
+ + "." + ProtocolProviderFactory.ACCOUNT_UID);// propname
+
+ for(AccountID acc : storedAccounts)
+ {
+ if(acc.getAccountUniqueID().equals(accountUID))
+ return acc;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Loads the accounts stored for a specific
+ * <tt>ProtocolProviderFactory</tt> and notifies the registered
+ * {@link #listeners} that the stored accounts of the specified
+ * <tt>factory</tt> have just been loaded
+ *
+ * @param factory the <tt>ProtocolProviderFactory</tt> to load the
+ * stored accounts of
+ */
+ private void loadStoredAccounts(ProtocolProviderFactory factory)
+ {
+ doLoadStoredAccounts(factory);
+
+ fireStoredAccountsLoaded(factory);
+ }
+
+ /**
+ * Notifies this manager that a specific
+ * <tt>ProtocolProviderFactory</tt> has been registered as a service.
+ * The current implementation queues the specified <tt>factory</tt> to
+ * have its stored accounts as soon as possible.
+ *
+ * @param factory the <tt>ProtocolProviderFactory</tt> which has been
+ * registered as a service.
+ */
+ private void protocolProviderFactoryRegistered(
+ ProtocolProviderFactory factory)
+ {
+ queueLoadStoredAccounts(factory);
+ }
+
+ /**
+ * Queues a specific <tt>ProtocolProviderFactory</tt> to have its stored
+ * accounts loaded as soon as possible.
+ *
+ * @param factory the <tt>ProtocolProviderFactory</tt> to be queued for
+ * loading its stored accounts as soon as possible
+ */
+ private void queueLoadStoredAccounts(ProtocolProviderFactory factory)
+ {
+ synchronized (loadStoredAccountsQueue)
+ {
+ loadStoredAccountsQueue.add(factory);
+ loadStoredAccountsQueue.notifyAll();
+
+ if (loadStoredAccountsThread == null)
+ {
+ loadStoredAccountsThread = new Thread()
+ {
+ @Override
+ public void run()
+ {
+ runInLoadStoredAccountsThread();
+ }
+ };
+ loadStoredAccountsThread.setDaemon(true);
+ loadStoredAccountsThread.setName(
+ "AccountManager.loadStoredAccounts");
+ loadStoredAccountsThread.start();
+ }
+ }
+ }
+
+ /**
+ * Implements AccountManager#removeListener(AccountManagerListener).
+ * @param listener the <tt>AccountManagerListener</tt> to remove
+ */
+ public void removeListener(AccountManagerListener listener)
+ {
+ synchronized (listeners)
+ {
+ listeners.remove(listener);
+ }
+ }
+
+ /**
+ * Running in {@link #loadStoredAccountsThread}, loads the stored accounts
+ * of the <tt>ProtocolProviderFactory</tt> services waiting in
+ * {@link #loadStoredAccountsQueue}
+ */
+ private void runInLoadStoredAccountsThread()
+ {
+ boolean interrupted = false;
+ while (!interrupted)
+ {
+ try
+ {
+ ProtocolProviderFactory factory;
+
+ synchronized (loadStoredAccountsQueue)
+ {
+ factory = loadStoredAccountsQueue.poll();
+ if (factory == null)
+ {
+ /*
+ * Technically, we should be handing spurious wakeups.
+ * However, we cannot check the condition in a queue.
+ * Anyway, we just want to keep this Thread alive long
+ * enough to allow it to not be re-created multiple
+ * times and not handing a spurious wakeup will just
+ * cause such an inconvenience.
+ */
+ try
+ {
+ loadStoredAccountsQueue
+ .wait(LOAD_STORED_ACCOUNTS_TIMEOUT);
+ }
+ catch (InterruptedException ex)
+ {
+ logger
+ .warn(
+ "The loading of the stored accounts has"
+ + " been interrupted",
+ ex);
+ interrupted = true;
+ break;
+ }
+ factory = loadStoredAccountsQueue.poll();
+ }
+ if (factory != null)
+ loadStoredAccountsQueue.notifyAll();
+ }
+
+ if (factory != null)
+ {
+ try
+ {
+ loadStoredAccounts(factory);
+ }
+ catch (Exception ex)
+ {
+
+ /*
+ * Swallow the exception in order to prevent a single
+ * factory from halting the loading of subsequent
+ * factories.
+ */
+ logger.error("Failed to load accounts for " + factory,
+ ex);
+ }
+ }
+ }
+ finally
+ {
+ synchronized (loadStoredAccountsQueue)
+ {
+ if (!interrupted && (loadStoredAccountsQueue.size() <= 0))
+ {
+ if (loadStoredAccountsThread == Thread.currentThread())
+ {
+ loadStoredAccountsThread = null;
+ loadStoredAccountsQueue.notifyAll();
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Notifies this manager that an OSGi service has changed. The current
+ * implementation tracks the registrations of
+ * <tt>ProtocolProviderFactory</tt> services in order to queue them for
+ * loading their stored accounts.
+ *
+ * @param serviceEvent the <tt>ServiceEvent</tt> containing the event
+ * data
+ */
+ private void serviceChanged(ServiceEvent serviceEvent)
+ {
+ switch (serviceEvent.getType())
+ {
+ case ServiceEvent.REGISTERED:
+ Object service
+ = bundleContext.getService(serviceEvent.getServiceReference());
+
+ if (service instanceof ProtocolProviderFactory)
+ {
+ protocolProviderFactoryRegistered(
+ (ProtocolProviderFactory) service);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * Stores an account represented in the form of an <tt>AccountID</tt>
+ * created by a specific <tt>ProtocolProviderFactory</tt>.
+ *
+ * @param factory the <tt>ProtocolProviderFactory</tt> which created the
+ * account to be stored
+ * @param accountID the account in the form of <tt>AccountID</tt> to be
+ * stored
+ * @throws OperationFailedException if anything goes wrong while storing the
+ * account
+ */
+ public void storeAccount(
+ ProtocolProviderFactory factory,
+ AccountID accountID)
+ throws OperationFailedException
+ {
+ synchronized (storedAccounts)
+ {
+ if (!storedAccounts.contains(accountID))
+ storedAccounts.add(accountID);
+ }
+
+ ConfigurationService configurationService
+ = ProtocolProviderActivator.getConfigurationService();
+ String factoryPackage = getFactoryImplPackageName(factory);
+
+ String accountNodeName
+ = getAccountNodeName( factory,
+ accountID.getAccountUniqueID() );
+
+ Map<String, Object> configurationProperties
+ = new HashMap<String, Object>();
+
+ // Create a unique node name of the properties node that will contain
+ // this account's properties.
+ if (accountNodeName == null)
+ {
+ accountNodeName
+ = ACCOUNT_UID_PREFIX + Long.toString(System.currentTimeMillis());
+
+ // set a value for the persistent node so that we could later
+ // retrieve it as a property
+ configurationProperties.put(
+ factoryPackage /* prefix */ + "." + accountNodeName,
+ accountNodeName);
+
+ // register the account in the configuration service.
+ // we register all the properties in the following hierarchy
+ //net.java.sip.communicator.impl.protocol.PROTO_NAME.ACC_ID.PROP_NAME
+ configurationProperties.put(factoryPackage// prefix
+ + "." + accountNodeName // node name for the account id
+ + "." + ProtocolProviderFactory.ACCOUNT_UID, // propname
+ accountID.getAccountUniqueID()); // value
+ }
+
+ // store the rest of the properties
+ Map<String, String> accountProperties = accountID.getAccountProperties();
+
+ for (Map.Entry<String, String> entry : accountProperties.entrySet())
+ {
+ String property = entry.getKey();
+ String value = entry.getValue();
+ String secureStorePrefix = null;
+
+ // If the property is a password, store it securely.
+ if (property.equals(ProtocolProviderFactory.PASSWORD))
+ {
+ String accountPrefix = factoryPackage + "." + accountNodeName;
+ secureStorePrefix = accountPrefix;
+ }
+ else if(property.endsWith("." + ProtocolProviderFactory.PASSWORD))
+ {
+ secureStorePrefix = factoryPackage + "." + accountNodeName +
+ "." + property.substring(0, property.lastIndexOf("."));
+ }
+
+ if(secureStorePrefix != null)
+ {
+ CredentialsStorageService credentialsStorage
+ = ServiceUtils.getService(
+ bundleContext,
+ CredentialsStorageService.class);
+
+ // encrypt and store
+ if ((value != null)
+ && (value.length() != 0)
+ && !credentialsStorage.storePassword(
+ secureStorePrefix,
+ value))
+ {
+ throw
+ new OperationFailedException(
+ "CredentialsStorageService failed to"
+ + " storePassword",
+ OperationFailedException.GENERAL_ERROR);
+ }
+ }
+ else
+ {
+ configurationProperties.put(
+ factoryPackage // prefix
+ + "." + accountNodeName // a unique node name for the account id
+ + "." + property, // propname
+ value); // value
+ }
+ }
+
+ // clear the password if missing property, modification can request
+ // password delete
+ if(!accountProperties.containsKey(ProtocolProviderFactory.PASSWORD)
+ && // And only if it's not stored already in encrypted form.
+ // Account registration object clears also this property
+ // in order to forget the password
+ !configurationProperties.containsKey(
+ factoryPackage+"."+accountNodeName+".ENCRYPTED_PASSWORD"))
+ {
+ CredentialsStorageService credentialsStorage
+ = ServiceUtils.getService(
+ bundleContext,
+ CredentialsStorageService.class);
+ credentialsStorage.removePassword(
+ factoryPackage + "." + accountNodeName);
+ }
+
+ if (configurationProperties.size() > 0)
+ configurationService.setProperties(configurationProperties);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Stored account for id " + accountID.getAccountUniqueID()
+ + " for package " + factoryPackage);
+ }
+
+ /**
+ * Gets account node name under which account configuration properties are
+ * stored.
+ *
+ * @param factory account's protocol provider factory
+ * @param accountUID account for which the prefix will be returned
+ * @return configuration prefix for given <tt>accountID</tt> if exists or
+ * <tt>null</tt> otherwise
+ */
+ public String getAccountNodeName( ProtocolProviderFactory factory,
+ String accountUID )
+ {
+ ConfigurationService configurationService
+ = ProtocolProviderActivator.getConfigurationService();
+ String factoryPackage = getFactoryImplPackageName(factory);
+
+ // First check if such accountID already exists in the configuration.
+ List<String> storedAccounts =
+ configurationService.getPropertyNamesByPrefix(factoryPackage, true);
+ String accountNodeName = null;
+
+ for (Iterator<String> storedAccountIter = storedAccounts.iterator();
+ storedAccountIter.hasNext();)
+ {
+ String storedAccount = storedAccountIter.next();
+
+ // If the property is not related to an account we skip it.
+ int dotIndex = storedAccount.lastIndexOf(".");
+ if (!storedAccount.substring(dotIndex + 1)
+ .startsWith(ACCOUNT_UID_PREFIX))
+ continue;
+
+ String storedAccountUID
+ = configurationService.getString(
+ storedAccount + "." + ProtocolProviderFactory.ACCOUNT_UID);
+
+ if(storedAccountUID == null)
+ continue;
+
+ if (storedAccountUID.equals(accountUID))
+ accountNodeName = configurationService.getString(storedAccount);
+ }
+ return accountNodeName;
+ }
+
+ /**
+ * Removes the account with <tt>accountID</tt> from the set of accounts
+ * that are persistently stored inside the configuration service.
+ *
+ * @param factory the <tt>ProtocolProviderFactory</tt> which created the
+ * account to be stored
+ * @param accountID the AccountID of the account to remove.
+ * @return true if an account has been removed and false otherwise.
+ */
+ public boolean removeStoredAccount(ProtocolProviderFactory factory,
+ AccountID accountID)
+ {
+ synchronized (storedAccounts)
+ {
+ if (storedAccounts.contains(accountID))
+ storedAccounts.remove(accountID);
+ }
+
+ /*
+ * We're already doing it in #unloadAccount(AccountID) - we're figuring
+ * out the ProtocolProviderFactory by the AccountID.
+ */
+ if (factory == null)
+ {
+ factory
+ = ProtocolProviderActivator.getProtocolProviderFactory(
+ accountID.getProtocolName());
+ }
+
+ String factoryPackage = getFactoryImplPackageName(factory);
+
+ // remove the stored password explicitly using credentials service
+ CredentialsStorageService credentialsStorage
+ = ServiceUtils.getService(
+ bundleContext,
+ CredentialsStorageService.class);
+ String accountPrefix =
+ ProtocolProviderFactory.findAccountPrefix(bundleContext, accountID,
+ factoryPackage);
+
+ credentialsStorage.removePassword(accountPrefix);
+
+ ConfigurationService configurationService
+ = ServiceUtils.getService(
+ bundleContext,
+ ConfigurationService.class);
+ //first retrieve all accounts that we've registered
+ List<String> storedAccounts
+ = configurationService.getPropertyNamesByPrefix(
+ factoryPackage, true);
+
+ //find an account with the corresponding id.
+ for (String accountRootPropertyName : storedAccounts)
+ {
+ //unregister the account in the configuration service.
+ //all the properties must have been registered in the following
+ //hierarchy:
+ //net.java.sip.communicator.impl.protocol.PROTO_NAME.ACC_ID.PROP_NAME
+ String accountUID = configurationService.getString(
+ accountRootPropertyName //node id
+ + "." + ProtocolProviderFactory.ACCOUNT_UID); // propname
+
+ if (accountID.getAccountUniqueID().equals(accountUID))
+ {
+ //retrieve the names of all properties registered for the
+ //current account.
+ List<String> accountPropertyNames
+ = configurationService.getPropertyNamesByPrefix(
+ accountRootPropertyName, false);
+
+ //set all account properties to null in order to remove them.
+ for (String propName : accountPropertyNames)
+ configurationService.setProperty(propName, null);
+
+ //and now remove the parent too.
+ configurationService.setProperty(accountRootPropertyName, null);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Removes all accounts which have been persistently stored.
+ *
+ * @see #removeStoredAccount(ProtocolProviderFactory, AccountID)
+ */
+ public void removeStoredAccounts()
+ {
+ synchronized (loadStoredAccountsQueue)
+ {
+ /*
+ * Wait for the Thread which loads the stored account to complete so
+ * that we can be sure later on that it will not load a stored
+ * account while we are deleting it or another one for that matter.
+ */
+ boolean interrupted = false;
+
+ while (loadStoredAccountsThread != null)
+ try
+ {
+ loadStoredAccountsQueue.wait(LOAD_STORED_ACCOUNTS_TIMEOUT);
+ }
+ catch (InterruptedException ie)
+ {
+ interrupted = true;
+ }
+ if (interrupted)
+ Thread.currentThread().interrupt();
+
+ synchronized (this.storedAccounts)
+ {
+ AccountID[] storedAccounts
+ = this.storedAccounts.toArray(
+ new AccountID[this.storedAccounts.size()]);
+
+ for (AccountID storedAccount : storedAccounts)
+ {
+ ProtocolProviderFactory ppf
+ = ProtocolProviderActivator.getProtocolProviderFactory(
+ storedAccount.getProtocolName());
+
+ if (ppf != null)
+ ppf.uninstallAccount(storedAccount);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns an <tt>Iterator</tt> over a list of all stored
+ * <tt>AccountID</tt>s. The list of stored accounts include all registered
+ * accounts and all disabled accounts. In other words in this list we could
+ * find accounts that aren't loaded.
+ * <p>
+ * In order to check if an account is already loaded please use the
+ * #isAccountLoaded(AccountID accountID) method. To load an account use the
+ * #loadAccount(AccountID accountID) method.
+ *
+ * @return an <tt>Iterator</tt> over a list of all stored
+ * <tt>AccountID</tt>s
+ */
+ public Collection<AccountID> getStoredAccounts()
+ {
+ synchronized (storedAccounts)
+ {
+ return new Vector<AccountID>(storedAccounts);
+ }
+ }
+
+ /**
+ * Loads the account corresponding to the given <tt>AccountID</tt>. An
+ * account is loaded when its <tt>ProtocolProviderService</tt> is registered
+ * in the bundle context. This method is meant to load the account through
+ * the corresponding <tt>ProtocolProviderFactory</tt>.
+ *
+ * @param accountID the identifier of the account to load
+ * @throws OperationFailedException if anything goes wrong while loading the
+ * account corresponding to the specified <tt>accountID</tt>
+ */
+ public void loadAccount(AccountID accountID)
+ throws OperationFailedException
+ {
+ // If the account with the given id is already loaded we have nothing
+ // to do here.
+ if (isAccountLoaded(accountID))
+ return;
+
+ ProtocolProviderFactory providerFactory
+ = ProtocolProviderActivator.getProtocolProviderFactory(
+ accountID.getProtocolName());
+
+ if(providerFactory.loadAccount(accountID))
+ {
+ accountID.putAccountProperty(
+ ProtocolProviderFactory.IS_ACCOUNT_DISABLED,
+ String.valueOf(false));
+ // Finally store the modified properties.
+ storeAccount(providerFactory, accountID);
+ }
+ }
+
+ /**
+ * Unloads the account corresponding to the given <tt>AccountID</tt>. An
+ * account is unloaded when its <tt>ProtocolProviderService</tt> is
+ * unregistered in the bundle context. This method is meant to unload the
+ * account through the corresponding <tt>ProtocolProviderFactory</tt>.
+ *
+ * @param accountID the identifier of the account to load
+ * @throws OperationFailedException if anything goes wrong while unloading
+ * the account corresponding to the specified <tt>accountID</tt>
+ */
+ public void unloadAccount(AccountID accountID)
+ throws OperationFailedException
+ {
+ // If the account with the given id is already unloaded we have nothing
+ // to do here.
+ if (!isAccountLoaded(accountID))
+ return;
+
+ ProtocolProviderFactory providerFactory
+ = ProtocolProviderActivator.getProtocolProviderFactory(
+ accountID.getProtocolName());
+
+ // Obtain the protocol provider.
+ ServiceReference<ProtocolProviderService> serRef
+ = providerFactory.getProviderForAccount(accountID);
+
+ // If there's no such provider we have nothing to do here.
+ if (serRef == null)
+ return;
+
+ ProtocolProviderService protocolProvider
+ = bundleContext.getService(serRef);
+
+ // Set the account icon path for unloaded accounts.
+ String iconPathProperty = accountID.getAccountPropertyString(
+ ProtocolProviderFactory.ACCOUNT_ICON_PATH);
+
+ if (iconPathProperty == null)
+ {
+ accountID.putAccountProperty(
+ ProtocolProviderFactory.ACCOUNT_ICON_PATH,
+ protocolProvider.getProtocolIcon()
+ .getIconPath(ProtocolIcon.ICON_SIZE_32x32));
+ }
+
+ accountID.putAccountProperty(
+ ProtocolProviderFactory.IS_ACCOUNT_DISABLED,
+ String.valueOf(true));
+
+ if (!providerFactory.unloadAccount(accountID))
+ {
+ accountID.putAccountProperty(
+ ProtocolProviderFactory.IS_ACCOUNT_DISABLED,
+ String.valueOf(false));
+ }
+ // Finally store the modified properties.
+ storeAccount(providerFactory, accountID);
+ }
+
+ /**
+ * Checks if the account corresponding to the given <tt>accountID</tt> is
+ * loaded. An account is loaded if its <tt>ProtocolProviderService</tt> is
+ * registered in the bundle context. By default all accounts are loaded.
+ * However the user could manually unload an account, which would be
+ * unregistered from the bundle context, but would remain in the
+ * configuration file.
+ *
+ * @param accountID the identifier of the account to load
+ * @return <tt>true</tt> to indicate that the account with the given
+ * <tt>accountID</tt> is loaded, <tt>false</tt> - otherwise
+ */
+ public boolean isAccountLoaded(AccountID accountID)
+ {
+ return storedAccounts.contains(accountID) && accountID.isEnabled();
+ }
+
+ private String stripPackagePrefix(String property)
+ {
+ int packageEndIndex = property.lastIndexOf('.');
+
+ if (packageEndIndex != -1)
+ property = property.substring(packageEndIndex + 1);
+ return property;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/protocol/AccountManagerUtils.java b/src/net/java/sip/communicator/service/protocol/AccountManagerUtils.java
index 5b64e06..1400a2d 100644
--- a/src/net/java/sip/communicator/service/protocol/AccountManagerUtils.java
+++ b/src/net/java/sip/communicator/service/protocol/AccountManagerUtils.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,168 +15,168 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.protocol;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.event.*;
-
-import org.osgi.framework.*;
-
-/**
- * Provides utilities to aid the manipulation of {@link AccountManager}.
- *
- * @author Lyubomir Marinov
- */
-public final class AccountManagerUtils
-{
- private static AccountManager getAccountManager(BundleContext bundleContext)
- {
- return
- bundleContext.getService(
- bundleContext.getServiceReference(AccountManager.class));
- }
-
- /**
- * Starts a specific <code>Bundle</code> and waits for the
- * <code>AccountManager</code> available in a specific
- * <code>BundleContext</code> to load the stored accounts of a
- * <code>ProtocolProviderFactory</code> with a specific protocol name.
- *
- * @param bundleContextWithAccountManager
- * the <code>BundleContext</code> in which an
- * <code>AccountManager</code> service is registered
- * @param bundleToStart
- * the <code>Bundle</code> to be started
- * @param protocolNameToWait
- * the protocol name of a <code>ProtocolProviderFactory</code> to
- * wait the end of the loading of the stored accounts for
- * @throws BundleException
- * @throws InterruptedException
- * if any thread interrupted the current thread before or while
- * the current thread was waiting for the loading of the stored
- * accounts
- */
- public static void startBundleAndWaitStoredAccountsLoaded(
- BundleContext bundleContextWithAccountManager,
- final Bundle bundleToStart,
- final String protocolNameToWait)
- throws BundleException,
- InterruptedException
- {
- AccountManager accountManager
- = getAccountManager(bundleContextWithAccountManager);
- final boolean[] storedAccountsAreLoaded = new boolean[1];
- AccountManagerListener listener = new AccountManagerListener()
- {
- public void handleAccountManagerEvent(AccountManagerEvent event)
- {
- if (AccountManagerEvent.STORED_ACCOUNTS_LOADED
- != event.getType())
- return;
-
- ProtocolProviderFactory factory = event.getFactory();
-
- /*
- * If the event is for a factory with a protocol name other than
- * protocolNameToWait, it's not the one we're waiting for.
- */
- if ((factory != null)
- && !protocolNameToWait
- .equals(factory.getProtocolName()))
- return;
-
- /*
- * If the event if for a factory which is no longer registered,
- * then it's not the one we're waiting for because we're waiting
- * for the specified bundle to start and register a factory.
- */
- if (factory != null)
- {
- BundleContext bundleContext
- = bundleToStart.getBundleContext();
-
- /*
- * If the specified bundle still hasn't started, the event
- * cannot be the one we're waiting for.
- */
- if (bundleContext == null)
- return;
-
- Collection<ServiceReference<ProtocolProviderFactory>> factoryRefs;
-
- try
- {
- factoryRefs
- = bundleContext.getServiceReferences(
- ProtocolProviderFactory.class,
- "("
- + ProtocolProviderFactory.PROTOCOL
- + "="
- + protocolNameToWait
- + ")");
- }
- catch (InvalidSyntaxException isex)
- {
- /*
- * Not likely so ignore it and assume the event is for
- * a valid factory.
- */
- factoryRefs = null;
- }
- if ((factoryRefs != null) && !factoryRefs.isEmpty())
- {
- boolean factoryIsRegistered = false;
-
- for (ServiceReference<ProtocolProviderFactory> factoryRef
- : factoryRefs)
- {
- if (factory == bundleContext.getService(factoryRef))
- {
- factoryIsRegistered = true;
- break;
- }
- }
- if (!factoryIsRegistered)
- return;
- }
- }
-
- synchronized (storedAccountsAreLoaded)
- {
- storedAccountsAreLoaded[0] = true;
- storedAccountsAreLoaded.notify();
- }
- }
- };
-
- accountManager.addListener(listener);
- try
- {
- bundleToStart.start();
-
- while (true)
- {
- synchronized (storedAccountsAreLoaded)
- {
- if (storedAccountsAreLoaded[0])
- {
- break;
- }
- storedAccountsAreLoaded.wait();
- }
- }
- }
- finally
- {
- accountManager.removeListener(listener);
- }
- }
-
- /**
- * Prevents the creation of <code>AccountManagerUtils</code> instances.
- */
- private AccountManagerUtils()
- {
- }
-}
+package net.java.sip.communicator.service.protocol;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.event.*;
+
+import org.osgi.framework.*;
+
+/**
+ * Provides utilities to aid the manipulation of {@link AccountManager}.
+ *
+ * @author Lyubomir Marinov
+ */
+public final class AccountManagerUtils
+{
+ private static AccountManager getAccountManager(BundleContext bundleContext)
+ {
+ return
+ bundleContext.getService(
+ bundleContext.getServiceReference(AccountManager.class));
+ }
+
+ /**
+ * Starts a specific <code>Bundle</code> and waits for the
+ * <code>AccountManager</code> available in a specific
+ * <code>BundleContext</code> to load the stored accounts of a
+ * <code>ProtocolProviderFactory</code> with a specific protocol name.
+ *
+ * @param bundleContextWithAccountManager
+ * the <code>BundleContext</code> in which an
+ * <code>AccountManager</code> service is registered
+ * @param bundleToStart
+ * the <code>Bundle</code> to be started
+ * @param protocolNameToWait
+ * the protocol name of a <code>ProtocolProviderFactory</code> to
+ * wait the end of the loading of the stored accounts for
+ * @throws BundleException
+ * @throws InterruptedException
+ * if any thread interrupted the current thread before or while
+ * the current thread was waiting for the loading of the stored
+ * accounts
+ */
+ public static void startBundleAndWaitStoredAccountsLoaded(
+ BundleContext bundleContextWithAccountManager,
+ final Bundle bundleToStart,
+ final String protocolNameToWait)
+ throws BundleException,
+ InterruptedException
+ {
+ AccountManager accountManager
+ = getAccountManager(bundleContextWithAccountManager);
+ final boolean[] storedAccountsAreLoaded = new boolean[1];
+ AccountManagerListener listener = new AccountManagerListener()
+ {
+ public void handleAccountManagerEvent(AccountManagerEvent event)
+ {
+ if (AccountManagerEvent.STORED_ACCOUNTS_LOADED
+ != event.getType())
+ return;
+
+ ProtocolProviderFactory factory = event.getFactory();
+
+ /*
+ * If the event is for a factory with a protocol name other than
+ * protocolNameToWait, it's not the one we're waiting for.
+ */
+ if ((factory != null)
+ && !protocolNameToWait
+ .equals(factory.getProtocolName()))
+ return;
+
+ /*
+ * If the event if for a factory which is no longer registered,
+ * then it's not the one we're waiting for because we're waiting
+ * for the specified bundle to start and register a factory.
+ */
+ if (factory != null)
+ {
+ BundleContext bundleContext
+ = bundleToStart.getBundleContext();
+
+ /*
+ * If the specified bundle still hasn't started, the event
+ * cannot be the one we're waiting for.
+ */
+ if (bundleContext == null)
+ return;
+
+ Collection<ServiceReference<ProtocolProviderFactory>> factoryRefs;
+
+ try
+ {
+ factoryRefs
+ = bundleContext.getServiceReferences(
+ ProtocolProviderFactory.class,
+ "("
+ + ProtocolProviderFactory.PROTOCOL
+ + "="
+ + protocolNameToWait
+ + ")");
+ }
+ catch (InvalidSyntaxException isex)
+ {
+ /*
+ * Not likely so ignore it and assume the event is for
+ * a valid factory.
+ */
+ factoryRefs = null;
+ }
+ if ((factoryRefs != null) && !factoryRefs.isEmpty())
+ {
+ boolean factoryIsRegistered = false;
+
+ for (ServiceReference<ProtocolProviderFactory> factoryRef
+ : factoryRefs)
+ {
+ if (factory == bundleContext.getService(factoryRef))
+ {
+ factoryIsRegistered = true;
+ break;
+ }
+ }
+ if (!factoryIsRegistered)
+ return;
+ }
+ }
+
+ synchronized (storedAccountsAreLoaded)
+ {
+ storedAccountsAreLoaded[0] = true;
+ storedAccountsAreLoaded.notify();
+ }
+ }
+ };
+
+ accountManager.addListener(listener);
+ try
+ {
+ bundleToStart.start();
+
+ while (true)
+ {
+ synchronized (storedAccountsAreLoaded)
+ {
+ if (storedAccountsAreLoaded[0])
+ {
+ break;
+ }
+ storedAccountsAreLoaded.wait();
+ }
+ }
+ }
+ finally
+ {
+ accountManager.removeListener(listener);
+ }
+ }
+
+ /**
+ * Prevents the creation of <code>AccountManagerUtils</code> instances.
+ */
+ private AccountManagerUtils()
+ {
+ }
+}
diff --git a/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java b/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java
index 6f07bd1..e2af0a8 100644
--- a/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java
+++ b/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java
@@ -25,8 +25,7 @@ import net.java.sip.communicator.service.protocol.event.*;
* Represents an ad-hoc rendez-vous point where multiple chat users could
* communicate together. This interface describes the main methods used by some
* protocols for multi user chat, without useless methods (such as kicking a
- * participant) which aren't supported by these protocols (MSN, ICQ, Yahoo!,
- * etc.).
+ * participant) which aren't supported by these protocols (MSN, ICQ, etc.).
*
* <tt>AdHocChatRoom</tt> acts like a simplified <tt>ChatRoom</tt>.
*
diff --git a/src/net/java/sip/communicator/service/protocol/Call.java b/src/net/java/sip/communicator/service/protocol/Call.java
index d342373..a952cfd 100644
--- a/src/net/java/sip/communicator/service/protocol/Call.java
+++ b/src/net/java/sip/communicator/service/protocol/Call.java
@@ -111,6 +111,13 @@ public abstract class Call
private boolean isAutoAnswer = false;
/**
+ * The indicator which determines whether any telephony conference
+ * represented by this instance is mixing or relaying.
+ * By default what can be mixed is mixed (audio) and rest is relayed.
+ */
+ protected final boolean useTranslator;
+
+ /**
* Creates a new Call instance.
*
* @param sourceProvider the proto provider that created us.
@@ -133,6 +140,11 @@ public abstract class Call
= accountID.getAccountPropertyBoolean(
ProtocolProviderFactory.DEFAULT_SIPZRTP_ATTRIBUTE,
true);
+
+ useTranslator
+ = accountID.getAccountPropertyBoolean(
+ ProtocolProviderFactory.USE_TRANSLATOR_IN_CONFERENCE,
+ false);
}
/**
diff --git a/src/net/java/sip/communicator/service/protocol/CallConference.java b/src/net/java/sip/communicator/service/protocol/CallConference.java
index 890b0cb..b6752cd 100644
--- a/src/net/java/sip/communicator/service/protocol/CallConference.java
+++ b/src/net/java/sip/communicator/service/protocol/CallConference.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,931 +15,931 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.protocol;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.event.*;
-
-import org.jitsi.util.event.*;
-
-/**
- * Represents the telephony conference-related state of a <tt>Call</tt>.
- * Multiple <tt>Call</tt> instances share a single <tt>CallConference</tt>
- * instance when the former are into a telephony conference i.e. the local
- * peer/user is the conference focus. <tt>CallConference</tt> is
- * protocol-agnostic and thus enables cross-protocol conferences. Since a
- * non-conference <tt>Call</tt> may be converted into a conference <tt>Call</tt>
- * at any time, every <tt>Call</tt> instance maintains a <tt>CallConference</tt>
- * instance regardless of whether the <tt>Call</tt> in question is participating
- * in a telephony conference.
- *
- * @author Lyubomir Marinov
- */
-public class CallConference
- extends PropertyChangeNotifier
-{
- /**
- * The name of the <tt>CallConference</tt> property which specifies the list
- * of <tt>Call</tt>s participating in a telephony conference. A change in
- * the value of the property is delivered in the form of a
- * <tt>PropertyChangeEvent</tt> which has its <tt>oldValue</tt> or
- * <tt>newValue</tt> set to the <tt>Call</tt> which has been removed or
- * added to the list of <tt>Call</tt>s participating in the telephony
- * conference.
- */
- public static final String CALLS = "calls";
-
- /**
- * Gets the number of <tt>CallPeer</tt>s associated with the <tt>Call</tt>s
- * participating in the telephony conference-related state of a specific
- * <tt>Call</tt>.
- *
- * @param call the <tt>Call</tt> for which the number of <tt>CallPeer</tt>s
- * associated with the <tt>Call</tt>s participating in its associated
- * telephony conference-related state
- * @return the number of <tt>CallPeer</tt>s associated with the
- * <tt>Call</tt>s participating in the telephony conference-related state
- * of the specified <tt>Call</tt>
- */
- public static int getCallPeerCount(Call call)
- {
- CallConference conference = call.getConference();
-
- /*
- * A Call instance is supposed to always maintain a CallConference
- * instance. Anyway, if it turns out that it is not the case, we will
- * consider the Call as a representation of a telephony conference.
- */
- return
- (conference == null)
- ? call.getCallPeerCount()
- : conference.getCallPeerCount();
- }
-
- /**
- * Gets a list of the <tt>CallPeer</tt>s associated with the <tt>Call</tt>s
- * participating in the telephony conference in which a specific
- * <tt>Call</tt> is participating.
- *
- * @param call the <tt>Call</tt> which specifies the telephony conference
- * the <tt>CallPeer</tt>s of which are to be retrieved
- * @return a list of the <tt>CallPeer</tt>s associated with the
- * <tt>Call</tt>s participating in the telephony conference in which the
- * specified <tt>call</tt> is participating
- */
- public static List<CallPeer> getCallPeers(Call call)
- {
- CallConference conference = call.getConference();
- List<CallPeer> callPeers = new ArrayList<CallPeer>();
-
- if (conference == null)
- {
- Iterator<? extends CallPeer> callPeerIt = call.getCallPeers();
-
- while (callPeerIt.hasNext())
- callPeers.add(callPeerIt.next());
- }
- else
- conference.getCallPeers(callPeers);
- return callPeers;
- }
-
- /**
- * Gets the list of <tt>Call</tt>s participating in the telephony conference
- * in which a specific <tt>Call</tt> is participating.
- *
- * @param call the <tt>Call</tt> which participates in the telephony
- * conference the list of participating <tt>Call</tt>s of which is to be
- * returned
- * @return the list of <tt>Call</tt>s participating in the telephony
- * conference in which the specified <tt>call</tt> is participating
- */
- public static List<Call> getCalls(Call call)
- {
- CallConference conference = call.getConference();
- List<Call> calls;
-
- if (conference == null)
- calls = Collections.emptyList();
- else
- calls = conference.getCalls();
- return calls;
- }
-
- /**
- * Determines whether a <tt>CallConference</tt> is to report the local
- * peer/user as a conference focus judging by a specific list of
- * <tt>Call</tt>s.
- *
- * @param calls the list of <tt>Call</tt> which are to be judged whether
- * the local peer/user that they represent is to be considered as a
- * conference focus
- * @return <tt>true</tt> if the local peer/user represented by the specified
- * <tt>calls</tt> is judged to be a conference focus; otherwise,
- * <tt>false</tt>
- */
- private static boolean isConferenceFocus(List<Call> calls)
- {
- int callCount = calls.size();
- boolean conferenceFocus;
-
- if (callCount < 1)
- conferenceFocus = false;
- else if (callCount > 1)
- conferenceFocus = true;
- else
- conferenceFocus = (calls.get(0).getCallPeerCount() > 1);
- return conferenceFocus;
- }
-
- /**
- * The <tt>CallChangeListener</tt> which listens to changes in the
- * <tt>Call</tt>s participating in this telephony conference.
- */
- private final CallChangeListener callChangeListener
- = new CallChangeListener()
- {
- @Override
- public void callPeerAdded(CallPeerEvent ev)
- {
- CallConference.this.onCallPeerEvent(ev);
- }
-
- @Override
- public void callPeerRemoved(CallPeerEvent ev)
- {
- CallConference.this.onCallPeerEvent(ev);
- }
-
- @Override
- public void callStateChanged(CallChangeEvent ev)
- {
- CallConference.this.callStateChanged(ev);
- }
- };
-
- /**
- * The list of <tt>CallChangeListener</tt>s added to the <tt>Call</tt>s
- * participating in this telephony conference via
- * {@link #addCallChangeListener(CallChangeListener)}.
- */
- private final List<CallChangeListener> callChangeListeners
- = new LinkedList<CallChangeListener>();
-
- /**
- * The <tt>CallPeerConferenceListener</tt> which listens to the
- * <tt>CallPeer</tt>s associated with the <tt>Call</tt>s participating in
- * this telephony conference.
- */
- private final CallPeerConferenceListener callPeerConferenceListener
- = new CallPeerConferenceAdapter()
- {
- /**
- * {@inheritDoc}
- *
- * Invokes
- * {@link CallConference#onCallPeerConferenceEvent(
- * CallPeerConferenceEvent)}.
- */
- @Override
- protected void onCallPeerConferenceEvent(CallPeerConferenceEvent ev)
- {
- CallConference.this.onCallPeerConferenceEvent(ev);
- }
-
- /**
- * {@inheritDoc}
- *
- * Invokes
- * {@link CallConference#onCallPeerConferenceEvent(
- * CallPeerConferenceEvent)}.
- */
- @Override
- public void conferenceMemberErrorReceived(
- CallPeerConferenceEvent ev)
- {
- CallConference.this.onCallPeerConferenceEvent(ev);
- }
- };
-
- /**
- * The list of <tt>CallPeerConferenceListener</tt>s added to the
- * <tt>CallPeer</tt>s associated with the <tt>CallPeer</tt>s participating
- * in this telephony conference via
- * {@link #addCallPeerConferenceListener}.
- */
- private final List<CallPeerConferenceListener> callPeerConferenceListeners
- = new LinkedList<CallPeerConferenceListener>();
-
- /**
- * The synchronization root/<tt>Object</tt> which protects the access to
- * {@link #immutableCalls} and {@link #mutableCalls}.
- */
- private final Object callsSyncRoot = new Object();
-
- /**
- * The indicator which determines whether the local peer represented by this
- * instance and the <tt>Call</tt>s participating in it is acting as a
- * conference focus. The SIP protocol, for example, will add the
- * &quot;isfocus&quot; parameter to the Contact headers of its outgoing
- * signaling if <tt>true</tt>.
- */
- private boolean conferenceFocus = false;
-
- /**
- * The list of <tt>Call</tt>s participating in this telephony conference as
- * an immutable <tt>List</tt> which can be exposed out of this instance
- * without the need to make a copy. In other words, it is an unmodifiable
- * view of {@link #mutableCalls}.
- */
- private List<Call> immutableCalls;
-
- /**
- * The indicator which determines whether the telephony conference
- * represented by this instance is utilizing the Jitsi Videobridge
- * server-side telephony conferencing technology.
- */
- private final boolean jitsiVideobridge;
-
- /**
- * The list of <tt>Call</tt>s participating in this telephony conference as
- * a mutable <tt>List</tt> which should not be exposed out of this instance.
- */
- private List<Call> mutableCalls;
-
- /**
- * Initializes a new <tt>CallConference</tt> instance.
- */
- public CallConference()
- {
- this(false);
- }
-
- /**
- * Initializes a new <tt>CallConference</tt> instance which is to optionally
- * utilize the Jitsi Videobridge server-side telephony conferencing
- * technology.
- *
- * @param jitsiVideobridge <tt>true</tt> if the telephony conference
- * represented by the new instance is to utilize the Jitsi Videobridge
- * server-side telephony conferencing technology; otherwise, <tt>false</tt>
- */
- public CallConference(boolean jitsiVideobridge)
- {
- this.jitsiVideobridge = jitsiVideobridge;
-
- mutableCalls = new ArrayList<Call>();
- immutableCalls = Collections.unmodifiableList(mutableCalls);
- }
-
- /**
- * Adds a specific <tt>Call</tt> to the list of <tt>Call</tt>s participating
- * in this telephony conference.
- *
- * @param call the <tt>Call</tt> to add to the list of <tt>Call</tt>s
- * participating in this telephony conference
- * @return <tt>true</tt> if the list of <tt>Call</tt>s participating in this
- * telephony conference changed as a result of the method call; otherwise,
- * <tt>false</tt>
- * @throws NullPointerException if <tt>call</tt> is <tt>null</tt>
- */
- boolean addCall(Call call)
- {
- if (call == null)
- throw new NullPointerException("call");
-
- synchronized (callsSyncRoot)
- {
- if (mutableCalls.contains(call))
- return false;
-
- /*
- * Implement the List of Calls participating in this telephony
- * conference as a copy-on-write storage in order to optimize the
- * getCalls method which is likely to be executed much more often
- * than the addCall and removeCall methods.
- */
- List<Call> newMutableCalls = new ArrayList<Call>(mutableCalls);
-
- if (newMutableCalls.add(call))
- {
- mutableCalls = newMutableCalls;
- immutableCalls = Collections.unmodifiableList(mutableCalls);
- }
- else
- return false;
- }
-
- callAdded(call);
- return true;
- }
-
- /**
- * Adds a <tt>CallChangeListener</tt> to the <tt>Call</tt>s participating in
- * this telephony conference. The method is a convenience that takes on the
- * responsibility of tracking the <tt>Call</tt>s that get added/removed
- * to/from this telephony conference.
- *
- * @param listener the <tt>CallChangeListner</tt> to be added to the
- * <tt>Call</tt>s participating in this telephony conference
- * @throws NullPointerException if <tt>listener</tt> is <tt>null</tt>
- */
- public void addCallChangeListener(CallChangeListener listener)
- {
- if (listener == null)
- throw new NullPointerException("listener");
- else
- {
- synchronized (callChangeListeners)
- {
- if (!callChangeListeners.contains(listener))
- callChangeListeners.add(listener);
- }
- }
- }
-
- /**
- * Adds {@link #callPeerConferenceListener} to the <tt>CallPeer</tt>s
- * associated with a specific <tt>Call</tt>.
- *
- * @param call the <tt>Call</tt> to whose associated <tt>CallPeer</tt>s
- * <tt>callPeerConferenceListener</tt> is to be added
- */
- private void addCallPeerConferenceListener(Call call)
- {
- Iterator<? extends CallPeer> callPeerIter = call.getCallPeers();
-
- while (callPeerIter.hasNext())
- {
- callPeerIter.next().addCallPeerConferenceListener(
- callPeerConferenceListener);
- }
- }
-
- /**
- * Adds a <tt>CallPeerConferenceListener</tt> to the <tt>CallPeer</tt>s
- * associated with the <tt>Call</tt>s participating in this telephony
- * conference. The method is a convenience that takes on the responsibility
- * of tracking the <tt>Call</tt>s that get added/removed to/from this
- * telephony conference and the <tt>CallPeer</tt> that get added/removed
- * to/from these <tt>Call</tt>s.
- *
- * @param listener the <tt>CallPeerConferenceListener</tt> to be added to
- * the <tt>CallPeer</tt>s associated with the <tt>Call</tt>s participating
- * in this telephony conference
- * @throws NullPointerException if <tt>listener</tt> is <tt>null</tt>
- */
- public void addCallPeerConferenceListener(
- CallPeerConferenceListener listener)
- {
- if (listener == null)
- throw new NullPointerException("listener");
- else
- {
- synchronized (callPeerConferenceListeners)
- {
- if (!callPeerConferenceListeners.contains(listener))
- callPeerConferenceListeners.add(listener);
- }
- }
- }
-
- /**
- * Notifies this <tt>CallConference</tt> that a specific <tt>Call</tt> has
- * been added to the list of <tt>Call</tt>s participating in this telephony
- * conference.
- *
- * @param call the <tt>Call</tt> which has been added to the list of
- * <tt>Call</tt>s participating in this telephony conference
- */
- protected void callAdded(Call call)
- {
- call.addCallChangeListener(callChangeListener);
- addCallPeerConferenceListener(call);
-
- /*
- * Update the conferenceFocus state. Because the public
- * setConferenceFocus method allows forcing a specific value on the
- * state in question and because it does not sound right to have the
- * adding of a Call set conferenceFocus to false, only update it if the
- * new conferenceFocus value is true,
- */
- boolean conferenceFocus = isConferenceFocus(getCalls());
-
- if (conferenceFocus)
- setConferenceFocus(conferenceFocus);
-
- firePropertyChange(CALLS, null, call);
- }
-
- /**
- * Notifies this <tt>CallConference</tt> that a specific <tt>Call</tt> has
- * been removed from the list of <tt>Call</tt>s participating in this
- * telephony conference.
- *
- * @param call the <tt>Call</tt> which has been removed from the list of
- * <tt>Call</tt>s participating in this telephony conference
- */
- protected void callRemoved(Call call)
- {
- call.removeCallChangeListener(callChangeListener);
- removeCallPeerConferenceListener(call);
-
- /*
- * Update the conferenceFocus state. Following the line of thinking
- * expressed in the callAdded method, only update it if the new
- * conferenceFocus value is false.
- */
- boolean conferenceFocus = isConferenceFocus(getCalls());
-
- if (!conferenceFocus)
- setConferenceFocus(conferenceFocus);
-
- firePropertyChange(CALLS, call, null);
- }
-
- /**
- * Notifies this telephony conference that the <tt>CallState</tt> of a
- * <tt>Call</tt> has changed.
- *
- * @param ev a <tt>CallChangeEvent</tt> which specifies the <tt>Call</tt>
- * which had its <tt>CallState</tt> changed and the old and new
- * <tt>CallState</tt>s of that <tt>Call</tt>
- */
- private void callStateChanged(CallChangeEvent ev)
- {
- Call call = ev.getSourceCall();
-
- if (containsCall(call))
- {
- try
- {
- // Forward the CallChangeEvent to the callChangeListeners.
- for (CallChangeListener l : getCallChangeListeners())
- l.callStateChanged(ev);
- }
- finally
- {
- if (CallChangeEvent.CALL_STATE_CHANGE
- .equals(ev.getPropertyName())
- && CallState.CALL_ENDED.equals(ev.getNewValue()))
- {
- /*
- * Should not be vital because Call will remove itself.
- * Anyway, do it for the sake of completeness.
- */
- removeCall(call);
- }
- }
- }
- }
-
- /**
- * Notifies this <tt>CallConference</tt> that the value of its
- * <tt>conferenceFocus</tt> property has changed from a specific old value
- * to a specific new value.
- *
- * @param oldValue the value of the <tt>conferenceFocus</tt> property of
- * this instance before the change
- * @param newValue the value of the <tt>conferenceFocus</tt> property of
- * this instance after the change
- */
- protected void conferenceFocusChanged(boolean oldValue, boolean newValue)
- {
- firePropertyChange(Call.CONFERENCE_FOCUS, oldValue, newValue);
- }
-
- /**
- * Determines whether a specific <tt>Call</tt> is participating in this
- * telephony conference.
- *
- * @param call the <tt>Call</tt> which is to be checked whether it is
- * participating in this telephony conference
- * @return <tt>true</tt> if the specified <tt>call</tt> is participating in
- * this telephony conference
- */
- public boolean containsCall(Call call)
- {
- synchronized (callsSyncRoot)
- {
- return mutableCalls.contains(call);
- }
- }
-
- /**
- * Gets the list of <tt>CallChangeListener</tt>s added to the <tt>Call</tt>s
- * participating in this telephony conference via
- * {@link #addCallChangeListener(CallChangeListener)}.
- *
- * @return the list of <tt>CallChangeListener</tt>s added to the
- * <tt>Call</tt>s participating in this telephony conference via
- * {@link #addCallChangeListener(CallChangeListener)}
- */
- private CallChangeListener[] getCallChangeListeners()
- {
- synchronized (callChangeListeners)
- {
- return
- callChangeListeners.toArray(
- new CallChangeListener[callChangeListeners.size()]);
- }
- }
-
- /**
- * Gets the number of <tt>Call</tt>s that are participating in this
- * telephony conference.
- *
- * @return the number of <tt>Call</tt>s that are participating in this
- * telephony conference
- */
- public int getCallCount()
- {
- synchronized (callsSyncRoot)
- {
- return mutableCalls.size();
- }
- }
-
- /**
- * Gets the list of <tt>CallPeerConferenceListener</tt>s added to the
- * <tt>CallPeer</tt>s associated with the <tt>Call</tt>s participating in
- * this telephony conference via
- * {@link #addCallPeerConferenceListener(CallPeerConferenceListener)}.
- *
- * @return the list of <tt>CallPeerConferenceListener</tt>s added to the
- * <tt>CallPeer</tt>s associated with the <tt>Call</tt>s participating in
- * this telephony conference via
- * {@link #addCallPeerConferenceListener(CallPeerConferenceListener)}
- */
- private CallPeerConferenceListener[] getCallPeerConferenceListeners()
- {
- synchronized (callPeerConferenceListeners)
- {
- return
- callPeerConferenceListeners.toArray(
- new CallPeerConferenceListener[
- callPeerConferenceListeners.size()]);
- }
- }
-
- /**
- * Gets the number of <tt>CallPeer</tt>s associated with the <tt>Call</tt>s
- * participating in this telephony conference.
- *
- * @return the number of <tt>CallPeer</tt>s associated with the
- * <tt>Call</tt>s participating in this telephony conference
- */
- public int getCallPeerCount()
- {
- int callPeerCount = 0;
-
- for (Call call : getCalls())
- callPeerCount += call.getCallPeerCount();
- return callPeerCount;
- }
-
- /**
- * Gets a list of the <tt>CallPeer</tt>s associated with the <tt>Call</tt>s
- * participating in this telephony conference.
- *
- * @return a list of the <tt>CallPeer</tt>s associated with the
- * <tt>Call</tt>s participating in this telephony conference
- */
- public List<CallPeer> getCallPeers()
- {
- List<CallPeer> callPeers = new ArrayList<CallPeer>();
-
- getCallPeers(callPeers);
- return callPeers;
- }
-
- /**
- * Adds the <tt>CallPeer</tt>s associated with the <tt>Call</tt>s
- * participating in this telephony conference into a specific <tt>List</tt>.
- *
- * @param callPeers a <tt>List</tt> into which the <tt>CallPeer</tt>s
- * associated with the <tt>Call</tt>s participating in this telephony
- * conference are to be added
- */
- protected void getCallPeers(List<CallPeer> callPeers)
- {
- for (Call call : getCalls())
- {
- Iterator<? extends CallPeer> callPeerIt = call.getCallPeers();
-
- while (callPeerIt.hasNext())
- callPeers.add(callPeerIt.next());
- }
- }
-
- /**
- * Gets the list of <tt>Call</tt> participating in this telephony
- * conference.
- *
- * @return the list of <tt>Call</tt>s participating in this telephony
- * conference. An empty array of <tt>Call</tt> element type is returned if
- * there are no <tt>Call</tt>s in this telephony conference-related state.
- */
- public List<Call> getCalls()
- {
- synchronized (callsSyncRoot)
- {
- return immutableCalls;
- }
- }
-
- /**
- * Determines whether the local peer/user associated with this instance and
- * represented by the <tt>Call</tt>s participating into it is acting as a
- * conference focus.
- *
- * @return <tt>true</tt> if the local peer/user associated by this instance
- * is acting as a conference focus; otherwise, <tt>false</tt>
- */
- public boolean isConferenceFocus()
- {
- return conferenceFocus;
- }
-
- /**
- * Determines whether the current state of this instance suggests that the
- * telephony conference it represents has ended. Iterates over the
- * <tt>Call</tt>s participating in this telephony conference and looks for a
- * <tt>Call</tt> which is not in the {@link CallState#CALL_ENDED} state.
- *
- * @return <tt>true</tt> if the current state of this instance suggests that
- * the telephony conference it represents has ended; otherwise,
- * <tt>false</tt>
- */
- public boolean isEnded()
- {
- for (Call call : getCalls())
- {
- if (!CallState.CALL_ENDED.equals(call.getCallState()))
- return false;
- }
- return true;
- }
-
- /**
- * Determines whether the telephony conference represented by this instance
- * is utilizing the Jitsi Videobridge server-side telephony conferencing
- * technology.
- *
- * @return <tt>true</tt> if the telephony conference represented by this
- * instance is utilizing the Jitsi Videobridge server-side telephony
- * conferencing technology
- */
- public boolean isJitsiVideobridge()
- {
- return jitsiVideobridge;
- }
-
- /**
- * Notifies this telephony conference that a
- * <tt>CallPeerConferenceEvent</tt> was fired by a <tt>CallPeer</tt>
- * associated with a <tt>Call</tt> participating in this telephony
- * conference. Forwards the specified <tt>CallPeerConferenceEvent</tt> to
- * {@link #callPeerConferenceListeners}.
- *
- * @param ev the <tt>CallPeerConferenceEvent</tt> which was fired
- */
- private void onCallPeerConferenceEvent(CallPeerConferenceEvent ev)
- {
- int eventID = ev.getEventID();
-
- for (CallPeerConferenceListener l : getCallPeerConferenceListeners())
- {
- switch (eventID)
- {
- case CallPeerConferenceEvent.CONFERENCE_FOCUS_CHANGED:
- l.conferenceFocusChanged(ev);
- break;
- case CallPeerConferenceEvent.CONFERENCE_MEMBER_ADDED:
- l.conferenceMemberAdded(ev);
- break;
- case CallPeerConferenceEvent.CONFERENCE_MEMBER_REMOVED:
- l.conferenceMemberRemoved(ev);
- break;
- case CallPeerConferenceEvent.CONFERENCE_MEMBER_ERROR_RECEIVED:
- l.conferenceMemberErrorReceived(ev);
- break;
- default:
- throw new UnsupportedOperationException(
- "Unsupported CallPeerConferenceEvent eventID.");
- }
- }
- }
-
- /**
- * Notifies this telephony conference about a specific
- * <tt>CallPeerEvent</tt> i.e. that a <tt>CallPeer</tt> was either added to
- * or removed from a <tt>Call</tt>.
- *
- * @param ev a <tt>CallPeerEvent</tt> which specifies the <tt>CallPeer</tt>
- * which was added or removed and the <tt>Call</tt> to which it was added or
- * from which is was removed
- */
- private void onCallPeerEvent(CallPeerEvent ev)
- {
- Call call = ev.getSourceCall();
-
- if (containsCall(call))
- {
- /*
- * Update the conferenceFocus state. Following the line of thinking
- * expressed in the callAdded and callRemoved methods, only update
- * it if the new conferenceFocus value is in accord with the
- * expectations.
- */
- int eventID = ev.getEventID();
- boolean conferenceFocus = isConferenceFocus(getCalls());
-
- switch (eventID)
- {
- case CallPeerEvent.CALL_PEER_ADDED:
- if (conferenceFocus)
- setConferenceFocus(conferenceFocus);
- break;
- case CallPeerEvent.CALL_PEER_REMOVED:
- if (!conferenceFocus)
- setConferenceFocus(conferenceFocus);
- break;
- default:
- /*
- * We're interested in the adding and removing of CallPeers
- * only.
- */
- break;
- }
-
- try
- {
- // Forward the CallPeerEvent to the callChangeListeners.
- for (CallChangeListener l : getCallChangeListeners())
- {
- switch (eventID)
- {
- case CallPeerEvent.CALL_PEER_ADDED:
- l.callPeerAdded(ev);
- break;
- case CallPeerEvent.CALL_PEER_REMOVED:
- l.callPeerRemoved(ev);
- break;
- default:
- break;
- }
- }
- }
- finally
- {
- /*
- * Add/remove the callPeerConferenceListener to/from the source
- * CallPeer (for the purposes of the
- * addCallPeerConferenceListener method of this CallConference).
- */
- CallPeer callPeer = ev.getSourceCallPeer();
-
- switch (eventID)
- {
- case CallPeerEvent.CALL_PEER_ADDED:
- callPeer.addCallPeerConferenceListener(
- callPeerConferenceListener);
- break;
- case CallPeerEvent.CALL_PEER_REMOVED:
- callPeer.removeCallPeerConferenceListener(
- callPeerConferenceListener);
- break;
- default:
- break;
- }
- }
- }
- }
-
- /**
- * Removes a specific <tt>Call</tt> from the list of <tt>Call</tt>s
- * participating in this telephony conference.
- *
- * @param call the <tt>Call</tt> to remove from the list of <tt>Call</tt>s
- * participating in this telephony conference
- * @return <tt>true</tt> if the list of <tt>Call</tt>s participating in this
- * telephony conference changed as a result of the method call; otherwise,
- * <tt>false</tt>
- */
- boolean removeCall(Call call)
- {
- if (call == null)
- return false;
-
- synchronized (callsSyncRoot)
- {
- if (!mutableCalls.contains(call))
- return false;
-
- /*
- * Implement the List of Calls participating in this telephony
- * conference as a copy-on-write storage in order to optimize the
- * getCalls method which is likely to be executed much more often
- * than the addCall and removeCall methods.
- */
- List<Call> newMutableCalls = new ArrayList<Call>(mutableCalls);
-
- if (newMutableCalls.remove(call))
- {
- mutableCalls = newMutableCalls;
- immutableCalls = Collections.unmodifiableList(mutableCalls);
- }
- else
- return false;
- }
-
- callRemoved(call);
- return true;
- }
-
- /**
- * Removes a <tt>CallChangeListener</tt> from the <tt>Call</tt>s
- * participating in this telephony conference.
- *
- * @param listener the <tt>CallChangeListener</tt> to be removed from the
- * <tt>Call</tt>s participating in this telephony conference
- * @see #addCallChangeListener(CallChangeListener)
- */
- public void removeCallChangeListener(CallChangeListener listener)
- {
- if (listener != null)
- {
- synchronized (callChangeListeners)
- {
- callChangeListeners.remove(listener);
- }
- }
- }
-
- /**
- * Removes {@link #callPeerConferenceListener} from the <tt>CallPeer</tt>s
- * associated with a specific <tt>Call</tt>.
- *
- * @param call the <tt>Call</tt> from whose associated <tt>CallPeer</tt>s
- * <tt>callPeerConferenceListener</tt> is to be removed
- */
- private void removeCallPeerConferenceListener(Call call)
- {
- Iterator<? extends CallPeer> callPeerIter = call.getCallPeers();
-
- while (callPeerIter.hasNext())
- {
- callPeerIter.next().removeCallPeerConferenceListener(
- callPeerConferenceListener);
- }
- }
-
- /**
- * Removes a <tt>CallPeerConferenceListener</tt> from the <tt>CallPeer</tt>s
- * associated with the <tt>Call</tt>s participating in this telephony
- * conference.
- *
- * @param listener the <tt>CallPeerConferenceListener</tt> to be removed
- * from the <tt>CallPeer</tt>s associated with the <tt>Call</tt>s
- * participating in this telephony conference
- * @see #addCallPeerConferenceListener(CallPeerConferenceListener)
- */
- public void removeCallPeerConferenceListener(
- CallPeerConferenceListener listener)
- {
- if (listener != null)
- {
- synchronized (callPeerConferenceListeners)
- {
- callPeerConferenceListeners.remove(listener);
- }
- }
- }
-
- /**
- * Sets the indicator which determines whether the local peer represented by
- * this instance and the <tt>Call</tt>s participating in it is acting as a
- * conference focus (and thus may, for example, need to send the
- * corresponding parameters in its outgoing signaling).
- *
- * @param conferenceFocus <tt>true</tt> if the local peer represented by
- * this instance and the <tt>Call</tt>s participating in it is to act as a
- * conference focus; otherwise, <tt>false</tt>
- */
- public void setConferenceFocus(boolean conferenceFocus)
- {
- if (this.conferenceFocus != conferenceFocus)
- {
- boolean oldValue = isConferenceFocus();
-
- this.conferenceFocus = conferenceFocus;
-
- boolean newValue = isConferenceFocus();
-
- if (oldValue != newValue)
- conferenceFocusChanged(oldValue, newValue);
- }
- }
-}
+package net.java.sip.communicator.service.protocol;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.event.*;
+
+import org.jitsi.util.event.*;
+
+/**
+ * Represents the telephony conference-related state of a <tt>Call</tt>.
+ * Multiple <tt>Call</tt> instances share a single <tt>CallConference</tt>
+ * instance when the former are into a telephony conference i.e. the local
+ * peer/user is the conference focus. <tt>CallConference</tt> is
+ * protocol-agnostic and thus enables cross-protocol conferences. Since a
+ * non-conference <tt>Call</tt> may be converted into a conference <tt>Call</tt>
+ * at any time, every <tt>Call</tt> instance maintains a <tt>CallConference</tt>
+ * instance regardless of whether the <tt>Call</tt> in question is participating
+ * in a telephony conference.
+ *
+ * @author Lyubomir Marinov
+ */
+public class CallConference
+ extends PropertyChangeNotifier
+{
+ /**
+ * The name of the <tt>CallConference</tt> property which specifies the list
+ * of <tt>Call</tt>s participating in a telephony conference. A change in
+ * the value of the property is delivered in the form of a
+ * <tt>PropertyChangeEvent</tt> which has its <tt>oldValue</tt> or
+ * <tt>newValue</tt> set to the <tt>Call</tt> which has been removed or
+ * added to the list of <tt>Call</tt>s participating in the telephony
+ * conference.
+ */
+ public static final String CALLS = "calls";
+
+ /**
+ * Gets the number of <tt>CallPeer</tt>s associated with the <tt>Call</tt>s
+ * participating in the telephony conference-related state of a specific
+ * <tt>Call</tt>.
+ *
+ * @param call the <tt>Call</tt> for which the number of <tt>CallPeer</tt>s
+ * associated with the <tt>Call</tt>s participating in its associated
+ * telephony conference-related state
+ * @return the number of <tt>CallPeer</tt>s associated with the
+ * <tt>Call</tt>s participating in the telephony conference-related state
+ * of the specified <tt>Call</tt>
+ */
+ public static int getCallPeerCount(Call call)
+ {
+ CallConference conference = call.getConference();
+
+ /*
+ * A Call instance is supposed to always maintain a CallConference
+ * instance. Anyway, if it turns out that it is not the case, we will
+ * consider the Call as a representation of a telephony conference.
+ */
+ return
+ (conference == null)
+ ? call.getCallPeerCount()
+ : conference.getCallPeerCount();
+ }
+
+ /**
+ * Gets a list of the <tt>CallPeer</tt>s associated with the <tt>Call</tt>s
+ * participating in the telephony conference in which a specific
+ * <tt>Call</tt> is participating.
+ *
+ * @param call the <tt>Call</tt> which specifies the telephony conference
+ * the <tt>CallPeer</tt>s of which are to be retrieved
+ * @return a list of the <tt>CallPeer</tt>s associated with the
+ * <tt>Call</tt>s participating in the telephony conference in which the
+ * specified <tt>call</tt> is participating
+ */
+ public static List<CallPeer> getCallPeers(Call call)
+ {
+ CallConference conference = call.getConference();
+ List<CallPeer> callPeers = new ArrayList<CallPeer>();
+
+ if (conference == null)
+ {
+ Iterator<? extends CallPeer> callPeerIt = call.getCallPeers();
+
+ while (callPeerIt.hasNext())
+ callPeers.add(callPeerIt.next());
+ }
+ else
+ conference.getCallPeers(callPeers);
+ return callPeers;
+ }
+
+ /**
+ * Gets the list of <tt>Call</tt>s participating in the telephony conference
+ * in which a specific <tt>Call</tt> is participating.
+ *
+ * @param call the <tt>Call</tt> which participates in the telephony
+ * conference the list of participating <tt>Call</tt>s of which is to be
+ * returned
+ * @return the list of <tt>Call</tt>s participating in the telephony
+ * conference in which the specified <tt>call</tt> is participating
+ */
+ public static List<Call> getCalls(Call call)
+ {
+ CallConference conference = call.getConference();
+ List<Call> calls;
+
+ if (conference == null)
+ calls = Collections.emptyList();
+ else
+ calls = conference.getCalls();
+ return calls;
+ }
+
+ /**
+ * Determines whether a <tt>CallConference</tt> is to report the local
+ * peer/user as a conference focus judging by a specific list of
+ * <tt>Call</tt>s.
+ *
+ * @param calls the list of <tt>Call</tt> which are to be judged whether
+ * the local peer/user that they represent is to be considered as a
+ * conference focus
+ * @return <tt>true</tt> if the local peer/user represented by the specified
+ * <tt>calls</tt> is judged to be a conference focus; otherwise,
+ * <tt>false</tt>
+ */
+ private static boolean isConferenceFocus(List<Call> calls)
+ {
+ int callCount = calls.size();
+ boolean conferenceFocus;
+
+ if (callCount < 1)
+ conferenceFocus = false;
+ else if (callCount > 1)
+ conferenceFocus = true;
+ else
+ conferenceFocus = (calls.get(0).getCallPeerCount() > 1);
+ return conferenceFocus;
+ }
+
+ /**
+ * The <tt>CallChangeListener</tt> which listens to changes in the
+ * <tt>Call</tt>s participating in this telephony conference.
+ */
+ private final CallChangeListener callChangeListener
+ = new CallChangeListener()
+ {
+ @Override
+ public void callPeerAdded(CallPeerEvent ev)
+ {
+ CallConference.this.onCallPeerEvent(ev);
+ }
+
+ @Override
+ public void callPeerRemoved(CallPeerEvent ev)
+ {
+ CallConference.this.onCallPeerEvent(ev);
+ }
+
+ @Override
+ public void callStateChanged(CallChangeEvent ev)
+ {
+ CallConference.this.callStateChanged(ev);
+ }
+ };
+
+ /**
+ * The list of <tt>CallChangeListener</tt>s added to the <tt>Call</tt>s
+ * participating in this telephony conference via
+ * {@link #addCallChangeListener(CallChangeListener)}.
+ */
+ private final List<CallChangeListener> callChangeListeners
+ = new LinkedList<CallChangeListener>();
+
+ /**
+ * The <tt>CallPeerConferenceListener</tt> which listens to the
+ * <tt>CallPeer</tt>s associated with the <tt>Call</tt>s participating in
+ * this telephony conference.
+ */
+ private final CallPeerConferenceListener callPeerConferenceListener
+ = new CallPeerConferenceAdapter()
+ {
+ /**
+ * {@inheritDoc}
+ *
+ * Invokes
+ * {@link CallConference#onCallPeerConferenceEvent(
+ * CallPeerConferenceEvent)}.
+ */
+ @Override
+ protected void onCallPeerConferenceEvent(CallPeerConferenceEvent ev)
+ {
+ CallConference.this.onCallPeerConferenceEvent(ev);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Invokes
+ * {@link CallConference#onCallPeerConferenceEvent(
+ * CallPeerConferenceEvent)}.
+ */
+ @Override
+ public void conferenceMemberErrorReceived(
+ CallPeerConferenceEvent ev)
+ {
+ CallConference.this.onCallPeerConferenceEvent(ev);
+ }
+ };
+
+ /**
+ * The list of <tt>CallPeerConferenceListener</tt>s added to the
+ * <tt>CallPeer</tt>s associated with the <tt>CallPeer</tt>s participating
+ * in this telephony conference via
+ * {@link #addCallPeerConferenceListener}.
+ */
+ private final List<CallPeerConferenceListener> callPeerConferenceListeners
+ = new LinkedList<CallPeerConferenceListener>();
+
+ /**
+ * The synchronization root/<tt>Object</tt> which protects the access to
+ * {@link #immutableCalls} and {@link #mutableCalls}.
+ */
+ private final Object callsSyncRoot = new Object();
+
+ /**
+ * The indicator which determines whether the local peer represented by this
+ * instance and the <tt>Call</tt>s participating in it is acting as a
+ * conference focus. The SIP protocol, for example, will add the
+ * &quot;isfocus&quot; parameter to the Contact headers of its outgoing
+ * signaling if <tt>true</tt>.
+ */
+ private boolean conferenceFocus = false;
+
+ /**
+ * The list of <tt>Call</tt>s participating in this telephony conference as
+ * an immutable <tt>List</tt> which can be exposed out of this instance
+ * without the need to make a copy. In other words, it is an unmodifiable
+ * view of {@link #mutableCalls}.
+ */
+ private List<Call> immutableCalls;
+
+ /**
+ * The indicator which determines whether the telephony conference
+ * represented by this instance is utilizing the Jitsi Videobridge
+ * server-side telephony conferencing technology.
+ */
+ private final boolean jitsiVideobridge;
+
+ /**
+ * The list of <tt>Call</tt>s participating in this telephony conference as
+ * a mutable <tt>List</tt> which should not be exposed out of this instance.
+ */
+ private List<Call> mutableCalls;
+
+ /**
+ * Initializes a new <tt>CallConference</tt> instance.
+ */
+ public CallConference()
+ {
+ this(false);
+ }
+
+ /**
+ * Initializes a new <tt>CallConference</tt> instance which is to optionally
+ * utilize the Jitsi Videobridge server-side telephony conferencing
+ * technology.
+ *
+ * @param jitsiVideobridge <tt>true</tt> if the telephony conference
+ * represented by the new instance is to utilize the Jitsi Videobridge
+ * server-side telephony conferencing technology; otherwise, <tt>false</tt>
+ */
+ public CallConference(boolean jitsiVideobridge)
+ {
+ this.jitsiVideobridge = jitsiVideobridge;
+
+ mutableCalls = new ArrayList<Call>();
+ immutableCalls = Collections.unmodifiableList(mutableCalls);
+ }
+
+ /**
+ * Adds a specific <tt>Call</tt> to the list of <tt>Call</tt>s participating
+ * in this telephony conference.
+ *
+ * @param call the <tt>Call</tt> to add to the list of <tt>Call</tt>s
+ * participating in this telephony conference
+ * @return <tt>true</tt> if the list of <tt>Call</tt>s participating in this
+ * telephony conference changed as a result of the method call; otherwise,
+ * <tt>false</tt>
+ * @throws NullPointerException if <tt>call</tt> is <tt>null</tt>
+ */
+ boolean addCall(Call call)
+ {
+ if (call == null)
+ throw new NullPointerException("call");
+
+ synchronized (callsSyncRoot)
+ {
+ if (mutableCalls.contains(call))
+ return false;
+
+ /*
+ * Implement the List of Calls participating in this telephony
+ * conference as a copy-on-write storage in order to optimize the
+ * getCalls method which is likely to be executed much more often
+ * than the addCall and removeCall methods.
+ */
+ List<Call> newMutableCalls = new ArrayList<Call>(mutableCalls);
+
+ if (newMutableCalls.add(call))
+ {
+ mutableCalls = newMutableCalls;
+ immutableCalls = Collections.unmodifiableList(mutableCalls);
+ }
+ else
+ return false;
+ }
+
+ callAdded(call);
+ return true;
+ }
+
+ /**
+ * Adds a <tt>CallChangeListener</tt> to the <tt>Call</tt>s participating in
+ * this telephony conference. The method is a convenience that takes on the
+ * responsibility of tracking the <tt>Call</tt>s that get added/removed
+ * to/from this telephony conference.
+ *
+ * @param listener the <tt>CallChangeListner</tt> to be added to the
+ * <tt>Call</tt>s participating in this telephony conference
+ * @throws NullPointerException if <tt>listener</tt> is <tt>null</tt>
+ */
+ public void addCallChangeListener(CallChangeListener listener)
+ {
+ if (listener == null)
+ throw new NullPointerException("listener");
+ else
+ {
+ synchronized (callChangeListeners)
+ {
+ if (!callChangeListeners.contains(listener))
+ callChangeListeners.add(listener);
+ }
+ }
+ }
+
+ /**
+ * Adds {@link #callPeerConferenceListener} to the <tt>CallPeer</tt>s
+ * associated with a specific <tt>Call</tt>.
+ *
+ * @param call the <tt>Call</tt> to whose associated <tt>CallPeer</tt>s
+ * <tt>callPeerConferenceListener</tt> is to be added
+ */
+ private void addCallPeerConferenceListener(Call call)
+ {
+ Iterator<? extends CallPeer> callPeerIter = call.getCallPeers();
+
+ while (callPeerIter.hasNext())
+ {
+ callPeerIter.next().addCallPeerConferenceListener(
+ callPeerConferenceListener);
+ }
+ }
+
+ /**
+ * Adds a <tt>CallPeerConferenceListener</tt> to the <tt>CallPeer</tt>s
+ * associated with the <tt>Call</tt>s participating in this telephony
+ * conference. The method is a convenience that takes on the responsibility
+ * of tracking the <tt>Call</tt>s that get added/removed to/from this
+ * telephony conference and the <tt>CallPeer</tt> that get added/removed
+ * to/from these <tt>Call</tt>s.
+ *
+ * @param listener the <tt>CallPeerConferenceListener</tt> to be added to
+ * the <tt>CallPeer</tt>s associated with the <tt>Call</tt>s participating
+ * in this telephony conference
+ * @throws NullPointerException if <tt>listener</tt> is <tt>null</tt>
+ */
+ public void addCallPeerConferenceListener(
+ CallPeerConferenceListener listener)
+ {
+ if (listener == null)
+ throw new NullPointerException("listener");
+ else
+ {
+ synchronized (callPeerConferenceListeners)
+ {
+ if (!callPeerConferenceListeners.contains(listener))
+ callPeerConferenceListeners.add(listener);
+ }
+ }
+ }
+
+ /**
+ * Notifies this <tt>CallConference</tt> that a specific <tt>Call</tt> has
+ * been added to the list of <tt>Call</tt>s participating in this telephony
+ * conference.
+ *
+ * @param call the <tt>Call</tt> which has been added to the list of
+ * <tt>Call</tt>s participating in this telephony conference
+ */
+ protected void callAdded(Call call)
+ {
+ call.addCallChangeListener(callChangeListener);
+ addCallPeerConferenceListener(call);
+
+ /*
+ * Update the conferenceFocus state. Because the public
+ * setConferenceFocus method allows forcing a specific value on the
+ * state in question and because it does not sound right to have the
+ * adding of a Call set conferenceFocus to false, only update it if the
+ * new conferenceFocus value is true,
+ */
+ boolean conferenceFocus = isConferenceFocus(getCalls());
+
+ if (conferenceFocus)
+ setConferenceFocus(conferenceFocus);
+
+ firePropertyChange(CALLS, null, call);
+ }
+
+ /**
+ * Notifies this <tt>CallConference</tt> that a specific <tt>Call</tt> has
+ * been removed from the list of <tt>Call</tt>s participating in this
+ * telephony conference.
+ *
+ * @param call the <tt>Call</tt> which has been removed from the list of
+ * <tt>Call</tt>s participating in this telephony conference
+ */
+ protected void callRemoved(Call call)
+ {
+ call.removeCallChangeListener(callChangeListener);
+ removeCallPeerConferenceListener(call);
+
+ /*
+ * Update the conferenceFocus state. Following the line of thinking
+ * expressed in the callAdded method, only update it if the new
+ * conferenceFocus value is false.
+ */
+ boolean conferenceFocus = isConferenceFocus(getCalls());
+
+ if (!conferenceFocus)
+ setConferenceFocus(conferenceFocus);
+
+ firePropertyChange(CALLS, call, null);
+ }
+
+ /**
+ * Notifies this telephony conference that the <tt>CallState</tt> of a
+ * <tt>Call</tt> has changed.
+ *
+ * @param ev a <tt>CallChangeEvent</tt> which specifies the <tt>Call</tt>
+ * which had its <tt>CallState</tt> changed and the old and new
+ * <tt>CallState</tt>s of that <tt>Call</tt>
+ */
+ private void callStateChanged(CallChangeEvent ev)
+ {
+ Call call = ev.getSourceCall();
+
+ if (containsCall(call))
+ {
+ try
+ {
+ // Forward the CallChangeEvent to the callChangeListeners.
+ for (CallChangeListener l : getCallChangeListeners())
+ l.callStateChanged(ev);
+ }
+ finally
+ {
+ if (CallChangeEvent.CALL_STATE_CHANGE
+ .equals(ev.getPropertyName())
+ && CallState.CALL_ENDED.equals(ev.getNewValue()))
+ {
+ /*
+ * Should not be vital because Call will remove itself.
+ * Anyway, do it for the sake of completeness.
+ */
+ removeCall(call);
+ }
+ }
+ }
+ }
+
+ /**
+ * Notifies this <tt>CallConference</tt> that the value of its
+ * <tt>conferenceFocus</tt> property has changed from a specific old value
+ * to a specific new value.
+ *
+ * @param oldValue the value of the <tt>conferenceFocus</tt> property of
+ * this instance before the change
+ * @param newValue the value of the <tt>conferenceFocus</tt> property of
+ * this instance after the change
+ */
+ protected void conferenceFocusChanged(boolean oldValue, boolean newValue)
+ {
+ firePropertyChange(Call.CONFERENCE_FOCUS, oldValue, newValue);
+ }
+
+ /**
+ * Determines whether a specific <tt>Call</tt> is participating in this
+ * telephony conference.
+ *
+ * @param call the <tt>Call</tt> which is to be checked whether it is
+ * participating in this telephony conference
+ * @return <tt>true</tt> if the specified <tt>call</tt> is participating in
+ * this telephony conference
+ */
+ public boolean containsCall(Call call)
+ {
+ synchronized (callsSyncRoot)
+ {
+ return mutableCalls.contains(call);
+ }
+ }
+
+ /**
+ * Gets the list of <tt>CallChangeListener</tt>s added to the <tt>Call</tt>s
+ * participating in this telephony conference via
+ * {@link #addCallChangeListener(CallChangeListener)}.
+ *
+ * @return the list of <tt>CallChangeListener</tt>s added to the
+ * <tt>Call</tt>s participating in this telephony conference via
+ * {@link #addCallChangeListener(CallChangeListener)}
+ */
+ private CallChangeListener[] getCallChangeListeners()
+ {
+ synchronized (callChangeListeners)
+ {
+ return
+ callChangeListeners.toArray(
+ new CallChangeListener[callChangeListeners.size()]);
+ }
+ }
+
+ /**
+ * Gets the number of <tt>Call</tt>s that are participating in this
+ * telephony conference.
+ *
+ * @return the number of <tt>Call</tt>s that are participating in this
+ * telephony conference
+ */
+ public int getCallCount()
+ {
+ synchronized (callsSyncRoot)
+ {
+ return mutableCalls.size();
+ }
+ }
+
+ /**
+ * Gets the list of <tt>CallPeerConferenceListener</tt>s added to the
+ * <tt>CallPeer</tt>s associated with the <tt>Call</tt>s participating in
+ * this telephony conference via
+ * {@link #addCallPeerConferenceListener(CallPeerConferenceListener)}.
+ *
+ * @return the list of <tt>CallPeerConferenceListener</tt>s added to the
+ * <tt>CallPeer</tt>s associated with the <tt>Call</tt>s participating in
+ * this telephony conference via
+ * {@link #addCallPeerConferenceListener(CallPeerConferenceListener)}
+ */
+ private CallPeerConferenceListener[] getCallPeerConferenceListeners()
+ {
+ synchronized (callPeerConferenceListeners)
+ {
+ return
+ callPeerConferenceListeners.toArray(
+ new CallPeerConferenceListener[
+ callPeerConferenceListeners.size()]);
+ }
+ }
+
+ /**
+ * Gets the number of <tt>CallPeer</tt>s associated with the <tt>Call</tt>s
+ * participating in this telephony conference.
+ *
+ * @return the number of <tt>CallPeer</tt>s associated with the
+ * <tt>Call</tt>s participating in this telephony conference
+ */
+ public int getCallPeerCount()
+ {
+ int callPeerCount = 0;
+
+ for (Call call : getCalls())
+ callPeerCount += call.getCallPeerCount();
+ return callPeerCount;
+ }
+
+ /**
+ * Gets a list of the <tt>CallPeer</tt>s associated with the <tt>Call</tt>s
+ * participating in this telephony conference.
+ *
+ * @return a list of the <tt>CallPeer</tt>s associated with the
+ * <tt>Call</tt>s participating in this telephony conference
+ */
+ public List<CallPeer> getCallPeers()
+ {
+ List<CallPeer> callPeers = new ArrayList<CallPeer>();
+
+ getCallPeers(callPeers);
+ return callPeers;
+ }
+
+ /**
+ * Adds the <tt>CallPeer</tt>s associated with the <tt>Call</tt>s
+ * participating in this telephony conference into a specific <tt>List</tt>.
+ *
+ * @param callPeers a <tt>List</tt> into which the <tt>CallPeer</tt>s
+ * associated with the <tt>Call</tt>s participating in this telephony
+ * conference are to be added
+ */
+ protected void getCallPeers(List<CallPeer> callPeers)
+ {
+ for (Call call : getCalls())
+ {
+ Iterator<? extends CallPeer> callPeerIt = call.getCallPeers();
+
+ while (callPeerIt.hasNext())
+ callPeers.add(callPeerIt.next());
+ }
+ }
+
+ /**
+ * Gets the list of <tt>Call</tt> participating in this telephony
+ * conference.
+ *
+ * @return the list of <tt>Call</tt>s participating in this telephony
+ * conference. An empty array of <tt>Call</tt> element type is returned if
+ * there are no <tt>Call</tt>s in this telephony conference-related state.
+ */
+ public List<Call> getCalls()
+ {
+ synchronized (callsSyncRoot)
+ {
+ return immutableCalls;
+ }
+ }
+
+ /**
+ * Determines whether the local peer/user associated with this instance and
+ * represented by the <tt>Call</tt>s participating into it is acting as a
+ * conference focus.
+ *
+ * @return <tt>true</tt> if the local peer/user associated by this instance
+ * is acting as a conference focus; otherwise, <tt>false</tt>
+ */
+ public boolean isConferenceFocus()
+ {
+ return conferenceFocus;
+ }
+
+ /**
+ * Determines whether the current state of this instance suggests that the
+ * telephony conference it represents has ended. Iterates over the
+ * <tt>Call</tt>s participating in this telephony conference and looks for a
+ * <tt>Call</tt> which is not in the {@link CallState#CALL_ENDED} state.
+ *
+ * @return <tt>true</tt> if the current state of this instance suggests that
+ * the telephony conference it represents has ended; otherwise,
+ * <tt>false</tt>
+ */
+ public boolean isEnded()
+ {
+ for (Call call : getCalls())
+ {
+ if (!CallState.CALL_ENDED.equals(call.getCallState()))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Determines whether the telephony conference represented by this instance
+ * is utilizing the Jitsi Videobridge server-side telephony conferencing
+ * technology.
+ *
+ * @return <tt>true</tt> if the telephony conference represented by this
+ * instance is utilizing the Jitsi Videobridge server-side telephony
+ * conferencing technology
+ */
+ public boolean isJitsiVideobridge()
+ {
+ return jitsiVideobridge;
+ }
+
+ /**
+ * Notifies this telephony conference that a
+ * <tt>CallPeerConferenceEvent</tt> was fired by a <tt>CallPeer</tt>
+ * associated with a <tt>Call</tt> participating in this telephony
+ * conference. Forwards the specified <tt>CallPeerConferenceEvent</tt> to
+ * {@link #callPeerConferenceListeners}.
+ *
+ * @param ev the <tt>CallPeerConferenceEvent</tt> which was fired
+ */
+ private void onCallPeerConferenceEvent(CallPeerConferenceEvent ev)
+ {
+ int eventID = ev.getEventID();
+
+ for (CallPeerConferenceListener l : getCallPeerConferenceListeners())
+ {
+ switch (eventID)
+ {
+ case CallPeerConferenceEvent.CONFERENCE_FOCUS_CHANGED:
+ l.conferenceFocusChanged(ev);
+ break;
+ case CallPeerConferenceEvent.CONFERENCE_MEMBER_ADDED:
+ l.conferenceMemberAdded(ev);
+ break;
+ case CallPeerConferenceEvent.CONFERENCE_MEMBER_REMOVED:
+ l.conferenceMemberRemoved(ev);
+ break;
+ case CallPeerConferenceEvent.CONFERENCE_MEMBER_ERROR_RECEIVED:
+ l.conferenceMemberErrorReceived(ev);
+ break;
+ default:
+ throw new UnsupportedOperationException(
+ "Unsupported CallPeerConferenceEvent eventID.");
+ }
+ }
+ }
+
+ /**
+ * Notifies this telephony conference about a specific
+ * <tt>CallPeerEvent</tt> i.e. that a <tt>CallPeer</tt> was either added to
+ * or removed from a <tt>Call</tt>.
+ *
+ * @param ev a <tt>CallPeerEvent</tt> which specifies the <tt>CallPeer</tt>
+ * which was added or removed and the <tt>Call</tt> to which it was added or
+ * from which is was removed
+ */
+ private void onCallPeerEvent(CallPeerEvent ev)
+ {
+ Call call = ev.getSourceCall();
+
+ if (containsCall(call))
+ {
+ /*
+ * Update the conferenceFocus state. Following the line of thinking
+ * expressed in the callAdded and callRemoved methods, only update
+ * it if the new conferenceFocus value is in accord with the
+ * expectations.
+ */
+ int eventID = ev.getEventID();
+ boolean conferenceFocus = isConferenceFocus(getCalls());
+
+ switch (eventID)
+ {
+ case CallPeerEvent.CALL_PEER_ADDED:
+ if (conferenceFocus)
+ setConferenceFocus(conferenceFocus);
+ break;
+ case CallPeerEvent.CALL_PEER_REMOVED:
+ if (!conferenceFocus)
+ setConferenceFocus(conferenceFocus);
+ break;
+ default:
+ /*
+ * We're interested in the adding and removing of CallPeers
+ * only.
+ */
+ break;
+ }
+
+ try
+ {
+ // Forward the CallPeerEvent to the callChangeListeners.
+ for (CallChangeListener l : getCallChangeListeners())
+ {
+ switch (eventID)
+ {
+ case CallPeerEvent.CALL_PEER_ADDED:
+ l.callPeerAdded(ev);
+ break;
+ case CallPeerEvent.CALL_PEER_REMOVED:
+ l.callPeerRemoved(ev);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ finally
+ {
+ /*
+ * Add/remove the callPeerConferenceListener to/from the source
+ * CallPeer (for the purposes of the
+ * addCallPeerConferenceListener method of this CallConference).
+ */
+ CallPeer callPeer = ev.getSourceCallPeer();
+
+ switch (eventID)
+ {
+ case CallPeerEvent.CALL_PEER_ADDED:
+ callPeer.addCallPeerConferenceListener(
+ callPeerConferenceListener);
+ break;
+ case CallPeerEvent.CALL_PEER_REMOVED:
+ callPeer.removeCallPeerConferenceListener(
+ callPeerConferenceListener);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes a specific <tt>Call</tt> from the list of <tt>Call</tt>s
+ * participating in this telephony conference.
+ *
+ * @param call the <tt>Call</tt> to remove from the list of <tt>Call</tt>s
+ * participating in this telephony conference
+ * @return <tt>true</tt> if the list of <tt>Call</tt>s participating in this
+ * telephony conference changed as a result of the method call; otherwise,
+ * <tt>false</tt>
+ */
+ boolean removeCall(Call call)
+ {
+ if (call == null)
+ return false;
+
+ synchronized (callsSyncRoot)
+ {
+ if (!mutableCalls.contains(call))
+ return false;
+
+ /*
+ * Implement the List of Calls participating in this telephony
+ * conference as a copy-on-write storage in order to optimize the
+ * getCalls method which is likely to be executed much more often
+ * than the addCall and removeCall methods.
+ */
+ List<Call> newMutableCalls = new ArrayList<Call>(mutableCalls);
+
+ if (newMutableCalls.remove(call))
+ {
+ mutableCalls = newMutableCalls;
+ immutableCalls = Collections.unmodifiableList(mutableCalls);
+ }
+ else
+ return false;
+ }
+
+ callRemoved(call);
+ return true;
+ }
+
+ /**
+ * Removes a <tt>CallChangeListener</tt> from the <tt>Call</tt>s
+ * participating in this telephony conference.
+ *
+ * @param listener the <tt>CallChangeListener</tt> to be removed from the
+ * <tt>Call</tt>s participating in this telephony conference
+ * @see #addCallChangeListener(CallChangeListener)
+ */
+ public void removeCallChangeListener(CallChangeListener listener)
+ {
+ if (listener != null)
+ {
+ synchronized (callChangeListeners)
+ {
+ callChangeListeners.remove(listener);
+ }
+ }
+ }
+
+ /**
+ * Removes {@link #callPeerConferenceListener} from the <tt>CallPeer</tt>s
+ * associated with a specific <tt>Call</tt>.
+ *
+ * @param call the <tt>Call</tt> from whose associated <tt>CallPeer</tt>s
+ * <tt>callPeerConferenceListener</tt> is to be removed
+ */
+ private void removeCallPeerConferenceListener(Call call)
+ {
+ Iterator<? extends CallPeer> callPeerIter = call.getCallPeers();
+
+ while (callPeerIter.hasNext())
+ {
+ callPeerIter.next().removeCallPeerConferenceListener(
+ callPeerConferenceListener);
+ }
+ }
+
+ /**
+ * Removes a <tt>CallPeerConferenceListener</tt> from the <tt>CallPeer</tt>s
+ * associated with the <tt>Call</tt>s participating in this telephony
+ * conference.
+ *
+ * @param listener the <tt>CallPeerConferenceListener</tt> to be removed
+ * from the <tt>CallPeer</tt>s associated with the <tt>Call</tt>s
+ * participating in this telephony conference
+ * @see #addCallPeerConferenceListener(CallPeerConferenceListener)
+ */
+ public void removeCallPeerConferenceListener(
+ CallPeerConferenceListener listener)
+ {
+ if (listener != null)
+ {
+ synchronized (callPeerConferenceListeners)
+ {
+ callPeerConferenceListeners.remove(listener);
+ }
+ }
+ }
+
+ /**
+ * Sets the indicator which determines whether the local peer represented by
+ * this instance and the <tt>Call</tt>s participating in it is acting as a
+ * conference focus (and thus may, for example, need to send the
+ * corresponding parameters in its outgoing signaling).
+ *
+ * @param conferenceFocus <tt>true</tt> if the local peer represented by
+ * this instance and the <tt>Call</tt>s participating in it is to act as a
+ * conference focus; otherwise, <tt>false</tt>
+ */
+ public void setConferenceFocus(boolean conferenceFocus)
+ {
+ if (this.conferenceFocus != conferenceFocus)
+ {
+ boolean oldValue = isConferenceFocus();
+
+ this.conferenceFocus = conferenceFocus;
+
+ boolean newValue = isConferenceFocus();
+
+ if (oldValue != newValue)
+ conferenceFocusChanged(oldValue, newValue);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetBasicInstantMessaging.java b/src/net/java/sip/communicator/service/protocol/OperationSetBasicInstantMessaging.java
index c0918cb..55dec9a 100644
--- a/src/net/java/sip/communicator/service/protocol/OperationSetBasicInstantMessaging.java
+++ b/src/net/java/sip/communicator/service/protocol/OperationSetBasicInstantMessaging.java
@@ -80,22 +80,6 @@ public interface OperationSetBasicInstantMessaging
String messageText, String contentType, String messageUID);
/**
- * Create a Message instance with the specified UID and a default
- * (text/plain) content type and encoding.
- * This method can be useful when message correction is required. One can
- * construct the corrected message to have the same UID as the message
- * before correction.
- *
- * @param messageText the string content of the message.
- * @param messageUID the unique identifier of this message.
- * @return Message the newly created message
- *
- * @deprecated Method will be removed once OTR bundle is updated on Android.
- */
- @Deprecated
- public Message createMessageWithUID(String messageText, String messageUID);
-
- /**
* Sends the <tt>message</tt> to the destination indicated by the
* <tt>to</tt> contact.
*
diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetJitsiMeetTools.java b/src/net/java/sip/communicator/service/protocol/OperationSetJitsiMeetTools.java
index 08c8cff..41af2b4 100644
--- a/src/net/java/sip/communicator/service/protocol/OperationSetJitsiMeetTools.java
+++ b/src/net/java/sip/communicator/service/protocol/OperationSetJitsiMeetTools.java
@@ -56,6 +56,17 @@ public interface OperationSetJitsiMeetTools
PacketExtension extension);
/**
+ * Removes given <tt>PacketExtension</tt> from the multi user chat presence
+ * and sends presence update packet to the chat room.
+ * @param chatRoom the <tt>ChatRoom</tt> for which the presence will be
+ * updated.
+ * @param extension the <tt>PacketExtension</tt> to be removed from the MUC
+ * presence.
+ */
+ public void removePresenceExtension(ChatRoom chatRoom,
+ PacketExtension extension);
+
+ /**
* Sets the status message of our MUC presence and sends presence status
* update packet to the server.
* @param chatRoom the <tt>ChatRoom</tt> for which the presence status
diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetSecureSDesTelephony.java b/src/net/java/sip/communicator/service/protocol/OperationSetSecureSDesTelephony.java
index e0c75fd..f336de1 100644
--- a/src/net/java/sip/communicator/service/protocol/OperationSetSecureSDesTelephony.java
+++ b/src/net/java/sip/communicator/service/protocol/OperationSetSecureSDesTelephony.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,15 +15,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.protocol;
-
-/**
- * Marker interface to indicate that a protocol supports SDES encryption.
- *
- * @author Ingo Bauersachs
- */
-public interface OperationSetSecureSDesTelephony
- extends OperationSetSecureTelephony
-{
-
-}
+package net.java.sip.communicator.service.protocol;
+
+/**
+ * Marker interface to indicate that a protocol supports SDES encryption.
+ *
+ * @author Ingo Bauersachs
+ */
+public interface OperationSetSecureSDesTelephony
+ extends OperationSetSecureTelephony
+{
+
+}
diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetSecureZrtpTelephony.java b/src/net/java/sip/communicator/service/protocol/OperationSetSecureZrtpTelephony.java
index 7213af4..eb5dcdd 100644
--- a/src/net/java/sip/communicator/service/protocol/OperationSetSecureZrtpTelephony.java
+++ b/src/net/java/sip/communicator/service/protocol/OperationSetSecureZrtpTelephony.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,15 +15,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.protocol;
-
-/**
- * Marker interface to indicate that a protocol supports ZRTP encryption.
- *
- * @author Ingo Bauersachs
- */
-public interface OperationSetSecureZrtpTelephony
- extends OperationSetSecureTelephony
-{
-
-}
+package net.java.sip.communicator.service.protocol;
+
+/**
+ * Marker interface to indicate that a protocol supports ZRTP encryption.
+ *
+ * @author Ingo Bauersachs
+ */
+public interface OperationSetSecureZrtpTelephony
+ extends OperationSetSecureTelephony
+{
+
+}
diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetTelephonyBLF.java b/src/net/java/sip/communicator/service/protocol/OperationSetTelephonyBLF.java
index 028c2ae..f6a50dc 100644
--- a/src/net/java/sip/communicator/service/protocol/OperationSetTelephonyBLF.java
+++ b/src/net/java/sip/communicator/service/protocol/OperationSetTelephonyBLF.java
@@ -80,6 +80,11 @@ public interface OperationSetTelephonyBLF
private String group;
/**
+ * Asterisk pickup prefix.
+ */
+ private String pickupTemplate;
+
+ /**
* The parent provider.
*/
private ProtocolProviderService provider;
@@ -90,14 +95,16 @@ public interface OperationSetTelephonyBLF
* @param address the address of the line.
* @param name the display name if any
* @param group the group name if any
+ * @param pickup the pickup dial template
* @param provider the parent provider.
*/
- public Line(String address, String name, String group,
+ public Line(String address, String name, String group, String pickup,
ProtocolProviderService provider)
{
this.address = address;
this.name = name;
this.group = group;
+ this.pickupTemplate = pickup;
this.provider = provider;
}
@@ -129,6 +136,15 @@ public interface OperationSetTelephonyBLF
}
/**
+ * The pickup template.
+ * @return the pickup template.
+ */
+ public String getPickupTemplate()
+ {
+ return pickupTemplate;
+ }
+
+ /**
* The provider.
* @return the provider.
*/
diff --git a/src/net/java/sip/communicator/service/protocol/PhoneNumberI18nService.java b/src/net/java/sip/communicator/service/protocol/PhoneNumberI18nService.java
index df71e0c..521afc5 100644
--- a/src/net/java/sip/communicator/service/protocol/PhoneNumberI18nService.java
+++ b/src/net/java/sip/communicator/service/protocol/PhoneNumberI18nService.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,49 +15,59 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.protocol;
-
-/**
- * Implements <tt>PhoneNumberI18nService</tt> which aids the parsing, formatting
- * and validating of international phone numbers.
- *
- * @author Lyubomir Marinov
- * @author Vincent Lucas
- * @author Damian Minkov
- */
-public interface PhoneNumberI18nService
-{
- /**
- * Normalizes a <tt>String</tt> which may be a phone number or a identifier
- * by removing useless characters and, if necessary, replacing the alpahe
- * characters in corresponding dial pad numbers.
- *
- * @param possibleNumber a <tt>String</tt> which may represents a phone
- * number or an identifier to normalize.
- *
- * @return a <tt>String</tt> which is a normalized form of the specified
- * <tt>possibleNumber</tt>.
- */
- public String normalize(String possibleNumber);
-
- /**
- * Determines whether two <tt>String</tt> phone numbers match.
- *
- * @param aPhoneNumber a <tt>String</tt> which represents a phone number to
- * match to <tt>bPhoneNumber</tt>
- * @param bPhoneNumber a <tt>String</tt> which represents a phone number to
- * match to <tt>aPhoneNumber</tt>
- * @return <tt>true</tt> if the specified <tt>String</tt>s match as phone
- * numbers; otherwise, <tt>false</tt>
- */
- public boolean phoneNumbersMatch(String aPhoneNumber, String bPhoneNumber);
-
- /**
- * Indicates if the given string is possibly a phone number.
- *
- * @param possibleNumber the string to be verified
- * @return <tt>true</tt> if the possibleNumber is a phone number,
- * <tt>false</tt> - otherwise
- */
- public boolean isPhoneNumber(String possibleNumber);
-}
+package net.java.sip.communicator.service.protocol;
+
+/**
+ * Implements <tt>PhoneNumberI18nService</tt> which aids the parsing, formatting
+ * and validating of international phone numbers.
+ *
+ * @author Lyubomir Marinov
+ * @author Vincent Lucas
+ * @author Damian Minkov
+ */
+public interface PhoneNumberI18nService
+{
+ /**
+ * Normalizes a <tt>String</tt> which may be a phone number or a identifier
+ * by removing useless characters and, if necessary, replacing the alpahe
+ * characters in corresponding dial pad numbers.
+ *
+ * @param possibleNumber a <tt>String</tt> which may represents a phone
+ * number or an identifier to normalize.
+ *
+ * @return a <tt>String</tt> which is a normalized form of the specified
+ * <tt>possibleNumber</tt>.
+ */
+ public String normalize(String possibleNumber);
+
+ /**
+ * Tries to format the passed phone number into the international format. If
+ * parsing fails or the string is not recognized as a valid phone number,
+ * the input is returned as is.
+ *
+ * @param phoneNumber The phone number to format.
+ * @return the formatted phone number in the international format.
+ */
+ public String formatForDisplay(String phoneNumber);
+
+ /**
+ * Determines whether two <tt>String</tt> phone numbers match.
+ *
+ * @param aPhoneNumber a <tt>String</tt> which represents a phone number to
+ * match to <tt>bPhoneNumber</tt>
+ * @param bPhoneNumber a <tt>String</tt> which represents a phone number to
+ * match to <tt>aPhoneNumber</tt>
+ * @return <tt>true</tt> if the specified <tt>String</tt>s match as phone
+ * numbers; otherwise, <tt>false</tt>
+ */
+ public boolean phoneNumbersMatch(String aPhoneNumber, String bPhoneNumber);
+
+ /**
+ * Indicates if the given string is possibly a phone number.
+ *
+ * @param possibleNumber the string to be verified
+ * @return <tt>true</tt> if the possibleNumber is a phone number,
+ * <tt>false</tt> - otherwise
+ */
+ public boolean isPhoneNumber(String possibleNumber);
+}
diff --git a/src/net/java/sip/communicator/service/protocol/ProtocolNames.java b/src/net/java/sip/communicator/service/protocol/ProtocolNames.java
index 8332557..ba51c91 100644
--- a/src/net/java/sip/communicator/service/protocol/ProtocolNames.java
+++ b/src/net/java/sip/communicator/service/protocol/ProtocolNames.java
@@ -44,16 +44,6 @@ public interface ProtocolNames
public static final String IRC = "IRC";
/**
- * The Gadu-Gadu protocol.
- */
- public static final String GADU_GADU = "Gadu-Gadu";
-
- /**
- * The GroupWise protocol.
- */
- public static final String GROUP_WISE = "GroupWise";
-
- /**
* The ICQ service protocol.
*/
public static final String ICQ = "ICQ";
@@ -64,26 +54,11 @@ public interface ProtocolNames
public static final String AIM = "AIM";
/**
- * The Yahoo! messenger protocol.
- */
- public static final String YAHOO = "Yahoo!";
-
- /**
- * The Skype protocol.
- */
- public static final String SKYPE = "Skype";
-
- /**
* The SIP Communicator MOCK protocol.
*/
public static final String SIP_COMMUNICATOR_MOCK = "sip-communicator-mock";
/**
- * The Zeroconf protocol.
- */
- public static final String ZEROCONF = "Zeroconf";
-
- /**
* The SSH protocol.
*/
public static final String SSH = "SSH";
@@ -92,14 +67,4 @@ public interface ProtocolNames
* The Gibberish protocol.
*/
public static final String GIBBERISH = "Gibberish";
-
- /**
- * The Dict protocol.
- */
- public static final String DICT = "Dict";
-
- /**
- * The Facebook protocol.
- */
- public static final String FACEBOOK = "Facebook";
}
diff --git a/src/net/java/sip/communicator/service/protocol/ProtocolProviderActivator.java b/src/net/java/sip/communicator/service/protocol/ProtocolProviderActivator.java
index 60cdf5c..a9d7c7c 100644
--- a/src/net/java/sip/communicator/service/protocol/ProtocolProviderActivator.java
+++ b/src/net/java/sip/communicator/service/protocol/ProtocolProviderActivator.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,295 +15,295 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.protocol;
-
-import net.java.sip.communicator.service.calendar.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.configuration.*;
-import org.jitsi.service.resources.*;
-import org.osgi.framework.*;
-
-import java.util.*;
-
-/**
- * Implements <code>BundleActivator</code> for the purposes of
- * protocol.jar/protocol.provider.manifest.mf and in order to register and start
- * services independent of the specifics of a particular protocol.
- *
- * @author Lubomir Marinov
- * @author Yana Stamcheva
- */
-public class ProtocolProviderActivator
- implements BundleActivator
-{
- /**
- * The object used for logging.
- */
- private final static Logger logger
- = Logger.getLogger(ProtocolProviderActivator.class);
-
- /**
- * The <code>ServiceRegistration</code> of the <code>AccountManager</code>
- * implementation registered as a service by this activator and cached so
- * that the service in question can be properly disposed of upon stopping
- * this activator.
- */
- private ServiceRegistration accountManagerServiceRegistration;
-
- /**
- * The account manager.
- */
- private static AccountManager accountManager;
-
- /**
- * The <code>BundleContext</code> of the one and only
- * <code>ProtocolProviderActivator</code> instance which is currently
- * started.
- */
- private static BundleContext bundleContext;
-
- /**
- * The <code>ConfigurationService</code> used by the classes in the bundle
- * represented by <code>ProtocolProviderActivator</code>.
- */
- private static ConfigurationService configurationService;
-
- /**
- * The resource service through which we obtain localized strings.
- */
- private static ResourceManagementService resourceService;
-
- /**
- * The calendar service instance.
- */
- private static CalendarService calendarService;
-
- /**
- * The <code>SingleCallInProgressPolicy</code> making sure that the
- * <code>Call</code>s accessible in the <code>BundleContext</code> of this
- * activator will obey to the rule that a new <code>Call</code> should put
- * the other existing <code>Call</code>s on hold.
- */
- private SingleCallInProgressPolicy singleCallInProgressPolicy;
-
- /**
- * Gets the <code>ConfigurationService</code> to be used by the classes in
- * the bundle represented by <code>ProtocolProviderActivator</code>.
- *
- * @return the <code>ConfigurationService</code> to be used by the classes
- * in the bundle represented by
- * <code>ProtocolProviderActivator</code>
- */
- public static ConfigurationService getConfigurationService()
- {
- if (configurationService == null)
- {
- configurationService
- = (ConfigurationService)
- bundleContext.getService(
- bundleContext.getServiceReference(
- ConfigurationService.class.getName()));
- }
- return configurationService;
- }
-
- /**
- * Gets the <code>ResourceManagementService</code> to be used by the classes
- * in the bundle represented by <code>ProtocolProviderActivator</code>.
- *
- * @return the <code>ResourceManagementService</code> to be used by the
- * classes in the bundle represented by
- * <code>ProtocolProviderActivator</code>
- */
- public static ResourceManagementService getResourceService()
- {
- if (resourceService == null)
- {
- resourceService
- = (ResourceManagementService)
- bundleContext.getService(
- bundleContext.getServiceReference(
- ResourceManagementService.class.getName()));
- }
- return resourceService;
- }
-
- /**
- * Gets the <code>CalendarService</code> to be used by the classes
- * in the bundle represented by <code>ProtocolProviderActivator</code>.
- *
- * @return the <code>CalendarService</code> to be used by the
- * classes in the bundle represented by
- * <code>ProtocolProviderActivator</code>
- */
- public static CalendarService getCalendarService()
- {
- if (calendarService == null)
- {
- ServiceReference serviceReference
- = bundleContext.getServiceReference(
- CalendarService.class.getName());
- if(serviceReference == null)
- return null;
- calendarService
- = (CalendarService)
- bundleContext.getService(serviceReference);
- }
- return calendarService;
- }
-
- /**
- * Returns a <tt>ProtocolProviderFactory</tt> for a given protocol
- * provider.
- * @param protocolName the name of the protocol, which factory we're
- * looking for
- * @return a <tt>ProtocolProviderFactory</tt> for a given protocol
- * provider
- */
- public static ProtocolProviderFactory getProtocolProviderFactory(
- String protocolName)
- {
- String osgiFilter
- = "(" + ProtocolProviderFactory.PROTOCOL + "=" + protocolName + ")";
- ProtocolProviderFactory protocolProviderFactory = null;
-
- try
- {
- ServiceReference[] serRefs
- = bundleContext.getServiceReferences(
- ProtocolProviderFactory.class.getName(),
- osgiFilter);
-
- if ((serRefs != null) && (serRefs.length != 0))
- {
- protocolProviderFactory
- = (ProtocolProviderFactory)
- bundleContext.getService(serRefs[0]);
- }
- }
- catch (InvalidSyntaxException ex)
- {
- if (logger.isInfoEnabled())
- logger.info("ProtocolProviderActivator : " + ex);
- }
-
- return protocolProviderFactory;
- }
-
- /**
- * Registers a new <code>AccountManagerImpl</code> instance as an
- * <code>AccountManager</code> service and starts a new
- * <code>SingleCallInProgressPolicy</code> instance to ensure that only one
- * of the <code>Call</code>s accessible in the <code>BundleContext</code>
- * in which this activator is to execute will be in progress and the others
- * will automatically be put on hold.
- *
- * @param bundleContext the <code>BundleContext</code> in which the bundle
- * activation represented by this <code>BundleActivator</code>
- * executes
- */
- public void start(BundleContext bundleContext)
- {
- ProtocolProviderActivator.bundleContext = bundleContext;
-
- accountManager = new AccountManager(bundleContext);
- accountManagerServiceRegistration =
- bundleContext.registerService(AccountManager.class.getName(),
- accountManager, null);
- if(logger.isTraceEnabled())
- {
- logger.trace("ProtocolProviderActivator will create "
- + "SingleCallInProgressPolicy instance.");
- }
-
- singleCallInProgressPolicy =
- new SingleCallInProgressPolicy(bundleContext);
- }
-
- /**
- * Unregisters the <code>AccountManagerImpl</code> instance registered as an
- * <code>AccountManager</code> service in {@link #start(BundleContext)} and
- * stops the <code>SingleCallInProgressPolicy</code> started there as well.
- *
- * @param bundleContext the <code>BundleContext</code> in which the bundle
- * activation represented by this <code>BundleActivator</code>
- * executes
- */
- public void stop(BundleContext bundleContext)
- {
- if (accountManagerServiceRegistration != null)
- {
- accountManagerServiceRegistration.unregister();
- accountManagerServiceRegistration = null;
- accountManager = null;
- }
-
- if (singleCallInProgressPolicy != null)
- {
- singleCallInProgressPolicy.dispose();
- singleCallInProgressPolicy = null;
- }
-
- if (bundleContext.equals(ProtocolProviderActivator.bundleContext))
- ProtocolProviderActivator.bundleContext = null;
-
- configurationService = null;
- resourceService = null;
- }
-
- /**
- * Returns all protocol providers currently registered.
- * @return all protocol providers currently registered.
- */
- public static List<ProtocolProviderService>
- getProtocolProviders()
- {
- ServiceReference[] serRefs = null;
- try
- {
- // get all registered provider factories
- serRefs = bundleContext.getServiceReferences(
- ProtocolProviderService.class.getName(),
- null);
- }
- catch (InvalidSyntaxException e)
- {
- logger.error("ProtocolProviderActivator : " + e);
- }
-
- List<ProtocolProviderService>
- providersList = new ArrayList<ProtocolProviderService>();
-
- if (serRefs != null)
- {
- for (ServiceReference serRef : serRefs)
- {
- ProtocolProviderService pp
- = (ProtocolProviderService)bundleContext.getService(serRef);
-
- providersList.add(pp);
- }
- }
- return providersList;
- }
-
- /**
- * Get the <tt>AccountManager</tt> of the protocol.
- *
- * @return <tt>AccountManager</tt> of the protocol
- */
- public static AccountManager getAccountManager()
- {
- return accountManager;
- }
-
- /**
- * Returns OSGI bundle context.
- * @return OSGI bundle context.
- */
- public static BundleContext getBundleContext()
- {
- return bundleContext;
- }
-}
+package net.java.sip.communicator.service.protocol;
+
+import net.java.sip.communicator.service.calendar.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.configuration.*;
+import org.jitsi.service.resources.*;
+import org.osgi.framework.*;
+
+import java.util.*;
+
+/**
+ * Implements <code>BundleActivator</code> for the purposes of
+ * protocol.jar/protocol.provider.manifest.mf and in order to register and start
+ * services independent of the specifics of a particular protocol.
+ *
+ * @author Lubomir Marinov
+ * @author Yana Stamcheva
+ */
+public class ProtocolProviderActivator
+ implements BundleActivator
+{
+ /**
+ * The object used for logging.
+ */
+ private final static Logger logger
+ = Logger.getLogger(ProtocolProviderActivator.class);
+
+ /**
+ * The <code>ServiceRegistration</code> of the <code>AccountManager</code>
+ * implementation registered as a service by this activator and cached so
+ * that the service in question can be properly disposed of upon stopping
+ * this activator.
+ */
+ private ServiceRegistration accountManagerServiceRegistration;
+
+ /**
+ * The account manager.
+ */
+ private static AccountManager accountManager;
+
+ /**
+ * The <code>BundleContext</code> of the one and only
+ * <code>ProtocolProviderActivator</code> instance which is currently
+ * started.
+ */
+ private static BundleContext bundleContext;
+
+ /**
+ * The <code>ConfigurationService</code> used by the classes in the bundle
+ * represented by <code>ProtocolProviderActivator</code>.
+ */
+ private static ConfigurationService configurationService;
+
+ /**
+ * The resource service through which we obtain localized strings.
+ */
+ private static ResourceManagementService resourceService;
+
+ /**
+ * The calendar service instance.
+ */
+ private static CalendarService calendarService;
+
+ /**
+ * The <code>SingleCallInProgressPolicy</code> making sure that the
+ * <code>Call</code>s accessible in the <code>BundleContext</code> of this
+ * activator will obey to the rule that a new <code>Call</code> should put
+ * the other existing <code>Call</code>s on hold.
+ */
+ private SingleCallInProgressPolicy singleCallInProgressPolicy;
+
+ /**
+ * Gets the <code>ConfigurationService</code> to be used by the classes in
+ * the bundle represented by <code>ProtocolProviderActivator</code>.
+ *
+ * @return the <code>ConfigurationService</code> to be used by the classes
+ * in the bundle represented by
+ * <code>ProtocolProviderActivator</code>
+ */
+ public static ConfigurationService getConfigurationService()
+ {
+ if (configurationService == null)
+ {
+ configurationService
+ = (ConfigurationService)
+ bundleContext.getService(
+ bundleContext.getServiceReference(
+ ConfigurationService.class.getName()));
+ }
+ return configurationService;
+ }
+
+ /**
+ * Gets the <code>ResourceManagementService</code> to be used by the classes
+ * in the bundle represented by <code>ProtocolProviderActivator</code>.
+ *
+ * @return the <code>ResourceManagementService</code> to be used by the
+ * classes in the bundle represented by
+ * <code>ProtocolProviderActivator</code>
+ */
+ public static ResourceManagementService getResourceService()
+ {
+ if (resourceService == null)
+ {
+ resourceService
+ = (ResourceManagementService)
+ bundleContext.getService(
+ bundleContext.getServiceReference(
+ ResourceManagementService.class.getName()));
+ }
+ return resourceService;
+ }
+
+ /**
+ * Gets the <code>CalendarService</code> to be used by the classes
+ * in the bundle represented by <code>ProtocolProviderActivator</code>.
+ *
+ * @return the <code>CalendarService</code> to be used by the
+ * classes in the bundle represented by
+ * <code>ProtocolProviderActivator</code>
+ */
+ public static CalendarService getCalendarService()
+ {
+ if (calendarService == null)
+ {
+ ServiceReference serviceReference
+ = bundleContext.getServiceReference(
+ CalendarService.class.getName());
+ if(serviceReference == null)
+ return null;
+ calendarService
+ = (CalendarService)
+ bundleContext.getService(serviceReference);
+ }
+ return calendarService;
+ }
+
+ /**
+ * Returns a <tt>ProtocolProviderFactory</tt> for a given protocol
+ * provider.
+ * @param protocolName the name of the protocol, which factory we're
+ * looking for
+ * @return a <tt>ProtocolProviderFactory</tt> for a given protocol
+ * provider
+ */
+ public static ProtocolProviderFactory getProtocolProviderFactory(
+ String protocolName)
+ {
+ String osgiFilter
+ = "(" + ProtocolProviderFactory.PROTOCOL + "=" + protocolName + ")";
+ ProtocolProviderFactory protocolProviderFactory = null;
+
+ try
+ {
+ ServiceReference[] serRefs
+ = bundleContext.getServiceReferences(
+ ProtocolProviderFactory.class.getName(),
+ osgiFilter);
+
+ if ((serRefs != null) && (serRefs.length != 0))
+ {
+ protocolProviderFactory
+ = (ProtocolProviderFactory)
+ bundleContext.getService(serRefs[0]);
+ }
+ }
+ catch (InvalidSyntaxException ex)
+ {
+ if (logger.isInfoEnabled())
+ logger.info("ProtocolProviderActivator : " + ex);
+ }
+
+ return protocolProviderFactory;
+ }
+
+ /**
+ * Registers a new <code>AccountManagerImpl</code> instance as an
+ * <code>AccountManager</code> service and starts a new
+ * <code>SingleCallInProgressPolicy</code> instance to ensure that only one
+ * of the <code>Call</code>s accessible in the <code>BundleContext</code>
+ * in which this activator is to execute will be in progress and the others
+ * will automatically be put on hold.
+ *
+ * @param bundleContext the <code>BundleContext</code> in which the bundle
+ * activation represented by this <code>BundleActivator</code>
+ * executes
+ */
+ public void start(BundleContext bundleContext)
+ {
+ ProtocolProviderActivator.bundleContext = bundleContext;
+
+ accountManager = new AccountManager(bundleContext);
+ accountManagerServiceRegistration =
+ bundleContext.registerService(AccountManager.class.getName(),
+ accountManager, null);
+ if(logger.isTraceEnabled())
+ {
+ logger.trace("ProtocolProviderActivator will create "
+ + "SingleCallInProgressPolicy instance.");
+ }
+
+ singleCallInProgressPolicy =
+ new SingleCallInProgressPolicy(bundleContext);
+ }
+
+ /**
+ * Unregisters the <code>AccountManagerImpl</code> instance registered as an
+ * <code>AccountManager</code> service in {@link #start(BundleContext)} and
+ * stops the <code>SingleCallInProgressPolicy</code> started there as well.
+ *
+ * @param bundleContext the <code>BundleContext</code> in which the bundle
+ * activation represented by this <code>BundleActivator</code>
+ * executes
+ */
+ public void stop(BundleContext bundleContext)
+ {
+ if (accountManagerServiceRegistration != null)
+ {
+ accountManagerServiceRegistration.unregister();
+ accountManagerServiceRegistration = null;
+ accountManager = null;
+ }
+
+ if (singleCallInProgressPolicy != null)
+ {
+ singleCallInProgressPolicy.dispose();
+ singleCallInProgressPolicy = null;
+ }
+
+ if (bundleContext.equals(ProtocolProviderActivator.bundleContext))
+ ProtocolProviderActivator.bundleContext = null;
+
+ configurationService = null;
+ resourceService = null;
+ }
+
+ /**
+ * Returns all protocol providers currently registered.
+ * @return all protocol providers currently registered.
+ */
+ public static List<ProtocolProviderService>
+ getProtocolProviders()
+ {
+ ServiceReference[] serRefs = null;
+ try
+ {
+ // get all registered provider factories
+ serRefs = bundleContext.getServiceReferences(
+ ProtocolProviderService.class.getName(),
+ null);
+ }
+ catch (InvalidSyntaxException e)
+ {
+ logger.error("ProtocolProviderActivator : " + e);
+ }
+
+ List<ProtocolProviderService>
+ providersList = new ArrayList<ProtocolProviderService>();
+
+ if (serRefs != null)
+ {
+ for (ServiceReference serRef : serRefs)
+ {
+ ProtocolProviderService pp
+ = (ProtocolProviderService)bundleContext.getService(serRef);
+
+ providersList.add(pp);
+ }
+ }
+ return providersList;
+ }
+
+ /**
+ * Get the <tt>AccountManager</tt> of the protocol.
+ *
+ * @return <tt>AccountManager</tt> of the protocol
+ */
+ public static AccountManager getAccountManager()
+ {
+ return accountManager;
+ }
+
+ /**
+ * Returns OSGI bundle context.
+ * @return OSGI bundle context.
+ */
+ public static BundleContext getBundleContext()
+ {
+ return bundleContext;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java b/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java
index 7e8b9c8..561a092 100644
--- a/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java
+++ b/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,1302 +15,1311 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.protocol;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.credentialsstorage.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.configuration.*;
-import org.osgi.framework.*;
-
-/**
- * The ProtocolProviderFactory is what actually creates instances of a
- * ProtocolProviderService implementation. A provider factory would register,
- * persistently store, and remove when necessary, ProtocolProviders. The way
- * things are in the SIP Communicator, a user account is represented (in a 1:1
- * relationship) by an AccountID and a ProtocolProvider. In other words - one
- * would have as many protocol providers installed in a given moment as they
- * would user account registered through the various services.
- *
- * @author Emil Ivov
- * @author Lubomir Marinov
- */
-public abstract class ProtocolProviderFactory
-{
- /**
- * The <tt>Logger</tt> used by the <tt>ProtocolProviderFactory</tt> class
- * and its instances for logging output.
- */
- private static final Logger logger
- = Logger.getLogger(ProtocolProviderFactory.class);
-
- /**
- * Then name of a property which represents a password.
- */
- public static final String PASSWORD = "PASSWORD";
-
- /**
- * The name of a property representing the name of the protocol for an
- * ProtocolProviderFactory.
- */
- public static final String PROTOCOL = "PROTOCOL_NAME";
-
- /**
- * The name of a property representing the path to protocol icons.
- */
- public static final String PROTOCOL_ICON_PATH = "PROTOCOL_ICON_PATH";
-
- /**
- * The name of a property representing the path to the account icon to
- * be used in the user interface, when the protocol provider service is not
- * available.
- */
- public static final String ACCOUNT_ICON_PATH = "ACCOUNT_ICON_PATH";
-
- /**
- * The name of a property which represents the AccountID of a
- * ProtocolProvider and that, together with a password is used to login
- * on the protocol network..
- */
- public static final String USER_ID = "USER_ID";
-
- /**
- * The name that should be displayed to others when we are calling or
- * writing them.
- */
- public static final String DISPLAY_NAME = "DISPLAY_NAME";
-
- /**
- * The name that should be displayed to the user on call via and chat via
- * lists.
- */
- public static final String ACCOUNT_DISPLAY_NAME = "ACCOUNT_DISPLAY_NAME";
-
- /**
- * The name of the property under which we store protocol AccountID-s.
- */
- public static final String ACCOUNT_UID = "ACCOUNT_UID";
-
- /**
- * The name of the property under which we store protocol the address of
- * a protocol centric entity (any protocol server).
- */
- public static final String SERVER_ADDRESS = "SERVER_ADDRESS";
-
- /**
- * The name of the property under which we store the number of the port
- * where the server stored against the SERVER_ADDRESS property is expecting
- * connections to be made via this protocol.
- */
- public static final String SERVER_PORT = "SERVER_PORT";
-
- /**
- * The name of the property under which we store the name of the transport
- * protocol that needs to be used to access the server.
- */
- public static final String SERVER_TRANSPORT = "SERVER_TRANSPORT";
-
- /**
- * The name of the property under which we store protocol the address of
- * a protocol proxy.
- */
- public static final String PROXY_ADDRESS = "PROXY_ADDRESS";
-
- /**
- * The name of the property under which we store the number of the port
- * where the proxy stored against the PROXY_ADDRESS property is expecting
- * connections to be made via this protocol.
- */
- public static final String PROXY_PORT = "PROXY_PORT";
-
- /**
- * The name of the property which defines whether proxy is auto configured
- * by the protocol by using known methods such as specific DNS queries.
- */
- public static final String PROXY_AUTO_CONFIG = "PROXY_AUTO_CONFIG";
-
- /**
- * The property indicating the preferred UDP and TCP
- * port to bind to for clear communications.
- */
- public static final String PREFERRED_CLEAR_PORT_PROPERTY_NAME
- = "net.java.sip.communicator.SIP_PREFERRED_CLEAR_PORT";
-
- /**
- * The property indicating the preferred TLS (TCP)
- * port to bind to for secure communications.
- */
- public static final String PREFERRED_SECURE_PORT_PROPERTY_NAME
- = "net.java.sip.communicator.SIP_PREFERRED_SECURE_PORT";
-
- /**
- * The name of the property under which we store the the type of the proxy
- * stored against the PROXY_ADDRESS property. Exact type values depend on
- * protocols and among them are socks4, socks5, http and possibly others.
- */
- public static final String PROXY_TYPE = "PROXY_TYPE";
-
- /**
- * The name of the property under which we store the the username for the
- * proxy stored against the PROXY_ADDRESS property.
- */
- public static final String PROXY_USERNAME = "PROXY_USERNAME";
-
- /**
- * The name of the property under which we store the the authorization name
- * for the proxy stored against the PROXY_ADDRESS property.
- */
- public static final String AUTHORIZATION_NAME = "AUTHORIZATION_NAME";
-
- /**
- * The name of the property under which we store the password for the proxy
- * stored against the PROXY_ADDRESS property.
- */
- public static final String PROXY_PASSWORD = "PROXY_PASSWORD";
-
- /**
- * The name of the property under which we store the name of the transport
- * protocol that needs to be used to access the proxy.
- */
- public static final String PROXY_TRANSPORT = "PROXY_TRANSPORT";
-
- /**
- * The name of the property that indicates whether loose routing should be
- * forced for all traffic in an account, rather than routing through an
- * outbound proxy which is the default for Jitsi.
- */
- public static final String FORCE_PROXY_BYPASS = "FORCE_PROXY_BYPASS";
-
- /**
- * The name of the property that indicates whether the client must
- * be registered with a registrar when making outgoing calls.
- */
- public static final String MUST_REGISTER_TO_CALL = "MUST_REGISTER_TO_CALL";
-
- /**
- * The name of the property under which we store the user preference for a
- * transport protocol to use (i.e. tcp or udp).
- */
- public static final String PREFERRED_TRANSPORT = "PREFERRED_TRANSPORT";
-
- /**
- * The name of the property under which we store whether we generate
- * resource values or we just use the stored one.
- */
- public static final String AUTO_GENERATE_RESOURCE = "AUTO_GENERATE_RESOURCE";
-
- /**
- * The name of the property under which we store resources such as the
- * jabber resource property.
- */
- public static final String RESOURCE = "RESOURCE";
-
- /**
- * The name of the property under which we store resource priority.
- */
- public static final String RESOURCE_PRIORITY = "RESOURCE_PRIORITY";
-
- /**
- * The name of the property which defines that the call is encrypted by
- * default
- */
- public static final String DEFAULT_ENCRYPTION = "DEFAULT_ENCRYPTION";
-
- /**
- * The name of the property that indicates the encryption protocols for this
- * account.
- */
- public static final String ENCRYPTION_PROTOCOL = "ENCRYPTION_PROTOCOL";
-
- /**
- * The name of the property that indicates the status (enabed or disabled)
- * encryption protocols for this account.
- */
- public static final String ENCRYPTION_PROTOCOL_STATUS
- = "ENCRYPTION_PROTOCOL_STATUS";
-
- /**
- * The name of the property which defines if to include the ZRTP attribute
- * to SIP/SDP
- */
- public static final String DEFAULT_SIPZRTP_ATTRIBUTE =
- "DEFAULT_SIPZRTP_ATTRIBUTE";
-
- /**
- * The name of the property which defines the ID of the client TLS
- * certificate configuration entry.
- */
- public static final String CLIENT_TLS_CERTIFICATE =
- "CLIENT_TLS_CERTIFICATE";
-
- /**
- * The name of the property under which we store the boolean value
- * indicating if the user name should be automatically changed if the
- * specified name already exists. This property is meant to be used by IRC
- * implementations.
- */
- public static final String AUTO_CHANGE_USER_NAME = "AUTO_CHANGE_USER_NAME";
-
- /**
- * The name of the property under which we store the boolean value
- * indicating if a password is required. Initially this property is meant to
- * be used by IRC implementations.
- */
- public static final String NO_PASSWORD_REQUIRED = "NO_PASSWORD_REQUIRED";
-
- /**
- * The name of the property under which we store if the presence is enabled.
- */
- public static final String IS_PRESENCE_ENABLED = "IS_PRESENCE_ENABLED";
-
- /**
- * The name of the property under which we store if the p2p mode for SIMPLE
- * should be forced.
- */
- public static final String FORCE_P2P_MODE = "FORCE_P2P_MODE";
-
- /**
- * The name of the property under which we store the offline contact polling
- * period for SIMPLE.
- */
- public static final String POLLING_PERIOD = "POLLING_PERIOD";
-
- /**
- * The name of the property under which we store the chosen default
- * subscription expiration value for SIMPLE.
- */
- public static final String SUBSCRIPTION_EXPIRATION
- = "SUBSCRIPTION_EXPIRATION";
-
- /**
- * Indicates if the server address has been validated.
- */
- public static final String SERVER_ADDRESS_VALIDATED
- = "SERVER_ADDRESS_VALIDATED";
-
- /**
- * Indicates if the server settings are over
- */
- public static final String IS_SERVER_OVERRIDDEN
- = "IS_SERVER_OVERRIDDEN";
- /**
- * Indicates if the proxy address has been validated.
- */
- public static final String PROXY_ADDRESS_VALIDATED
- = "PROXY_ADDRESS_VALIDATED";
-
- /**
- * Indicates the search strategy chosen for the DICT protocole.
- */
- public static final String STRATEGY = "STRATEGY";
-
- /**
- * Indicates a protocol that would not be shown in the user interface as an
- * account.
- */
- public static final String IS_PROTOCOL_HIDDEN = "IS_PROTOCOL_HIDDEN";
-
- /**
- * Indicates if the given account is the preferred account.
- */
- public static final String IS_PREFERRED_PROTOCOL = "IS_PREFERRED_PROTOCOL";
-
- /**
- * The name of the property that would indicate if a given account is
- * currently enabled or disabled.
- */
- public static final String IS_ACCOUNT_DISABLED = "IS_ACCOUNT_DISABLED";
-
- /**
- * The name of the property that would indicate if a given account
- * configuration form is currently hidden.
- */
- public static final String IS_ACCOUNT_CONFIG_HIDDEN = "IS_CONFIG_HIDDEN";
-
- /**
- * The name of the property that would indicate if a given account
- * status menu is currently hidden.
- */
- public static final String IS_ACCOUNT_STATUS_MENU_HIDDEN =
- "IS_STATUS_MENU_HIDDEN";
-
- /**
- * The name of the property that would indicate if a given account
- * configuration is read only.
- */
- public static final String IS_ACCOUNT_READ_ONLY = "IS_READ_ONLY";
-
- /**
- * The name of the property that would indicate if a given account
- * groups are readonly, values can be all or a comma separated
- * group names including root.
- */
- public static final String ACCOUNT_READ_ONLY_GROUPS = "READ_ONLY_GROUPS";
-
- /**
- * Indicates if ICE should be used.
- */
- public static final String IS_USE_ICE = "ICE_ENABLED";
-
- /**
- * Indicates if STUN server should be automatically discovered.
- */
- public static final String AUTO_DISCOVER_STUN = "AUTO_DISCOVER_STUN";
-
- /**
- * Indicates if default STUN server would be used if no other STUN/TURN
- * server are available.
- */
- public static final String USE_DEFAULT_STUN_SERVER
- = "USE_DEFAULT_STUN_SERVER";
-
- /**
- * The name of the boolean account property which indicates whether Jitsi
- * Videobridge is to be used, if available and supported, for conference
- * calls.
- */
- public static final String USE_JITSI_VIDEO_BRIDGE
- = "USE_JITSI_VIDEO_BRIDGE";
-
- /**
- * The property name prefix for all stun server properties. We generally use
- * this prefix in conjunction with an index which is how we store multiple
- * servers.
- */
- public static final String STUN_PREFIX = "STUN";
-
- /**
- * The base property name for address of additional STUN servers specified.
- */
- public static final String STUN_ADDRESS = "ADDRESS";
-
- /**
- * The base property name for port of additional STUN servers specified.
- */
- public static final String STUN_PORT = "PORT";
-
- /**
- * The base property name for username of additional STUN servers specified.
- */
- public static final String STUN_USERNAME = "USERNAME";
-
- /**
- * The base property name for password of additional STUN servers specified.
- */
- public static final String STUN_PASSWORD = "PASSWORD";
-
- /**
- * The base property name for the turn supported property of additional
- * STUN servers specified.
- */
- public static final String STUN_IS_TURN_SUPPORTED = "IS_TURN_SUPPORTED";
-
- /**
- * Indicates if JingleNodes should be used with ICE.
- */
- public static final String IS_USE_JINGLE_NODES = "JINGLE_NODES_ENABLED";
-
- /**
- * Indicates if JingleNodes should be used with ICE.
- */
- public static final String AUTO_DISCOVER_JINGLE_NODES
- = "AUTO_DISCOVER_JINGLE_NODES";
-
- /**
- * Indicates if JingleNodes should use buddies to search for nodes.
- */
- public static final String JINGLE_NODES_SEARCH_BUDDIES
- = "JINGLE_NODES_SEARCH_BUDDIES";
-
- /**
- * Indicates if UPnP should be used with ICE.
- */
- public static final String IS_USE_UPNP = "UPNP_ENABLED";
-
- /**
- * Indicates if we allow non-TLS connection.
- */
- public static final String IS_ALLOW_NON_SECURE = "ALLOW_NON_SECURE";
-
- /**
- * Enable notifications for new voicemail messages.
- */
- public static final String VOICEMAIL_ENABLED = "VOICEMAIL_ENABLED";
-
- /**
- * Address used to reach voicemail box, by services able to
- * subscribe for voicemail new messages notifications.
- */
- public static final String VOICEMAIL_URI = "VOICEMAIL_URI";
-
- /**
- * Address used to call to hear your messages stored on the server
- * for your voicemail.
- */
- public static final String VOICEMAIL_CHECK_URI = "VOICEMAIL_CHECK_URI";
-
- /**
- * Indicates if calling is disabled for a certain account.
- */
- public static final String IS_CALLING_DISABLED_FOR_ACCOUNT
- = "CALLING_DISABLED";
-
- /**
- * Indicates if desktop streaming/sharing is disabled for a certain account.
- */
- public static final String IS_DESKTOP_STREAMING_DISABLED
- = "DESKTOP_STREAMING_DISABLED";
-
- /**
- * Indicates if desktop remote control is disabled for a certain account.
- */
- public static final String IS_DESKTOP_REMOTE_CONTROL_DISABLED
- = "DESKTOP_REMOTE_CONTROL_DISABLED";
-
- /**
- * The sms default server address.
- */
- public static final String SMS_SERVER_ADDRESS = "SMS_SERVER_ADDRESS";
-
- /**
- * Keep-alive method used by the protocol.
- */
- public static final String KEEP_ALIVE_METHOD = "KEEP_ALIVE_METHOD";
-
- /**
- * The interval for keep-alives if any.
- */
- public static final String KEEP_ALIVE_INTERVAL = "KEEP_ALIVE_INTERVAL";
-
- /**
- * The name of the property holding DTMF method.
- */
- public static final String DTMF_METHOD = "DTMF_METHOD";
-
- /**
- * The minimal DTMF tone duration.
- */
- public static final String DTMF_MINIMAL_TONE_DURATION
- = "DTMF_MINIMAL_TONE_DURATION";
-
- /**
- * Paranoia mode when turned on requires all calls to be secure and
- * indicated as such.
- */
- public static final String MODE_PARANOIA = "MODE_PARANOIA";
-
- /**
- * The name of the "override encodings" property
- */
- public static final String OVERRIDE_ENCODINGS = "OVERRIDE_ENCODINGS";
-
- /**
- * The prefix used to store account encoding properties
- */
- public static final String ENCODING_PROP_PREFIX = "Encodings";
-
- /**
- * An account property to provide a connected account to check for
- * its status. Used when the current provider need to reject calls
- * but is missing presence operation set and need to check other
- * provider for status.
- */
- public static final String CUSAX_PROVIDER_ACCOUNT_PROP
- = "cusax.XMPP_ACCOUNT_ID";
-
- /**
- * The <code>BundleContext</code> containing (or to contain) the service
- * registration of this factory.
- */
- private final BundleContext bundleContext;
-
- /**
- * The name of the protocol this factory registers its
- * <code>ProtocolProviderService</code>s with and to be placed in the
- * properties of the accounts created by this factory.
- */
- private final String protocolName;
-
- /**
- * The table that we store our accounts in.
- * <p>
- * TODO Synchronize the access to the field which may in turn be better
- * achieved by also hiding it from protected into private access.
- * </p>
- */
- protected final Map<AccountID, ServiceRegistration<ProtocolProviderService>>
- registeredAccounts
- = new HashMap<AccountID, ServiceRegistration<ProtocolProviderService>>();
-
- /**
- * The name of the property that indicates the AVP type.
- * <ul>
- * <li>{@link #SAVP_OFF}</li>
- * <li>{@link #SAVP_MANDATORY}</li>
- * <li>{@link #SAVP_OPTIONAL}</li>
- * </ul>
- */
- public static final String SAVP_OPTION = "SAVP_OPTION";
-
- /**
- * Always use RTP/AVP
- */
- public static final int SAVP_OFF = 0;
-
- /**
- * Always use RTP/SAVP
- */
- public static final int SAVP_MANDATORY = 1;
-
- /**
- * Sends two media description, with RTP/SAVP being first.
- */
- public static final int SAVP_OPTIONAL = 2;
-
- /**
- * The name of the property that defines the enabled SDES cipher suites.
- * Enabled suites are listed as CSV by their RFC name.
- */
- public static final String SDES_CIPHER_SUITES = "SDES_CIPHER_SUITES";
-
- /**
- * The name of the property that defines the enabled/disabled state of
- * message carbons.
- */
- public static final String IS_CARBON_DISABLED = "CARBON_DISABLED";
-
- /**
- * Creates a new <tt>ProtocolProviderFactory</tt>.
- *
- * @param bundleContext the bundle context reference of the service
- * @param protocolName the name of the protocol
- */
- protected ProtocolProviderFactory(BundleContext bundleContext,
- String protocolName)
- {
- this.bundleContext = bundleContext;
- this.protocolName = protocolName;
- }
-
- /**
- * Gets the <code>BundleContext</code> containing (or to contain) the
- * service registration of this factory.
- *
- * @return the <code>BundleContext</code> containing (or to contain) the
- * service registration of this factory
- */
- public BundleContext getBundleContext()
- {
- return bundleContext;
- }
-
- /**
- * Initializes and creates an account corresponding to the specified
- * accountProperties and registers the resulting ProtocolProvider in the
- * <tt>context</tt> BundleContext parameter. Note that account
- * registration is persistent and accounts that are registered during
- * a particular sip-communicator session would be automatically reloaded
- * during all following sessions until they are removed through the
- * removeAccount method.
- *
- * @param userID the user identifier uniquely representing the newly
- * created account within the protocol namespace.
- * @param accountProperties a set of protocol (or implementation) specific
- * properties defining the new account.
- * @return the AccountID of the newly created account.
- * @throws java.lang.IllegalArgumentException if userID does not correspond
- * to an identifier in the context of the underlying protocol or if
- * accountProperties does not contain a complete set of account installation
- * properties.
- * @throws java.lang.IllegalStateException if the account has already been
- * installed.
- * @throws java.lang.NullPointerException if any of the arguments is null.
- */
- public abstract AccountID installAccount(String userID,
- Map<String, String> accountProperties)
- throws IllegalArgumentException,
- IllegalStateException,
- NullPointerException;
-
-
- /**
- * Modifies the account corresponding to the specified accountID. This
- * method is meant to be used to change properties of already existing
- * accounts. Note that if the given accountID doesn't correspond to any
- * registered account this method would do nothing.
- *
- * @param protocolProvider the protocol provider service corresponding to
- * the modified account.
- * @param accountProperties a set of protocol (or implementation) specific
- * properties defining the new account.
- *
- * @throws java.lang.NullPointerException if any of the arguments is null.
- */
- public abstract void modifyAccount(
- ProtocolProviderService protocolProvider,
- Map<String, String> accountProperties)
- throws NullPointerException;
-
- /**
- * Returns a copy of the list containing the <tt>AccountID</tt>s of all
- * accounts currently registered in this protocol provider.
- * @return a copy of the list containing the <tt>AccountID</tt>s of all
- * accounts currently registered in this protocol provider.
- */
- public ArrayList<AccountID> getRegisteredAccounts()
- {
- synchronized (registeredAccounts)
- {
- return new ArrayList<AccountID>(registeredAccounts.keySet());
- }
- }
-
- /**
- * Returns the ServiceReference for the protocol provider corresponding to
- * the specified accountID or null if the accountID is unknown.
- * @param accountID the accountID of the protocol provider we'd like to get
- * @return a ServiceReference object to the protocol provider with the
- * specified account id and null if the account id is unknown to the
- * provider factory.
- */
- public ServiceReference<ProtocolProviderService> getProviderForAccount(
- AccountID accountID)
- {
- ServiceRegistration<ProtocolProviderService> registration;
-
- synchronized (registeredAccounts)
- {
- registration = registeredAccounts.get(accountID);
- }
-
- try
- {
- if (registration != null)
- return registration.getReference();
- }
- catch (IllegalStateException ise)
- {
- synchronized (registeredAccounts)
- {
- registeredAccounts.remove(accountID);
- }
- }
-
- return null;
- }
-
- /**
- * Removes the specified account from the list of accounts that this
- * provider factory is handling. If the specified accountID is unknown to
- * the ProtocolProviderFactory, the call has no effect and false is
- * returned. This method is persistent in nature and once called the account
- * corresponding to the specified ID will not be loaded during future runs
- * of the project.
- *
- * @param accountID the ID of the account to remove.
- * @return true if an account with the specified ID existed and was removed
- * and false otherwise.
- */
- public boolean uninstallAccount(AccountID accountID)
- {
- // Unregister the protocol provider.
- ServiceReference<ProtocolProviderService> serRef
- = getProviderForAccount(accountID);
-
- boolean wasAccountExisting = false;
-
- // If the protocol provider service is registered, first unregister the
- // service.
- if (serRef != null)
- {
- BundleContext bundleContext = getBundleContext();
- ProtocolProviderService protocolProvider
- = bundleContext.getService(serRef);
-
- try
- {
- protocolProvider.unregister();
- }
- catch (OperationFailedException ex)
- {
- logger.error(
- "Failed to unregister protocol provider for account: "
- + accountID + " caused by: " + ex);
- }
- }
-
- ServiceRegistration<ProtocolProviderService> registration;
-
- synchronized (registeredAccounts)
- {
- registration = registeredAccounts.remove(accountID);
- }
-
- // first remove the stored account so when PP is unregistered we can
- // distinguish between deleted or just disabled account
- wasAccountExisting = removeStoredAccount(accountID);
-
- if (registration != null)
- {
- // Kill the service.
- registration.unregister();
- }
-
- return wasAccountExisting;
- }
-
- /**
- * The method stores the specified account in the configuration service
- * under the package name of the source factory. The restore and remove
- * account methods are to be used to obtain access to and control the stored
- * accounts.
- * <p>
- * In order to store all account properties, the method would create an
- * entry in the configuration service corresponding (beginning with) the
- * <tt>sourceFactory</tt>'s package name and add to it a unique identifier
- * (e.g. the current miliseconds.)
- * </p>
- *
- * @param accountID the AccountID corresponding to the account that we would
- * like to store.
- */
- protected void storeAccount(AccountID accountID)
- {
- this.storeAccount(accountID, true);
- }
-
- /**
- * The method stores the specified account in the configuration service
- * under the package name of the source factory. The restore and remove
- * account methods are to be used to obtain access to and control the stored
- * accounts.
- * <p>
- * In order to store all account properties, the method would create an
- * entry in the configuration service corresponding (beginning with) the
- * <tt>sourceFactory</tt>'s package name and add to it a unique identifier
- * (e.g. the current miliseconds.)
- * </p>
- *
- * @param accountID the AccountID corresponding to the account that we would
- * like to store.
- * @param isModification if <tt>false</tt> there must be no such already
- * loaded account, it <tt>true</tt> ist modification of an existing account.
- * Usually we use this method with <tt>false</tt> in method installAccount
- * and with <tt>true</tt> or the overridden method in method
- * modifyAccount.
- */
- protected void storeAccount(AccountID accountID, boolean isModification)
- {
- if(!isModification
- && getAccountManager().getStoredAccounts().contains(accountID))
- {
- throw new IllegalStateException(
- "An account for id " + accountID.getUserID()
- + " was already loaded!");
- }
-
- try
- {
- getAccountManager().storeAccount(this, accountID);
- }
- catch (OperationFailedException ofex)
- {
- throw new UndeclaredThrowableException(ofex);
- }
- }
-
- /**
- * Saves the password for the specified account after scrambling it a bit so
- * that it is not visible from first sight. (The method remains highly
- * insecure).
- *
- * @param accountID the AccountID for the account whose password we're
- * storing
- * @param password the password itself
- *
- * @throws IllegalArgumentException if no account corresponding to
- * <code>accountID</code> has been previously stored
- */
- public void storePassword(AccountID accountID, String password)
- throws IllegalArgumentException
- {
- try
- {
- storePassword(getBundleContext(), accountID, password);
- }
- catch (OperationFailedException ofex)
- {
- throw new UndeclaredThrowableException(ofex);
- }
- }
-
- /**
- * Saves the password for the specified account after scrambling it a bit
- * so that it is not visible from first sight (Method remains highly
- * insecure).
- * <p>
- * TODO Delegate the implementation to {@link AccountManager} because it
- * knows the format in which the password (among the other account
- * properties) is to be saved.
- * </p>
- *
- * @param bundleContext a currently valid bundle context.
- * @param accountID the <tt>AccountID</tt> of the account whose password is
- * to be stored
- * @param password the password to be stored
- *
- * @throws IllegalArgumentException if no account corresponding to
- * <tt>accountID</tt> has been previously stored.
- * @throws OperationFailedException if anything goes wrong while storing the
- * specified <tt>password</tt>
- */
- protected void storePassword(BundleContext bundleContext,
- AccountID accountID,
- String password)
- throws IllegalArgumentException,
- OperationFailedException
- {
- String accountPrefix
- = findAccountPrefix(
- bundleContext,
- accountID,
- getFactoryImplPackageName());
-
- if (accountPrefix == null)
- {
- throw
- new IllegalArgumentException(
- "No previous records found for account ID: "
- + accountID.getAccountUniqueID()
- + " in package"
- + getFactoryImplPackageName());
- }
-
- CredentialsStorageService credentialsStorage
- = ServiceUtils.getService(
- bundleContext,
- CredentialsStorageService.class);
-
- if (!credentialsStorage.storePassword(accountPrefix, password))
- {
- throw
- new OperationFailedException(
- "CredentialsStorageService failed to storePassword",
- OperationFailedException.GENERAL_ERROR);
- }
-
- // Update password property also in the AccountID
- // to prevent it from being removed during account reload
- // in some cases.
- accountID.setPassword(password);
-
- }
-
- /**
- * Returns the password last saved for the specified account.
- *
- * @param accountID the AccountID for the account whose password we're
- * looking for
- *
- * @return a String containing the password for the specified accountID
- */
- public String loadPassword(AccountID accountID)
- {
- return loadPassword(getBundleContext(), accountID);
- }
-
- /**
- * Returns the password last saved for the specified account.
- * <p>
- * TODO Delegate the implementation to {@link AccountManager} because it
- * knows the format in which the password (among the other account
- * properties) was saved.
- * </p>
- *
- * @param bundleContext a currently valid bundle context.
- * @param accountID the AccountID for the account whose password we're
- * looking for..
- *
- * @return a String containing the password for the specified accountID.
- */
- protected String loadPassword(BundleContext bundleContext,
- AccountID accountID)
- {
- String accountPrefix = findAccountPrefix(
- bundleContext, accountID, getFactoryImplPackageName());
-
- if (accountPrefix == null)
- return null;
-
- CredentialsStorageService credentialsStorage
- = ServiceUtils.getService(
- bundleContext,
- CredentialsStorageService.class);
-
- return credentialsStorage.loadPassword(accountPrefix);
- }
-
- /**
- * Initializes and creates an account corresponding to the specified
- * accountProperties and registers the resulting ProtocolProvider in the
- * <tt>context</tt> BundleContext parameter. This method has a persistent
- * effect. Once created the resulting account will remain installed until
- * removed through the uninstallAccount method.
- *
- * @param accountProperties a set of protocol (or implementation) specific
- * properties defining the new account.
- * @return the AccountID of the newly loaded account
- */
- public AccountID loadAccount(Map<String, String> accountProperties)
- {
- AccountID accountID = createAccount(accountProperties);
-
- loadAccount(accountID);
-
- return accountID;
- }
-
- /**
- * Creates a protocol provider for the given <tt>accountID</tt> and
- * registers it in the bundle context. This method has a persistent
- * effect. Once created the resulting account will remain installed until
- * removed through the uninstallAccount method.
- *
- * @param accountID the account identifier
- * @return <tt>true</tt> if the account with the given <tt>accountID</tt> is
- * successfully loaded, otherwise returns <tt>false</tt>
- */
- public boolean loadAccount(AccountID accountID)
- {
- // Need to obtain the original user id property, instead of calling
- // accountID.getUserID(), because this method could return a modified
- // version of the user id property.
- String userID
- = accountID.getAccountPropertyString(
- ProtocolProviderFactory.USER_ID);
-
- ProtocolProviderService service = createService(userID, accountID);
-
- Dictionary<String, String> properties = new Hashtable<String, String>();
- properties.put(PROTOCOL, protocolName);
- properties.put(USER_ID, userID);
-
- ServiceRegistration<ProtocolProviderService> serviceRegistration
- = bundleContext.registerService(
- ProtocolProviderService.class,
- service,
- properties);
-
- if (serviceRegistration == null)
- {
- return false;
- }
- else
- {
- synchronized (registeredAccounts)
- {
- registeredAccounts.put(accountID, serviceRegistration);
- }
- return true;
- }
- }
-
- /**
- * Unloads the account corresponding to the given <tt>accountID</tt>.
- * Unregisters the corresponding protocol provider, but keeps the account in
- * contrast to the uninstallAccount method.
- *
- * @param accountID the account identifier
- * @return true if an account with the specified ID existed and was unloaded
- * and false otherwise.
- */
- public boolean unloadAccount(AccountID accountID)
- {
- // Unregister the protocol provider.
- ServiceReference<ProtocolProviderService> serRef
- = getProviderForAccount(accountID);
-
- if (serRef == null)
- {
- return false;
- }
-
- BundleContext bundleContext = getBundleContext();
- ProtocolProviderService protocolProvider
- = bundleContext.getService(serRef);
-
- try
- {
- protocolProvider.unregister();
- }
- catch (OperationFailedException ex)
- {
- logger.error(
- "Failed to unregister protocol provider for account: "
- + accountID + " caused by: " + ex);
- }
-
- ServiceRegistration<ProtocolProviderService> registration;
-
- synchronized (registeredAccounts)
- {
- registration = registeredAccounts.remove(accountID);
- }
- if (registration == null)
- {
- return false;
- }
-
- // Kill the service.
- registration.unregister();
-
- return true;
- }
-
- /**
- * Initializes and creates an account corresponding to the specified
- * accountProperties.
- *
- * @param accountProperties a set of protocol (or implementation) specific
- * properties defining the new account.
- * @return the AccountID of the newly created account
- */
- public AccountID createAccount(Map<String, String> accountProperties)
- {
- BundleContext bundleContext = getBundleContext();
- if (bundleContext == null)
- throw new NullPointerException(
- "The specified BundleContext was null");
-
- if (accountProperties == null)
- throw new NullPointerException(
- "The specified property map was null");
-
- String userID = accountProperties.get(USER_ID);
- if (userID == null)
- throw new NullPointerException(
- "The account properties contained no user id.");
-
- String protocolName = getProtocolName();
- if (!accountProperties.containsKey(PROTOCOL))
- accountProperties.put(PROTOCOL, protocolName);
-
- return createAccountID(userID, accountProperties);
- }
-
- /**
- * Creates a new <code>AccountID</code> instance with a specific user ID to
- * represent a given set of account properties.
- * <p>
- * The method is a pure factory allowing implementers to specify the runtime
- * type of the created <code>AccountID</code> and customize the instance.
- * The returned <code>AccountID</code> will later be associated with a
- * <code>ProtocolProviderService</code> by the caller (e.g. using
- * {@link #createService(String, AccountID)}).
- * </p>
- *
- * @param userID the user ID of the new instance
- * @param accountProperties the set of properties to be represented by the
- * new instance
- * @return a new <code>AccountID</code> instance with the specified user ID
- * representing the given set of account properties
- */
- protected abstract AccountID createAccountID(
- String userID, Map<String, String> accountProperties);
-
- /**
- * Gets the name of the protocol this factory registers its
- * <code>ProtocolProviderService</code>s with and to be placed in the
- * properties of the accounts created by this factory.
- *
- * @return the name of the protocol this factory registers its
- * <code>ProtocolProviderService</code>s with and to be placed in
- * the properties of the accounts created by this factory
- */
- public String getProtocolName()
- {
- return protocolName;
- }
-
- /**
- * Initializes a new <code>ProtocolProviderService</code> instance with a
- * specific user ID to represent a specific <code>AccountID</code>.
- * <p>
- * The method is a pure factory allowing implementers to specify the runtime
- * type of the created <code>ProtocolProviderService</code> and customize
- * the instance. The caller will later register the returned service with
- * the <code>BundleContext</code> of this factory.
- * </p>
- *
- * @param userID the user ID to initialize the new instance with
- * @param accountID the <code>AccountID</code> to be represented by the new
- * instance
- * @return a new <code>ProtocolProviderService</code> instance with the
- * specific user ID representing the specified
- * <code>AccountID</code>
- */
- protected abstract ProtocolProviderService createService(String userID,
- AccountID accountID);
-
- /**
- * Removes the account with <tt>accountID</tt> from the set of accounts
- * that are persistently stored inside the configuration service.
- *
- * @param accountID the AccountID of the account to remove.
- *
- * @return true if an account has been removed and false otherwise.
- */
- protected boolean removeStoredAccount(AccountID accountID)
- {
- return getAccountManager().removeStoredAccount(this, accountID);
- }
-
- /**
- * Returns the prefix for all persistently stored properties of the account
- * with the specified id.
- * @param bundleContext a currently valid bundle context.
- * @param accountID the AccountID of the account whose properties we're
- * looking for.
- * @param sourcePackageName a String containing the package name of the
- * concrete factory class that extends us.
- * @return a String indicating the ConfigurationService property name
- * prefix under which all account properties are stored or null if no
- * account corresponding to the specified id was found.
- */
- public static String findAccountPrefix(BundleContext bundleContext,
- AccountID accountID,
- String sourcePackageName)
- {
- ServiceReference<ConfigurationService> confReference
- = bundleContext.getServiceReference(ConfigurationService.class);
- ConfigurationService configurationService
- = bundleContext.getService(confReference);
-
- //first retrieve all accounts that we've registered
- List<String> storedAccounts =
- configurationService.getPropertyNamesByPrefix(sourcePackageName,
- true);
-
- //find an account with the corresponding id.
- for (String accountRootPropertyName : storedAccounts)
- {
- //unregister the account in the configuration service.
- //all the properties must have been registered in the following
- //hierarchy:
- //net.java.sip.communicator.impl.protocol.PROTO_NAME.ACC_ID.PROP_NAME
- String accountUID = configurationService.getString(
- accountRootPropertyName //node id
- + "." + ACCOUNT_UID); // propname
-
- if (accountID.getAccountUniqueID().equals(accountUID))
- {
- return accountRootPropertyName;
- }
- }
- return null;
- }
-
- /**
- * Returns the name of the package that we're currently running in (i.e.
- * the name of the package containing the proto factory that extends us).
- *
- * @return a String containing the package name of the concrete factory
- * class that extends us.
- */
- private String getFactoryImplPackageName()
- {
- String className = getClass().getName();
-
- return className.substring(0, className.lastIndexOf('.'));
- }
-
- /**
- * Prepares the factory for bundle shutdown.
- */
- public void stop()
- {
- if (logger.isTraceEnabled())
- logger.trace("Preparing to stop all protocol providers of" + this);
-
- synchronized (registeredAccounts)
- {
- for (ServiceRegistration<ProtocolProviderService> reg
- : registeredAccounts.values())
- {
- stop(reg);
- reg.unregister();
- }
-
- registeredAccounts.clear();
- }
- }
-
- /**
- * Shuts down the <code>ProtocolProviderService</code> representing an
- * account registered with this factory.
- *
- * @param registeredAccount the <code>ServiceRegistration</code> of the
- * <code>ProtocolProviderService</code> representing an account
- * registered with this factory
- */
- protected void stop(
- ServiceRegistration<ProtocolProviderService> registeredAccount)
- {
- ProtocolProviderService protocolProviderService
- = getBundleContext().getService(registeredAccount.getReference());
-
- protocolProviderService.shutdown();
- }
-
- /**
- * Get the <tt>AccountManager</tt> of the protocol.
- *
- * @return <tt>AccountManager</tt> of the protocol
- */
- private AccountManager getAccountManager()
- {
- BundleContext bundleContext = getBundleContext();
- ServiceReference<AccountManager> serviceReference
- = bundleContext.getServiceReference(AccountManager.class);
-
- return bundleContext.getService(serviceReference);
- }
-
-
- /**
- * Finds registered <tt>ProtocolProviderFactory</tt> for given
- * <tt>protocolName</tt>.
- * @param bundleContext the OSGI bundle context that will be used.
- * @param protocolName the protocol name.
- * @return Registered <tt>ProtocolProviderFactory</tt> for given protocol
- * name or <tt>null</tt> if no provider was found.
- */
- static public ProtocolProviderFactory getProtocolProviderFactory(
- BundleContext bundleContext,
- String protocolName)
- {
- Collection<ServiceReference<ProtocolProviderFactory>> serRefs;
- String osgiFilter
- = "(" + ProtocolProviderFactory.PROTOCOL + "=" + protocolName + ")";
-
- try
- {
- serRefs
- = bundleContext.getServiceReferences(
- ProtocolProviderFactory.class,
- osgiFilter);
- }
- catch (InvalidSyntaxException ex)
- {
- serRefs = null;
- logger.error(ex);
- }
- if ((serRefs == null) || serRefs.isEmpty())
- return null;
- else
- return bundleContext.getService(serRefs.iterator().next());
- }
-}
+package net.java.sip.communicator.service.protocol;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import net.java.sip.communicator.service.credentialsstorage.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.configuration.*;
+import org.osgi.framework.*;
+
+/**
+ * The ProtocolProviderFactory is what actually creates instances of a
+ * ProtocolProviderService implementation. A provider factory would register,
+ * persistently store, and remove when necessary, ProtocolProviders. The way
+ * things are in the SIP Communicator, a user account is represented (in a 1:1
+ * relationship) by an AccountID and a ProtocolProvider. In other words - one
+ * would have as many protocol providers installed in a given moment as they
+ * would user account registered through the various services.
+ *
+ * @author Emil Ivov
+ * @author Lubomir Marinov
+ */
+public abstract class ProtocolProviderFactory
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>ProtocolProviderFactory</tt> class
+ * and its instances for logging output.
+ */
+ private static final Logger logger
+ = Logger.getLogger(ProtocolProviderFactory.class);
+
+ /**
+ * Then name of a property which represents a password.
+ */
+ public static final String PASSWORD = "PASSWORD";
+
+ /**
+ * The name of a property representing the name of the protocol for an
+ * ProtocolProviderFactory.
+ */
+ public static final String PROTOCOL = "PROTOCOL_NAME";
+
+ /**
+ * The name of a property representing the path to protocol icons.
+ */
+ public static final String PROTOCOL_ICON_PATH = "PROTOCOL_ICON_PATH";
+
+ /**
+ * The name of a property representing the path to the account icon to
+ * be used in the user interface, when the protocol provider service is not
+ * available.
+ */
+ public static final String ACCOUNT_ICON_PATH = "ACCOUNT_ICON_PATH";
+
+ /**
+ * The name of a property which represents the AccountID of a
+ * ProtocolProvider and that, together with a password is used to login
+ * on the protocol network..
+ */
+ public static final String USER_ID = "USER_ID";
+
+ /**
+ * The name that should be displayed to others when we are calling or
+ * writing them.
+ */
+ public static final String DISPLAY_NAME = "DISPLAY_NAME";
+
+ /**
+ * The name that should be displayed to the user on call via and chat via
+ * lists.
+ */
+ public static final String ACCOUNT_DISPLAY_NAME = "ACCOUNT_DISPLAY_NAME";
+
+ /**
+ * The name of the property under which we store protocol AccountID-s.
+ */
+ public static final String ACCOUNT_UID = "ACCOUNT_UID";
+
+ /**
+ * The name of the property under which we store protocol the address of
+ * a protocol centric entity (any protocol server).
+ */
+ public static final String SERVER_ADDRESS = "SERVER_ADDRESS";
+
+ /**
+ * The name of the property under which we store the number of the port
+ * where the server stored against the SERVER_ADDRESS property is expecting
+ * connections to be made via this protocol.
+ */
+ public static final String SERVER_PORT = "SERVER_PORT";
+
+ /**
+ * The name of the property under which we store the name of the transport
+ * protocol that needs to be used to access the server.
+ */
+ public static final String SERVER_TRANSPORT = "SERVER_TRANSPORT";
+
+ /**
+ * The name of the property under which we store protocol the address of
+ * a protocol proxy.
+ */
+ public static final String PROXY_ADDRESS = "PROXY_ADDRESS";
+
+ /**
+ * The name of the property under which we store the number of the port
+ * where the proxy stored against the PROXY_ADDRESS property is expecting
+ * connections to be made via this protocol.
+ */
+ public static final String PROXY_PORT = "PROXY_PORT";
+
+ /**
+ * The name of the property which defines whether proxy is auto configured
+ * by the protocol by using known methods such as specific DNS queries.
+ */
+ public static final String PROXY_AUTO_CONFIG = "PROXY_AUTO_CONFIG";
+
+ /**
+ * The property indicating the preferred UDP and TCP
+ * port to bind to for clear communications.
+ */
+ public static final String PREFERRED_CLEAR_PORT_PROPERTY_NAME
+ = "net.java.sip.communicator.SIP_PREFERRED_CLEAR_PORT";
+
+ /**
+ * The property indicating the preferred TLS (TCP)
+ * port to bind to for secure communications.
+ */
+ public static final String PREFERRED_SECURE_PORT_PROPERTY_NAME
+ = "net.java.sip.communicator.SIP_PREFERRED_SECURE_PORT";
+
+ /**
+ * The name of the property under which we store the the type of the proxy
+ * stored against the PROXY_ADDRESS property. Exact type values depend on
+ * protocols and among them are socks4, socks5, http and possibly others.
+ */
+ public static final String PROXY_TYPE = "PROXY_TYPE";
+
+ /**
+ * The name of the property under which we store the the username for the
+ * proxy stored against the PROXY_ADDRESS property.
+ */
+ public static final String PROXY_USERNAME = "PROXY_USERNAME";
+
+ /**
+ * The name of the property under which we store the the authorization name
+ * for the proxy stored against the PROXY_ADDRESS property.
+ */
+ public static final String AUTHORIZATION_NAME = "AUTHORIZATION_NAME";
+
+ /**
+ * The name of the property under which we store the password for the proxy
+ * stored against the PROXY_ADDRESS property.
+ */
+ public static final String PROXY_PASSWORD = "PROXY_PASSWORD";
+
+ /**
+ * The name of the property under which we store the name of the transport
+ * protocol that needs to be used to access the proxy.
+ */
+ public static final String PROXY_TRANSPORT = "PROXY_TRANSPORT";
+
+ /**
+ * The name of the property that indicates whether loose routing should be
+ * forced for all traffic in an account, rather than routing through an
+ * outbound proxy which is the default for Jitsi.
+ */
+ public static final String FORCE_PROXY_BYPASS = "FORCE_PROXY_BYPASS";
+
+ /**
+ * The name of the property that indicates whether the client must
+ * be registered with a registrar when making outgoing calls.
+ */
+ public static final String MUST_REGISTER_TO_CALL = "MUST_REGISTER_TO_CALL";
+
+ /**
+ * The name of the property under which we store the user preference for a
+ * transport protocol to use (i.e. tcp or udp).
+ */
+ public static final String PREFERRED_TRANSPORT = "PREFERRED_TRANSPORT";
+
+ /**
+ * The name of the property under which we store whether we generate
+ * resource values or we just use the stored one.
+ */
+ public static final String AUTO_GENERATE_RESOURCE = "AUTO_GENERATE_RESOURCE";
+
+ /**
+ * The name of the property under which we store resources such as the
+ * jabber resource property.
+ */
+ public static final String RESOURCE = "RESOURCE";
+
+ /**
+ * The name of the property under which we store resource priority.
+ */
+ public static final String RESOURCE_PRIORITY = "RESOURCE_PRIORITY";
+
+ /**
+ * The name of the property which defines that the call is encrypted by
+ * default
+ */
+ public static final String DEFAULT_ENCRYPTION = "DEFAULT_ENCRYPTION";
+
+ /**
+ * The name of the property that indicates the encryption protocols for this
+ * account.
+ */
+ public static final String ENCRYPTION_PROTOCOL = "ENCRYPTION_PROTOCOL";
+
+ /**
+ * The name of the property that indicates the status (enabed or disabled)
+ * encryption protocols for this account.
+ */
+ public static final String ENCRYPTION_PROTOCOL_STATUS
+ = "ENCRYPTION_PROTOCOL_STATUS";
+
+ /**
+ * The name of the property which defines if to include the ZRTP attribute
+ * to SIP/SDP
+ */
+ public static final String DEFAULT_SIPZRTP_ATTRIBUTE =
+ "DEFAULT_SIPZRTP_ATTRIBUTE";
+
+ /**
+ * The name of the property which defines the ID of the client TLS
+ * certificate configuration entry.
+ */
+ public static final String CLIENT_TLS_CERTIFICATE =
+ "CLIENT_TLS_CERTIFICATE";
+
+ /**
+ * The name of the property under which we store the boolean value
+ * indicating if the user name should be automatically changed if the
+ * specified name already exists. This property is meant to be used by IRC
+ * implementations.
+ */
+ public static final String AUTO_CHANGE_USER_NAME = "AUTO_CHANGE_USER_NAME";
+
+ /**
+ * The name of the property under which we store the boolean value
+ * indicating if a password is required. Initially this property is meant to
+ * be used by IRC implementations.
+ */
+ public static final String NO_PASSWORD_REQUIRED = "NO_PASSWORD_REQUIRED";
+
+ /**
+ * The name of the property under which we store if the presence is enabled.
+ */
+ public static final String IS_PRESENCE_ENABLED = "IS_PRESENCE_ENABLED";
+
+ /**
+ * The name of the property under which we store if the p2p mode for SIMPLE
+ * should be forced.
+ */
+ public static final String FORCE_P2P_MODE = "FORCE_P2P_MODE";
+
+ /**
+ * The name of the property under which we store the offline contact polling
+ * period for SIMPLE.
+ */
+ public static final String POLLING_PERIOD = "POLLING_PERIOD";
+
+ /**
+ * The name of the property under which we store the chosen default
+ * subscription expiration value for SIMPLE.
+ */
+ public static final String SUBSCRIPTION_EXPIRATION
+ = "SUBSCRIPTION_EXPIRATION";
+
+ /**
+ * Indicates if the server address has been validated.
+ */
+ public static final String SERVER_ADDRESS_VALIDATED
+ = "SERVER_ADDRESS_VALIDATED";
+
+ /**
+ * Indicates if the server settings are over
+ */
+ public static final String IS_SERVER_OVERRIDDEN
+ = "IS_SERVER_OVERRIDDEN";
+ /**
+ * Indicates if the proxy address has been validated.
+ */
+ public static final String PROXY_ADDRESS_VALIDATED
+ = "PROXY_ADDRESS_VALIDATED";
+
+ /**
+ * Indicates the search strategy chosen for the DICT protocole.
+ */
+ public static final String STRATEGY = "STRATEGY";
+
+ /**
+ * Indicates a protocol that would not be shown in the user interface as an
+ * account.
+ */
+ public static final String IS_PROTOCOL_HIDDEN = "IS_PROTOCOL_HIDDEN";
+
+ /**
+ * Indicates if the given account is the preferred account.
+ */
+ public static final String IS_PREFERRED_PROTOCOL = "IS_PREFERRED_PROTOCOL";
+
+ /**
+ * The name of the property that would indicate if a given account is
+ * currently enabled or disabled.
+ */
+ public static final String IS_ACCOUNT_DISABLED = "IS_ACCOUNT_DISABLED";
+
+ /**
+ * The name of the property that would indicate if a given account
+ * configuration form is currently hidden.
+ */
+ public static final String IS_ACCOUNT_CONFIG_HIDDEN = "IS_CONFIG_HIDDEN";
+
+ /**
+ * The name of the property that would indicate if a given account
+ * status menu is currently hidden.
+ */
+ public static final String IS_ACCOUNT_STATUS_MENU_HIDDEN =
+ "IS_STATUS_MENU_HIDDEN";
+
+ /**
+ * The name of the property that would indicate if a given account
+ * configuration is read only.
+ */
+ public static final String IS_ACCOUNT_READ_ONLY = "IS_READ_ONLY";
+
+ /**
+ * The name of the property that would indicate if a given account
+ * groups are readonly, values can be all or a comma separated
+ * group names including root.
+ */
+ public static final String ACCOUNT_READ_ONLY_GROUPS = "READ_ONLY_GROUPS";
+
+ /**
+ * Indicates if ICE should be used.
+ */
+ public static final String IS_USE_ICE = "ICE_ENABLED";
+
+ /**
+ * Indicates if STUN server should be automatically discovered.
+ */
+ public static final String AUTO_DISCOVER_STUN = "AUTO_DISCOVER_STUN";
+
+ /**
+ * Indicates if default STUN server would be used if no other STUN/TURN
+ * server are available.
+ */
+ public static final String USE_DEFAULT_STUN_SERVER
+ = "USE_DEFAULT_STUN_SERVER";
+
+ /**
+ * The name of the boolean account property which indicates whether Jitsi
+ * Videobridge is to be used, if available and supported, for conference
+ * calls.
+ */
+ public static final String USE_JITSI_VIDEO_BRIDGE
+ = "USE_JITSI_VIDEO_BRIDGE";
+
+ /**
+ * The name of the boolean account property which indicates whether Jitsi
+ * will use translator for media, instead of mixing, for conference
+ * calls.
+ * By default if supported mixing is used (audio mixed, video relayed).
+ */
+ public static final String USE_TRANSLATOR_IN_CONFERENCE
+ = "USE_TRANSLATOR_IN_CONFERENCE";
+
+ /**
+ * The property name prefix for all stun server properties. We generally use
+ * this prefix in conjunction with an index which is how we store multiple
+ * servers.
+ */
+ public static final String STUN_PREFIX = "STUN";
+
+ /**
+ * The base property name for address of additional STUN servers specified.
+ */
+ public static final String STUN_ADDRESS = "ADDRESS";
+
+ /**
+ * The base property name for port of additional STUN servers specified.
+ */
+ public static final String STUN_PORT = "PORT";
+
+ /**
+ * The base property name for username of additional STUN servers specified.
+ */
+ public static final String STUN_USERNAME = "USERNAME";
+
+ /**
+ * The base property name for password of additional STUN servers specified.
+ */
+ public static final String STUN_PASSWORD = "PASSWORD";
+
+ /**
+ * The base property name for the turn supported property of additional
+ * STUN servers specified.
+ */
+ public static final String STUN_IS_TURN_SUPPORTED = "IS_TURN_SUPPORTED";
+
+ /**
+ * Indicates if JingleNodes should be used with ICE.
+ */
+ public static final String IS_USE_JINGLE_NODES = "JINGLE_NODES_ENABLED";
+
+ /**
+ * Indicates if JingleNodes should be used with ICE.
+ */
+ public static final String AUTO_DISCOVER_JINGLE_NODES
+ = "AUTO_DISCOVER_JINGLE_NODES";
+
+ /**
+ * Indicates if JingleNodes should use buddies to search for nodes.
+ */
+ public static final String JINGLE_NODES_SEARCH_BUDDIES
+ = "JINGLE_NODES_SEARCH_BUDDIES";
+
+ /**
+ * Indicates if UPnP should be used with ICE.
+ */
+ public static final String IS_USE_UPNP = "UPNP_ENABLED";
+
+ /**
+ * Indicates if we allow non-TLS connection.
+ */
+ public static final String IS_ALLOW_NON_SECURE = "ALLOW_NON_SECURE";
+
+ /**
+ * Enable notifications for new voicemail messages.
+ */
+ public static final String VOICEMAIL_ENABLED = "VOICEMAIL_ENABLED";
+
+ /**
+ * Address used to reach voicemail box, by services able to
+ * subscribe for voicemail new messages notifications.
+ */
+ public static final String VOICEMAIL_URI = "VOICEMAIL_URI";
+
+ /**
+ * Address used to call to hear your messages stored on the server
+ * for your voicemail.
+ */
+ public static final String VOICEMAIL_CHECK_URI = "VOICEMAIL_CHECK_URI";
+
+ /**
+ * Indicates if calling is disabled for a certain account.
+ */
+ public static final String IS_CALLING_DISABLED_FOR_ACCOUNT
+ = "CALLING_DISABLED";
+
+ /**
+ * Indicates if desktop streaming/sharing is disabled for a certain account.
+ */
+ public static final String IS_DESKTOP_STREAMING_DISABLED
+ = "DESKTOP_STREAMING_DISABLED";
+
+ /**
+ * Indicates if desktop remote control is disabled for a certain account.
+ */
+ public static final String IS_DESKTOP_REMOTE_CONTROL_DISABLED
+ = "DESKTOP_REMOTE_CONTROL_DISABLED";
+
+ /**
+ * The sms default server address.
+ */
+ public static final String SMS_SERVER_ADDRESS = "SMS_SERVER_ADDRESS";
+
+ /**
+ * Keep-alive method used by the protocol.
+ */
+ public static final String KEEP_ALIVE_METHOD = "KEEP_ALIVE_METHOD";
+
+ /**
+ * The interval for keep-alives if any.
+ */
+ public static final String KEEP_ALIVE_INTERVAL = "KEEP_ALIVE_INTERVAL";
+
+ /**
+ * The name of the property holding DTMF method.
+ */
+ public static final String DTMF_METHOD = "DTMF_METHOD";
+
+ /**
+ * The minimal DTMF tone duration.
+ */
+ public static final String DTMF_MINIMAL_TONE_DURATION
+ = "DTMF_MINIMAL_TONE_DURATION";
+
+ /**
+ * Paranoia mode when turned on requires all calls to be secure and
+ * indicated as such.
+ */
+ public static final String MODE_PARANOIA = "MODE_PARANOIA";
+
+ /**
+ * The name of the "override encodings" property
+ */
+ public static final String OVERRIDE_ENCODINGS = "OVERRIDE_ENCODINGS";
+
+ /**
+ * The prefix used to store account encoding properties
+ */
+ public static final String ENCODING_PROP_PREFIX = "Encodings";
+
+ /**
+ * An account property to provide a connected account to check for
+ * its status. Used when the current provider need to reject calls
+ * but is missing presence operation set and need to check other
+ * provider for status.
+ */
+ public static final String CUSAX_PROVIDER_ACCOUNT_PROP
+ = "cusax.XMPP_ACCOUNT_ID";
+
+ /**
+ * The <code>BundleContext</code> containing (or to contain) the service
+ * registration of this factory.
+ */
+ private final BundleContext bundleContext;
+
+ /**
+ * The name of the protocol this factory registers its
+ * <code>ProtocolProviderService</code>s with and to be placed in the
+ * properties of the accounts created by this factory.
+ */
+ private final String protocolName;
+
+ /**
+ * The table that we store our accounts in.
+ * <p>
+ * TODO Synchronize the access to the field which may in turn be better
+ * achieved by also hiding it from protected into private access.
+ * </p>
+ */
+ protected final Map<AccountID, ServiceRegistration<ProtocolProviderService>>
+ registeredAccounts
+ = new HashMap<AccountID, ServiceRegistration<ProtocolProviderService>>();
+
+ /**
+ * The name of the property that indicates the AVP type.
+ * <ul>
+ * <li>{@link #SAVP_OFF}</li>
+ * <li>{@link #SAVP_MANDATORY}</li>
+ * <li>{@link #SAVP_OPTIONAL}</li>
+ * </ul>
+ */
+ public static final String SAVP_OPTION = "SAVP_OPTION";
+
+ /**
+ * Always use RTP/AVP
+ */
+ public static final int SAVP_OFF = 0;
+
+ /**
+ * Always use RTP/SAVP
+ */
+ public static final int SAVP_MANDATORY = 1;
+
+ /**
+ * Sends two media description, with RTP/SAVP being first.
+ */
+ public static final int SAVP_OPTIONAL = 2;
+
+ /**
+ * The name of the property that defines the enabled SDES cipher suites.
+ * Enabled suites are listed as CSV by their RFC name.
+ */
+ public static final String SDES_CIPHER_SUITES = "SDES_CIPHER_SUITES";
+
+ /**
+ * The name of the property that defines the enabled/disabled state of
+ * message carbons.
+ */
+ public static final String IS_CARBON_DISABLED = "CARBON_DISABLED";
+
+ /**
+ * Creates a new <tt>ProtocolProviderFactory</tt>.
+ *
+ * @param bundleContext the bundle context reference of the service
+ * @param protocolName the name of the protocol
+ */
+ protected ProtocolProviderFactory(BundleContext bundleContext,
+ String protocolName)
+ {
+ this.bundleContext = bundleContext;
+ this.protocolName = protocolName;
+ }
+
+ /**
+ * Gets the <code>BundleContext</code> containing (or to contain) the
+ * service registration of this factory.
+ *
+ * @return the <code>BundleContext</code> containing (or to contain) the
+ * service registration of this factory
+ */
+ public BundleContext getBundleContext()
+ {
+ return bundleContext;
+ }
+
+ /**
+ * Initializes and creates an account corresponding to the specified
+ * accountProperties and registers the resulting ProtocolProvider in the
+ * <tt>context</tt> BundleContext parameter. Note that account
+ * registration is persistent and accounts that are registered during
+ * a particular sip-communicator session would be automatically reloaded
+ * during all following sessions until they are removed through the
+ * removeAccount method.
+ *
+ * @param userID the user identifier uniquely representing the newly
+ * created account within the protocol namespace.
+ * @param accountProperties a set of protocol (or implementation) specific
+ * properties defining the new account.
+ * @return the AccountID of the newly created account.
+ * @throws java.lang.IllegalArgumentException if userID does not correspond
+ * to an identifier in the context of the underlying protocol or if
+ * accountProperties does not contain a complete set of account installation
+ * properties.
+ * @throws java.lang.IllegalStateException if the account has already been
+ * installed.
+ * @throws java.lang.NullPointerException if any of the arguments is null.
+ */
+ public abstract AccountID installAccount(String userID,
+ Map<String, String> accountProperties)
+ throws IllegalArgumentException,
+ IllegalStateException,
+ NullPointerException;
+
+
+ /**
+ * Modifies the account corresponding to the specified accountID. This
+ * method is meant to be used to change properties of already existing
+ * accounts. Note that if the given accountID doesn't correspond to any
+ * registered account this method would do nothing.
+ *
+ * @param protocolProvider the protocol provider service corresponding to
+ * the modified account.
+ * @param accountProperties a set of protocol (or implementation) specific
+ * properties defining the new account.
+ *
+ * @throws java.lang.NullPointerException if any of the arguments is null.
+ */
+ public abstract void modifyAccount(
+ ProtocolProviderService protocolProvider,
+ Map<String, String> accountProperties)
+ throws NullPointerException;
+
+ /**
+ * Returns a copy of the list containing the <tt>AccountID</tt>s of all
+ * accounts currently registered in this protocol provider.
+ * @return a copy of the list containing the <tt>AccountID</tt>s of all
+ * accounts currently registered in this protocol provider.
+ */
+ public ArrayList<AccountID> getRegisteredAccounts()
+ {
+ synchronized (registeredAccounts)
+ {
+ return new ArrayList<AccountID>(registeredAccounts.keySet());
+ }
+ }
+
+ /**
+ * Returns the ServiceReference for the protocol provider corresponding to
+ * the specified accountID or null if the accountID is unknown.
+ * @param accountID the accountID of the protocol provider we'd like to get
+ * @return a ServiceReference object to the protocol provider with the
+ * specified account id and null if the account id is unknown to the
+ * provider factory.
+ */
+ public ServiceReference<ProtocolProviderService> getProviderForAccount(
+ AccountID accountID)
+ {
+ ServiceRegistration<ProtocolProviderService> registration;
+
+ synchronized (registeredAccounts)
+ {
+ registration = registeredAccounts.get(accountID);
+ }
+
+ try
+ {
+ if (registration != null)
+ return registration.getReference();
+ }
+ catch (IllegalStateException ise)
+ {
+ synchronized (registeredAccounts)
+ {
+ registeredAccounts.remove(accountID);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Removes the specified account from the list of accounts that this
+ * provider factory is handling. If the specified accountID is unknown to
+ * the ProtocolProviderFactory, the call has no effect and false is
+ * returned. This method is persistent in nature and once called the account
+ * corresponding to the specified ID will not be loaded during future runs
+ * of the project.
+ *
+ * @param accountID the ID of the account to remove.
+ * @return true if an account with the specified ID existed and was removed
+ * and false otherwise.
+ */
+ public boolean uninstallAccount(AccountID accountID)
+ {
+ // Unregister the protocol provider.
+ ServiceReference<ProtocolProviderService> serRef
+ = getProviderForAccount(accountID);
+
+ boolean wasAccountExisting = false;
+
+ // If the protocol provider service is registered, first unregister the
+ // service.
+ if (serRef != null)
+ {
+ BundleContext bundleContext = getBundleContext();
+ ProtocolProviderService protocolProvider
+ = bundleContext.getService(serRef);
+
+ try
+ {
+ protocolProvider.unregister();
+ }
+ catch (OperationFailedException ex)
+ {
+ logger.error(
+ "Failed to unregister protocol provider for account: "
+ + accountID + " caused by: " + ex);
+ }
+ }
+
+ ServiceRegistration<ProtocolProviderService> registration;
+
+ synchronized (registeredAccounts)
+ {
+ registration = registeredAccounts.remove(accountID);
+ }
+
+ // first remove the stored account so when PP is unregistered we can
+ // distinguish between deleted or just disabled account
+ wasAccountExisting = removeStoredAccount(accountID);
+
+ if (registration != null)
+ {
+ // Kill the service.
+ registration.unregister();
+ }
+
+ return wasAccountExisting;
+ }
+
+ /**
+ * The method stores the specified account in the configuration service
+ * under the package name of the source factory. The restore and remove
+ * account methods are to be used to obtain access to and control the stored
+ * accounts.
+ * <p>
+ * In order to store all account properties, the method would create an
+ * entry in the configuration service corresponding (beginning with) the
+ * <tt>sourceFactory</tt>'s package name and add to it a unique identifier
+ * (e.g. the current miliseconds.)
+ * </p>
+ *
+ * @param accountID the AccountID corresponding to the account that we would
+ * like to store.
+ */
+ protected void storeAccount(AccountID accountID)
+ {
+ this.storeAccount(accountID, true);
+ }
+
+ /**
+ * The method stores the specified account in the configuration service
+ * under the package name of the source factory. The restore and remove
+ * account methods are to be used to obtain access to and control the stored
+ * accounts.
+ * <p>
+ * In order to store all account properties, the method would create an
+ * entry in the configuration service corresponding (beginning with) the
+ * <tt>sourceFactory</tt>'s package name and add to it a unique identifier
+ * (e.g. the current miliseconds.)
+ * </p>
+ *
+ * @param accountID the AccountID corresponding to the account that we would
+ * like to store.
+ * @param isModification if <tt>false</tt> there must be no such already
+ * loaded account, it <tt>true</tt> ist modification of an existing account.
+ * Usually we use this method with <tt>false</tt> in method installAccount
+ * and with <tt>true</tt> or the overridden method in method
+ * modifyAccount.
+ */
+ protected void storeAccount(AccountID accountID, boolean isModification)
+ {
+ if(!isModification
+ && getAccountManager().getStoredAccounts().contains(accountID))
+ {
+ throw new IllegalStateException(
+ "An account for id " + accountID.getUserID()
+ + " was already loaded!");
+ }
+
+ try
+ {
+ getAccountManager().storeAccount(this, accountID);
+ }
+ catch (OperationFailedException ofex)
+ {
+ throw new UndeclaredThrowableException(ofex);
+ }
+ }
+
+ /**
+ * Saves the password for the specified account after scrambling it a bit so
+ * that it is not visible from first sight. (The method remains highly
+ * insecure).
+ *
+ * @param accountID the AccountID for the account whose password we're
+ * storing
+ * @param password the password itself
+ *
+ * @throws IllegalArgumentException if no account corresponding to
+ * <code>accountID</code> has been previously stored
+ */
+ public void storePassword(AccountID accountID, String password)
+ throws IllegalArgumentException
+ {
+ try
+ {
+ storePassword(getBundleContext(), accountID, password);
+ }
+ catch (OperationFailedException ofex)
+ {
+ throw new UndeclaredThrowableException(ofex);
+ }
+ }
+
+ /**
+ * Saves the password for the specified account after scrambling it a bit
+ * so that it is not visible from first sight (Method remains highly
+ * insecure).
+ * <p>
+ * TODO Delegate the implementation to {@link AccountManager} because it
+ * knows the format in which the password (among the other account
+ * properties) is to be saved.
+ * </p>
+ *
+ * @param bundleContext a currently valid bundle context.
+ * @param accountID the <tt>AccountID</tt> of the account whose password is
+ * to be stored
+ * @param password the password to be stored
+ *
+ * @throws IllegalArgumentException if no account corresponding to
+ * <tt>accountID</tt> has been previously stored.
+ * @throws OperationFailedException if anything goes wrong while storing the
+ * specified <tt>password</tt>
+ */
+ protected void storePassword(BundleContext bundleContext,
+ AccountID accountID,
+ String password)
+ throws IllegalArgumentException,
+ OperationFailedException
+ {
+ String accountPrefix
+ = findAccountPrefix(
+ bundleContext,
+ accountID,
+ getFactoryImplPackageName());
+
+ if (accountPrefix == null)
+ {
+ throw
+ new IllegalArgumentException(
+ "No previous records found for account ID: "
+ + accountID.getAccountUniqueID()
+ + " in package"
+ + getFactoryImplPackageName());
+ }
+
+ CredentialsStorageService credentialsStorage
+ = ServiceUtils.getService(
+ bundleContext,
+ CredentialsStorageService.class);
+
+ if (!credentialsStorage.storePassword(accountPrefix, password))
+ {
+ throw
+ new OperationFailedException(
+ "CredentialsStorageService failed to storePassword",
+ OperationFailedException.GENERAL_ERROR);
+ }
+
+ // Update password property also in the AccountID
+ // to prevent it from being removed during account reload
+ // in some cases.
+ accountID.setPassword(password);
+
+ }
+
+ /**
+ * Returns the password last saved for the specified account.
+ *
+ * @param accountID the AccountID for the account whose password we're
+ * looking for
+ *
+ * @return a String containing the password for the specified accountID
+ */
+ public String loadPassword(AccountID accountID)
+ {
+ return loadPassword(getBundleContext(), accountID);
+ }
+
+ /**
+ * Returns the password last saved for the specified account.
+ * <p>
+ * TODO Delegate the implementation to {@link AccountManager} because it
+ * knows the format in which the password (among the other account
+ * properties) was saved.
+ * </p>
+ *
+ * @param bundleContext a currently valid bundle context.
+ * @param accountID the AccountID for the account whose password we're
+ * looking for..
+ *
+ * @return a String containing the password for the specified accountID.
+ */
+ protected String loadPassword(BundleContext bundleContext,
+ AccountID accountID)
+ {
+ String accountPrefix = findAccountPrefix(
+ bundleContext, accountID, getFactoryImplPackageName());
+
+ if (accountPrefix == null)
+ return null;
+
+ CredentialsStorageService credentialsStorage
+ = ServiceUtils.getService(
+ bundleContext,
+ CredentialsStorageService.class);
+
+ return credentialsStorage.loadPassword(accountPrefix);
+ }
+
+ /**
+ * Initializes and creates an account corresponding to the specified
+ * accountProperties and registers the resulting ProtocolProvider in the
+ * <tt>context</tt> BundleContext parameter. This method has a persistent
+ * effect. Once created the resulting account will remain installed until
+ * removed through the uninstallAccount method.
+ *
+ * @param accountProperties a set of protocol (or implementation) specific
+ * properties defining the new account.
+ * @return the AccountID of the newly loaded account
+ */
+ public AccountID loadAccount(Map<String, String> accountProperties)
+ {
+ AccountID accountID = createAccount(accountProperties);
+
+ loadAccount(accountID);
+
+ return accountID;
+ }
+
+ /**
+ * Creates a protocol provider for the given <tt>accountID</tt> and
+ * registers it in the bundle context. This method has a persistent
+ * effect. Once created the resulting account will remain installed until
+ * removed through the uninstallAccount method.
+ *
+ * @param accountID the account identifier
+ * @return <tt>true</tt> if the account with the given <tt>accountID</tt> is
+ * successfully loaded, otherwise returns <tt>false</tt>
+ */
+ public boolean loadAccount(AccountID accountID)
+ {
+ // Need to obtain the original user id property, instead of calling
+ // accountID.getUserID(), because this method could return a modified
+ // version of the user id property.
+ String userID
+ = accountID.getAccountPropertyString(
+ ProtocolProviderFactory.USER_ID);
+
+ ProtocolProviderService service = createService(userID, accountID);
+
+ Dictionary<String, String> properties = new Hashtable<String, String>();
+ properties.put(PROTOCOL, protocolName);
+ properties.put(USER_ID, userID);
+
+ ServiceRegistration<ProtocolProviderService> serviceRegistration
+ = bundleContext.registerService(
+ ProtocolProviderService.class,
+ service,
+ properties);
+
+ if (serviceRegistration == null)
+ {
+ return false;
+ }
+ else
+ {
+ synchronized (registeredAccounts)
+ {
+ registeredAccounts.put(accountID, serviceRegistration);
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Unloads the account corresponding to the given <tt>accountID</tt>.
+ * Unregisters the corresponding protocol provider, but keeps the account in
+ * contrast to the uninstallAccount method.
+ *
+ * @param accountID the account identifier
+ * @return true if an account with the specified ID existed and was unloaded
+ * and false otherwise.
+ */
+ public boolean unloadAccount(AccountID accountID)
+ {
+ // Unregister the protocol provider.
+ ServiceReference<ProtocolProviderService> serRef
+ = getProviderForAccount(accountID);
+
+ if (serRef == null)
+ {
+ return false;
+ }
+
+ BundleContext bundleContext = getBundleContext();
+ ProtocolProviderService protocolProvider
+ = bundleContext.getService(serRef);
+
+ try
+ {
+ protocolProvider.unregister();
+ }
+ catch (OperationFailedException ex)
+ {
+ logger.error(
+ "Failed to unregister protocol provider for account: "
+ + accountID + " caused by: " + ex);
+ }
+
+ ServiceRegistration<ProtocolProviderService> registration;
+
+ synchronized (registeredAccounts)
+ {
+ registration = registeredAccounts.remove(accountID);
+ }
+ if (registration == null)
+ {
+ return false;
+ }
+
+ // Kill the service.
+ registration.unregister();
+
+ return true;
+ }
+
+ /**
+ * Initializes and creates an account corresponding to the specified
+ * accountProperties.
+ *
+ * @param accountProperties a set of protocol (or implementation) specific
+ * properties defining the new account.
+ * @return the AccountID of the newly created account
+ */
+ public AccountID createAccount(Map<String, String> accountProperties)
+ {
+ BundleContext bundleContext = getBundleContext();
+ if (bundleContext == null)
+ throw new NullPointerException(
+ "The specified BundleContext was null");
+
+ if (accountProperties == null)
+ throw new NullPointerException(
+ "The specified property map was null");
+
+ String userID = accountProperties.get(USER_ID);
+ if (userID == null)
+ throw new NullPointerException(
+ "The account properties contained no user id.");
+
+ String protocolName = getProtocolName();
+ if (!accountProperties.containsKey(PROTOCOL))
+ accountProperties.put(PROTOCOL, protocolName);
+
+ return createAccountID(userID, accountProperties);
+ }
+
+ /**
+ * Creates a new <code>AccountID</code> instance with a specific user ID to
+ * represent a given set of account properties.
+ * <p>
+ * The method is a pure factory allowing implementers to specify the runtime
+ * type of the created <code>AccountID</code> and customize the instance.
+ * The returned <code>AccountID</code> will later be associated with a
+ * <code>ProtocolProviderService</code> by the caller (e.g. using
+ * {@link #createService(String, AccountID)}).
+ * </p>
+ *
+ * @param userID the user ID of the new instance
+ * @param accountProperties the set of properties to be represented by the
+ * new instance
+ * @return a new <code>AccountID</code> instance with the specified user ID
+ * representing the given set of account properties
+ */
+ protected abstract AccountID createAccountID(
+ String userID, Map<String, String> accountProperties);
+
+ /**
+ * Gets the name of the protocol this factory registers its
+ * <code>ProtocolProviderService</code>s with and to be placed in the
+ * properties of the accounts created by this factory.
+ *
+ * @return the name of the protocol this factory registers its
+ * <code>ProtocolProviderService</code>s with and to be placed in
+ * the properties of the accounts created by this factory
+ */
+ public String getProtocolName()
+ {
+ return protocolName;
+ }
+
+ /**
+ * Initializes a new <code>ProtocolProviderService</code> instance with a
+ * specific user ID to represent a specific <code>AccountID</code>.
+ * <p>
+ * The method is a pure factory allowing implementers to specify the runtime
+ * type of the created <code>ProtocolProviderService</code> and customize
+ * the instance. The caller will later register the returned service with
+ * the <code>BundleContext</code> of this factory.
+ * </p>
+ *
+ * @param userID the user ID to initialize the new instance with
+ * @param accountID the <code>AccountID</code> to be represented by the new
+ * instance
+ * @return a new <code>ProtocolProviderService</code> instance with the
+ * specific user ID representing the specified
+ * <code>AccountID</code>
+ */
+ protected abstract ProtocolProviderService createService(String userID,
+ AccountID accountID);
+
+ /**
+ * Removes the account with <tt>accountID</tt> from the set of accounts
+ * that are persistently stored inside the configuration service.
+ *
+ * @param accountID the AccountID of the account to remove.
+ *
+ * @return true if an account has been removed and false otherwise.
+ */
+ protected boolean removeStoredAccount(AccountID accountID)
+ {
+ return getAccountManager().removeStoredAccount(this, accountID);
+ }
+
+ /**
+ * Returns the prefix for all persistently stored properties of the account
+ * with the specified id.
+ * @param bundleContext a currently valid bundle context.
+ * @param accountID the AccountID of the account whose properties we're
+ * looking for.
+ * @param sourcePackageName a String containing the package name of the
+ * concrete factory class that extends us.
+ * @return a String indicating the ConfigurationService property name
+ * prefix under which all account properties are stored or null if no
+ * account corresponding to the specified id was found.
+ */
+ public static String findAccountPrefix(BundleContext bundleContext,
+ AccountID accountID,
+ String sourcePackageName)
+ {
+ ServiceReference<ConfigurationService> confReference
+ = bundleContext.getServiceReference(ConfigurationService.class);
+ ConfigurationService configurationService
+ = bundleContext.getService(confReference);
+
+ //first retrieve all accounts that we've registered
+ List<String> storedAccounts =
+ configurationService.getPropertyNamesByPrefix(sourcePackageName,
+ true);
+
+ //find an account with the corresponding id.
+ for (String accountRootPropertyName : storedAccounts)
+ {
+ //unregister the account in the configuration service.
+ //all the properties must have been registered in the following
+ //hierarchy:
+ //net.java.sip.communicator.impl.protocol.PROTO_NAME.ACC_ID.PROP_NAME
+ String accountUID = configurationService.getString(
+ accountRootPropertyName //node id
+ + "." + ACCOUNT_UID); // propname
+
+ if (accountID.getAccountUniqueID().equals(accountUID))
+ {
+ return accountRootPropertyName;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the name of the package that we're currently running in (i.e.
+ * the name of the package containing the proto factory that extends us).
+ *
+ * @return a String containing the package name of the concrete factory
+ * class that extends us.
+ */
+ private String getFactoryImplPackageName()
+ {
+ String className = getClass().getName();
+
+ return className.substring(0, className.lastIndexOf('.'));
+ }
+
+ /**
+ * Prepares the factory for bundle shutdown.
+ */
+ public void stop()
+ {
+ if (logger.isTraceEnabled())
+ logger.trace("Preparing to stop all protocol providers of" + this);
+
+ synchronized (registeredAccounts)
+ {
+ for (ServiceRegistration<ProtocolProviderService> reg
+ : registeredAccounts.values())
+ {
+ stop(reg);
+ reg.unregister();
+ }
+
+ registeredAccounts.clear();
+ }
+ }
+
+ /**
+ * Shuts down the <code>ProtocolProviderService</code> representing an
+ * account registered with this factory.
+ *
+ * @param registeredAccount the <code>ServiceRegistration</code> of the
+ * <code>ProtocolProviderService</code> representing an account
+ * registered with this factory
+ */
+ protected void stop(
+ ServiceRegistration<ProtocolProviderService> registeredAccount)
+ {
+ ProtocolProviderService protocolProviderService
+ = getBundleContext().getService(registeredAccount.getReference());
+
+ protocolProviderService.shutdown();
+ }
+
+ /**
+ * Get the <tt>AccountManager</tt> of the protocol.
+ *
+ * @return <tt>AccountManager</tt> of the protocol
+ */
+ private AccountManager getAccountManager()
+ {
+ BundleContext bundleContext = getBundleContext();
+ ServiceReference<AccountManager> serviceReference
+ = bundleContext.getServiceReference(AccountManager.class);
+
+ return bundleContext.getService(serviceReference);
+ }
+
+
+ /**
+ * Finds registered <tt>ProtocolProviderFactory</tt> for given
+ * <tt>protocolName</tt>.
+ * @param bundleContext the OSGI bundle context that will be used.
+ * @param protocolName the protocol name.
+ * @return Registered <tt>ProtocolProviderFactory</tt> for given protocol
+ * name or <tt>null</tt> if no provider was found.
+ */
+ static public ProtocolProviderFactory getProtocolProviderFactory(
+ BundleContext bundleContext,
+ String protocolName)
+ {
+ Collection<ServiceReference<ProtocolProviderFactory>> serRefs;
+ String osgiFilter
+ = "(" + ProtocolProviderFactory.PROTOCOL + "=" + protocolName + ")";
+
+ try
+ {
+ serRefs
+ = bundleContext.getServiceReferences(
+ ProtocolProviderFactory.class,
+ osgiFilter);
+ }
+ catch (InvalidSyntaxException ex)
+ {
+ serRefs = null;
+ logger.error(ex);
+ }
+ if ((serRefs == null) || serRefs.isEmpty())
+ return null;
+ else
+ return bundleContext.getService(serRefs.iterator().next());
+ }
+}
diff --git a/src/net/java/sip/communicator/service/protocol/ProtocolProviderService.java b/src/net/java/sip/communicator/service/protocol/ProtocolProviderService.java
index 0c85e98..ffc356c 100644
--- a/src/net/java/sip/communicator/service/protocol/ProtocolProviderService.java
+++ b/src/net/java/sip/communicator/service/protocol/ProtocolProviderService.java
@@ -211,13 +211,6 @@ public interface ProtocolProviderService
public void shutdown();
/**
- * A hashcode allowing usage of protocol providers as keys in Hashtables.
- * @return an int that may be used when storing protocol providers as
- * hashtable keys.
- */
- public int hashCode();
-
- /**
* Returns the AccountID that uniquely identifies the account represented by
* this instance of the ProtocolProviderService.
* @return the id of the account represented by this provider.
@@ -225,6 +218,23 @@ public interface ProtocolProviderService
public AccountID getAccountID();
/**
+ * Validates the given protocol specific contact identifier and returns an
+ * error message if applicable and a suggested correction.
+ *
+ * @param contactId the contact identifier to validate
+ * @param result Must be supplied as an empty a list. Implementors add
+ * items:
+ * <ol>
+ * <li>is the error message if applicable
+ * <li>a suggested correction. Index 1 is optional and can only
+ * be present if there was a validation failure.
+ * </ol>
+ * @return true if the contact id is valid, false otherwise
+ */
+ public boolean validateContactAddress(String contactId,
+ List<String> result);
+
+ /**
* Indicate if the signaling transport of this protocol instance uses a
* secure (e.g. via TLS) connection.
*
diff --git a/src/net/java/sip/communicator/service/protocol/RegistrationState.java b/src/net/java/sip/communicator/service/protocol/RegistrationState.java
index 9bd3eb0..368e5b1 100644
--- a/src/net/java/sip/communicator/service/protocol/RegistrationState.java
+++ b/src/net/java/sip/communicator/service/protocol/RegistrationState.java
@@ -177,4 +177,10 @@ public class RegistrationState
&& obj != null
&& statusString.equals(((RegistrationState)obj).statusString);
}
+
+ @Override
+ public int hashCode()
+ {
+ return statusString.hashCode();
+ }
}
diff --git a/src/net/java/sip/communicator/service/protocol/ServerStoredDetails.java b/src/net/java/sip/communicator/service/protocol/ServerStoredDetails.java
index 23cb895..4d21864 100644
--- a/src/net/java/sip/communicator/service/protocol/ServerStoredDetails.java
+++ b/src/net/java/sip/communicator/service/protocol/ServerStoredDetails.java
@@ -156,6 +156,12 @@ public class ServerStoredDetails
else
return false;
}
+
+ @Override
+ public int hashCode()
+ {
+ return Objects.hash(detailDisplayName, value);
+ }
}
/**
diff --git a/src/net/java/sip/communicator/service/protocol/WhiteboardPoint.java b/src/net/java/sip/communicator/service/protocol/WhiteboardPoint.java
index 1774718..3e26e7a 100644
--- a/src/net/java/sip/communicator/service/protocol/WhiteboardPoint.java
+++ b/src/net/java/sip/communicator/service/protocol/WhiteboardPoint.java
@@ -17,6 +17,8 @@
*/
package net.java.sip.communicator.service.protocol;
+import java.util.Objects;
+
/**
* A point representing a location in {@code (x,y)} coordinate space,
* specified in integer precision.
@@ -126,6 +128,12 @@ public class WhiteboardPoint implements Cloneable
return false;
}
+ @Override
+ public int hashCode()
+ {
+ return Objects.hash(x, y);
+ }
+
/**
* Returns a string representation of this point and its location
* in the {@code (x,y)} coordinate space. This method is intended to be
diff --git a/src/net/java/sip/communicator/service/protocol/event/AccountManagerEvent.java b/src/net/java/sip/communicator/service/protocol/event/AccountManagerEvent.java
index db594bf..ecbd971 100644
--- a/src/net/java/sip/communicator/service/protocol/event/AccountManagerEvent.java
+++ b/src/net/java/sip/communicator/service/protocol/event/AccountManagerEvent.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,86 +15,86 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.protocol.event;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * Represents a notifying event fired by a specific {@link AccountManager}.
- *
- * @author Lubomir Marinov
- */
-public class AccountManagerEvent
- extends EventObject
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * The type of event notifying that the loading of the stored accounts of a
- * specific <code>ProtocolProviderFactory</code> has finished.
- */
- public static final int STORED_ACCOUNTS_LOADED = 1;
-
- /**
- * The <code>ProtocolProviderFactory</code> being worked on at the time this
- * event has been fired.
- */
- private final ProtocolProviderFactory factory;
-
- /**
- * The (detail) type of this event which is one of
- * {@link #STORED_ACCOUNTS_LOADED}.
- */
- private final int type;
-
- /**
- * Initializes a new <code>AccountManagerEvent</code> instance fired by a
- * specific <code>AccountManager</code> in order to notify of an event of a
- * specific type occurring while working on a specific
- * <code>ProtocolProviderFactory</code>.
- *
- * @param accountManager the <code>AccountManager</code> issuing the
- * notification i.e. the source of the event
- * @param type the type of the event which is one of
- * {@link #STORED_ACCOUNTS_LOADED}
- * @param factory the <code>ProtocolProviderFactory</code> being worked on
- * at the time this event has been fired
- */
- public AccountManagerEvent(AccountManager accountManager, int type,
- ProtocolProviderFactory factory)
- {
- super(accountManager);
-
- this.type = type;
- this.factory = factory;
- }
-
- /**
- * Gets the <code>ProtocolProviderFactory</code> being worked on at the time
- * this event has been fired.
- *
- * @return the <code>ProtocolProviderFactory</code> being worked on at the
- * time this event has been fired
- */
- public ProtocolProviderFactory getFactory()
- {
- return factory;
- }
-
- /**
- * Gets the (detail) type of this event which is one of
- * <code>STORED_ACCOUNTS_LOADED</code>.
- *
- * @return the (detail) type of this event which is one of
- * <code>STORED_ACCOUNTS_LOADED</code>
- */
- public int getType()
- {
- return type;
- }
-}
+package net.java.sip.communicator.service.protocol.event;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * Represents a notifying event fired by a specific {@link AccountManager}.
+ *
+ * @author Lubomir Marinov
+ */
+public class AccountManagerEvent
+ extends EventObject
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * The type of event notifying that the loading of the stored accounts of a
+ * specific <code>ProtocolProviderFactory</code> has finished.
+ */
+ public static final int STORED_ACCOUNTS_LOADED = 1;
+
+ /**
+ * The <code>ProtocolProviderFactory</code> being worked on at the time this
+ * event has been fired.
+ */
+ private final ProtocolProviderFactory factory;
+
+ /**
+ * The (detail) type of this event which is one of
+ * {@link #STORED_ACCOUNTS_LOADED}.
+ */
+ private final int type;
+
+ /**
+ * Initializes a new <code>AccountManagerEvent</code> instance fired by a
+ * specific <code>AccountManager</code> in order to notify of an event of a
+ * specific type occurring while working on a specific
+ * <code>ProtocolProviderFactory</code>.
+ *
+ * @param accountManager the <code>AccountManager</code> issuing the
+ * notification i.e. the source of the event
+ * @param type the type of the event which is one of
+ * {@link #STORED_ACCOUNTS_LOADED}
+ * @param factory the <code>ProtocolProviderFactory</code> being worked on
+ * at the time this event has been fired
+ */
+ public AccountManagerEvent(AccountManager accountManager, int type,
+ ProtocolProviderFactory factory)
+ {
+ super(accountManager);
+
+ this.type = type;
+ this.factory = factory;
+ }
+
+ /**
+ * Gets the <code>ProtocolProviderFactory</code> being worked on at the time
+ * this event has been fired.
+ *
+ * @return the <code>ProtocolProviderFactory</code> being worked on at the
+ * time this event has been fired
+ */
+ public ProtocolProviderFactory getFactory()
+ {
+ return factory;
+ }
+
+ /**
+ * Gets the (detail) type of this event which is one of
+ * <code>STORED_ACCOUNTS_LOADED</code>.
+ *
+ * @return the (detail) type of this event which is one of
+ * <code>STORED_ACCOUNTS_LOADED</code>
+ */
+ public int getType()
+ {
+ return type;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/protocol/event/AccountManagerListener.java b/src/net/java/sip/communicator/service/protocol/event/AccountManagerListener.java
index 607caea..6bcf4e0 100644
--- a/src/net/java/sip/communicator/service/protocol/event/AccountManagerListener.java
+++ b/src/net/java/sip/communicator/service/protocol/event/AccountManagerListener.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,28 +15,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.protocol.event;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * Represents a listener receiving notifications from {@link AccountManager}.
- *
- * @author Lubomir Marinov
- */
-public interface AccountManagerListener
- extends EventListener
-{
-
- /**
- * Notifies this listener about an event fired by a specific
- * <code>AccountManager</code>.
- *
- * @param event the <code>AccountManagerEvent</code> describing the
- * <code>AccountManager</code> firing the notification and the
- * other details of the specific notification.
- */
- void handleAccountManagerEvent(AccountManagerEvent event);
-}
+package net.java.sip.communicator.service.protocol.event;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * Represents a listener receiving notifications from {@link AccountManager}.
+ *
+ * @author Lubomir Marinov
+ */
+public interface AccountManagerListener
+ extends EventListener
+{
+
+ /**
+ * Notifies this listener about an event fired by a specific
+ * <code>AccountManager</code>.
+ *
+ * @param event the <code>AccountManagerEvent</code> describing the
+ * <code>AccountManager</code> firing the notification and the
+ * other details of the specific notification.
+ */
+ void handleAccountManagerEvent(AccountManagerEvent event);
+}
diff --git a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityMessageEvent.java b/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityMessageEvent.java
index bcbb66a..92a3f31 100644
--- a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityMessageEvent.java
+++ b/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityMessageEvent.java
@@ -1,8 +1,19 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package net.java.sip.communicator.service.protocol.event;
diff --git a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityStatusEvent.java b/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityStatusEvent.java
index 6720f4b..931998b 100644
--- a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityStatusEvent.java
+++ b/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityStatusEvent.java
@@ -1,8 +1,19 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package net.java.sip.communicator.service.protocol.event;
diff --git a/src/net/java/sip/communicator/service/protocol/jabber/AbstractSmackInteroperabilityLayer.java b/src/net/java/sip/communicator/service/protocol/jabber/AbstractSmackInteroperabilityLayer.java
new file mode 100644
index 0000000..277da84
--- /dev/null
+++ b/src/net/java/sip/communicator/service/protocol/jabber/AbstractSmackInteroperabilityLayer.java
@@ -0,0 +1,141 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.service.protocol.jabber;
+
+import net.java.sip.communicator.util.*;
+import org.jivesoftware.smack.provider.*;
+
+
+/**
+ *
+ * This class abstracts interactions within Smack XMPP library (mostly with
+ * its <tt>ProviderManager</tt> class).
+ * This exists because <tt>JingleIQProvider</tt> and <tt>ColibriIQProvider</tt>
+ * are in need to be used with Smack v4, where <tt>ProviderManager</tt>
+ * has a different interface.
+ *
+ * @author Maksym Kulish
+ */
+abstract public class AbstractSmackInteroperabilityLayer {
+
+ /**
+ * The <tt>Logger</tt> used by the
+ * <tt>AbstractSmackInteroperabilityLayer</tt> class for
+ * reporting on improper implementations instantiation
+ */
+ private static final Logger logger = Logger.getLogger(
+ AbstractSmackInteroperabilityLayer.class);
+
+ /**
+ * The implementation class to be used within its Jitsi application
+ */
+ private static Class<AbstractSmackInteroperabilityLayer>
+ implementationClass;
+
+ /**
+ * The instance of Smack interoperability layer implementation class
+ */
+ private static AbstractSmackInteroperabilityLayer
+ interopLayerInstance;
+
+ /**
+ * Get the instance of Smack interoperability layer implementation class
+ *
+ * @return Smack interoperation layer implementation class
+ */
+ public static AbstractSmackInteroperabilityLayer getInstance()
+ {
+ if (interopLayerInstance == null)
+ {
+ try
+ {
+ interopLayerInstance =
+ implementationClass.newInstance();
+ }
+ catch (IllegalAccessException e)
+ {
+ // Never thrown within proper implementation
+ logger.fatal("Your AbstractSmackInteroperabilityLayer " +
+ "implementation " +
+ "cannot be accessed properly. " +
+ "Please fix the implementation");
+ }
+ catch (InstantiationException e)
+ {
+ // Never thrown within proper implementation
+ logger.fatal("Your AbstractSmackInteroperabilityLayer " +
+ "implementation " +
+ "cannot be instantiated properly. " +
+ "Please fix the implementation");
+ }
+ }
+ return interopLayerInstance;
+ }
+
+ /**
+ * Set the Smack interoperation layer
+ * implementation class to be used within this Jitsi application
+ * @param implementationClass Smack interoperation layer
+ * implementation class
+ */
+ public static void setImplementationClass(
+ Class implementationClass)
+ {
+ AbstractSmackInteroperabilityLayer.implementationClass
+ = implementationClass;
+ }
+
+
+ /**
+ * Add <tt>PacketExtensionProvider</tt> to the list of known
+ * providers
+ *
+ * @param elementName The element name where the matching is happening
+ * @param namespace The XML namespace used in that element
+ * @param provider <tt>PacketExtensionProvider</tt> implementation to be
+ * used
+ */
+ abstract public void addExtensionProvider(
+ String elementName, String namespace, Object provider);
+
+ /**
+ * Add <tt>IQProvider</tt> to the list of known
+ * providers
+ *
+ * @param elementName The element name where the matching is happening
+ * @param namespace The XML namespace used in that element
+ * @param provider <tt>IQProvider</tt> implementation to be
+ * used
+ */
+ abstract public void addIQProvider(
+ String elementName, String namespace, Object provider);
+
+ /**
+ * Get the <tt>PacketExtensionProvider</tt> for given element name and XML
+ * namespace
+ *
+ * @param elementName The element name where the matching is happening
+ * @param namespace The XML namespace used in that element
+ * @return <tt>PacketExtensionProvider</tt> implementation to be
+ * used
+ */
+ abstract public PacketExtensionProvider getExtensionProvider(
+ String elementName, String namespace);
+
+
+}
diff --git a/src/net/java/sip/communicator/service/protocol/jabber/JabberAccountID.java b/src/net/java/sip/communicator/service/protocol/jabber/JabberAccountID.java
index 81473c2..dce28d6 100644
--- a/src/net/java/sip/communicator/service/protocol/jabber/JabberAccountID.java
+++ b/src/net/java/sip/communicator/service/protocol/jabber/JabberAccountID.java
@@ -44,6 +44,12 @@ public class JabberAccountID
public static final String ANONYMOUS_AUTH = "ANONYMOUS_AUTH";
/**
+ * Configures the URL which is to be used with BOSH transport. If the value
+ * is <tt>null</tt> or empty then the TCP transport will be used instead.
+ */
+ public static final String BOSH_URL = "BOSH_URL";
+
+ /**
* Account suffix for Google service.
*/
public static final String GOOGLE_USER_SUFFIX = "gmail.com";
@@ -119,6 +125,29 @@ public class JabberAccountID
}
/**
+ * Returns the BOSH URL which should be used to connect to the XMPP server.
+ * If the value is set then BOSH transport instead of TCP will be used.
+ *
+ * @return a <tt>String</tt> with the URL which should be used for BOSH
+ * transport or <tt>null</tt> if disabled.
+ */
+ public String getBoshUrl()
+ {
+ return getAccountPropertyString(BOSH_URL);
+ }
+
+ /**
+ * Sets new URL which should be used for the BOSH transport.
+ *
+ * @param boshPath a <tt>String</tt> with the new BOSH URL or <tt>null</tt>
+ * to disable BOSH.
+ */
+ public void setBoshUrl(String boshPath)
+ {
+ putAccountProperty(BOSH_URL, boshPath);
+ }
+
+ /**
* Returns the override phone suffix.
*
* @return the phone suffix
diff --git a/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java b/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java
index b0d62ed..ead01d1 100644
--- a/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java
+++ b/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java
@@ -87,6 +87,16 @@ public abstract class CallPeerMediaHandler<T extends MediaAwareCallPeer<?,?,?>>
public static final String VIDEO_REMOTE_SSRC = "VIDEO_REMOTE_SSRC";
/**
+ * The initial content of a hole punch packet. It has some fields pre-set.
+ * Like rtp verion, sequence number and timestamp.
+ */
+ private static final byte[] HOLE_PUNCH_PACKET =
+ {
+ (byte)0x80, 0x00, 0x02, (byte)0x9E, 0x00, 0x09,
+ (byte)0xD0, (byte)0x80, 0x00, 0x00, 0x00, (byte)0x00,
+ };
+
+ /**
* List of advertised encryption methods. Indicated before establishing the
* call.
*/
@@ -374,7 +384,7 @@ public abstract class CallPeerMediaHandler<T extends MediaAwareCallPeer<?,?,?>>
if (call == null)
return;
- for (MediaType mediaType : MediaType.values())
+ for (MediaType mediaType : new MediaType[] {MediaType.AUDIO, MediaType.VIDEO} )
{
MediaStream stream = getStream(mediaType);
@@ -622,10 +632,8 @@ public abstract class CallPeerMediaHandler<T extends MediaAwareCallPeer<?,?,?>>
return audioDirectionUserPreference;
case VIDEO:
return videoDirectionUserPreference;
- case DATA:
- return MediaDirection.INACTIVE;
default:
- throw new IllegalArgumentException("mediaType");
+ return MediaDirection.INACTIVE;
}
}
@@ -689,7 +697,7 @@ public abstract class CallPeerMediaHandler<T extends MediaAwareCallPeer<?,?,?>>
return
(transportManager == null)
- ? null
+ ? 0
: transportManager.getHarvestingTime(harvesterName);
}
@@ -942,7 +950,9 @@ public abstract class CallPeerMediaHandler<T extends MediaAwareCallPeer<?,?,?>>
/**
* Returns the number of harvesting for this agent.
*
- * @return The number of harvesting for this agent.
+ * @return The number of harvesting for this agent. 0 if this harvester
+ * does not exists, if the ICE agent is null, or
+ * if the agent has never harvested with this harvester.
*/
public int getNbHarvesting()
{
@@ -950,7 +960,7 @@ public abstract class CallPeerMediaHandler<T extends MediaAwareCallPeer<?,?,?>>
return
(transportManager == null)
- ? null
+ ? 0
: transportManager.getNbHarvesting();
}
@@ -961,7 +971,8 @@ public abstract class CallPeerMediaHandler<T extends MediaAwareCallPeer<?,?,?>>
* @param harvesterName The class name if the harvester.
*
* @return The number of harvesting time for the harvester given in
- * parameter.
+ * parameter. 0 if this harvester does not exists, if the ICE agent is null, or if the
+ * agent has never harvested with this harvester.
*/
public int getNbHarvesting(String harvesterName)
{
@@ -969,7 +980,7 @@ public abstract class CallPeerMediaHandler<T extends MediaAwareCallPeer<?,?,?>>
return
(transportManager == null)
- ? null
+ ? 0
: transportManager.getNbHarvesting(harvesterName);
}
@@ -1036,17 +1047,10 @@ public abstract class CallPeerMediaHandler<T extends MediaAwareCallPeer<?,?,?>>
{
case AUDIO:
return audioStream;
- case DATA:
- /*
- * DATA is a valid MediaType value and CallPeerMediaHandler does not
- * utilize it at this time so no IllegalArgumentException is thrown
- * and null is returned (as documented).
- */
- return null;
case VIDEO:
return videoStream;
default:
- throw new IllegalArgumentException("mediaType");
+ return null;
}
}
@@ -1054,7 +1058,7 @@ public abstract class CallPeerMediaHandler<T extends MediaAwareCallPeer<?,?,?>>
* Returns the total harvesting time (in ms) for all harvesters.
*
* @return The total harvesting time (in ms) for all the harvesters. 0 if
- * the ICE agent is null, or if the agent has nevers harvested.
+ * the ICE agent is null, or if the agent has never harvested.
*/
public long getTotalHarvestingTime()
{
@@ -1062,7 +1066,7 @@ public abstract class CallPeerMediaHandler<T extends MediaAwareCallPeer<?,?,?>>
return
(transportManager == null)
- ? null
+ ? 0
: transportManager.getTotalHarvestingTime();
}
@@ -1581,11 +1585,21 @@ public abstract class CallPeerMediaHandler<T extends MediaAwareCallPeer<?,?,?>>
* to open port on NAT or RTP proxy if any. In order to be really efficient,
* this method should be called after we send our offer or answer.
*
- * @param target <tt>MediaStreamTarget</tt>
+ * @param stream <tt>MediaStream</tt> non-null stream
+ * @param mediaType <tt>MediaType</tt>
*/
- protected void sendHolePunchPacket(MediaStreamTarget target)
+ protected void sendHolePunchPacket(MediaStream stream, MediaType mediaType)
{
- getTransportManager().sendHolePunchPacket(target, MediaType.VIDEO);
+ // send as a hole punch packet a constructed rtp packet
+ // has the correct payload type and ssrc
+ RawPacket packet = new RawPacket(
+ HOLE_PUNCH_PACKET, 0, RawPacket.FIXED_HEADER_SIZE);
+ packet.setPayloadType(
+ dynamicPayloadTypes.getPayloadType(stream.getFormat()));
+ packet.setSSRC((int)stream.getLocalSourceID());
+
+ getTransportManager().sendHolePunchPacket(
+ stream.getTarget(), mediaType, packet);
}
/**
@@ -1942,6 +1956,8 @@ public abstract class CallPeerMediaHandler<T extends MediaAwareCallPeer<?,?,?>>
stream.getTarget(),
MediaType.AUDIO);
stream.start();
+
+ sendHolePunchPacket(stream, MediaType.AUDIO);
}
stream = getStream(MediaType.VIDEO);
@@ -1970,7 +1986,7 @@ public abstract class CallPeerMediaHandler<T extends MediaAwareCallPeer<?,?,?>>
* send the hole-punch packet anyway to let the remote video
* reach this local peer.
*/
- sendHolePunchPacket(stream.getTarget());
+ sendHolePunchPacket(stream, MediaType.VIDEO);
}
}
}
diff --git a/src/net/java/sip/communicator/service/protocol/media/MediaAwareCall.java b/src/net/java/sip/communicator/service/protocol/media/MediaAwareCall.java
index f9b6c2f..2bf802b 100644
--- a/src/net/java/sip/communicator/service/protocol/media/MediaAwareCall.java
+++ b/src/net/java/sip/communicator/service/protocol/media/MediaAwareCall.java
@@ -906,7 +906,7 @@ public abstract class MediaAwareCall<
@Override
protected CallConference createConference()
{
- return new MediaAwareCallConference();
+ return new MediaAwareCallConference(false, this.useTranslator);
}
/**
diff --git a/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallConference.java b/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallConference.java
index 7a58e4a..81e917c 100644
--- a/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallConference.java
+++ b/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallConference.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,623 +15,667 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.protocol.media;
-
-import java.beans.*;
-import java.lang.ref.*;
-import java.util.*;
-
-import org.jitsi.service.neomedia.*;
-import org.jitsi.service.neomedia.device.*;
-import org.jitsi.util.*;
-import org.jitsi.util.event.*;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * Extends <tt>CallConference</tt> to represent the media-specific information
- * associated with the telephony conference-related state of a
- * <tt>MediaAwareCall</tt>.
- *
- * @author Lyubomir Marinov
- */
-public class MediaAwareCallConference
- extends CallConference
-{
- /**
- * The <tt>PropertyChangeListener</tt> which will listen to the
- * <tt>MediaService</tt> about <tt>PropertyChangeEvent</tt>s.
- */
- private static WeakPropertyChangeListener
- mediaServicePropertyChangeListener;
-
- /**
- * The <tt>MediaDevice</tt>s indexed by <tt>MediaType</tt> ordinal which are
- * to be used by this telephony conference for media capture and/or
- * playback. If the <tt>MediaDevice</tt> for a specific <tt>MediaType</tt>
- * is <tt>null</tt>,
- * {@link MediaService#getDefaultDevice(MediaType, MediaUseCase)} is called.
- */
- private final MediaDevice[] devices;
-
- /**
- * The <tt>MediaDevice</tt>s which implement media mixing on the respective
- * <tt>MediaDevice</tt> in {@link #devices} for the purposes of this
- * telephony conference.
- */
- private final MediaDevice[] mixers;
-
- /**
- * The <tt>VolumeControl</tt> implementation which is to control the volume
- * (level) of the audio played back the telephony conference represented by
- * this instance.
- */
- private final VolumeControl outputVolumeControl
- = new BasicVolumeControl(
- VolumeControl.PLAYBACK_VOLUME_LEVEL_PROPERTY_NAME);
-
- /**
- * The <tt>PropertyChangeListener</tt> which listens to sources of
- * <tt>PropertyChangeEvent</tt>s on behalf of this instance.
- */
- private final PropertyChangeListener propertyChangeListener
- = new PropertyChangeListener()
- {
- @Override
- public void propertyChange(PropertyChangeEvent ev)
- {
- MediaAwareCallConference.this.propertyChange(ev);
- }
- };
-
- /**
- * The <tt>RTPTranslator</tt> which forwards video RTP and RTCP traffic
- * between the <tt>CallPeer</tt>s of the <tt>Call</tt>s participating in
- * this telephony conference when the local peer is acting as a conference
- * focus.
- */
- private RTPTranslator videoRTPTranslator;
-
- /**
- * Initializes a new <tt>MediaAwareCallConference</tt> instance.
- */
- public MediaAwareCallConference()
- {
- this(false);
- }
-
- /**
- * Initializes a new <tt>MediaAwareCallConference</tt> instance which is to
- * optionally utilize the Jitsi Videobridge server-side telephony
- * conferencing technology.
- *
- * @param jitsiVideobridge <tt>true</tt> if the telephony conference
- * represented by the new instance is to utilize the Jitsi Videobridge
- * server-side telephony conferencing technology; otherwise, <tt>false</tt>
- */
- public MediaAwareCallConference(boolean jitsiVideobridge)
- {
- super(jitsiVideobridge);
-
- int mediaTypeCount = MediaType.values().length;
-
- devices = new MediaDevice[mediaTypeCount];
- mixers = new MediaDevice[mediaTypeCount];
-
- /*
- * Listen to the MediaService in order to reflect changes in the user's
- * selection with respect to the default media device.
- */
- addMediaServicePropertyChangeListener(propertyChangeListener);
- }
-
- /**
- * Adds a specific <tt>PropertyChangeListener</tt> to be notified about
- * <tt>PropertyChangeEvent</tt>s fired by the current <tt>MediaService</tt>
- * implementation. The implementation adds a <tt>WeakReference</tt> to the
- * specified <tt>listener</tt> because <tt>MediaAwareCallConference</tt>
- * is unable to determine when the <tt>PropertyChangeListener</tt> is to be
- * removed.
- *
- * @param listener the <tt>PropertyChangeListener</tt> to add
- */
- private static synchronized void addMediaServicePropertyChangeListener(
- PropertyChangeListener listener)
- {
- if (mediaServicePropertyChangeListener == null)
- {
- final MediaService mediaService
- = ProtocolMediaActivator.getMediaService();
-
- if (mediaService != null)
- {
- mediaServicePropertyChangeListener
- = new WeakPropertyChangeListener()
- {
- @Override
- protected void addThisToNotifier()
- {
- mediaService.addPropertyChangeListener(this);
- }
-
- @Override
- protected void removeThisFromNotifier()
- {
- mediaService.removePropertyChangeListener(this);
- }
- };
- }
- }
- if (mediaServicePropertyChangeListener != null)
- {
- mediaServicePropertyChangeListener.addPropertyChangeListener(
- listener);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * If this telephony conference switches from being a conference focus to
- * not being such, disposes of the mixers used by this instance when it was
- * a conference focus
- */
- @Override
- protected void conferenceFocusChanged(boolean oldValue, boolean newValue)
- {
- /*
- * If this telephony conference switches from being a conference
- * focus to not being one, dispose of the mixers used when it was a
- * conference focus.
- */
- if (oldValue && !newValue)
- {
- Arrays.fill(mixers, null);
-
- /* Disposing the video translator is not needed when the conference
- changes as we have video and we will want to continue with
- the video
- Removed when chasing a bug where video call becomes conference
- call and then back again video call and the video from the
- conference focus side is not transmitted.
- if (videoRTPTranslator != null)
- {
- videoRTPTranslator.dispose();
- videoRTPTranslator = null;
- }
- */
- }
-
- super.conferenceFocusChanged(oldValue, newValue);
- }
-
- /**
- * {@inheritDoc}
- *
- * Disposes of <tt>this.videoRTPTranslator</tt> if the removed <tt>Call</tt>
- * was the last <tt>Call</tt> in this <tt>CallConference</tt>.
- *
- * @param call the <tt>Call</tt> which has been removed from the list of
- * <tt>Call</tt>s participating in this telephony conference.
- */
- @Override
- protected void callRemoved(Call call)
- {
- super.callRemoved(call);
-
- if (getCallCount() == 0 && (videoRTPTranslator != null))
- {
- videoRTPTranslator.dispose();
- videoRTPTranslator = null;
- }
- }
-
- /**
- * Gets a <tt>MediaDevice</tt> which is capable of capture and/or playback
- * of media of the specified <tt>MediaType</tt> and is the default choice of
- * the user with respect to such a <tt>MediaDevice</tt>.
- *
- * @param mediaType the <tt>MediaType</tt> in which the retrieved
- * <tt>MediaDevice</tt> is to capture and/or play back media
- * @param useCase the <tt>MediaUseCase</tt> associated with the intended
- * utilization of the <tt>MediaDevice</tt> to be retrieved
- * @return a <tt>MediaDevice</tt> which is capable of capture and/or
- * playback of media of the specified <tt>mediaType</tt> and is the default
- * choice of the user with respect to such a <tt>MediaDevice</tt>
- */
- public MediaDevice getDefaultDevice(
- MediaType mediaType,
- MediaUseCase useCase)
- {
- int mediaTypeIndex = mediaType.ordinal();
- MediaDevice device = devices[mediaTypeIndex];
- MediaService mediaService = ProtocolMediaActivator.getMediaService();
-
- if (device == null)
- device = mediaService.getDefaultDevice(mediaType, useCase);
-
- /*
- * Make sure that the device is capable of mixing in order to support
- * conferencing and call recording.
- */
- if (device != null)
- {
- MediaDevice mixer = mixers[mediaTypeIndex];
-
- if (mixer == null)
- {
- switch (mediaType)
- {
- case AUDIO:
- /*
- * TODO AudioMixer leads to very poor audio quality on
- * Android so do not use it unless it is really really
- * necessary.
- */
- if ((!OSUtils.IS_ANDROID || isConferenceFocus())
- /*
- * We can use the AudioMixer only if the device is
- * able to capture (because the AudioMixer will push
- * when the capture device pushes).
- */
- && device.getDirection().allowsSending())
- {
- mixer = mediaService.createMixer(device);
- }
- break;
-
- case VIDEO:
- if (isConferenceFocus())
- mixer = mediaService.createMixer(device);
- break;
- }
-
- mixers[mediaTypeIndex] = mixer;
- }
-
- if (mixer != null)
- device = mixer;
- }
-
- return device;
- }
-
- /**
- * Gets the <tt>VolumeControl</tt> which controls the volume (level) of the
- * audio played back in the telephony conference represented by this
- * instance.
- *
- * @return the <tt>VolumeControl</tt> which controls the volume (level) of
- * the audio played back in the telephony conference represented by this
- * instance
- */
- public VolumeControl getOutputVolumeControl()
- {
- return outputVolumeControl;
- }
-
- /**
- * Gets the <tt>RTPTranslator</tt> which forwards RTP and RTCP traffic
- * between the <tt>CallPeer</tt>s of the <tt>Call</tt>s participating in
- * this telephony conference when the local peer is acting as a conference
- * focus.
- *
- * @param mediaType the <tt>MediaType</tt> of the <tt>MediaStream</tt> which
- * RTP and RTCP traffic is to be forwarded between
- * @return the <tt>RTPTranslator</tt> which forwards RTP and RTCP traffic
- * between the <tt>CallPeer</tt>s of the <tt>Call</tt>s participating in
- * this telephony conference when the local peer is acting as a conference
- * focus
- */
- public RTPTranslator getRTPTranslator(MediaType mediaType)
- {
- RTPTranslator rtpTranslator = null;
-
- /*
- * XXX A mixer is created for audio even when the local peer is not a
- * conference focus in order to enable additional functionality.
- * Similarly, the videoRTPTranslator is created even when the local peer
- * is not a conference focus in order to enable the local peer to turn
- * into a conference focus at a later time. More specifically,
- * MediaStreamImpl is unable to accommodate an RTPTranslator after it
- * has created its RTPManager. Yet again like the audio mixer, we'd
- * better not try to use it on Android at this time because of
- * performance issues that might arise.
- */
- if (MediaType.VIDEO.equals(mediaType)
- && (!OSUtils.IS_ANDROID || isConferenceFocus()))
- {
- if (videoRTPTranslator == null)
- {
- videoRTPTranslator
- = ProtocolMediaActivator
- .getMediaService()
- .createRTPTranslator();
- }
- rtpTranslator = videoRTPTranslator;
- }
- return rtpTranslator;
- }
-
- /**
- * Notifies this <tt>MediaAwareCallConference</tt> about changes in the
- * values of the properties of sources of <tt>PropertyChangeEvent</tt>s. For
- * example, this instance listens to changes of the value of
- * {@link MediaService#DEFAULT_DEVICE} which represents the user's choice
- * with respect to the default audio device.
- *
- * @param ev a <tt>PropertyChangeEvent</tt> which specifies the name of the
- * property which had its value changed and the old and new values of that
- * property
- */
- private void propertyChange(PropertyChangeEvent ev)
- {
- String propertyName = ev.getPropertyName();
-
- if (MediaService.DEFAULT_DEVICE.equals(propertyName))
- {
- Object source = ev.getSource();
-
- if (source instanceof MediaService)
- {
- /*
- * XXX We only support changing the default audio device at the
- * time of this writing.
- */
- int mediaTypeIndex = MediaType.AUDIO.ordinal();
- MediaDevice mixer = mixers[mediaTypeIndex];
- MediaDevice oldValue
- = (mixer instanceof MediaDeviceWrapper)
- ? ((MediaDeviceWrapper) mixer).getWrappedDevice()
- : null;
- MediaDevice newValue = devices[mediaTypeIndex];
-
- if (newValue == null)
- {
- newValue
- = ProtocolMediaActivator
- .getMediaService()
- .getDefaultDevice(
- MediaType.AUDIO,
- MediaUseCase.ANY);
- }
-
- /*
- * XXX If MediaService#getDefaultDevice(MediaType, MediaUseCase)
- * above returns null and its earlier return value was not null,
- * we will not notify of an actual change in the value of the
- * user's choice with respect to the default audio device.
- */
- if (oldValue != newValue)
- {
- mixers[mediaTypeIndex] = null;
- firePropertyChange(
- MediaAwareCall.DEFAULT_DEVICE,
- oldValue, newValue);
- }
- }
- }
- }
-
- /**
- * Sets the <tt>MediaDevice</tt> to be used by this telephony conference for
- * capture and/or playback of media of a specific <tt>MediaType</tt>.
- *
- * @param mediaType the <tt>MediaType</tt> of the media which is to be
- * captured and/or played back by the specified <tt>device</tt>
- * @param device the <tt>MediaDevice</tt> to be used by this telephony
- * conference for capture and/or playback of media of the specified
- * <tt>mediaType</tt>
- */
- void setDevice(MediaType mediaType, MediaDevice device)
- {
- int mediaTypeIndex = mediaType.ordinal();
- MediaDevice oldValue = devices[mediaTypeIndex];
-
- /*
- * XXX While we know the old and the new master/wrapped devices, we
- * are not sure whether the mixer has been used. Anyway, we have to
- * report different values in order to have PropertyChangeSupport
- * really fire an event.
- */
- MediaDevice mixer = mixers[mediaTypeIndex];
-
- if (mixer instanceof MediaDeviceWrapper)
- oldValue = ((MediaDeviceWrapper) mixer).getWrappedDevice();
-
- MediaDevice newValue = devices[mediaTypeIndex] = device;
-
- if (oldValue != newValue)
- {
- mixers[mediaTypeIndex] = null;
- firePropertyChange(
- MediaAwareCall.DEFAULT_DEVICE,
- oldValue, newValue);
- }
- }
-
- /**
- * Implements a <tt>PropertyChangeListener</tt> which weakly references and
- * delegates to specific <tt>PropertyChangeListener</tt>s and automatically
- * adds itself to and removes itself from a specific
- * <tt>PropertyChangeNotifier</tt> depending on whether there are
- * <tt>PropertyChangeListener</tt>s to delegate to. Thus enables listening
- * to a <tt>PropertyChangeNotifier</tt> by invoking
- * {@link PropertyChangeNotifier#addPropertyChangeListener(
- * PropertyChangeListener)} without
- * {@link PropertyChangeNotifier#removePropertyChangeListener(
- * PropertyChangeListener)}.
- */
- private static class WeakPropertyChangeListener
- implements PropertyChangeListener
- {
- /**
- * The indicator which determines whether this
- * <tt>PropertyChangeListener</tt> has been added to {@link #notifier}.
- */
- private boolean added = false;
-
- /**
- * The list of <tt>PropertyChangeListener</tt>s which are to be notified
- * about <tt>PropertyChangeEvent</tt>s fired by {@link #notifier}.
- */
- private final List<WeakReference<PropertyChangeListener>> listeners
- = new LinkedList<WeakReference<PropertyChangeListener>>();
-
- /**
- * The <tt>PropertyChangeNotifier</tt> this instance is to listen to
- * about <tt>PropertyChangeEvent</tt>s which are to be forwarded to
- * {@link #listeners}.
- */
- private final PropertyChangeNotifier notifier;
-
- /**
- * Initializes a new <tt>WeakPropertyChangeListener</tt> instance.
- */
- protected WeakPropertyChangeListener()
- {
- this(null);
- }
-
- /**
- * Initializes a new <tt>WeakPropertyChangeListener</tt> instance which
- * is to listen to a specific <tt>PropertyChangeNotifier</tt>.
- *
- * @param notifier the <tt>PropertyChangeNotifier</tt> the new instance
- * is to listen to
- */
- public WeakPropertyChangeListener(PropertyChangeNotifier notifier)
- {
- this.notifier = notifier;
- }
-
- /**
- * Adds a specific <tt>PropertyChangeListener</tt> to the list of
- * <tt>PropertyChangeListener</tt>s to be notified about
- * <tt>PropertyChangeEvent</tt>s fired by the
- * <tt>PropertyChangeNotifier</tt> associated with this instance.
- *
- * @param listener the <tt>PropertyChangeListener</tt> to add
- */
- public synchronized void addPropertyChangeListener(
- PropertyChangeListener listener)
- {
- Iterator<WeakReference<PropertyChangeListener>> i
- = listeners.iterator();
- boolean add = true;
-
- while (i.hasNext())
- {
- PropertyChangeListener l = i.next().get();
-
- if (l == null)
- i.remove();
- else if (l.equals(listener))
- add = false;
- }
- if (add
- && listeners.add(
- new WeakReference<PropertyChangeListener>(listener))
- && !this.added)
- {
- addThisToNotifier();
- this.added = true;
- }
- }
-
- /**
- * Adds this as a <tt>PropertyChangeListener</tt> to {@link #notifier}.
- */
- protected void addThisToNotifier()
- {
- if (notifier != null)
- notifier.addPropertyChangeListener(this);
- }
-
- /**
- * {@inheritDoc}
- *
- * Notifies this instance about a <tt>PropertyChangeEvent</tt> fired by
- * {@link #notifier}.
- */
- @Override
- public void propertyChange(PropertyChangeEvent ev)
- {
- PropertyChangeListener[] ls;
- int n;
-
- synchronized (this)
- {
- Iterator<WeakReference<PropertyChangeListener>> i
- = listeners.iterator();
-
- ls = new PropertyChangeListener[listeners.size()];
- n = 0;
- while (i.hasNext())
- {
- PropertyChangeListener l = i.next().get();
-
- if (l == null)
- i.remove();
- else
- ls[n++] = l;
- }
- if ((n == 0) && this.added)
- {
- removeThisFromNotifier();
- this.added = false;
- }
- }
-
- if (n != 0)
- {
- for (PropertyChangeListener l : ls)
- {
- if (l == null)
- break;
- else
- l.propertyChange(ev);
- }
- }
- }
-
- /**
- * Removes a specific <tt>PropertyChangeListener</tt> from the list of
- * <tt>PropertyChangeListener</tt>s to be notified about
- * <tt>PropertyChangeEvent</tt>s fired by the
- * <tt>PropertyChangeNotifier</tt> associated with this instance.
- *
- * @param listener the <tt>PropertyChangeListener</tt> to remove
- */
- @SuppressWarnings("unused")
- public synchronized void removePropertyChangeListener(
- PropertyChangeListener listener)
- {
- Iterator<WeakReference<PropertyChangeListener>> i
- = listeners.iterator();
-
- while (i.hasNext())
- {
- PropertyChangeListener l = i.next().get();
-
- if ((l == null) || l.equals(listener))
- i.remove();
- }
- if (this.added && (listeners.size() == 0))
- {
- removeThisFromNotifier();
- this.added = false;
- }
- }
-
- /**
- * Removes this as a <tt>PropertyChangeListener</tt> from
- * {@link #notifier}.
- */
- protected void removeThisFromNotifier()
- {
- if (notifier != null)
- notifier.removePropertyChangeListener(this);
- }
- }
-}
+package net.java.sip.communicator.service.protocol.media;
+
+import java.beans.*;
+import java.lang.ref.*;
+import java.util.*;
+
+import org.jitsi.service.neomedia.*;
+import org.jitsi.service.neomedia.device.*;
+import org.jitsi.util.*;
+import org.jitsi.util.event.*;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * Extends <tt>CallConference</tt> to represent the media-specific information
+ * associated with the telephony conference-related state of a
+ * <tt>MediaAwareCall</tt>.
+ *
+ * @author Lyubomir Marinov
+ */
+public class MediaAwareCallConference
+ extends CallConference
+{
+ /**
+ * The <tt>PropertyChangeListener</tt> which will listen to the
+ * <tt>MediaService</tt> about <tt>PropertyChangeEvent</tt>s.
+ */
+ private static WeakPropertyChangeListener
+ mediaServicePropertyChangeListener;
+
+ /**
+ * The <tt>MediaDevice</tt>s indexed by <tt>MediaType</tt> ordinal which are
+ * to be used by this telephony conference for media capture and/or
+ * playback. If the <tt>MediaDevice</tt> for a specific <tt>MediaType</tt>
+ * is <tt>null</tt>,
+ * {@link MediaService#getDefaultDevice(MediaType, MediaUseCase)} is called.
+ */
+ private final MediaDevice[] devices;
+
+ /**
+ * The <tt>MediaDevice</tt>s which implement media mixing on the respective
+ * <tt>MediaDevice</tt> in {@link #devices} for the purposes of this
+ * telephony conference.
+ */
+ private final MediaDevice[] mixers;
+
+ /**
+ * The <tt>VolumeControl</tt> implementation which is to control the volume
+ * (level) of the audio played back the telephony conference represented by
+ * this instance.
+ */
+ private final VolumeControl outputVolumeControl
+ = new BasicVolumeControl(
+ VolumeControl.PLAYBACK_VOLUME_LEVEL_PROPERTY_NAME);
+
+ /**
+ * The <tt>PropertyChangeListener</tt> which listens to sources of
+ * <tt>PropertyChangeEvent</tt>s on behalf of this instance.
+ */
+ private final PropertyChangeListener propertyChangeListener
+ = new PropertyChangeListener()
+ {
+ @Override
+ public void propertyChange(PropertyChangeEvent ev)
+ {
+ MediaAwareCallConference.this.propertyChange(ev);
+ }
+ };
+
+ /**
+ * The <tt>RTPTranslator</tt> which forwards video RTP and RTCP traffic
+ * between the <tt>CallPeer</tt>s of the <tt>Call</tt>s participating in
+ * this telephony conference when the local peer is acting as a conference
+ * focus.
+ */
+ private RTPTranslator videoRTPTranslator;
+
+ /**
+ * The <tt>RTPTranslator</tt> which forwards autio RTP and RTCP traffic
+ * between the <tt>CallPeer</tt>s of the <tt>Call</tt>s participating in
+ * this telephony conference when the local peer is acting as a conference
+ * focus.
+ */
+ private RTPTranslator audioRTPTranslator;
+
+ /**
+ * The indicator which determines whether the telephony conference
+ * represented by this instance is mixing or relaying.
+ * By default what can be mixed is mixed (audio) and rest is relayed.
+ */
+ private boolean translator = false;
+
+ /**
+ * Initializes a new <tt>MediaAwareCallConference</tt> instance.
+ */
+ public MediaAwareCallConference()
+ {
+ this(false);
+ }
+
+ /**
+ * Initializes a new <tt>MediaAwareCallConference</tt> instance which is to
+ * optionally utilize the Jitsi Videobridge server-side telephony
+ * conferencing technology.
+ *
+ * @param jitsiVideobridge <tt>true</tt> if the telephony conference
+ * represented by the new instance is to utilize the Jitsi Videobridge
+ * server-side telephony conferencing technology; otherwise, <tt>false</tt>
+ */
+ public MediaAwareCallConference(boolean jitsiVideobridge)
+ {
+ this(jitsiVideobridge, false);
+ }
+
+ /**
+ * Initializes a new <tt>MediaAwareCallConference</tt> instance which is to
+ * optionally utilize the Jitsi Videobridge server-side telephony
+ * conferencing technology.
+ *
+ * @param jitsiVideobridge <tt>true</tt> if the telephony conference
+ * represented by the new instance is to utilize the Jitsi Videobridge
+ * server-side telephony conferencing technology; otherwise, <tt>false</tt>
+ */
+ public MediaAwareCallConference(boolean jitsiVideobridge,
+ boolean translator)
+ {
+ super(jitsiVideobridge);
+
+ this.translator = translator;
+
+ int mediaTypeCount = MediaType.values().length;
+
+ devices = new MediaDevice[mediaTypeCount];
+ mixers = new MediaDevice[mediaTypeCount];
+
+ /*
+ * Listen to the MediaService in order to reflect changes in the user's
+ * selection with respect to the default media device.
+ */
+ addMediaServicePropertyChangeListener(propertyChangeListener);
+ }
+
+ /**
+ * Adds a specific <tt>PropertyChangeListener</tt> to be notified about
+ * <tt>PropertyChangeEvent</tt>s fired by the current <tt>MediaService</tt>
+ * implementation. The implementation adds a <tt>WeakReference</tt> to the
+ * specified <tt>listener</tt> because <tt>MediaAwareCallConference</tt>
+ * is unable to determine when the <tt>PropertyChangeListener</tt> is to be
+ * removed.
+ *
+ * @param listener the <tt>PropertyChangeListener</tt> to add
+ */
+ private static synchronized void addMediaServicePropertyChangeListener(
+ PropertyChangeListener listener)
+ {
+ if (mediaServicePropertyChangeListener == null)
+ {
+ final MediaService mediaService
+ = ProtocolMediaActivator.getMediaService();
+
+ if (mediaService != null)
+ {
+ mediaServicePropertyChangeListener
+ = new WeakPropertyChangeListener()
+ {
+ @Override
+ protected void addThisToNotifier()
+ {
+ mediaService.addPropertyChangeListener(this);
+ }
+
+ @Override
+ protected void removeThisFromNotifier()
+ {
+ mediaService.removePropertyChangeListener(this);
+ }
+ };
+ }
+ }
+ if (mediaServicePropertyChangeListener != null)
+ {
+ mediaServicePropertyChangeListener.addPropertyChangeListener(
+ listener);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * If this telephony conference switches from being a conference focus to
+ * not being such, disposes of the mixers used by this instance when it was
+ * a conference focus
+ */
+ @Override
+ protected void conferenceFocusChanged(boolean oldValue, boolean newValue)
+ {
+ /*
+ * If this telephony conference switches from being a conference
+ * focus to not being one, dispose of the mixers used when it was a
+ * conference focus.
+ */
+ if (oldValue && !newValue)
+ {
+ Arrays.fill(mixers, null);
+
+ /* Disposing the video translator is not needed when the conference
+ changes as we have video and we will want to continue with
+ the video
+ Removed when chasing a bug where video call becomes conference
+ call and then back again video call and the video from the
+ conference focus side is not transmitted.
+ if (videoRTPTranslator != null)
+ {
+ videoRTPTranslator.dispose();
+ videoRTPTranslator = null;
+ }
+ */
+ }
+
+ super.conferenceFocusChanged(oldValue, newValue);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Disposes of <tt>this.videoRTPTranslator</tt> if the removed <tt>Call</tt>
+ * was the last <tt>Call</tt> in this <tt>CallConference</tt>.
+ *
+ * @param call the <tt>Call</tt> which has been removed from the list of
+ * <tt>Call</tt>s participating in this telephony conference.
+ */
+ @Override
+ protected void callRemoved(Call call)
+ {
+ super.callRemoved(call);
+
+ if (getCallCount() == 0 && (videoRTPTranslator != null))
+ {
+ videoRTPTranslator.dispose();
+ videoRTPTranslator = null;
+ }
+ }
+
+ /**
+ * Gets a <tt>MediaDevice</tt> which is capable of capture and/or playback
+ * of media of the specified <tt>MediaType</tt> and is the default choice of
+ * the user with respect to such a <tt>MediaDevice</tt>.
+ *
+ * @param mediaType the <tt>MediaType</tt> in which the retrieved
+ * <tt>MediaDevice</tt> is to capture and/or play back media
+ * @param useCase the <tt>MediaUseCase</tt> associated with the intended
+ * utilization of the <tt>MediaDevice</tt> to be retrieved
+ * @return a <tt>MediaDevice</tt> which is capable of capture and/or
+ * playback of media of the specified <tt>mediaType</tt> and is the default
+ * choice of the user with respect to such a <tt>MediaDevice</tt>
+ */
+ public MediaDevice getDefaultDevice(
+ MediaType mediaType,
+ MediaUseCase useCase)
+ {
+ int mediaTypeIndex = mediaType.ordinal();
+ MediaDevice device = devices[mediaTypeIndex];
+ MediaService mediaService = ProtocolMediaActivator.getMediaService();
+
+ if (device == null)
+ device = mediaService.getDefaultDevice(mediaType, useCase);
+
+ /*
+ * Make sure that the device is capable of mixing in order to support
+ * conferencing and call recording.
+ */
+ if (device != null)
+ {
+ MediaDevice mixer = mixers[mediaTypeIndex];
+
+ if (mixer == null)
+ {
+ switch (mediaType)
+ {
+ case AUDIO:
+ /*
+ * TODO AudioMixer leads to very poor audio quality on
+ * Android so do not use it unless it is really really
+ * necessary.
+ */
+ if ((!OSUtils.IS_ANDROID || isConferenceFocus())
+ && !this.translator
+ /*
+ * We can use the AudioMixer only if the device is
+ * able to capture (because the AudioMixer will push
+ * when the capture device pushes).
+ */
+ && device.getDirection().allowsSending())
+ {
+ mixer = mediaService.createMixer(device);
+ }
+ break;
+
+ case VIDEO:
+ if (isConferenceFocus())
+ mixer = mediaService.createMixer(device);
+ break;
+ }
+
+ mixers[mediaTypeIndex] = mixer;
+ }
+
+ if (mixer != null)
+ device = mixer;
+ }
+
+ return device;
+ }
+
+ /**
+ * Gets the <tt>VolumeControl</tt> which controls the volume (level) of the
+ * audio played back in the telephony conference represented by this
+ * instance.
+ *
+ * @return the <tt>VolumeControl</tt> which controls the volume (level) of
+ * the audio played back in the telephony conference represented by this
+ * instance
+ */
+ public VolumeControl getOutputVolumeControl()
+ {
+ return outputVolumeControl;
+ }
+
+ /**
+ * Gets the <tt>RTPTranslator</tt> which forwards RTP and RTCP traffic
+ * between the <tt>CallPeer</tt>s of the <tt>Call</tt>s participating in
+ * this telephony conference when the local peer is acting as a conference
+ * focus.
+ *
+ * @param mediaType the <tt>MediaType</tt> of the <tt>MediaStream</tt> which
+ * RTP and RTCP traffic is to be forwarded between
+ * @return the <tt>RTPTranslator</tt> which forwards RTP and RTCP traffic
+ * between the <tt>CallPeer</tt>s of the <tt>Call</tt>s participating in
+ * this telephony conference when the local peer is acting as a conference
+ * focus
+ */
+ public RTPTranslator getRTPTranslator(MediaType mediaType)
+ {
+ /*
+ * XXX A mixer is created for audio even when the local peer is not a
+ * conference focus in order to enable additional functionality.
+ * Similarly, the videoRTPTranslator is created even when the local peer
+ * is not a conference focus in order to enable the local peer to turn
+ * into a conference focus at a later time. More specifically,
+ * MediaStreamImpl is unable to accommodate an RTPTranslator after it
+ * has created its RTPManager. Yet again like the audio mixer, we'd
+ * better not try to use it on Android at this time because of
+ * performance issues that might arise.
+ */
+ if (MediaType.VIDEO.equals(mediaType)
+ && (!OSUtils.IS_ANDROID || isConferenceFocus()))
+ {
+ if (videoRTPTranslator == null)
+ {
+ videoRTPTranslator
+ = ProtocolMediaActivator
+ .getMediaService()
+ .createRTPTranslator();
+ }
+ return videoRTPTranslator;
+ }
+
+ if (this.translator)
+ {
+ if(audioRTPTranslator == null)
+ {
+ audioRTPTranslator
+ = ProtocolMediaActivator
+ .getMediaService()
+ .createRTPTranslator();
+ }
+ return audioRTPTranslator;
+ }
+
+ return null;
+ }
+
+ /**
+ * Notifies this <tt>MediaAwareCallConference</tt> about changes in the
+ * values of the properties of sources of <tt>PropertyChangeEvent</tt>s. For
+ * example, this instance listens to changes of the value of
+ * {@link MediaService#DEFAULT_DEVICE} which represents the user's choice
+ * with respect to the default audio device.
+ *
+ * @param ev a <tt>PropertyChangeEvent</tt> which specifies the name of the
+ * property which had its value changed and the old and new values of that
+ * property
+ */
+ private void propertyChange(PropertyChangeEvent ev)
+ {
+ String propertyName = ev.getPropertyName();
+
+ if (MediaService.DEFAULT_DEVICE.equals(propertyName))
+ {
+ Object source = ev.getSource();
+
+ if (source instanceof MediaService)
+ {
+ /*
+ * XXX We only support changing the default audio device at the
+ * time of this writing.
+ */
+ int mediaTypeIndex = MediaType.AUDIO.ordinal();
+ MediaDevice mixer = mixers[mediaTypeIndex];
+ MediaDevice oldValue
+ = (mixer instanceof MediaDeviceWrapper)
+ ? ((MediaDeviceWrapper) mixer).getWrappedDevice()
+ : null;
+ MediaDevice newValue = devices[mediaTypeIndex];
+
+ if (newValue == null)
+ {
+ newValue
+ = ProtocolMediaActivator
+ .getMediaService()
+ .getDefaultDevice(
+ MediaType.AUDIO,
+ MediaUseCase.ANY);
+ }
+
+ /*
+ * XXX If MediaService#getDefaultDevice(MediaType, MediaUseCase)
+ * above returns null and its earlier return value was not null,
+ * we will not notify of an actual change in the value of the
+ * user's choice with respect to the default audio device.
+ */
+ if (oldValue != newValue)
+ {
+ mixers[mediaTypeIndex] = null;
+ firePropertyChange(
+ MediaAwareCall.DEFAULT_DEVICE,
+ oldValue, newValue);
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets the <tt>MediaDevice</tt> to be used by this telephony conference for
+ * capture and/or playback of media of a specific <tt>MediaType</tt>.
+ *
+ * @param mediaType the <tt>MediaType</tt> of the media which is to be
+ * captured and/or played back by the specified <tt>device</tt>
+ * @param device the <tt>MediaDevice</tt> to be used by this telephony
+ * conference for capture and/or playback of media of the specified
+ * <tt>mediaType</tt>
+ */
+ void setDevice(MediaType mediaType, MediaDevice device)
+ {
+ int mediaTypeIndex = mediaType.ordinal();
+ MediaDevice oldValue = devices[mediaTypeIndex];
+
+ /*
+ * XXX While we know the old and the new master/wrapped devices, we
+ * are not sure whether the mixer has been used. Anyway, we have to
+ * report different values in order to have PropertyChangeSupport
+ * really fire an event.
+ */
+ MediaDevice mixer = mixers[mediaTypeIndex];
+
+ if (mixer instanceof MediaDeviceWrapper)
+ oldValue = ((MediaDeviceWrapper) mixer).getWrappedDevice();
+
+ MediaDevice newValue = devices[mediaTypeIndex] = device;
+
+ if (oldValue != newValue)
+ {
+ mixers[mediaTypeIndex] = null;
+ firePropertyChange(
+ MediaAwareCall.DEFAULT_DEVICE,
+ oldValue, newValue);
+ }
+ }
+
+ /**
+ * Implements a <tt>PropertyChangeListener</tt> which weakly references and
+ * delegates to specific <tt>PropertyChangeListener</tt>s and automatically
+ * adds itself to and removes itself from a specific
+ * <tt>PropertyChangeNotifier</tt> depending on whether there are
+ * <tt>PropertyChangeListener</tt>s to delegate to. Thus enables listening
+ * to a <tt>PropertyChangeNotifier</tt> by invoking
+ * {@link PropertyChangeNotifier#addPropertyChangeListener(
+ * PropertyChangeListener)} without
+ * {@link PropertyChangeNotifier#removePropertyChangeListener(
+ * PropertyChangeListener)}.
+ */
+ private static class WeakPropertyChangeListener
+ implements PropertyChangeListener
+ {
+ /**
+ * The indicator which determines whether this
+ * <tt>PropertyChangeListener</tt> has been added to {@link #notifier}.
+ */
+ private boolean added = false;
+
+ /**
+ * The list of <tt>PropertyChangeListener</tt>s which are to be notified
+ * about <tt>PropertyChangeEvent</tt>s fired by {@link #notifier}.
+ */
+ private final List<WeakReference<PropertyChangeListener>> listeners
+ = new LinkedList<WeakReference<PropertyChangeListener>>();
+
+ /**
+ * The <tt>PropertyChangeNotifier</tt> this instance is to listen to
+ * about <tt>PropertyChangeEvent</tt>s which are to be forwarded to
+ * {@link #listeners}.
+ */
+ private final PropertyChangeNotifier notifier;
+
+ /**
+ * Initializes a new <tt>WeakPropertyChangeListener</tt> instance.
+ */
+ protected WeakPropertyChangeListener()
+ {
+ this(null);
+ }
+
+ /**
+ * Initializes a new <tt>WeakPropertyChangeListener</tt> instance which
+ * is to listen to a specific <tt>PropertyChangeNotifier</tt>.
+ *
+ * @param notifier the <tt>PropertyChangeNotifier</tt> the new instance
+ * is to listen to
+ */
+ public WeakPropertyChangeListener(PropertyChangeNotifier notifier)
+ {
+ this.notifier = notifier;
+ }
+
+ /**
+ * Adds a specific <tt>PropertyChangeListener</tt> to the list of
+ * <tt>PropertyChangeListener</tt>s to be notified about
+ * <tt>PropertyChangeEvent</tt>s fired by the
+ * <tt>PropertyChangeNotifier</tt> associated with this instance.
+ *
+ * @param listener the <tt>PropertyChangeListener</tt> to add
+ */
+ public synchronized void addPropertyChangeListener(
+ PropertyChangeListener listener)
+ {
+ Iterator<WeakReference<PropertyChangeListener>> i
+ = listeners.iterator();
+ boolean add = true;
+
+ while (i.hasNext())
+ {
+ PropertyChangeListener l = i.next().get();
+
+ if (l == null)
+ i.remove();
+ else if (l.equals(listener))
+ add = false;
+ }
+ if (add
+ && listeners.add(
+ new WeakReference<PropertyChangeListener>(listener))
+ && !this.added)
+ {
+ addThisToNotifier();
+ this.added = true;
+ }
+ }
+
+ /**
+ * Adds this as a <tt>PropertyChangeListener</tt> to {@link #notifier}.
+ */
+ protected void addThisToNotifier()
+ {
+ if (notifier != null)
+ notifier.addPropertyChangeListener(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Notifies this instance about a <tt>PropertyChangeEvent</tt> fired by
+ * {@link #notifier}.
+ */
+ @Override
+ public void propertyChange(PropertyChangeEvent ev)
+ {
+ PropertyChangeListener[] ls;
+ int n;
+
+ synchronized (this)
+ {
+ Iterator<WeakReference<PropertyChangeListener>> i
+ = listeners.iterator();
+
+ ls = new PropertyChangeListener[listeners.size()];
+ n = 0;
+ while (i.hasNext())
+ {
+ PropertyChangeListener l = i.next().get();
+
+ if (l == null)
+ i.remove();
+ else
+ ls[n++] = l;
+ }
+ if ((n == 0) && this.added)
+ {
+ removeThisFromNotifier();
+ this.added = false;
+ }
+ }
+
+ if (n != 0)
+ {
+ for (PropertyChangeListener l : ls)
+ {
+ if (l == null)
+ break;
+ else
+ l.propertyChange(ev);
+ }
+ }
+ }
+
+ /**
+ * Removes a specific <tt>PropertyChangeListener</tt> from the list of
+ * <tt>PropertyChangeListener</tt>s to be notified about
+ * <tt>PropertyChangeEvent</tt>s fired by the
+ * <tt>PropertyChangeNotifier</tt> associated with this instance.
+ *
+ * @param listener the <tt>PropertyChangeListener</tt> to remove
+ */
+ @SuppressWarnings("unused")
+ public synchronized void removePropertyChangeListener(
+ PropertyChangeListener listener)
+ {
+ Iterator<WeakReference<PropertyChangeListener>> i
+ = listeners.iterator();
+
+ while (i.hasNext())
+ {
+ PropertyChangeListener l = i.next().get();
+
+ if ((l == null) || l.equals(listener))
+ i.remove();
+ }
+ if (this.added && (listeners.size() == 0))
+ {
+ removeThisFromNotifier();
+ this.added = false;
+ }
+ }
+
+ /**
+ * Removes this as a <tt>PropertyChangeListener</tt> from
+ * {@link #notifier}.
+ */
+ protected void removeThisFromNotifier()
+ {
+ if (notifier != null)
+ notifier.removePropertyChangeListener(this);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java b/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java
index 4e15038..23e42d4 100644
--- a/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java
+++ b/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,1247 +15,1247 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.protocol.media;
-
-import java.beans.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.neomedia.*;
-import org.jitsi.service.neomedia.event.*;
-
-/**
- * A utility class implementing media control code shared between current
- * telephony implementations. This class is only meant for use by protocol
- * implementations and should/could not be accessed by bundles that are simply
- * using the telephony functionalities.
- *
- * @param <T> the peer extension class like for example <tt>CallSipImpl</tt>
- * or <tt>CallJabberImpl</tt>
- * @param <U> the media handler extension class like for example
- * <tt>CallPeerMediaHandlerSipImpl</tt> or
- * <tt>CallPeerMediaHandlerJabberImpl</tt>
- * @param <V> the provider extension class like for example
- * <tt>ProtocolProviderServiceSipImpl</tt> or
- * <tt>ProtocolProviderServiceJabberImpl</tt>
- *
- * @author Emil Ivov
- * @author Lyubomir Marinov
- * @author Boris Grozev
- */
-public abstract class MediaAwareCallPeer
- <T extends MediaAwareCall<?, ?, V>,
- U extends CallPeerMediaHandler<?>,
- V extends ProtocolProviderService>
- extends AbstractCallPeer<T, V>
- implements SrtpListener,
- CallPeerConferenceListener,
- CsrcAudioLevelListener,
- SimpleAudioLevelListener
-{
- /**
- * The <tt>Logger</tt> used by the <tt>MediaAwareCallPeer</tt> class and its
- * instances for logging output.
- */
- private static final Logger logger
- = Logger.getLogger(MediaAwareCallPeer.class);
-
- /**
- * The call this peer belongs to.
- */
- private T call;
-
- /**
- * The listeners registered for level changes in the audio of participants
- * that this peer might be mixing and that we are not directly communicating
- * with.
- */
- private final List<ConferenceMembersSoundLevelListener>
- conferenceMembersSoundLevelListeners
- = new ArrayList<ConferenceMembersSoundLevelListener>();
-
- /**
- * A byte array containing the image/photo representing the call peer.
- */
- private byte[] image;
-
- /**
- * The media handler class handles all media management for a single
- * <tt>CallPeer</tt>. This includes initializing and configuring streams,
- * generating SDP, handling ICE, etc. One instance of <tt>CallPeer</tt>always
- * corresponds to exactly one instance of <tt>CallPeerMediaHandler</tt> and
- * both classes are only separated for reasons of readability.
- */
- private U mediaHandler;
-
- /**
- * The <tt>PropertyChangeListener</tt> which listens to
- * {@link CallPeerMediaHandler} for changes in the values of its properties.
- */
- private PropertyChangeListener mediaHandlerPropertyChangeListener;
-
- /**
- * A string uniquely identifying the peer.
- */
- private String peerID;
-
- /**
- * The protocol provider that this peer belongs to.
- */
- private final V protocolProvider;
-
- /**
- * The list of <tt>SoundLevelListener</tt>s interested in level changes in
- * the audio we are getting from the remote peer.
- * <p>
- * It is implemented as a copy-on-write storage because the number of
- * additions and removals of <tt>SoundLevelListener</tt>s is expected to be
- * far smaller than the number of audio level changes. The access to it is
- * to be synchronized using {@link #streamSoundLevelListenersSyncRoot}.
- * </p>
- */
- private List<SoundLevelListener> streamSoundLevelListeners;
-
- /**
- * The <tt>Object</tt> to synchronize the access to
- * {@link #streamSoundLevelListeners}.
- */
- private final Object streamSoundLevelListenersSyncRoot = new Object();
-
- /**
- * The <tt>List</tt> of <tt>PropertyChangeListener</tt>s listening to this
- * <tt>CallPeer</tt> for changes in the values of its properties related to
- * video.
- */
- private final List<PropertyChangeListener> videoPropertyChangeListeners
- = new LinkedList<PropertyChangeListener>();
-
- /**
- * Represents the last Conference Information (RFC4575) document sent to
- * this <tt>CallPeer</tt>. This is always a document with state "full", even
- * if the last document actually sent was a "partial"
- */
- private ConferenceInfoDocument lastConferenceInfoSent = null;
-
- /**
- * The time (as obtained by <tt>System.currentTimeMillis()</tt>) at which
- * a Conference Information (RFC4575) document was last sent to this
- * <tt>CallPeer</tt>.
- */
- private long lastConferenceInfoSentTimestamp = -1;
-
- /**
- * The last Conference Information (RFC4575) document sent to us by this
- * <tt>CallPeer</tt>. This is always a document with state "full", which is
- * only gets updated by "partial" or "deleted" documents.
- */
- private ConferenceInfoDocument lastConferenceInfoReceived = null;
-
- /**
- * Whether a conference-info document has been scheduled to be sent to this
- * <tt>CallPeer</tt>
- */
- private boolean confInfoScheduled = false;
-
- /**
- * Synchronization object for confInfoScheduled
- */
- private final Object confInfoScheduledSyncRoot = new Object();
-
- /**
- * Creates a new call peer with address <tt>peerAddress</tt>.
- *
- * @param owningCall the call that contains this call peer.
- */
- public MediaAwareCallPeer(T owningCall)
- {
- this.call = owningCall;
- this.protocolProvider = owningCall.getProtocolProvider();
-
- // create the uid
- this.peerID
- = String.valueOf(System.currentTimeMillis())
- + String.valueOf(hashCode());
-
- // we listen for events when the call will become focus or not
- // of a conference so we will add or remove our sound level listeners
- super.addCallPeerConferenceListener(this);
- }
-
- /**
- * Adds a specific <tt>ConferenceMembersSoundLevelListener</tt> to the list
- * of listeners interested in and notified about changes in conference
- * members sound level.
- *
- * @param listener the <tt>ConferenceMembersSoundLevelListener</tt> to add
- * @throws NullPointerException if <tt>listener</tt> is <tt>null</tt>
- */
- public void addConferenceMembersSoundLevelListener(
- ConferenceMembersSoundLevelListener listener)
- {
- /*
- * XXX The uses of the method at the time of this writing rely on being
- * able to add a null listener so make it a no-op here.
- */
- if (listener == null)
- return;
-
- synchronized (conferenceMembersSoundLevelListeners)
- {
- if (conferenceMembersSoundLevelListeners.size() == 0)
- {
- // if this is the first listener that's being registered with
- // us, we also need to register ourselves as a CSRC audio level
- // listener with the media handler.
- getMediaHandler().setCsrcAudioLevelListener(this);
- }
- conferenceMembersSoundLevelListeners.add(listener);
- }
- }
-
- /**
- * Adds a specific <tt>SoundLevelListener</tt> to the list of listeners
- * interested in and notified about changes in the sound level of the audio
- * sent by the remote party. When the first listener is being registered
- * the method also registers its single listener with the media handler so
- * that it would receive level change events and delegate them to the
- * listeners that have registered with us.
- *
- * @param listener the <tt>SoundLevelListener</tt> to add
- */
- public void addStreamSoundLevelListener(SoundLevelListener listener)
- {
- synchronized (streamSoundLevelListenersSyncRoot)
- {
- if ((streamSoundLevelListeners == null)
- || streamSoundLevelListeners.isEmpty())
- {
- CallPeerMediaHandler<?> mediaHandler = getMediaHandler();
-
- if (isJitsiVideobridge())
- {
- /*
- * When the local user/peer has organized a telephony
- * conference utilizing the Jitsi Videobridge server-side
- * technology, the server will calculate the audio levels
- * and not the client.
- */
- mediaHandler.setCsrcAudioLevelListener(this);
- }
- else
- {
- /*
- * If this is the first listener that's being registered
- * with us, we also need to register ourselves as an audio
- * level listener with the media handler. We do this so that
- * audio levels would only be calculated if anyone is
- * interested in receiving them.
- */
- mediaHandler.setStreamAudioLevelListener(this);
- }
- }
-
- /*
- * Implement streamAudioLevelListeners as a copy-on-write storage so
- * that iterators over it can iterate without
- * ConcurrentModificationExceptions.
- */
- streamSoundLevelListeners
- = (streamSoundLevelListeners == null)
- ? new ArrayList<SoundLevelListener>()
- : new ArrayList<SoundLevelListener>(
- streamSoundLevelListeners);
- streamSoundLevelListeners.add(listener);
- }
- }
-
- /**
- * Adds a specific <tt>PropertyChangeListener</tt> to the list of
- * listeners which get notified when the properties (e.g.
- * LOCAL_VIDEO_STREAMING) associated with this <tt>CallPeer</tt> change
- * their values.
- *
- * @param listener the <tt>PropertyChangeListener</tt> to be notified
- * when the properties associated with the specified <tt>Call</tt> change
- * their values
- */
- public void addVideoPropertyChangeListener(PropertyChangeListener listener)
- {
- if (listener == null)
- throw new NullPointerException("listener");
-
- synchronized (videoPropertyChangeListeners)
- {
- /*
- * The video is part of the media-related functionality and thus it
- * is the responsibility of mediaHandler. So listen to mediaHandler
- * for video-related property changes and re-fire them as
- * originating from this instance.
- */
- if (!videoPropertyChangeListeners.contains(listener)
- && videoPropertyChangeListeners.add(listener)
- && (mediaHandlerPropertyChangeListener == null))
- {
- mediaHandlerPropertyChangeListener
- = new PropertyChangeListener()
- {
- public void propertyChange(PropertyChangeEvent event)
- {
- Iterable<PropertyChangeListener> listeners;
-
- synchronized (videoPropertyChangeListeners)
- {
- listeners
- = new LinkedList<PropertyChangeListener>(
- videoPropertyChangeListeners);
- }
-
- PropertyChangeEvent thisEvent
- = new PropertyChangeEvent(
- this,
- event.getPropertyName(),
- event.getOldValue(),
- event.getNewValue());
-
- for (PropertyChangeListener listener : listeners)
- listener.propertyChange(thisEvent);
- }
- };
- getMediaHandler()
- .addPropertyChangeListener(
- mediaHandlerPropertyChangeListener);
- }
- }
- }
-
- /**
- * Notified by its very majesty the media service about changes in the audio
- * level of the stream coming from this peer, the method generates the
- * corresponding events and delivers them to the listeners that have
- * registered here.
- *
- * @param newLevel the new audio level of the audio stream received from the
- * remote peer
- */
- public void audioLevelChanged(int newLevel)
- {
- /*
- * If we're in a conference in which this CallPeer is the focus and
- * we're the only member in it besides the focus, we will not receive
- * audio levels in the RTP and our media will instead measure the audio
- * levels of the received media. In order to make the UI oblivious of
- * the difference, we have to translate the event to the appropriate
- * type of listener.
- *
- * We may end up in a conference call with 0 members if the server
- * for some reason doesn't support sip conference (our subscribes
- * doesn't go to the focus of the conference) and so we must
- * pass the sound levels measured on the stream so we can see
- * the stream activity of the call.
- */
- int conferenceMemberCount = getConferenceMemberCount();
-
- if ((conferenceMemberCount > 0) && (conferenceMemberCount < 3))
- {
- long audioRemoteSSRC
- = getMediaHandler().getRemoteSSRC(MediaType.AUDIO);
-
- if (audioRemoteSSRC != CallPeerMediaHandler.SSRC_UNKNOWN)
- {
- audioLevelsReceived(new long[] { audioRemoteSSRC, newLevel });
- return;
- }
- }
-
- fireStreamSoundLevelChanged(newLevel);
- }
-
-
- /**
- * Implements {@link CsrcAudioLevelListener#audioLevelsReceived(long[])}.
- * Delivers the received audio levels to the
- * {@link ConferenceMembersSoundLevelListener}s registered with this
- * <tt>MediaAwareCallPeer</tt>..
- *
- * @param audioLevels the levels that we need to dispatch to all registered
- * <tt>ConferenceMemberSoundLevelListeners</tt>.
- */
- public void audioLevelsReceived(long[] audioLevels)
- {
- /*
- * When the local user/peer has organized a telephony conference
- * utilizing the Jitsi Videobridge server-side technology, the server
- * will calculate the audio levels and not the client.
- */
- if (isJitsiVideobridge())
- {
- long audioRemoteSSRC
- = getMediaHandler().getRemoteSSRC(MediaType.AUDIO);
-
- if (audioRemoteSSRC != CallPeerMediaHandler.SSRC_UNKNOWN)
- {
- for (int i = 0; i < audioLevels.length; i += 2)
- {
- if (audioLevels[i] == audioRemoteSSRC)
- {
- fireStreamSoundLevelChanged((int) audioLevels[i + 1]);
- break;
- }
- }
- }
- }
-
- if (getConferenceMemberCount() == 0)
- return;
-
- Map<ConferenceMember, Integer> levelsMap
- = new HashMap<ConferenceMember, Integer>();
-
- for (int i = 0; i < audioLevels.length; i += 2)
- {
- ConferenceMember mmbr = findConferenceMember(audioLevels[i]);
-
- if (mmbr != null)
- levelsMap.put(mmbr, (int) audioLevels[i + 1]);
- }
-
- synchronized (conferenceMembersSoundLevelListeners)
- {
- int conferenceMemberSoundLevelListenerCount
- = conferenceMembersSoundLevelListeners.size();
-
- if (conferenceMemberSoundLevelListenerCount > 0)
- {
- ConferenceMembersSoundLevelEvent ev
- = new ConferenceMembersSoundLevelEvent(this, levelsMap);
-
- for (int i = 0;
- i < conferenceMemberSoundLevelListenerCount;
- i++)
- {
- conferenceMembersSoundLevelListeners
- .get(i)
- .soundLevelChanged(ev);
- }
- }
- }
- }
-
- /**
- * Does nothing.
- * @param evt the event.
- */
- public void callPeerAdded(CallPeerEvent evt) {}
-
- /**
- * Does nothing.
- * @param evt the event.
- */
- public void callPeerRemoved(CallPeerEvent evt) {}
-
- /**
- * Dummy implementation of {@link CallPeerConferenceListener
- * #conferenceFocusChanged(CallPeerConferenceEvent)}.
- *
- * @param evt ignored
- */
- public void conferenceFocusChanged(CallPeerConferenceEvent evt)
- {
- }
-
- /**
- * Called when this peer becomes a mixer. The method add removes this class
- * as the stream audio level listener for the media coming from this peer
- * because the levels it delivers no longer represent the level of a
- * particular member. The method also adds this class as a member (CSRC)
- * audio level listener.
- *
- * @param conferenceEvent the event containing information (that we don't
- * really use) on the newly add member.
- */
- public void conferenceMemberAdded(CallPeerConferenceEvent conferenceEvent)
- {
- if (getConferenceMemberCount() > 2)
- {
- /*
- * This peer is now a conference focus with more than three
- * participants. It means that this peer is mixing and sending us
- * audio for at least two separate participants. We therefore need
- * to switch from stream to CSRC level listening.
- */
- CallPeerMediaHandler<?> mediaHandler = getMediaHandler();
-
- mediaHandler.setStreamAudioLevelListener(null);
- mediaHandler.setCsrcAudioLevelListener(this);
- }
- }
-
- /**
- * Dummy implementation of {@link CallPeerConferenceListener
- * #conferenceMemberErrorReceived(CallPeerConferenceEvent)}.
- *
- * @param ev the event
- */
- public void conferenceMemberErrorReceived(CallPeerConferenceEvent ev) {};
-
- /**
- * Called when this peer stops being a mixer. The method add removes this
- * class as the stream audio level listener for the media coming from this
- * peer because the levels it delivers no longer represent the level of a
- * particular member. The method also adds this class as a member (CSRC)
- * audio level listener.
- *
- * @param conferenceEvent the event containing information (that we don't
- * really use) on the freshly removed member.
- */
- public void conferenceMemberRemoved(CallPeerConferenceEvent conferenceEvent)
- {
- if (getConferenceMemberCount() < 3)
- {
- /*
- * This call peer is no longer mixing audio from multiple sources
- * since there's only us and her in the call. We therefore need to
- * switch from CSRC to stream level listening.
- */
- CallPeerMediaHandler<?> mediaHandler = getMediaHandler();
-
- mediaHandler.setStreamAudioLevelListener(this);
- mediaHandler.setCsrcAudioLevelListener(null);
- }
- }
-
- /**
- * Invokes {@link SoundLevelListener#soundLevelChanged(Object, int) on
- * the <tt>SoundLevelListener</tt>s interested in the changes of the audio
- * stream received from the remote peer i.e. in
- * {@link #streamSoundLevelListeners}.
- *
- * @param newLevel the new value of the sound level to notify
- * <tt>streamSoundLevelListeners</tt> about
- */
- private void fireStreamSoundLevelChanged(int newLevel)
- {
- List<SoundLevelListener> streamSoundLevelListeners;
-
- synchronized (streamSoundLevelListenersSyncRoot)
- {
- /*
- * Since the streamAudioLevelListeners field of this
- * MediaAwareCallPeer is implemented as a copy-on-write storage,
- * just get a reference to it and it should be safe to iterate over it
- * without ConcurrentModificationExceptions.
- */
- streamSoundLevelListeners = this.streamSoundLevelListeners;
- }
-
- if (streamSoundLevelListeners != null)
- {
- /*
- * Iterate over streamAudioLevelListeners using an index rather than
- * an Iterator in order to try to reduce the number of allocations
- * (as the number of audio level changes is expected to be very
- * large).
- */
- int streamSoundLevelListenerCount
- = streamSoundLevelListeners.size();
-
- for(int i = 0; i < streamSoundLevelListenerCount; i++)
- {
- streamSoundLevelListeners.get(i).soundLevelChanged(
- this,
- newLevel);
- }
- }
- }
-
- /**
- * Returns a reference to the call that this peer belongs to. Calls
- * are created by underlying telephony protocol implementations.
- *
- * @return a reference to the call containing this peer.
- */
- @Override
- public T getCall()
- {
- return call;
- }
-
- /**
- * The method returns an image representation of the call peer if one is
- * available.
- *
- * @return byte[] a byte array containing the image or null if no image is
- * available.
- */
- public byte[] getImage()
- {
- return image;
- }
-
- /**
- * Returns a reference to the <tt>CallPeerMediaHandler</tt> used by this
- * peer. The media handler class handles all media management for a single
- * <tt>CallPeer</tt>. This includes initializing and configuring streams,
- * generating SDP, handling ICE, etc. One instance of <tt>CallPeer</tt>
- * always corresponds to exactly one instance of
- * <tt>CallPeerMediaHandler</tt> and both classes are only separated for
- * reasons of readability.
- *
- * @return a reference to the <tt>CallPeerMediaHandler</tt> instance that
- * this peer uses for media related tips and tricks.
- */
- public U getMediaHandler()
- {
- return mediaHandler;
- }
-
- /**
- * Returns a unique identifier representing this peer.
- *
- * @return an identifier representing this call peer.
- */
- public String getPeerID()
- {
- return peerID;
- }
-
- /**
- * Returns the protocol provider that this peer belongs to.
- *
- * @return a reference to the <tt>ProtocolProviderService</tt> that this
- * peer belongs to.
- */
- @Override
- public V getProtocolProvider()
- {
- return protocolProvider;
- }
-
- /**
- * Determines whether this <tt>CallPeer</tt> is participating in a telephony
- * conference organized by the local user/peer utilizing the Jitsi
- * Videobridge server-side technology.
- *
- * @return <tt>true</tt> if this <tt>CallPeer</tt> is participating in a
- * telephony conference organized by the local user/peer utilizing the Jitsi
- * Videobridge server-side technology; otherwise, <tt>false</tt>
- */
- public final boolean isJitsiVideobridge()
- {
- Call call = getCall();
-
- if (call != null)
- {
- CallConference conference = call.getConference();
-
- if (conference != null)
- return conference.isJitsiVideobridge();
- }
- return false;
- }
-
- /**
- * Determines whether we are currently streaming video toward whoever this
- * <tt>MediaAwareCallPeer</tt> represents.
- *
- * @return <tt>true</tt> if we are currently streaming video toward this
- * <tt>CallPeer</tt> and <tt>false</tt> otherwise.
- */
- public boolean isLocalVideoStreaming()
- {
- return getMediaHandler().isLocalVideoTransmissionEnabled();
- }
-
- /**
- * Determines whether the audio stream (if any) being sent to this
- * peer is mute.
- *
- * @return <tt>true</tt> if an audio stream is being sent to this
- * peer and it is currently mute; <tt>false</tt>, otherwise
- */
- @Override
- public boolean isMute()
- {
- return getMediaHandler().isMute();
- }
-
- /**
- * Logs <tt>message</tt> and <tt>cause</tt> and sets this <tt>peer</tt>'s
- * state to <tt>CallPeerState.FAILED</tt>
- *
- * @param message a message to log and display to the user.
- * @param throwable the exception that cause the error we are logging
- */
- public void logAndFail(String message, Throwable throwable)
- {
- logger.error(message, throwable);
- setState(CallPeerState.FAILED, message);
- }
-
- /**
- * Updates the state of this <tt>CallPeer</tt> to match the locally-on-hold
- * status of our media handler.
- */
- public void reevalLocalHoldStatus()
- {
- CallPeerState state = getState();
- boolean locallyOnHold = getMediaHandler().isLocallyOnHold();
-
- if (CallPeerState.ON_HOLD_LOCALLY.equals(state))
- {
- if (!locallyOnHold)
- setState(CallPeerState.CONNECTED);
- }
- else if (CallPeerState.ON_HOLD_MUTUALLY.equals(state))
- {
- if (!locallyOnHold)
- setState(CallPeerState.ON_HOLD_REMOTELY);
- }
- else if (CallPeerState.ON_HOLD_REMOTELY.equals(state))
- {
- if (locallyOnHold)
- setState(CallPeerState.ON_HOLD_MUTUALLY);
- }
- else if (locallyOnHold)
- {
- setState(CallPeerState.ON_HOLD_LOCALLY);
- }
- }
-
- /**
- * Updates the state of this <tt>CallPeer</tt> to match the remotely-on-hold
- * status of our media handler.
- */
- public void reevalRemoteHoldStatus()
- {
- boolean remotelyOnHold = getMediaHandler().isRemotelyOnHold();
-
- CallPeerState state = getState();
- if (CallPeerState.ON_HOLD_LOCALLY.equals(state))
- {
- if (remotelyOnHold)
- setState(CallPeerState.ON_HOLD_MUTUALLY);
- }
- else if (CallPeerState.ON_HOLD_MUTUALLY.equals(state))
- {
- if (!remotelyOnHold)
- setState(CallPeerState.ON_HOLD_LOCALLY);
- }
- else if (CallPeerState.ON_HOLD_REMOTELY.equals(state))
- {
- if (!remotelyOnHold)
- setState(CallPeerState.CONNECTED);
- }
- else if (remotelyOnHold)
- {
- setState(CallPeerState.ON_HOLD_REMOTELY);
- }
- }
-
- /**
- * Removes a specific <tt>ConferenceMembersSoundLevelListener</tt> of the
- * list of listeners interested in and notified about changes in conference
- * members sound level.
- *
- * @param listener the <tt>ConferenceMembersSoundLevelListener</tt> to
- * remove
- */
- public void removeConferenceMembersSoundLevelListener(
- ConferenceMembersSoundLevelListener listener)
- {
- synchronized (conferenceMembersSoundLevelListeners)
- {
- if (conferenceMembersSoundLevelListeners.remove(listener)
- && (conferenceMembersSoundLevelListeners.size() == 0))
- {
- // if this was the last listener then we also remove ourselves
- // as a CSRC audio level listener from the handler so that we
- // don't have to create new events and maps for something no one
- // is interested in.
- getMediaHandler().setCsrcAudioLevelListener(null);
- }
- }
- }
-
- /**
- * Removes a specific <tt>SoundLevelListener</tt> of the list of
- * listeners interested in and notified about changes in stream sound level
- * related information.
- *
- * @param listener the <tt>SoundLevelListener</tt> to remove
- */
- public void removeStreamSoundLevelListener(SoundLevelListener listener)
- {
- synchronized (streamSoundLevelListenersSyncRoot)
- {
- /*
- * Implement streamAudioLevelListeners as a copy-on-write storage so
- * that iterators over it can iterate over it without
- * ConcurrentModificationExceptions.
- */
- if (streamSoundLevelListeners != null)
- {
- streamSoundLevelListeners
- = new ArrayList<SoundLevelListener>(
- streamSoundLevelListeners);
- if (streamSoundLevelListeners.remove(listener)
- && streamSoundLevelListeners.isEmpty())
- streamSoundLevelListeners = null;
- }
-
- if ((streamSoundLevelListeners == null)
- || streamSoundLevelListeners.isEmpty())
- {
- // if this was the last listener then we also need to remove
- // ourselves as an audio level so that audio levels would only
- // be calculated if anyone is interested in receiving them.
- getMediaHandler().setStreamAudioLevelListener(null);
- }
- }
- }
-
- /**
- * Removes a specific <tt>PropertyChangeListener</tt> from the list of
- * listeners which get notified when the properties (e.g.
- * LOCAL_VIDEO_STREAMING) associated with this <tt>CallPeer</tt> change
- * their values.
- *
- * @param listener the <tt>PropertyChangeListener</tt> to no longer be
- * notified when the properties associated with the specified <tt>Call</tt>
- * change their values
- */
- public void removeVideoPropertyChangeListener(
- PropertyChangeListener listener)
- {
- if (listener != null)
- synchronized (videoPropertyChangeListeners)
- {
- /*
- * The video is part of the media-related functionality and thus
- * it is the responsibility of mediaHandler. So we're listening
- * to mediaHandler for video-related property changes and w're
- * re-firing them as originating from this instance. Make sure
- * that we're not listening to mediaHandler if noone is
- * interested in video-related property changes originating from
- * this instance.
- */
- if (videoPropertyChangeListeners.remove(listener)
- && videoPropertyChangeListeners.isEmpty()
- && (mediaHandlerPropertyChangeListener != null))
- {
-// getMediaHandler()
-// .removePropertyChangeListener(
-// mediaHandlerPropertyChangeListener);
- mediaHandlerPropertyChangeListener = null;
- }
- }
- }
-
- /**
- * Sets the security message associated with a failure/warning or
- * information coming from the encryption protocol.
- *
- * @param messageType the type of the message.
- * @param i18nMessage the message
- * @param severity severity level
- */
- public void securityMessageReceived(
- String messageType,
- String i18nMessage,
- int severity)
- {
- fireCallPeerSecurityMessageEvent(messageType,
- i18nMessage,
- severity);
- }
-
- /**
- * Indicates that the other party has timeouted replying to our
- * offer to secure the connection.
- *
- * @param mediaType the <tt>MediaType</tt> of the call session
- * @param sender the security controller that caused the event
- */
- public void securityNegotiationStarted(
- MediaType mediaType,
- SrtpControl sender)
- {
- fireCallPeerSecurityNegotiationStartedEvent(
- new CallPeerSecurityNegotiationStartedEvent(
- this,
- toSessionType(mediaType),
- sender));
- }
-
- /**
- * Indicates that the other party has timeouted replying to our
- * offer to secure the connection.
- *
- * @param mediaType the <tt>MediaType</tt> of the call session
- */
- public void securityTimeout(MediaType mediaType)
- {
- fireCallPeerSecurityTimeoutEvent(
- new CallPeerSecurityTimeoutEvent(
- this,
- toSessionType(mediaType)));
- }
-
- /**
- * Sets the security status to OFF for this call peer.
- *
- * @param mediaType the <tt>MediaType</tt> of the call session
- */
- public void securityTurnedOff(MediaType mediaType)
- {
- // If this event has been triggered because of a call end event and the
- // call is already ended we don't need to alert the user for
- // security off.
- if((call != null) && !call.getCallState().equals(CallState.CALL_ENDED))
- {
- fireCallPeerSecurityOffEvent(
- new CallPeerSecurityOffEvent(
- this,
- toSessionType(mediaType)));
- }
- }
-
- /**
- * Sets the security status to ON for this call peer.
- *
- * @param mediaType the <tt>MediaType</tt> of the call session
- * @param cipher the cipher
- * @param sender the security controller that caused the event
- */
- public void securityTurnedOn(
- MediaType mediaType,
- String cipher,
- SrtpControl sender)
- {
- getMediaHandler().startSrtpMultistream(sender);
- fireCallPeerSecurityOnEvent(
- new CallPeerSecurityOnEvent(
- this,
- toSessionType(mediaType),
- cipher,
- sender));
- }
-
- /**
- * Sets the call containing this peer.
- *
- * @param call the call that this call peer is participating in.
- */
- public void setCall(T call)
- {
- this.call = call;
- }
-
- /**
- * Sets the byte array containing an image representation (photo or picture)
- * of the call peer.
- *
- * @param image a byte array containing the image
- */
- public void setImage(byte[] image)
- {
- byte[] oldImage = getImage();
- this.image = image;
-
- //Fire the Event
- fireCallPeerChangeEvent(
- CallPeerChangeEvent.CALL_PEER_IMAGE_CHANGE,
- oldImage,
- image);
- }
-
- /**
- * Modifies the local media setup to reflect the requested setting for the
- * streaming of the local video and then re-invites the peer represented by
- * this class using a corresponding SDP description..
- *
- * @param allowed <tt>true</tt> if local video transmission is allowed and
- * <tt>false</tt> otherwise.
- *
- * @throws OperationFailedException if video initialization fails.
- */
- public void setLocalVideoAllowed(boolean allowed)
- throws OperationFailedException
- {
- CallPeerMediaHandler<?> mediaHandler = getMediaHandler();
-
- if(mediaHandler.isLocalVideoTransmissionEnabled() != allowed)
- {
- // Modify the local media setup to reflect the requested setting for
- // the streaming of the local video.
- mediaHandler.setLocalVideoTransmissionEnabled(allowed);
- }
- }
-
- /**
- * Sets a reference to the <tt>CallPeerMediaHandler</tt> used by this
- * peer. The media handler class handles all media management for a single
- * <tt>CallPeer</tt>. This includes initializing and configuring streams,
- * generating SDP, handling ICE, etc. One instance of <tt>CallPeer</tt>
- * always corresponds to exactly one instance of
- * <tt>CallPeerMediaHandler</tt> and both classes are only separated for
- * reasons of readability.
- *
- * @param mediaHandler a reference to the <tt>CallPeerMediaHandler</tt>
- * instance that this peer uses for media related tips and tricks.
- */
- protected void setMediaHandler(U mediaHandler)
- {
- this.mediaHandler = mediaHandler;
- }
-
- /**
- * Sets the mute property for this call peer.
- *
- * @param newMuteValue the new value of the mute property for this call peer
- */
- @Override
- public void setMute(boolean newMuteValue)
- {
- getMediaHandler().setMute(newMuteValue);
- super.setMute(newMuteValue);
- }
-
- /**
- * Sets the String that serves as a unique identifier of this
- * CallPeer.
- * @param peerID the ID of this call peer.
- */
- public void setPeerID(String peerID)
- {
- this.peerID = peerID;
- }
-
- /**
- * Overrides the parent set state method in order to make sure that we
- * close our media handler whenever we enter a disconnected state.
- *
- * @param newState the <tt>CallPeerState</tt> that we are about to enter and
- * that we pass to our predecessor.
- * @param reason a reason phrase explaining the state (e.g. if newState
- * indicates a failure) and that we pass to our predecessor.
- * @param reasonCode the code for the reason of the state change.
- */
- @Override
- public void setState(CallPeerState newState, String reason, int reasonCode)
- {
- // synchronized to mediaHandler if there are currently jobs of
- // initializing, configuring and starting streams (method processAnswer
- // of CallPeerMediaHandler) we won't set and fire the current state
- // to Disconnected. Before closing the mediaHandler is setting the state
- // in order to deliver states as quick as possible.
- CallPeerMediaHandler<?> mediaHandler = getMediaHandler();
-
- synchronized(mediaHandler)
- {
- try
- {
- super.setState(newState, reason, reasonCode);
- }
- finally
- {
- // make sure whatever happens to close the media
- if (CallPeerState.DISCONNECTED.equals(newState)
- || CallPeerState.FAILED.equals(newState))
- mediaHandler.close();
- }
- }
- }
-
- /**
- * Returns the last <tt>ConferenceInfoDocument</tt> sent by us to this
- * <tt>CallPeer</tt>. It is a document with state <tt>full</tt>
- * @return the last <tt>ConferenceInfoDocument</tt> sent by us to this
- * <tt>CallPeer</tt>. It is a document with state <tt>full</tt>
- */
- public ConferenceInfoDocument getLastConferenceInfoSent()
- {
- return lastConferenceInfoSent;
- }
-
- /**
- * Sets the last <tt>ConferenceInfoDocument</tt> sent by us to this
- * <tt>CallPeer</tt>.
- * @param confInfo the document to set.
- */
- public void setLastConferenceInfoSent(ConferenceInfoDocument confInfo)
- {
- lastConferenceInfoSent = confInfo;
- }
-
- /**
- * Gets the time (as obtained by <tt>System.currentTimeMillis()</tt>)
- * at which we last sent a <tt>ConferenceInfoDocument</tt> to this
- * <tt>CallPeer</tt>.
- * @return the time (as obtained by <tt>System.currentTimeMillis()</tt>)
- * at which we last sent a <tt>ConferenceInfoDocument</tt> to this
- * <tt>CallPeer</tt>.
- */
- public long getLastConferenceInfoSentTimestamp()
- {
- return lastConferenceInfoSentTimestamp;
- }
-
- /**
- * Sets the time (as obtained by <tt>System.currentTimeMillis()</tt>)
- * at which we last sent a <tt>ConferenceInfoDocument</tt> to this
- * <tt>CallPeer</tt>.
- * @param newTimestamp the time to set
- */
- public void setLastConferenceInfoSentTimestamp(long newTimestamp)
- {
- lastConferenceInfoSentTimestamp = newTimestamp;
- }
-
- /**
- * Gets the last <tt>ConferenceInfoDocument</tt> sent to us by this
- * <tt>CallPeer</tt>.
- * @return the last <tt>ConferenceInfoDocument</tt> sent to us by this
- * <tt>CallPeer</tt>.
- */
- public ConferenceInfoDocument getLastConferenceInfoReceived()
- {
- return lastConferenceInfoReceived;
- }
-
- /**
- * Gets the last <tt>ConferenceInfoDocument</tt> sent to us by this
- * <tt>CallPeer</tt>.
- * @return the last <tt>ConferenceInfoDocument</tt> sent to us by this
- * <tt>CallPeer</tt>.
- */
- public void setLastConferenceInfoReceived(ConferenceInfoDocument confInfo)
- {
- lastConferenceInfoReceived = confInfo;
- }
-
- /**
- * Gets the <tt>version</tt> of the last <tt>ConferenceInfoDocument</tt>
- * sent to us by this <tt>CallPeer</tt>, or -1 if we haven't (yet) received
- * a <tt>ConferenceInformationDocument</tt> from this <tt>CallPeer</tt>.
- * @return
- */
- public int getLastConferenceInfoReceivedVersion()
- {
- return (lastConferenceInfoReceived == null)
- ? -1
- : lastConferenceInfoReceived.getVersion();
- }
-
- /**
- * Gets the <tt>String</tt> to be used for this <tt>CallPeer</tt> when
- * we describe it in a <tt>ConferenceInfoDocument</tt> (e.g. the
- * <tt>entity</tt> key attribute which to use for the <tt>user</tt>
- * element corresponding to this <tt>CallPeer</tt>)
- *
- * @return the <tt>String</tt> to be used for this <tt>CallPeer</tt> when
- * we describe it in a <tt>ConferenceInfoDocument</tt> (e.g. the
- * <tt>entity</tt> key attribute which to use for the <tt>user</tt>
- * element corresponding to this <tt>CallPeer</tt>)
- */
- public abstract String getEntity();
-
- /**
- * Check whether a conference-info document is scheduled to be sent to
- * this <tt>CallPeer</tt> (i.e. there is a thread which will eventually
- * (after sleeping a certain amount of time) trigger a document to be sent)
- * @return <tt>true</tt> if there is a conference-info document scheduled
- * to be sent to this <tt>CallPeer</tt> and <tt>false</tt> otherwise.
- */
- public boolean isConfInfoScheduled()
- {
- synchronized (confInfoScheduledSyncRoot)
- {
- return confInfoScheduled;
- }
- }
-
- /**
- * Sets the property which indicates whether a conference-info document
- * is scheduled to be sent to this <tt>CallPeer</tt>.
- * @param confInfoScheduled
- */
- public void setConfInfoScheduled(boolean confInfoScheduled)
- {
- synchronized (confInfoScheduledSyncRoot)
- {
- this.confInfoScheduled = confInfoScheduled;
- }
- }
-
- /**
- * Returns the direction of the session for media of type <tt>mediaType</tt>
- * that we have with this <tt>CallPeer</tt>. This is the direction of the
- * session negotiated in the signaling protocol, and it may or may not
- * coincide with the direction of the media stream.
- * For example, if we are the focus of a videobridge conference and another
- * peer is sending video to us, we have a <tt>RECVONLY</tt> video stream,
- * but <tt>SENDONLY</tt> or <tt>SENDRECV</tt> (Jingle) sessions with the
- * rest of the conference members.
- * Should always return non-null.
- *
- * @param mediaType the <tt>MediaType</tt> to use
- * @return Returns the direction of the session for media of type
- * <tt>mediaType</tt> that we have with this <tt>CallPeer</tt>.
- */
- public abstract MediaDirection getDirection(MediaType mediaType);
-
- /**
- * {@inheritDoc}
- *
- * When a <tt>ConferenceMember</tt> is removed from a conference with a
- * Jitsi-videobridge, an RTCP BYE packet is not always sent. Therefore,
- * if the <tt>ConferenceMember</tt> had an associated video SSRC, the stream
- * isn't be removed until it times out, leaving a blank video container in
- * the interface for a few seconds.
- * TODO: This works around the problem by removing the
- * <tt>ConferenceMember</tt>'s <tt>ReceiveStream</tt> when the
- * <tt>ConferenceMember</tt> is removed. The proper solution is to ensure
- * that RTCP BYEs are sent whenever necessary, and when it is deployed this
- * code should be removed.
- *
- * @param conferenceMember a <tt>ConferenceMember</tt> to be removed from
- * the list of <tt>ConferenceMember</tt> reported by this peer. If the
- * specified <tt>ConferenceMember</tt> is no contained in the list, no event
- */
- @Override
- public void removeConferenceMember(ConferenceMember conferenceMember)
- {
- MediaStream videoStream = getMediaHandler().getStream(MediaType.VIDEO);
- if (videoStream != null)
- videoStream.removeReceiveStreamForSsrc(
- conferenceMember.getVideoSsrc());
-
- super.removeConferenceMember(conferenceMember);
- }
-
- /**
- * Converts a specific <tt>MediaType</tt> into a <tt>sessionType</tt> value
- * in the terms of the <tt>CallPeerSecurityStatusEvent</tt> class.
- *
- * @param mediaType the <tt>MediaType</tt> to be converted
- * @return the <tt>sessionType</tt> value in the terms of the
- * <tt>CallPeerSecurityStatusEvent</tt> class that is equivalent to the
- * specified <tt>mediaType</tt>
- */
- private static int toSessionType(MediaType mediaType)
- {
- switch (mediaType)
- {
- case AUDIO:
- return CallPeerSecurityStatusEvent.AUDIO_SESSION;
- case VIDEO:
- return CallPeerSecurityStatusEvent.VIDEO_SESSION;
- default:
- throw new IllegalArgumentException("mediaType");
- }
- }
-}
+package net.java.sip.communicator.service.protocol.media;
+
+import java.beans.*;
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.neomedia.*;
+import org.jitsi.service.neomedia.event.*;
+
+/**
+ * A utility class implementing media control code shared between current
+ * telephony implementations. This class is only meant for use by protocol
+ * implementations and should/could not be accessed by bundles that are simply
+ * using the telephony functionalities.
+ *
+ * @param <T> the peer extension class like for example <tt>CallSipImpl</tt>
+ * or <tt>CallJabberImpl</tt>
+ * @param <U> the media handler extension class like for example
+ * <tt>CallPeerMediaHandlerSipImpl</tt> or
+ * <tt>CallPeerMediaHandlerJabberImpl</tt>
+ * @param <V> the provider extension class like for example
+ * <tt>ProtocolProviderServiceSipImpl</tt> or
+ * <tt>ProtocolProviderServiceJabberImpl</tt>
+ *
+ * @author Emil Ivov
+ * @author Lyubomir Marinov
+ * @author Boris Grozev
+ */
+public abstract class MediaAwareCallPeer
+ <T extends MediaAwareCall<?, ?, V>,
+ U extends CallPeerMediaHandler<?>,
+ V extends ProtocolProviderService>
+ extends AbstractCallPeer<T, V>
+ implements SrtpListener,
+ CallPeerConferenceListener,
+ CsrcAudioLevelListener,
+ SimpleAudioLevelListener
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>MediaAwareCallPeer</tt> class and its
+ * instances for logging output.
+ */
+ private static final Logger logger
+ = Logger.getLogger(MediaAwareCallPeer.class);
+
+ /**
+ * The call this peer belongs to.
+ */
+ private T call;
+
+ /**
+ * The listeners registered for level changes in the audio of participants
+ * that this peer might be mixing and that we are not directly communicating
+ * with.
+ */
+ private final List<ConferenceMembersSoundLevelListener>
+ conferenceMembersSoundLevelListeners
+ = new ArrayList<ConferenceMembersSoundLevelListener>();
+
+ /**
+ * A byte array containing the image/photo representing the call peer.
+ */
+ private byte[] image;
+
+ /**
+ * The media handler class handles all media management for a single
+ * <tt>CallPeer</tt>. This includes initializing and configuring streams,
+ * generating SDP, handling ICE, etc. One instance of <tt>CallPeer</tt>always
+ * corresponds to exactly one instance of <tt>CallPeerMediaHandler</tt> and
+ * both classes are only separated for reasons of readability.
+ */
+ private U mediaHandler;
+
+ /**
+ * The <tt>PropertyChangeListener</tt> which listens to
+ * {@link CallPeerMediaHandler} for changes in the values of its properties.
+ */
+ private PropertyChangeListener mediaHandlerPropertyChangeListener;
+
+ /**
+ * A string uniquely identifying the peer.
+ */
+ private String peerID;
+
+ /**
+ * The protocol provider that this peer belongs to.
+ */
+ private final V protocolProvider;
+
+ /**
+ * The list of <tt>SoundLevelListener</tt>s interested in level changes in
+ * the audio we are getting from the remote peer.
+ * <p>
+ * It is implemented as a copy-on-write storage because the number of
+ * additions and removals of <tt>SoundLevelListener</tt>s is expected to be
+ * far smaller than the number of audio level changes. The access to it is
+ * to be synchronized using {@link #streamSoundLevelListenersSyncRoot}.
+ * </p>
+ */
+ private List<SoundLevelListener> streamSoundLevelListeners;
+
+ /**
+ * The <tt>Object</tt> to synchronize the access to
+ * {@link #streamSoundLevelListeners}.
+ */
+ private final Object streamSoundLevelListenersSyncRoot = new Object();
+
+ /**
+ * The <tt>List</tt> of <tt>PropertyChangeListener</tt>s listening to this
+ * <tt>CallPeer</tt> for changes in the values of its properties related to
+ * video.
+ */
+ private final List<PropertyChangeListener> videoPropertyChangeListeners
+ = new LinkedList<PropertyChangeListener>();
+
+ /**
+ * Represents the last Conference Information (RFC4575) document sent to
+ * this <tt>CallPeer</tt>. This is always a document with state "full", even
+ * if the last document actually sent was a "partial"
+ */
+ private ConferenceInfoDocument lastConferenceInfoSent = null;
+
+ /**
+ * The time (as obtained by <tt>System.currentTimeMillis()</tt>) at which
+ * a Conference Information (RFC4575) document was last sent to this
+ * <tt>CallPeer</tt>.
+ */
+ private long lastConferenceInfoSentTimestamp = -1;
+
+ /**
+ * The last Conference Information (RFC4575) document sent to us by this
+ * <tt>CallPeer</tt>. This is always a document with state "full", which is
+ * only gets updated by "partial" or "deleted" documents.
+ */
+ private ConferenceInfoDocument lastConferenceInfoReceived = null;
+
+ /**
+ * Whether a conference-info document has been scheduled to be sent to this
+ * <tt>CallPeer</tt>
+ */
+ private boolean confInfoScheduled = false;
+
+ /**
+ * Synchronization object for confInfoScheduled
+ */
+ private final Object confInfoScheduledSyncRoot = new Object();
+
+ /**
+ * Creates a new call peer with address <tt>peerAddress</tt>.
+ *
+ * @param owningCall the call that contains this call peer.
+ */
+ public MediaAwareCallPeer(T owningCall)
+ {
+ this.call = owningCall;
+ this.protocolProvider = owningCall.getProtocolProvider();
+
+ // create the uid
+ this.peerID
+ = String.valueOf(System.currentTimeMillis())
+ + String.valueOf(hashCode());
+
+ // we listen for events when the call will become focus or not
+ // of a conference so we will add or remove our sound level listeners
+ super.addCallPeerConferenceListener(this);
+ }
+
+ /**
+ * Adds a specific <tt>ConferenceMembersSoundLevelListener</tt> to the list
+ * of listeners interested in and notified about changes in conference
+ * members sound level.
+ *
+ * @param listener the <tt>ConferenceMembersSoundLevelListener</tt> to add
+ * @throws NullPointerException if <tt>listener</tt> is <tt>null</tt>
+ */
+ public void addConferenceMembersSoundLevelListener(
+ ConferenceMembersSoundLevelListener listener)
+ {
+ /*
+ * XXX The uses of the method at the time of this writing rely on being
+ * able to add a null listener so make it a no-op here.
+ */
+ if (listener == null)
+ return;
+
+ synchronized (conferenceMembersSoundLevelListeners)
+ {
+ if (conferenceMembersSoundLevelListeners.size() == 0)
+ {
+ // if this is the first listener that's being registered with
+ // us, we also need to register ourselves as a CSRC audio level
+ // listener with the media handler.
+ getMediaHandler().setCsrcAudioLevelListener(this);
+ }
+ conferenceMembersSoundLevelListeners.add(listener);
+ }
+ }
+
+ /**
+ * Adds a specific <tt>SoundLevelListener</tt> to the list of listeners
+ * interested in and notified about changes in the sound level of the audio
+ * sent by the remote party. When the first listener is being registered
+ * the method also registers its single listener with the media handler so
+ * that it would receive level change events and delegate them to the
+ * listeners that have registered with us.
+ *
+ * @param listener the <tt>SoundLevelListener</tt> to add
+ */
+ public void addStreamSoundLevelListener(SoundLevelListener listener)
+ {
+ synchronized (streamSoundLevelListenersSyncRoot)
+ {
+ if ((streamSoundLevelListeners == null)
+ || streamSoundLevelListeners.isEmpty())
+ {
+ CallPeerMediaHandler<?> mediaHandler = getMediaHandler();
+
+ if (isJitsiVideobridge())
+ {
+ /*
+ * When the local user/peer has organized a telephony
+ * conference utilizing the Jitsi Videobridge server-side
+ * technology, the server will calculate the audio levels
+ * and not the client.
+ */
+ mediaHandler.setCsrcAudioLevelListener(this);
+ }
+ else
+ {
+ /*
+ * If this is the first listener that's being registered
+ * with us, we also need to register ourselves as an audio
+ * level listener with the media handler. We do this so that
+ * audio levels would only be calculated if anyone is
+ * interested in receiving them.
+ */
+ mediaHandler.setStreamAudioLevelListener(this);
+ }
+ }
+
+ /*
+ * Implement streamAudioLevelListeners as a copy-on-write storage so
+ * that iterators over it can iterate without
+ * ConcurrentModificationExceptions.
+ */
+ streamSoundLevelListeners
+ = (streamSoundLevelListeners == null)
+ ? new ArrayList<SoundLevelListener>()
+ : new ArrayList<SoundLevelListener>(
+ streamSoundLevelListeners);
+ streamSoundLevelListeners.add(listener);
+ }
+ }
+
+ /**
+ * Adds a specific <tt>PropertyChangeListener</tt> to the list of
+ * listeners which get notified when the properties (e.g.
+ * LOCAL_VIDEO_STREAMING) associated with this <tt>CallPeer</tt> change
+ * their values.
+ *
+ * @param listener the <tt>PropertyChangeListener</tt> to be notified
+ * when the properties associated with the specified <tt>Call</tt> change
+ * their values
+ */
+ public void addVideoPropertyChangeListener(PropertyChangeListener listener)
+ {
+ if (listener == null)
+ throw new NullPointerException("listener");
+
+ synchronized (videoPropertyChangeListeners)
+ {
+ /*
+ * The video is part of the media-related functionality and thus it
+ * is the responsibility of mediaHandler. So listen to mediaHandler
+ * for video-related property changes and re-fire them as
+ * originating from this instance.
+ */
+ if (!videoPropertyChangeListeners.contains(listener)
+ && videoPropertyChangeListeners.add(listener)
+ && (mediaHandlerPropertyChangeListener == null))
+ {
+ mediaHandlerPropertyChangeListener
+ = new PropertyChangeListener()
+ {
+ public void propertyChange(PropertyChangeEvent event)
+ {
+ Iterable<PropertyChangeListener> listeners;
+
+ synchronized (videoPropertyChangeListeners)
+ {
+ listeners
+ = new LinkedList<PropertyChangeListener>(
+ videoPropertyChangeListeners);
+ }
+
+ PropertyChangeEvent thisEvent
+ = new PropertyChangeEvent(
+ this,
+ event.getPropertyName(),
+ event.getOldValue(),
+ event.getNewValue());
+
+ for (PropertyChangeListener listener : listeners)
+ listener.propertyChange(thisEvent);
+ }
+ };
+ getMediaHandler()
+ .addPropertyChangeListener(
+ mediaHandlerPropertyChangeListener);
+ }
+ }
+ }
+
+ /**
+ * Notified by its very majesty the media service about changes in the audio
+ * level of the stream coming from this peer, the method generates the
+ * corresponding events and delivers them to the listeners that have
+ * registered here.
+ *
+ * @param newLevel the new audio level of the audio stream received from the
+ * remote peer
+ */
+ public void audioLevelChanged(int newLevel)
+ {
+ /*
+ * If we're in a conference in which this CallPeer is the focus and
+ * we're the only member in it besides the focus, we will not receive
+ * audio levels in the RTP and our media will instead measure the audio
+ * levels of the received media. In order to make the UI oblivious of
+ * the difference, we have to translate the event to the appropriate
+ * type of listener.
+ *
+ * We may end up in a conference call with 0 members if the server
+ * for some reason doesn't support sip conference (our subscribes
+ * doesn't go to the focus of the conference) and so we must
+ * pass the sound levels measured on the stream so we can see
+ * the stream activity of the call.
+ */
+ int conferenceMemberCount = getConferenceMemberCount();
+
+ if ((conferenceMemberCount > 0) && (conferenceMemberCount < 3))
+ {
+ long audioRemoteSSRC
+ = getMediaHandler().getRemoteSSRC(MediaType.AUDIO);
+
+ if (audioRemoteSSRC != CallPeerMediaHandler.SSRC_UNKNOWN)
+ {
+ audioLevelsReceived(new long[] { audioRemoteSSRC, newLevel });
+ return;
+ }
+ }
+
+ fireStreamSoundLevelChanged(newLevel);
+ }
+
+
+ /**
+ * Implements {@link CsrcAudioLevelListener#audioLevelsReceived(long[])}.
+ * Delivers the received audio levels to the
+ * {@link ConferenceMembersSoundLevelListener}s registered with this
+ * <tt>MediaAwareCallPeer</tt>..
+ *
+ * @param audioLevels the levels that we need to dispatch to all registered
+ * <tt>ConferenceMemberSoundLevelListeners</tt>.
+ */
+ public void audioLevelsReceived(long[] audioLevels)
+ {
+ /*
+ * When the local user/peer has organized a telephony conference
+ * utilizing the Jitsi Videobridge server-side technology, the server
+ * will calculate the audio levels and not the client.
+ */
+ if (isJitsiVideobridge())
+ {
+ long audioRemoteSSRC
+ = getMediaHandler().getRemoteSSRC(MediaType.AUDIO);
+
+ if (audioRemoteSSRC != CallPeerMediaHandler.SSRC_UNKNOWN)
+ {
+ for (int i = 0; i < audioLevels.length; i += 2)
+ {
+ if (audioLevels[i] == audioRemoteSSRC)
+ {
+ fireStreamSoundLevelChanged((int) audioLevels[i + 1]);
+ break;
+ }
+ }
+ }
+ }
+
+ if (getConferenceMemberCount() == 0)
+ return;
+
+ Map<ConferenceMember, Integer> levelsMap
+ = new HashMap<ConferenceMember, Integer>();
+
+ for (int i = 0; i < audioLevels.length; i += 2)
+ {
+ ConferenceMember mmbr = findConferenceMember(audioLevels[i]);
+
+ if (mmbr != null)
+ levelsMap.put(mmbr, (int) audioLevels[i + 1]);
+ }
+
+ synchronized (conferenceMembersSoundLevelListeners)
+ {
+ int conferenceMemberSoundLevelListenerCount
+ = conferenceMembersSoundLevelListeners.size();
+
+ if (conferenceMemberSoundLevelListenerCount > 0)
+ {
+ ConferenceMembersSoundLevelEvent ev
+ = new ConferenceMembersSoundLevelEvent(this, levelsMap);
+
+ for (int i = 0;
+ i < conferenceMemberSoundLevelListenerCount;
+ i++)
+ {
+ conferenceMembersSoundLevelListeners
+ .get(i)
+ .soundLevelChanged(ev);
+ }
+ }
+ }
+ }
+
+ /**
+ * Does nothing.
+ * @param evt the event.
+ */
+ public void callPeerAdded(CallPeerEvent evt) {}
+
+ /**
+ * Does nothing.
+ * @param evt the event.
+ */
+ public void callPeerRemoved(CallPeerEvent evt) {}
+
+ /**
+ * Dummy implementation of {@link CallPeerConferenceListener
+ * #conferenceFocusChanged(CallPeerConferenceEvent)}.
+ *
+ * @param evt ignored
+ */
+ public void conferenceFocusChanged(CallPeerConferenceEvent evt)
+ {
+ }
+
+ /**
+ * Called when this peer becomes a mixer. The method add removes this class
+ * as the stream audio level listener for the media coming from this peer
+ * because the levels it delivers no longer represent the level of a
+ * particular member. The method also adds this class as a member (CSRC)
+ * audio level listener.
+ *
+ * @param conferenceEvent the event containing information (that we don't
+ * really use) on the newly add member.
+ */
+ public void conferenceMemberAdded(CallPeerConferenceEvent conferenceEvent)
+ {
+ if (getConferenceMemberCount() > 2)
+ {
+ /*
+ * This peer is now a conference focus with more than three
+ * participants. It means that this peer is mixing and sending us
+ * audio for at least two separate participants. We therefore need
+ * to switch from stream to CSRC level listening.
+ */
+ CallPeerMediaHandler<?> mediaHandler = getMediaHandler();
+
+ mediaHandler.setStreamAudioLevelListener(null);
+ mediaHandler.setCsrcAudioLevelListener(this);
+ }
+ }
+
+ /**
+ * Dummy implementation of {@link CallPeerConferenceListener
+ * #conferenceMemberErrorReceived(CallPeerConferenceEvent)}.
+ *
+ * @param ev the event
+ */
+ public void conferenceMemberErrorReceived(CallPeerConferenceEvent ev) {};
+
+ /**
+ * Called when this peer stops being a mixer. The method add removes this
+ * class as the stream audio level listener for the media coming from this
+ * peer because the levels it delivers no longer represent the level of a
+ * particular member. The method also adds this class as a member (CSRC)
+ * audio level listener.
+ *
+ * @param conferenceEvent the event containing information (that we don't
+ * really use) on the freshly removed member.
+ */
+ public void conferenceMemberRemoved(CallPeerConferenceEvent conferenceEvent)
+ {
+ if (getConferenceMemberCount() < 3)
+ {
+ /*
+ * This call peer is no longer mixing audio from multiple sources
+ * since there's only us and her in the call. We therefore need to
+ * switch from CSRC to stream level listening.
+ */
+ CallPeerMediaHandler<?> mediaHandler = getMediaHandler();
+
+ mediaHandler.setStreamAudioLevelListener(this);
+ mediaHandler.setCsrcAudioLevelListener(null);
+ }
+ }
+
+ /**
+ * Invokes {@link SoundLevelListener#soundLevelChanged(Object, int) on
+ * the <tt>SoundLevelListener</tt>s interested in the changes of the audio
+ * stream received from the remote peer i.e. in
+ * {@link #streamSoundLevelListeners}.
+ *
+ * @param newLevel the new value of the sound level to notify
+ * <tt>streamSoundLevelListeners</tt> about
+ */
+ private void fireStreamSoundLevelChanged(int newLevel)
+ {
+ List<SoundLevelListener> streamSoundLevelListeners;
+
+ synchronized (streamSoundLevelListenersSyncRoot)
+ {
+ /*
+ * Since the streamAudioLevelListeners field of this
+ * MediaAwareCallPeer is implemented as a copy-on-write storage,
+ * just get a reference to it and it should be safe to iterate over it
+ * without ConcurrentModificationExceptions.
+ */
+ streamSoundLevelListeners = this.streamSoundLevelListeners;
+ }
+
+ if (streamSoundLevelListeners != null)
+ {
+ /*
+ * Iterate over streamAudioLevelListeners using an index rather than
+ * an Iterator in order to try to reduce the number of allocations
+ * (as the number of audio level changes is expected to be very
+ * large).
+ */
+ int streamSoundLevelListenerCount
+ = streamSoundLevelListeners.size();
+
+ for(int i = 0; i < streamSoundLevelListenerCount; i++)
+ {
+ streamSoundLevelListeners.get(i).soundLevelChanged(
+ this,
+ newLevel);
+ }
+ }
+ }
+
+ /**
+ * Returns a reference to the call that this peer belongs to. Calls
+ * are created by underlying telephony protocol implementations.
+ *
+ * @return a reference to the call containing this peer.
+ */
+ @Override
+ public T getCall()
+ {
+ return call;
+ }
+
+ /**
+ * The method returns an image representation of the call peer if one is
+ * available.
+ *
+ * @return byte[] a byte array containing the image or null if no image is
+ * available.
+ */
+ public byte[] getImage()
+ {
+ return image;
+ }
+
+ /**
+ * Returns a reference to the <tt>CallPeerMediaHandler</tt> used by this
+ * peer. The media handler class handles all media management for a single
+ * <tt>CallPeer</tt>. This includes initializing and configuring streams,
+ * generating SDP, handling ICE, etc. One instance of <tt>CallPeer</tt>
+ * always corresponds to exactly one instance of
+ * <tt>CallPeerMediaHandler</tt> and both classes are only separated for
+ * reasons of readability.
+ *
+ * @return a reference to the <tt>CallPeerMediaHandler</tt> instance that
+ * this peer uses for media related tips and tricks.
+ */
+ public U getMediaHandler()
+ {
+ return mediaHandler;
+ }
+
+ /**
+ * Returns a unique identifier representing this peer.
+ *
+ * @return an identifier representing this call peer.
+ */
+ public String getPeerID()
+ {
+ return peerID;
+ }
+
+ /**
+ * Returns the protocol provider that this peer belongs to.
+ *
+ * @return a reference to the <tt>ProtocolProviderService</tt> that this
+ * peer belongs to.
+ */
+ @Override
+ public V getProtocolProvider()
+ {
+ return protocolProvider;
+ }
+
+ /**
+ * Determines whether this <tt>CallPeer</tt> is participating in a telephony
+ * conference organized by the local user/peer utilizing the Jitsi
+ * Videobridge server-side technology.
+ *
+ * @return <tt>true</tt> if this <tt>CallPeer</tt> is participating in a
+ * telephony conference organized by the local user/peer utilizing the Jitsi
+ * Videobridge server-side technology; otherwise, <tt>false</tt>
+ */
+ public final boolean isJitsiVideobridge()
+ {
+ Call call = getCall();
+
+ if (call != null)
+ {
+ CallConference conference = call.getConference();
+
+ if (conference != null)
+ return conference.isJitsiVideobridge();
+ }
+ return false;
+ }
+
+ /**
+ * Determines whether we are currently streaming video toward whoever this
+ * <tt>MediaAwareCallPeer</tt> represents.
+ *
+ * @return <tt>true</tt> if we are currently streaming video toward this
+ * <tt>CallPeer</tt> and <tt>false</tt> otherwise.
+ */
+ public boolean isLocalVideoStreaming()
+ {
+ return getMediaHandler().isLocalVideoTransmissionEnabled();
+ }
+
+ /**
+ * Determines whether the audio stream (if any) being sent to this
+ * peer is mute.
+ *
+ * @return <tt>true</tt> if an audio stream is being sent to this
+ * peer and it is currently mute; <tt>false</tt>, otherwise
+ */
+ @Override
+ public boolean isMute()
+ {
+ return getMediaHandler().isMute();
+ }
+
+ /**
+ * Logs <tt>message</tt> and <tt>cause</tt> and sets this <tt>peer</tt>'s
+ * state to <tt>CallPeerState.FAILED</tt>
+ *
+ * @param message a message to log and display to the user.
+ * @param throwable the exception that cause the error we are logging
+ */
+ public void logAndFail(String message, Throwable throwable)
+ {
+ logger.error(message, throwable);
+ setState(CallPeerState.FAILED, message);
+ }
+
+ /**
+ * Updates the state of this <tt>CallPeer</tt> to match the locally-on-hold
+ * status of our media handler.
+ */
+ public void reevalLocalHoldStatus()
+ {
+ CallPeerState state = getState();
+ boolean locallyOnHold = getMediaHandler().isLocallyOnHold();
+
+ if (CallPeerState.ON_HOLD_LOCALLY.equals(state))
+ {
+ if (!locallyOnHold)
+ setState(CallPeerState.CONNECTED);
+ }
+ else if (CallPeerState.ON_HOLD_MUTUALLY.equals(state))
+ {
+ if (!locallyOnHold)
+ setState(CallPeerState.ON_HOLD_REMOTELY);
+ }
+ else if (CallPeerState.ON_HOLD_REMOTELY.equals(state))
+ {
+ if (locallyOnHold)
+ setState(CallPeerState.ON_HOLD_MUTUALLY);
+ }
+ else if (locallyOnHold)
+ {
+ setState(CallPeerState.ON_HOLD_LOCALLY);
+ }
+ }
+
+ /**
+ * Updates the state of this <tt>CallPeer</tt> to match the remotely-on-hold
+ * status of our media handler.
+ */
+ public void reevalRemoteHoldStatus()
+ {
+ boolean remotelyOnHold = getMediaHandler().isRemotelyOnHold();
+
+ CallPeerState state = getState();
+ if (CallPeerState.ON_HOLD_LOCALLY.equals(state))
+ {
+ if (remotelyOnHold)
+ setState(CallPeerState.ON_HOLD_MUTUALLY);
+ }
+ else if (CallPeerState.ON_HOLD_MUTUALLY.equals(state))
+ {
+ if (!remotelyOnHold)
+ setState(CallPeerState.ON_HOLD_LOCALLY);
+ }
+ else if (CallPeerState.ON_HOLD_REMOTELY.equals(state))
+ {
+ if (!remotelyOnHold)
+ setState(CallPeerState.CONNECTED);
+ }
+ else if (remotelyOnHold)
+ {
+ setState(CallPeerState.ON_HOLD_REMOTELY);
+ }
+ }
+
+ /**
+ * Removes a specific <tt>ConferenceMembersSoundLevelListener</tt> of the
+ * list of listeners interested in and notified about changes in conference
+ * members sound level.
+ *
+ * @param listener the <tt>ConferenceMembersSoundLevelListener</tt> to
+ * remove
+ */
+ public void removeConferenceMembersSoundLevelListener(
+ ConferenceMembersSoundLevelListener listener)
+ {
+ synchronized (conferenceMembersSoundLevelListeners)
+ {
+ if (conferenceMembersSoundLevelListeners.remove(listener)
+ && (conferenceMembersSoundLevelListeners.size() == 0))
+ {
+ // if this was the last listener then we also remove ourselves
+ // as a CSRC audio level listener from the handler so that we
+ // don't have to create new events and maps for something no one
+ // is interested in.
+ getMediaHandler().setCsrcAudioLevelListener(null);
+ }
+ }
+ }
+
+ /**
+ * Removes a specific <tt>SoundLevelListener</tt> of the list of
+ * listeners interested in and notified about changes in stream sound level
+ * related information.
+ *
+ * @param listener the <tt>SoundLevelListener</tt> to remove
+ */
+ public void removeStreamSoundLevelListener(SoundLevelListener listener)
+ {
+ synchronized (streamSoundLevelListenersSyncRoot)
+ {
+ /*
+ * Implement streamAudioLevelListeners as a copy-on-write storage so
+ * that iterators over it can iterate over it without
+ * ConcurrentModificationExceptions.
+ */
+ if (streamSoundLevelListeners != null)
+ {
+ streamSoundLevelListeners
+ = new ArrayList<SoundLevelListener>(
+ streamSoundLevelListeners);
+ if (streamSoundLevelListeners.remove(listener)
+ && streamSoundLevelListeners.isEmpty())
+ streamSoundLevelListeners = null;
+ }
+
+ if ((streamSoundLevelListeners == null)
+ || streamSoundLevelListeners.isEmpty())
+ {
+ // if this was the last listener then we also need to remove
+ // ourselves as an audio level so that audio levels would only
+ // be calculated if anyone is interested in receiving them.
+ getMediaHandler().setStreamAudioLevelListener(null);
+ }
+ }
+ }
+
+ /**
+ * Removes a specific <tt>PropertyChangeListener</tt> from the list of
+ * listeners which get notified when the properties (e.g.
+ * LOCAL_VIDEO_STREAMING) associated with this <tt>CallPeer</tt> change
+ * their values.
+ *
+ * @param listener the <tt>PropertyChangeListener</tt> to no longer be
+ * notified when the properties associated with the specified <tt>Call</tt>
+ * change their values
+ */
+ public void removeVideoPropertyChangeListener(
+ PropertyChangeListener listener)
+ {
+ if (listener != null)
+ synchronized (videoPropertyChangeListeners)
+ {
+ /*
+ * The video is part of the media-related functionality and thus
+ * it is the responsibility of mediaHandler. So we're listening
+ * to mediaHandler for video-related property changes and w're
+ * re-firing them as originating from this instance. Make sure
+ * that we're not listening to mediaHandler if noone is
+ * interested in video-related property changes originating from
+ * this instance.
+ */
+ if (videoPropertyChangeListeners.remove(listener)
+ && videoPropertyChangeListeners.isEmpty()
+ && (mediaHandlerPropertyChangeListener != null))
+ {
+// getMediaHandler()
+// .removePropertyChangeListener(
+// mediaHandlerPropertyChangeListener);
+ mediaHandlerPropertyChangeListener = null;
+ }
+ }
+ }
+
+ /**
+ * Sets the security message associated with a failure/warning or
+ * information coming from the encryption protocol.
+ *
+ * @param messageType the type of the message.
+ * @param i18nMessage the message
+ * @param severity severity level
+ */
+ public void securityMessageReceived(
+ String messageType,
+ String i18nMessage,
+ int severity)
+ {
+ fireCallPeerSecurityMessageEvent(messageType,
+ i18nMessage,
+ severity);
+ }
+
+ /**
+ * Indicates that the other party has timeouted replying to our
+ * offer to secure the connection.
+ *
+ * @param mediaType the <tt>MediaType</tt> of the call session
+ * @param sender the security controller that caused the event
+ */
+ public void securityNegotiationStarted(
+ MediaType mediaType,
+ SrtpControl sender)
+ {
+ fireCallPeerSecurityNegotiationStartedEvent(
+ new CallPeerSecurityNegotiationStartedEvent(
+ this,
+ toSessionType(mediaType),
+ sender));
+ }
+
+ /**
+ * Indicates that the other party has timeouted replying to our
+ * offer to secure the connection.
+ *
+ * @param mediaType the <tt>MediaType</tt> of the call session
+ */
+ public void securityTimeout(MediaType mediaType)
+ {
+ fireCallPeerSecurityTimeoutEvent(
+ new CallPeerSecurityTimeoutEvent(
+ this,
+ toSessionType(mediaType)));
+ }
+
+ /**
+ * Sets the security status to OFF for this call peer.
+ *
+ * @param mediaType the <tt>MediaType</tt> of the call session
+ */
+ public void securityTurnedOff(MediaType mediaType)
+ {
+ // If this event has been triggered because of a call end event and the
+ // call is already ended we don't need to alert the user for
+ // security off.
+ if((call != null) && !call.getCallState().equals(CallState.CALL_ENDED))
+ {
+ fireCallPeerSecurityOffEvent(
+ new CallPeerSecurityOffEvent(
+ this,
+ toSessionType(mediaType)));
+ }
+ }
+
+ /**
+ * Sets the security status to ON for this call peer.
+ *
+ * @param mediaType the <tt>MediaType</tt> of the call session
+ * @param cipher the cipher
+ * @param sender the security controller that caused the event
+ */
+ public void securityTurnedOn(
+ MediaType mediaType,
+ String cipher,
+ SrtpControl sender)
+ {
+ getMediaHandler().startSrtpMultistream(sender);
+ fireCallPeerSecurityOnEvent(
+ new CallPeerSecurityOnEvent(
+ this,
+ toSessionType(mediaType),
+ cipher,
+ sender));
+ }
+
+ /**
+ * Sets the call containing this peer.
+ *
+ * @param call the call that this call peer is participating in.
+ */
+ public void setCall(T call)
+ {
+ this.call = call;
+ }
+
+ /**
+ * Sets the byte array containing an image representation (photo or picture)
+ * of the call peer.
+ *
+ * @param image a byte array containing the image
+ */
+ public void setImage(byte[] image)
+ {
+ byte[] oldImage = getImage();
+ this.image = image;
+
+ //Fire the Event
+ fireCallPeerChangeEvent(
+ CallPeerChangeEvent.CALL_PEER_IMAGE_CHANGE,
+ oldImage,
+ image);
+ }
+
+ /**
+ * Modifies the local media setup to reflect the requested setting for the
+ * streaming of the local video and then re-invites the peer represented by
+ * this class using a corresponding SDP description..
+ *
+ * @param allowed <tt>true</tt> if local video transmission is allowed and
+ * <tt>false</tt> otherwise.
+ *
+ * @throws OperationFailedException if video initialization fails.
+ */
+ public void setLocalVideoAllowed(boolean allowed)
+ throws OperationFailedException
+ {
+ CallPeerMediaHandler<?> mediaHandler = getMediaHandler();
+
+ if(mediaHandler.isLocalVideoTransmissionEnabled() != allowed)
+ {
+ // Modify the local media setup to reflect the requested setting for
+ // the streaming of the local video.
+ mediaHandler.setLocalVideoTransmissionEnabled(allowed);
+ }
+ }
+
+ /**
+ * Sets a reference to the <tt>CallPeerMediaHandler</tt> used by this
+ * peer. The media handler class handles all media management for a single
+ * <tt>CallPeer</tt>. This includes initializing and configuring streams,
+ * generating SDP, handling ICE, etc. One instance of <tt>CallPeer</tt>
+ * always corresponds to exactly one instance of
+ * <tt>CallPeerMediaHandler</tt> and both classes are only separated for
+ * reasons of readability.
+ *
+ * @param mediaHandler a reference to the <tt>CallPeerMediaHandler</tt>
+ * instance that this peer uses for media related tips and tricks.
+ */
+ protected void setMediaHandler(U mediaHandler)
+ {
+ this.mediaHandler = mediaHandler;
+ }
+
+ /**
+ * Sets the mute property for this call peer.
+ *
+ * @param newMuteValue the new value of the mute property for this call peer
+ */
+ @Override
+ public void setMute(boolean newMuteValue)
+ {
+ getMediaHandler().setMute(newMuteValue);
+ super.setMute(newMuteValue);
+ }
+
+ /**
+ * Sets the String that serves as a unique identifier of this
+ * CallPeer.
+ * @param peerID the ID of this call peer.
+ */
+ public void setPeerID(String peerID)
+ {
+ this.peerID = peerID;
+ }
+
+ /**
+ * Overrides the parent set state method in order to make sure that we
+ * close our media handler whenever we enter a disconnected state.
+ *
+ * @param newState the <tt>CallPeerState</tt> that we are about to enter and
+ * that we pass to our predecessor.
+ * @param reason a reason phrase explaining the state (e.g. if newState
+ * indicates a failure) and that we pass to our predecessor.
+ * @param reasonCode the code for the reason of the state change.
+ */
+ @Override
+ public void setState(CallPeerState newState, String reason, int reasonCode)
+ {
+ // synchronized to mediaHandler if there are currently jobs of
+ // initializing, configuring and starting streams (method processAnswer
+ // of CallPeerMediaHandler) we won't set and fire the current state
+ // to Disconnected. Before closing the mediaHandler is setting the state
+ // in order to deliver states as quick as possible.
+ CallPeerMediaHandler<?> mediaHandler = getMediaHandler();
+
+ synchronized(mediaHandler)
+ {
+ try
+ {
+ super.setState(newState, reason, reasonCode);
+ }
+ finally
+ {
+ // make sure whatever happens to close the media
+ if (CallPeerState.DISCONNECTED.equals(newState)
+ || CallPeerState.FAILED.equals(newState))
+ mediaHandler.close();
+ }
+ }
+ }
+
+ /**
+ * Returns the last <tt>ConferenceInfoDocument</tt> sent by us to this
+ * <tt>CallPeer</tt>. It is a document with state <tt>full</tt>
+ * @return the last <tt>ConferenceInfoDocument</tt> sent by us to this
+ * <tt>CallPeer</tt>. It is a document with state <tt>full</tt>
+ */
+ public ConferenceInfoDocument getLastConferenceInfoSent()
+ {
+ return lastConferenceInfoSent;
+ }
+
+ /**
+ * Sets the last <tt>ConferenceInfoDocument</tt> sent by us to this
+ * <tt>CallPeer</tt>.
+ * @param confInfo the document to set.
+ */
+ public void setLastConferenceInfoSent(ConferenceInfoDocument confInfo)
+ {
+ lastConferenceInfoSent = confInfo;
+ }
+
+ /**
+ * Gets the time (as obtained by <tt>System.currentTimeMillis()</tt>)
+ * at which we last sent a <tt>ConferenceInfoDocument</tt> to this
+ * <tt>CallPeer</tt>.
+ * @return the time (as obtained by <tt>System.currentTimeMillis()</tt>)
+ * at which we last sent a <tt>ConferenceInfoDocument</tt> to this
+ * <tt>CallPeer</tt>.
+ */
+ public long getLastConferenceInfoSentTimestamp()
+ {
+ return lastConferenceInfoSentTimestamp;
+ }
+
+ /**
+ * Sets the time (as obtained by <tt>System.currentTimeMillis()</tt>)
+ * at which we last sent a <tt>ConferenceInfoDocument</tt> to this
+ * <tt>CallPeer</tt>.
+ * @param newTimestamp the time to set
+ */
+ public void setLastConferenceInfoSentTimestamp(long newTimestamp)
+ {
+ lastConferenceInfoSentTimestamp = newTimestamp;
+ }
+
+ /**
+ * Gets the last <tt>ConferenceInfoDocument</tt> sent to us by this
+ * <tt>CallPeer</tt>.
+ * @return the last <tt>ConferenceInfoDocument</tt> sent to us by this
+ * <tt>CallPeer</tt>.
+ */
+ public ConferenceInfoDocument getLastConferenceInfoReceived()
+ {
+ return lastConferenceInfoReceived;
+ }
+
+ /**
+ * Gets the last <tt>ConferenceInfoDocument</tt> sent to us by this
+ * <tt>CallPeer</tt>.
+ * @return the last <tt>ConferenceInfoDocument</tt> sent to us by this
+ * <tt>CallPeer</tt>.
+ */
+ public void setLastConferenceInfoReceived(ConferenceInfoDocument confInfo)
+ {
+ lastConferenceInfoReceived = confInfo;
+ }
+
+ /**
+ * Gets the <tt>version</tt> of the last <tt>ConferenceInfoDocument</tt>
+ * sent to us by this <tt>CallPeer</tt>, or -1 if we haven't (yet) received
+ * a <tt>ConferenceInformationDocument</tt> from this <tt>CallPeer</tt>.
+ * @return
+ */
+ public int getLastConferenceInfoReceivedVersion()
+ {
+ return (lastConferenceInfoReceived == null)
+ ? -1
+ : lastConferenceInfoReceived.getVersion();
+ }
+
+ /**
+ * Gets the <tt>String</tt> to be used for this <tt>CallPeer</tt> when
+ * we describe it in a <tt>ConferenceInfoDocument</tt> (e.g. the
+ * <tt>entity</tt> key attribute which to use for the <tt>user</tt>
+ * element corresponding to this <tt>CallPeer</tt>)
+ *
+ * @return the <tt>String</tt> to be used for this <tt>CallPeer</tt> when
+ * we describe it in a <tt>ConferenceInfoDocument</tt> (e.g. the
+ * <tt>entity</tt> key attribute which to use for the <tt>user</tt>
+ * element corresponding to this <tt>CallPeer</tt>)
+ */
+ public abstract String getEntity();
+
+ /**
+ * Check whether a conference-info document is scheduled to be sent to
+ * this <tt>CallPeer</tt> (i.e. there is a thread which will eventually
+ * (after sleeping a certain amount of time) trigger a document to be sent)
+ * @return <tt>true</tt> if there is a conference-info document scheduled
+ * to be sent to this <tt>CallPeer</tt> and <tt>false</tt> otherwise.
+ */
+ public boolean isConfInfoScheduled()
+ {
+ synchronized (confInfoScheduledSyncRoot)
+ {
+ return confInfoScheduled;
+ }
+ }
+
+ /**
+ * Sets the property which indicates whether a conference-info document
+ * is scheduled to be sent to this <tt>CallPeer</tt>.
+ * @param confInfoScheduled
+ */
+ public void setConfInfoScheduled(boolean confInfoScheduled)
+ {
+ synchronized (confInfoScheduledSyncRoot)
+ {
+ this.confInfoScheduled = confInfoScheduled;
+ }
+ }
+
+ /**
+ * Returns the direction of the session for media of type <tt>mediaType</tt>
+ * that we have with this <tt>CallPeer</tt>. This is the direction of the
+ * session negotiated in the signaling protocol, and it may or may not
+ * coincide with the direction of the media stream.
+ * For example, if we are the focus of a videobridge conference and another
+ * peer is sending video to us, we have a <tt>RECVONLY</tt> video stream,
+ * but <tt>SENDONLY</tt> or <tt>SENDRECV</tt> (Jingle) sessions with the
+ * rest of the conference members.
+ * Should always return non-null.
+ *
+ * @param mediaType the <tt>MediaType</tt> to use
+ * @return Returns the direction of the session for media of type
+ * <tt>mediaType</tt> that we have with this <tt>CallPeer</tt>.
+ */
+ public abstract MediaDirection getDirection(MediaType mediaType);
+
+ /**
+ * {@inheritDoc}
+ *
+ * When a <tt>ConferenceMember</tt> is removed from a conference with a
+ * Jitsi-videobridge, an RTCP BYE packet is not always sent. Therefore,
+ * if the <tt>ConferenceMember</tt> had an associated video SSRC, the stream
+ * isn't be removed until it times out, leaving a blank video container in
+ * the interface for a few seconds.
+ * TODO: This works around the problem by removing the
+ * <tt>ConferenceMember</tt>'s <tt>ReceiveStream</tt> when the
+ * <tt>ConferenceMember</tt> is removed. The proper solution is to ensure
+ * that RTCP BYEs are sent whenever necessary, and when it is deployed this
+ * code should be removed.
+ *
+ * @param conferenceMember a <tt>ConferenceMember</tt> to be removed from
+ * the list of <tt>ConferenceMember</tt> reported by this peer. If the
+ * specified <tt>ConferenceMember</tt> is no contained in the list, no event
+ */
+ @Override
+ public void removeConferenceMember(ConferenceMember conferenceMember)
+ {
+ MediaStream videoStream = getMediaHandler().getStream(MediaType.VIDEO);
+ if (videoStream != null)
+ videoStream.removeReceiveStreamForSsrc(
+ conferenceMember.getVideoSsrc());
+
+ super.removeConferenceMember(conferenceMember);
+ }
+
+ /**
+ * Converts a specific <tt>MediaType</tt> into a <tt>sessionType</tt> value
+ * in the terms of the <tt>CallPeerSecurityStatusEvent</tt> class.
+ *
+ * @param mediaType the <tt>MediaType</tt> to be converted
+ * @return the <tt>sessionType</tt> value in the terms of the
+ * <tt>CallPeerSecurityStatusEvent</tt> class that is equivalent to the
+ * specified <tt>mediaType</tt>
+ */
+ private static int toSessionType(MediaType mediaType)
+ {
+ switch (mediaType)
+ {
+ case AUDIO:
+ return CallPeerSecurityStatusEvent.AUDIO_SESSION;
+ case VIDEO:
+ return CallPeerSecurityStatusEvent.VIDEO_SESSION;
+ default:
+ throw new IllegalArgumentException("mediaType");
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/service/protocol/media/TransportManager.java b/src/net/java/sip/communicator/service/protocol/media/TransportManager.java
index 973ebcb..051a302 100644
--- a/src/net/java/sip/communicator/service/protocol/media/TransportManager.java
+++ b/src/net/java/sip/communicator/service/protocol/media/TransportManager.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,870 +15,890 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.protocol.media;
-
-import java.net.*;
-
-import net.java.sip.communicator.service.netaddr.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.ice4j.ice.*;
-import org.jitsi.service.configuration.*;
-import org.jitsi.service.neomedia.*;
-
-/**
- * <tt>TransportManager</tt>s are responsible for allocating ports, gathering
- * local candidates and managing ICE whenever we are using it.
- *
- * @param <U> the peer extension class like for example <tt>CallPeerSipImpl</tt>
- * or <tt>CallPeerJabberImpl</tt>
- *
- * @author Emil Ivov
- * @author Lyubomir Marinov
- * @author Sebastien Vincent
- */
-public abstract class TransportManager<U extends MediaAwareCallPeer<?, ?, ?>>
-{
- /**
- * The <tt>Logger</tt> used by the <tt>TransportManager</tt>
- * class and its instances for logging output.
- */
- private static final Logger logger
- = Logger.getLogger(TransportManager.class);
-
- /**
- * The port tracker that we should use when binding generic media streams.
- * <p>
- * Initialized by {@link #initializePortNumbers()}.
- * </p>
- */
- private static final PortTracker defaultPortTracker
- = new PortTracker(5000, 6000);
-
- /**
- * The port tracker that we should use when binding video media streams.
- * <p>
- * Potentially initialized by {@link #initializePortNumbers()} if the
- * necessary properties are set.
- * </p>
- */
- private static PortTracker videoPortTracker;
-
- /**
- * The port tracker that we should use when binding data channels.
- * <p>
- * Potentially initialized by {@link #initializePortNumbers()} if the
- * necessary properties are set.
- * </p>
- */
- private static PortTracker dataPortTracker;
-
- /**
- * The port tracker that we should use when binding data media streams.
- * <p>
- * Potentially initialized by {@link #initializePortNumbers()} if the
- * necessary properties are set.
- * </p>
- */
- private static PortTracker audioPortTracker;
-
- /**
- * RTP audio DSCP configuration property name.
- */
- private static final String RTP_AUDIO_DSCP_PROPERTY =
- "net.java.sip.communicator.impl.protocol.RTP_AUDIO_DSCP";
-
- /**
- * RTP video DSCP configuration property name.
- */
- private static final String RTP_VIDEO_DSCP_PROPERTY =
- "net.java.sip.communicator.impl.protocol.RTP_VIDEO_DSCP";
-
- /**
- * Number of empty UDP packets to send for NAT hole punching.
- */
- private static final String HOLE_PUNCH_PKT_COUNT_PROPERTY =
- "net.java.sip.communicator.impl.protocol.HOLE_PUNCH_PKT_COUNT";
-
- /**
- * Number of empty UDP packets to send for NAT hole punching.
- */
- private static final int DEFAULT_HOLE_PUNCH_PKT_COUNT = 3;
-
- /**
- * The {@link MediaAwareCallPeer} whose traffic we will be taking care of.
- */
- private U callPeer;
-
- /**
- * The RTP/RTCP socket couples that this <tt>TransportManager</tt> uses to
- * send and receive media flows through indexed by <tt>MediaType</tt>
- * (ordinal).
- */
- private final StreamConnector[] streamConnectors
- = new StreamConnector[MediaType.values().length];
-
- /**
- * Creates a new instance of this transport manager, binding it to the
- * specified peer.
- *
- * @param callPeer the {@link MediaAwareCallPeer} whose traffic we will be
- * taking care of.
- */
- protected TransportManager(U callPeer)
- {
- this.callPeer = callPeer;
- }
-
- /**
- * Returns the <tt>StreamConnector</tt> instance that this media handler
- * should use for streams of the specified <tt>mediaType</tt>. The method
- * would also create a new <tt>StreamConnector</tt> if no connector has
- * been initialized for this <tt>mediaType</tt> yet or in case one
- * of its underlying sockets has been closed.
- *
- * @param mediaType the <tt>MediaType</tt> that we'd like to create a
- * connector for.
- * @return this media handler's <tt>StreamConnector</tt> for the specified
- * <tt>mediaType</tt>.
- *
- * @throws OperationFailedException in case we failed to initialize our
- * connector.
- */
- public StreamConnector getStreamConnector(MediaType mediaType)
- throws OperationFailedException
- {
- int streamConnectorIndex = mediaType.ordinal();
- StreamConnector streamConnector
- = streamConnectors[streamConnectorIndex];
-
- if((streamConnector == null)
- || (streamConnector.getProtocol() == StreamConnector.Protocol.UDP))
- {
- DatagramSocket controlSocket;
-
- if((streamConnector == null)
- || streamConnector.getDataSocket().isClosed()
- || (((controlSocket = streamConnector.getControlSocket())
- != null)
- && controlSocket.isClosed()))
- {
- streamConnectors[streamConnectorIndex]
- = streamConnector
- = createStreamConnector(mediaType);
- }
- }
- else if(streamConnector.getProtocol() == StreamConnector.Protocol.TCP)
- {
- Socket controlTCPSocket;
-
- if(streamConnector.getDataTCPSocket().isClosed()
- || (((controlTCPSocket = streamConnector.getControlTCPSocket())
- != null)
- && controlTCPSocket.isClosed()))
- {
- streamConnectors[streamConnectorIndex]
- = streamConnector
- = createStreamConnector(mediaType);
- }
- }
- return streamConnector;
- }
-
- /**
- * Closes the existing <tt>StreamConnector</tt>, if any, associated with a
- * specific <tt>MediaType</tt> and removes its reference from this
- * <tt>TransportManager</tt>.
- *
- * @param mediaType the <tt>MediaType</tt> associated with the
- * <tt>StreamConnector</tt> to close
- */
- public void closeStreamConnector(MediaType mediaType)
- {
- int index = mediaType.ordinal();
- StreamConnector streamConnector = streamConnectors[index];
-
- if (streamConnector != null)
- {
- closeStreamConnector(mediaType, streamConnector);
- streamConnectors[index] = null;
- }
- }
-
- /**
- * Closes a specific <tt>StreamConnector</tt> associated with a specific
- * <tt>MediaType</tt>. If this <tt>TransportManager</tt> has a reference to
- * the specified <tt>streamConnector</tt>, it remains. Allows extenders to
- * override and perform additional customizations to the closing of the
- * specified <tt>streamConnector</tt>.
- *
- * @param mediaType the <tt>MediaType</tt> associated with the specified
- * <tt>streamConnector</tt>
- * @param streamConnector the <tt>StreamConnector</tt> to be closed
- * @see #closeStreamConnector(MediaType)
- */
- protected void closeStreamConnector(
- MediaType mediaType,
- StreamConnector streamConnector)
- {
- /*
- * XXX The connected owns the sockets so it is important that it
- * decides whether to close them i.e. this TransportManager is not
- * allowed to explicitly close the sockets by itself.
- */
- streamConnector.close();
- }
-
- /**
- * Creates a media <tt>StreamConnector</tt> for a stream of a specific
- * <tt>MediaType</tt>. The minimum and maximum of the media port boundaries
- * are taken into account.
- *
- * @param mediaType the <tt>MediaType</tt> of the stream for which a
- * <tt>StreamConnector</tt> is to be created
- * @return a <tt>StreamConnector</tt> for the stream of the specified
- * <tt>mediaType</tt>
- * @throws OperationFailedException if the binding of the sockets fails
- */
- protected StreamConnector createStreamConnector(MediaType mediaType)
- throws OperationFailedException
- {
- NetworkAddressManagerService nam
- = ProtocolMediaActivator.getNetworkAddressManagerService();
- InetAddress intendedDestination = getIntendedDestination(getCallPeer());
- InetAddress localHostForPeer = nam.getLocalHost(intendedDestination);
-
- PortTracker portTracker = getPortTracker(mediaType);
-
- //create the RTP socket.
- DatagramSocket rtpSocket = null;
- try
- {
- rtpSocket = nam.createDatagramSocket(
- localHostForPeer, portTracker.getPort(),
- portTracker.getMinPort(), portTracker.getMaxPort());
- }
- catch (Exception exc)
- {
- throw new OperationFailedException(
- "Failed to allocate the network ports necessary for the call.",
- OperationFailedException.INTERNAL_ERROR, exc);
- }
-
- //make sure that next time we don't try to bind on occupied ports
- //also, refuse validation in case someone set the tracker range to 1
- portTracker.setNextPort( rtpSocket.getLocalPort() + 1, false);
-
- //create the RTCP socket, preferably on the port following our RTP one.
- DatagramSocket rtcpSocket = null;
- try
- {
- rtcpSocket = nam.createDatagramSocket(
- localHostForPeer, portTracker.getPort(),
- portTracker.getMinPort(), portTracker.getMaxPort());
- }
- catch (Exception exc)
- {
- throw new OperationFailedException(
- "Failed to allocate the network ports necessary for the call.",
- OperationFailedException.INTERNAL_ERROR,
- exc);
- }
-
- //make sure that next time we don't try to bind on occupied ports
- portTracker.setNextPort( rtcpSocket.getLocalPort() + 1);
-
- return new DefaultStreamConnector(rtpSocket, rtcpSocket);
- }
-
- /**
- * Tries to set the ranges of the <tt>PortTracker</tt>s (e.g. default,
- * audio, video, data channel) to the values specified in the
- * <tt>ConfigurationService</tt>.
- */
- protected synchronized static void initializePortNumbers()
- {
- //try the default tracker first
- ConfigurationService cfg
- = ProtocolMediaActivator.getConfigurationService();
- String minPort, maxPort;
-
- minPort
- = cfg.getString(
- OperationSetBasicTelephony
- .MIN_MEDIA_PORT_NUMBER_PROPERTY_NAME);
- if (minPort != null)
- {
- maxPort
- = cfg.getString(
- OperationSetBasicTelephony
- .MAX_MEDIA_PORT_NUMBER_PROPERTY_NAME);
- if (maxPort != null)
- {
- //Try the specified range; otherwise, leave the tracker as it
- //is: [5000, 6000].
- defaultPortTracker.tryRange(minPort, maxPort);
- }
- }
-
- //try the VIDEO tracker
- minPort
- = cfg.getString(
- OperationSetBasicTelephony
- .MIN_VIDEO_PORT_NUMBER_PROPERTY_NAME);
- if (minPort != null)
- {
- maxPort
- = cfg.getString(
- OperationSetBasicTelephony
- .MAX_VIDEO_PORT_NUMBER_PROPERTY_NAME);
- if (maxPort != null)
- {
- //Try the specified range; otherwise, leave the tracker to null.
- if (videoPortTracker == null)
- {
- videoPortTracker
- = PortTracker.createTracker(minPort, maxPort);
- }
- else
- {
- videoPortTracker.tryRange(minPort, maxPort);
- }
- }
- }
-
- //try the AUDIO tracker
- minPort
- = cfg.getString(
- OperationSetBasicTelephony
- .MIN_AUDIO_PORT_NUMBER_PROPERTY_NAME);
- if (minPort != null)
- {
- maxPort
- = cfg.getString(
- OperationSetBasicTelephony
- .MAX_AUDIO_PORT_NUMBER_PROPERTY_NAME);
- if (maxPort != null)
- {
- //Try the specified range; otherwise, leave the tracker to null.
- if (audioPortTracker == null)
- {
- audioPortTracker
- = PortTracker.createTracker(minPort, maxPort);
- }
- else
- {
- audioPortTracker.tryRange(minPort, maxPort);
- }
- }
- }
-
- //try the DATA CHANNEL tracker
- minPort
- = cfg.getString(
- OperationSetBasicTelephony
- .MIN_DATA_CHANNEL_PORT_NUMBER_PROPERTY_NAME);
- if (minPort != null)
- {
- maxPort
- = cfg.getString(
- OperationSetBasicTelephony
- .MAX_DATA_CHANNEL_PORT_NUMBER_PROPERTY_NAME);
- if (maxPort != null)
- {
- //Try the specified range; otherwise, leave the tracker to null.
- if (dataPortTracker == null)
- {
- dataPortTracker
- = PortTracker.createTracker(minPort, maxPort);
- }
- else
- {
- dataPortTracker.tryRange(minPort, maxPort);
- }
- }
- }
- }
-
- /**
- * Returns the <tt>InetAddress</tt> that we are using in one of our
- * <tt>StreamConnector</tt>s or, in case we don't have any connectors yet
- * the address returned by the our network address manager as the best local
- * address to use when contacting the <tt>CallPeer</tt> associated with this
- * <tt>MediaHandler</tt>. This method is primarily meant for use with the
- * o= and c= fields of a newly created session description. The point is
- * that we create our <tt>StreamConnector</tt>s when constructing the media
- * descriptions so we already have a specific local address assigned to them
- * at the time we get ready to create the c= and o= fields. It is therefore
- * better to try and return one of these addresses before trying the net
- * address manager again and running the slight risk of getting a different
- * address.
- *
- * @return an <tt>InetAddress</tt> that we use in one of the
- * <tt>StreamConnector</tt>s in this class.
- */
- public InetAddress getLastUsedLocalHost()
- {
- for (MediaType mediaType : MediaType.values())
- {
- StreamConnector streamConnector
- = streamConnectors[mediaType.ordinal()];
-
- if (streamConnector != null)
- return streamConnector.getDataSocket().getLocalAddress();
- }
-
- NetworkAddressManagerService nam
- = ProtocolMediaActivator.getNetworkAddressManagerService();
- InetAddress intendedDestination = getIntendedDestination(getCallPeer());
-
- return nam.getLocalHost(intendedDestination);
- }
-
- /**
- * Sends empty UDP packets to target destination data/control ports in order
- * to open ports on NATs or and help RTP proxies latch onto our RTP ports.
- *
- * @param target <tt>MediaStreamTarget</tt>
- * @param type the {@link MediaType} of the connector we'd like to send the
- * hole punching packet through.
- */
- public void sendHolePunchPacket(MediaStreamTarget target, MediaType type)
- {
- logger.info("Send NAT hole punch packets");
-
- //check how many hole punch packets we would be supposed to send:
- int packetCount
- = ProtocolMediaActivator.getConfigurationService().getInt(
- HOLE_PUNCH_PKT_COUNT_PROPERTY,
- DEFAULT_HOLE_PUNCH_PKT_COUNT);
-
- if (packetCount < 0)
- packetCount = DEFAULT_HOLE_PUNCH_PKT_COUNT;
- if (packetCount == 0)
- return;
-
- try
- {
- StreamConnector connector = getStreamConnector(type);
-
- if(connector.getProtocol() == StreamConnector.Protocol.TCP)
- return;
-
- byte[] buf = new byte[0];
-
- synchronized(connector)
- {
- //we may want to send more than one packet in case they get lost
- for(int i=0; i < packetCount; i++)
- {
- DatagramSocket socket;
-
- // data/RTP
- if((socket = connector.getDataSocket()) != null)
- {
- InetSocketAddress dataAddress = target.getDataAddress();
-
- socket.send(
- new DatagramPacket(
- buf,
- buf.length,
- dataAddress.getAddress(),
- dataAddress.getPort()));
- }
-
- // control/RTCP
- if((socket = connector.getControlSocket()) != null)
- {
- InetSocketAddress controlAddress
- = target.getControlAddress();
-
- socket.send(
- new DatagramPacket(
- buf,
- buf.length,
- controlAddress.getAddress(),
- controlAddress.getPort()));
- }
- }
- }
- }
- catch(Exception e)
- {
- logger.error("Error cannot send to remote peer", e);
- }
- }
-
- /**
- * Set traffic class (QoS) for the RTP socket.
- *
- * @param target <tt>MediaStreamTarget</tt>
- * @param type the {@link MediaType} of the connector we'd like to set
- * traffic class
- */
- protected void setTrafficClass(MediaStreamTarget target, MediaType type)
- {
- // get traffic class value for RTP audio/video
- int trafficClass = getDSCP(type);
-
- if(trafficClass <= 0)
- return;
-
- if (logger.isInfoEnabled())
- logger.info(
- "Set traffic class for " + type + " to " + trafficClass);
- try
- {
- StreamConnector connector = getStreamConnector(type);
-
- synchronized(connector)
- {
- if(connector.getProtocol() == StreamConnector.Protocol.TCP)
- {
- connector.getDataTCPSocket().setTrafficClass(trafficClass);
-
- Socket controlTCPSocket = connector.getControlTCPSocket();
-
- if (controlTCPSocket != null)
- controlTCPSocket.setTrafficClass(trafficClass);
- }
- else
- {
- /* data port (RTP) */
- connector.getDataSocket().setTrafficClass(trafficClass);
-
- /* control port (RTCP) */
- DatagramSocket controlSocket = connector.getControlSocket();
-
- if (controlSocket != null)
- controlSocket.setTrafficClass(trafficClass);
- }
- }
- }
- catch(Exception e)
- {
- logger.error(
- "Failed to set traffic class for " + type + " to "
- + trafficClass,
- e);
- }
- }
-
- /**
- * Gets the SIP traffic class associated with a specific <tt>MediaType</tt>
- * from the configuration.
- *
- * @param type the <tt>MediaType</tt> to get the associated SIP traffic
- * class of
- * @return the SIP traffic class associated with the specified
- * <tt>MediaType</tt> or <tt>0</tt> if not configured
- */
- private int getDSCP(MediaType type)
- {
- String dscpPropertyName;
-
- switch (type)
- {
- case AUDIO:
- dscpPropertyName = RTP_AUDIO_DSCP_PROPERTY;
- break;
- case VIDEO:
- dscpPropertyName = RTP_VIDEO_DSCP_PROPERTY;
- break;
- default:
- dscpPropertyName = null;
- break;
- }
-
- return
- (dscpPropertyName == null)
- ? 0
- : (ProtocolMediaActivator.getConfigurationService().getInt(
- dscpPropertyName,
- 0)
- << 2);
- }
-
- /**
- * Returns the <tt>InetAddress</tt> that is most likely to be used as a
- * next hop when contacting the specified <tt>destination</tt>. This is
- * an utility method that is used whenever we have to choose one of our
- * local addresses to put in the Via, Contact or (in the case of no
- * registrar accounts) From headers.
- *
- * @param peer the CallPeer that we would contact.
- *
- * @return the <tt>InetAddress</tt> that is most likely to be to be used
- * as a next hop when contacting the specified <tt>destination</tt>.
- *
- * @throws IllegalArgumentException if <tt>destination</tt> is not a valid
- * host/ip/fqdn
- */
- protected abstract InetAddress getIntendedDestination(U peer);
-
- /**
- * Returns the {@link MediaAwareCallPeer} that this transport manager is
- * serving.
- *
- * @return the {@link MediaAwareCallPeer} that this transport manager is
- * serving.
- */
- public U getCallPeer()
- {
- return callPeer;
- }
-
- /**
- * Returns the port tracker that we are supposed to use when binding ports
- * for the specified {@link MediaType}.
- *
- * @param mediaType the media type that we want to obtain the port tracker
- * for. Use <tt>null</tt> to obtain the default port tracker.
- *
- * @return the port tracker that we are supposed to use when binding ports
- * for the specified {@link MediaType}.
- */
- protected static PortTracker getPortTracker(MediaType mediaType)
- {
- //make sure our port numbers reflect the configuration service settings
- initializePortNumbers();
-
- if (mediaType != null)
- {
- switch (mediaType)
- {
- case AUDIO:
- if (audioPortTracker != null)
- return audioPortTracker;
- else
- break;
- case VIDEO:
- if (videoPortTracker != null)
- return videoPortTracker;
- else
- break;
- case DATA:
- if (dataPortTracker != null)
- return dataPortTracker;
- else
- break;
- }
- }
-
- return defaultPortTracker;
- }
-
- /**
- * Returns the port tracker that we are supposed to use when binding ports
- * for the {@link MediaType} indicated by the string param. If we do not
- * recognize the string as a valid media type, we simply return the default
- * port tracker.
- *
- * @param mediaTypeStr the name of the media type that we want to obtain a
- * port tracker for.
- *
- * @return the port tracker that we are supposed to use when binding ports
- * for the {@link MediaType} with the specified name or the default tracker
- * in case the name doesn't ring a bell.
- */
- protected static PortTracker getPortTracker(String mediaTypeStr)
- {
- try
- {
- return getPortTracker(MediaType.parseString(mediaTypeStr));
- }
- catch (Exception e)
- {
- logger.info(
- "Returning default port tracker for unrecognized media type: "
- + mediaTypeStr);
-
- return defaultPortTracker;
- }
- }
-
- /**
- * Returns the extended type of the candidate selected if this transport
- * manager is using ICE.
- *
- * @param streamName The stream name (AUDIO, VIDEO);
- *
- * @return The extended type of the candidate selected if this transport
- * manager is using ICE. Otherwise, returns null.
- */
- public abstract String getICECandidateExtendedType(String streamName);
-
- /**
- * Returns the current state of ICE processing.
- *
- * @return the current state of ICE processing if this transport
- * manager is using ICE. Otherwise, returns null.
- */
- public abstract String getICEState();
-
- /**
- * Returns the ICE local host address.
- *
- * @param streamName The stream name (AUDIO, VIDEO);
- *
- * @return the ICE local host address if this transport
- * manager is using ICE. Otherwise, returns null.
- */
- public abstract InetSocketAddress getICELocalHostAddress(String streamName);
-
- /**
- * Returns the ICE remote host address.
- *
- * @param streamName The stream name (AUDIO, VIDEO);
- *
- * @return the ICE remote host address if this transport
- * manager is using ICE. Otherwise, returns null.
- */
- public abstract InetSocketAddress getICERemoteHostAddress(
- String streamName);
-
- /**
- * Returns the ICE local reflexive address (server or peer reflexive).
- *
- * @param streamName The stream name (AUDIO, VIDEO);
- *
- * @return the ICE local reflexive address. May be null if this transport
- * manager is not using ICE or if there is no reflexive address for the
- * local candidate used.
- */
- public abstract InetSocketAddress getICELocalReflexiveAddress(
- String streamName);
-
- /**
- * Returns the ICE remote reflexive address (server or peer reflexive).
- *
- * @param streamName The stream name (AUDIO, VIDEO);
- *
- * @return the ICE remote reflexive address. May be null if this transport
- * manager is not using ICE or if there is no reflexive address for the
- * remote candidate used.
- */
- public abstract InetSocketAddress getICERemoteReflexiveAddress(
- String streamName);
-
- /**
- * Returns the ICE local relayed address (server or peer relayed).
- *
- * @param streamName The stream name (AUDIO, VIDEO);
- *
- * @return the ICE local relayed address. May be null if this transport
- * manager is not using ICE or if there is no relayed address for the
- * local candidate used.
- */
- public abstract InetSocketAddress getICELocalRelayedAddress(
- String streamName);
-
- /**
- * Returns the ICE remote relayed address (server or peer relayed).
- *
- * @param streamName The stream name (AUDIO, VIDEO);
- *
- * @return the ICE remote relayed address. May be null if this transport
- * manager is not using ICE or if there is no relayed address for the
- * remote candidate used.
- */
- public abstract InetSocketAddress getICERemoteRelayedAddress(
- String streamName);
-
- /**
- * Returns the total harvesting time (in ms) for all harvesters.
- *
- * @return The total harvesting time (in ms) for all the harvesters. 0 if
- * the ICE agent is null, or if the agent has nevers harvested.
- */
- public abstract long getTotalHarvestingTime();
-
- /**
- * Returns the harvesting time (in ms) for the harvester given in parameter.
- *
- * @param harvesterName The class name if the harvester.
- *
- * @return The harvesting time (in ms) for the harvester given in parameter.
- * 0 if this harvester does not exists, if the ICE agent is null, or if the
- * agent has never harvested with this harvester.
- */
- public abstract long getHarvestingTime(String harvesterName);
-
- /**
- * Returns the number of harvesting for this agent.
- *
- * @return The number of harvesting for this agent.
- */
- public abstract int getNbHarvesting();
-
- /**
- * Returns the number of harvesting time for the harvester given in
- * parameter.
- *
- * @param harvesterName The class name if the harvester.
- *
- * @return The number of harvesting time for the harvester given in
- * parameter.
- */
- public abstract int getNbHarvesting(String harvesterName);
-
- /**
- * Returns the ICE candidate extended type selected by the given agent.
- *
- * @param iceAgent The ICE agent managing the ICE offer/answer exchange,
- * collecting and selecting the candidate.
- * @param streamName The stream name (AUDIO, VIDEO);
- *
- * @return The ICE candidate extended type selected by the given agent. null
- * if the iceAgent is null or if there is no candidate selected or
- * available.
- */
- public static String getICECandidateExtendedType(
- Agent iceAgent,
- String streamName)
- {
- if(iceAgent != null)
- {
- LocalCandidate localCandidate
- = iceAgent.getSelectedLocalCandidate(streamName);
-
- if(localCandidate != null)
- return localCandidate.getExtendedType().toString();
- }
- return null;
- }
-
-
- /**
- * Creates the ICE agent that we would be using in this transport manager
- * for all negotiation.
- *
- * @return the ICE agent to use for all the ICE negotiation that this
- * transport manager would be going through
- */
- protected Agent createIceAgent()
- {
- //work in progress
- return null;
- }
-
- /**
- * Creates an {@link IceMediaStream} with the specified <tt>media</tt>
- * name.
- *
- * @param media the name of the stream we'd like to create.
- * @param agent the ICE {@link Agent} that we will be appending the stream
- * to.
- *
- * @return the newly created {@link IceMediaStream}
- *
- * @throws OperationFailedException if binding on the specified media stream
- * fails for some reason.
- */
- protected IceMediaStream createIceStream(String media, Agent agent)
- throws OperationFailedException
- {
- return null;
- }
-}
+package net.java.sip.communicator.service.protocol.media;
+
+import java.net.*;
+
+import net.java.sip.communicator.service.netaddr.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+import org.ice4j.ice.*;
+import org.jitsi.service.configuration.*;
+import org.jitsi.service.neomedia.*;
+
+/**
+ * <tt>TransportManager</tt>s are responsible for allocating ports, gathering
+ * local candidates and managing ICE whenever we are using it.
+ *
+ * @param <U> the peer extension class like for example <tt>CallPeerSipImpl</tt>
+ * or <tt>CallPeerJabberImpl</tt>
+ *
+ * @author Emil Ivov
+ * @author Lyubomir Marinov
+ * @author Sebastien Vincent
+ */
+public abstract class TransportManager<U extends MediaAwareCallPeer<?, ?, ?>>
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>TransportManager</tt>
+ * class and its instances for logging output.
+ */
+ private static final Logger logger
+ = Logger.getLogger(TransportManager.class);
+
+ /**
+ * The port tracker that we should use when binding generic media streams.
+ * <p>
+ * Initialized by {@link #initializePortNumbers()}.
+ * </p>
+ */
+ private static final PortTracker defaultPortTracker
+ = new PortTracker(5000, 6000);
+
+ /**
+ * The port tracker that we should use when binding video media streams.
+ * <p>
+ * Potentially initialized by {@link #initializePortNumbers()} if the
+ * necessary properties are set.
+ * </p>
+ */
+ private static PortTracker videoPortTracker;
+
+ /**
+ * The port tracker that we should use when binding data channels.
+ * <p>
+ * Potentially initialized by {@link #initializePortNumbers()} if the
+ * necessary properties are set.
+ * </p>
+ */
+ private static PortTracker dataPortTracker;
+
+ /**
+ * The port tracker that we should use when binding data media streams.
+ * <p>
+ * Potentially initialized by {@link #initializePortNumbers()} if the
+ * necessary properties are set.
+ * </p>
+ */
+ private static PortTracker audioPortTracker;
+
+ /**
+ * RTP audio DSCP configuration property name.
+ */
+ private static final String RTP_AUDIO_DSCP_PROPERTY =
+ "net.java.sip.communicator.impl.protocol.RTP_AUDIO_DSCP";
+
+ /**
+ * RTP video DSCP configuration property name.
+ */
+ private static final String RTP_VIDEO_DSCP_PROPERTY =
+ "net.java.sip.communicator.impl.protocol.RTP_VIDEO_DSCP";
+
+ /**
+ * Number of empty UDP packets to send for NAT hole punching.
+ */
+ private static final String HOLE_PUNCH_PKT_COUNT_PROPERTY =
+ "net.java.sip.communicator.impl.protocol.HOLE_PUNCH_PKT_COUNT";
+
+ /**
+ * Number of empty UDP packets to send for NAT hole punching.
+ */
+ private static final int DEFAULT_HOLE_PUNCH_PKT_COUNT = 3;
+
+ /**
+ * Returns the port tracker that we are supposed to use when binding ports
+ * for the specified {@link MediaType}.
+ *
+ * @param mediaType the media type that we want to obtain the port tracker
+ * for. Use <tt>null</tt> to obtain the default port tracker.
+ *
+ * @return the port tracker that we are supposed to use when binding ports
+ * for the specified {@link MediaType}.
+ */
+ protected static PortTracker getPortTracker(MediaType mediaType)
+ {
+ //make sure our port numbers reflect the configuration service settings
+ initializePortNumbers();
+
+ if (mediaType != null)
+ {
+ switch (mediaType)
+ {
+ case AUDIO:
+ if (audioPortTracker != null)
+ return audioPortTracker;
+ else
+ break;
+ case VIDEO:
+ if (videoPortTracker != null)
+ return videoPortTracker;
+ else
+ break;
+ case DATA:
+ if (dataPortTracker != null)
+ return dataPortTracker;
+ else
+ break;
+ }
+ }
+
+ return defaultPortTracker;
+ }
+
+ /**
+ * Returns the port tracker that we are supposed to use when binding ports
+ * for the {@link MediaType} indicated by the string param. If we do not
+ * recognize the string as a valid media type, we simply return the default
+ * port tracker.
+ *
+ * @param mediaTypeStr the name of the media type that we want to obtain a
+ * port tracker for.
+ *
+ * @return the port tracker that we are supposed to use when binding ports
+ * for the {@link MediaType} with the specified name or the default tracker
+ * in case the name doesn't ring a bell.
+ */
+ protected static PortTracker getPortTracker(String mediaTypeStr)
+ {
+ try
+ {
+ return getPortTracker(MediaType.parseString(mediaTypeStr));
+ }
+ catch (Exception e)
+ {
+ logger.info(
+ "Returning default port tracker for unrecognized media type: "
+ + mediaTypeStr);
+
+ return defaultPortTracker;
+ }
+ }
+
+
+ /**
+ * The {@link MediaAwareCallPeer} whose traffic we will be taking care of.
+ */
+ private U callPeer;
+
+ /**
+ * The RTP/RTCP socket couples that this <tt>TransportManager</tt> uses to
+ * send and receive media flows through indexed by <tt>MediaType</tt>
+ * (ordinal).
+ */
+ private final StreamConnector[] streamConnectors
+ = new StreamConnector[MediaType.values().length];
+
+ /**
+ * Creates a new instance of this transport manager, binding it to the
+ * specified peer.
+ *
+ * @param callPeer the {@link MediaAwareCallPeer} whose traffic we will be
+ * taking care of.
+ */
+ protected TransportManager(U callPeer)
+ {
+ this.callPeer = callPeer;
+ }
+
+ /**
+ * Returns the <tt>StreamConnector</tt> instance that this media handler
+ * should use for streams of the specified <tt>mediaType</tt>. The method
+ * would also create a new <tt>StreamConnector</tt> if no connector has
+ * been initialized for this <tt>mediaType</tt> yet or in case one
+ * of its underlying sockets has been closed.
+ *
+ * @param mediaType the <tt>MediaType</tt> that we'd like to create a
+ * connector for.
+ * @return this media handler's <tt>StreamConnector</tt> for the specified
+ * <tt>mediaType</tt>.
+ *
+ * @throws OperationFailedException in case we failed to initialize our
+ * connector.
+ */
+ public StreamConnector getStreamConnector(MediaType mediaType)
+ throws OperationFailedException
+ {
+ int streamConnectorIndex = mediaType.ordinal();
+ StreamConnector streamConnector
+ = streamConnectors[streamConnectorIndex];
+
+ if((streamConnector == null)
+ || (streamConnector.getProtocol() == StreamConnector.Protocol.UDP))
+ {
+ DatagramSocket controlSocket;
+
+ if((streamConnector == null)
+ || streamConnector.getDataSocket().isClosed()
+ || (((controlSocket = streamConnector.getControlSocket())
+ != null)
+ && controlSocket.isClosed()))
+ {
+ streamConnectors[streamConnectorIndex]
+ = streamConnector
+ = createStreamConnector(mediaType);
+ }
+ }
+ else if(streamConnector.getProtocol() == StreamConnector.Protocol.TCP)
+ {
+ Socket controlTCPSocket;
+
+ if(streamConnector.getDataTCPSocket().isClosed()
+ || (((controlTCPSocket = streamConnector.getControlTCPSocket())
+ != null)
+ && controlTCPSocket.isClosed()))
+ {
+ streamConnectors[streamConnectorIndex]
+ = streamConnector
+ = createStreamConnector(mediaType);
+ }
+ }
+ return streamConnector;
+ }
+
+ /**
+ * Closes the existing <tt>StreamConnector</tt>, if any, associated with a
+ * specific <tt>MediaType</tt> and removes its reference from this
+ * <tt>TransportManager</tt>.
+ *
+ * @param mediaType the <tt>MediaType</tt> associated with the
+ * <tt>StreamConnector</tt> to close
+ */
+ public void closeStreamConnector(MediaType mediaType)
+ {
+ int index = mediaType.ordinal();
+ StreamConnector streamConnector = streamConnectors[index];
+
+ if (streamConnector != null)
+ {
+ closeStreamConnector(mediaType, streamConnector);
+ streamConnectors[index] = null;
+ }
+ }
+
+ /**
+ * Closes a specific <tt>StreamConnector</tt> associated with a specific
+ * <tt>MediaType</tt>. If this <tt>TransportManager</tt> has a reference to
+ * the specified <tt>streamConnector</tt>, it remains. Allows extenders to
+ * override and perform additional customizations to the closing of the
+ * specified <tt>streamConnector</tt>.
+ *
+ * @param mediaType the <tt>MediaType</tt> associated with the specified
+ * <tt>streamConnector</tt>
+ * @param streamConnector the <tt>StreamConnector</tt> to be closed
+ * @see #closeStreamConnector(MediaType)
+ */
+ protected void closeStreamConnector(
+ MediaType mediaType,
+ StreamConnector streamConnector)
+ {
+ /*
+ * XXX The connected owns the sockets so it is important that it
+ * decides whether to close them i.e. this TransportManager is not
+ * allowed to explicitly close the sockets by itself.
+ */
+ streamConnector.close();
+ }
+
+ /**
+ * Creates a media <tt>StreamConnector</tt> for a stream of a specific
+ * <tt>MediaType</tt>. The minimum and maximum of the media port boundaries
+ * are taken into account.
+ *
+ * @param mediaType the <tt>MediaType</tt> of the stream for which a
+ * <tt>StreamConnector</tt> is to be created
+ * @return a <tt>StreamConnector</tt> for the stream of the specified
+ * <tt>mediaType</tt>
+ * @throws OperationFailedException if the binding of the sockets fails
+ */
+ protected StreamConnector createStreamConnector(MediaType mediaType)
+ throws OperationFailedException
+ {
+ NetworkAddressManagerService nam
+ = ProtocolMediaActivator.getNetworkAddressManagerService();
+ InetAddress intendedDestination = getIntendedDestination(getCallPeer());
+ InetAddress localHostForPeer = nam.getLocalHost(intendedDestination);
+
+ PortTracker portTracker = getPortTracker(mediaType);
+
+ //create the RTP socket.
+ DatagramSocket rtpSocket = null;
+ try
+ {
+ rtpSocket = nam.createDatagramSocket(
+ localHostForPeer, portTracker.getPort(),
+ portTracker.getMinPort(), portTracker.getMaxPort());
+ }
+ catch (Exception exc)
+ {
+ throw new OperationFailedException(
+ "Failed to allocate the network ports necessary for the call.",
+ OperationFailedException.INTERNAL_ERROR, exc);
+ }
+
+ //make sure that next time we don't try to bind on occupied ports
+ //also, refuse validation in case someone set the tracker range to 1
+ portTracker.setNextPort( rtpSocket.getLocalPort() + 1, false);
+
+ //create the RTCP socket, preferably on the port following our RTP one.
+ DatagramSocket rtcpSocket = null;
+ try
+ {
+ rtcpSocket = nam.createDatagramSocket(
+ localHostForPeer, portTracker.getPort(),
+ portTracker.getMinPort(), portTracker.getMaxPort());
+ }
+ catch (Exception exc)
+ {
+ throw new OperationFailedException(
+ "Failed to allocate the network ports necessary for the call.",
+ OperationFailedException.INTERNAL_ERROR,
+ exc);
+ }
+
+ //make sure that next time we don't try to bind on occupied ports
+ portTracker.setNextPort( rtcpSocket.getLocalPort() + 1);
+
+ return new DefaultStreamConnector(rtpSocket, rtcpSocket);
+ }
+
+ /**
+ * Tries to set the ranges of the <tt>PortTracker</tt>s (e.g. default,
+ * audio, video, data channel) to the values specified in the
+ * <tt>ConfigurationService</tt>.
+ */
+ protected synchronized static void initializePortNumbers()
+ {
+ //try the default tracker first
+ ConfigurationService cfg
+ = ProtocolMediaActivator.getConfigurationService();
+ String minPort, maxPort;
+
+ minPort
+ = cfg.getString(
+ OperationSetBasicTelephony
+ .MIN_MEDIA_PORT_NUMBER_PROPERTY_NAME);
+ if (minPort != null)
+ {
+ maxPort
+ = cfg.getString(
+ OperationSetBasicTelephony
+ .MAX_MEDIA_PORT_NUMBER_PROPERTY_NAME);
+ if (maxPort != null)
+ {
+ //Try the specified range; otherwise, leave the tracker as it
+ //is: [5000, 6000].
+ defaultPortTracker.tryRange(minPort, maxPort);
+ }
+ }
+
+ //try the VIDEO tracker
+ minPort
+ = cfg.getString(
+ OperationSetBasicTelephony
+ .MIN_VIDEO_PORT_NUMBER_PROPERTY_NAME);
+ if (minPort != null)
+ {
+ maxPort
+ = cfg.getString(
+ OperationSetBasicTelephony
+ .MAX_VIDEO_PORT_NUMBER_PROPERTY_NAME);
+ if (maxPort != null)
+ {
+ //Try the specified range; otherwise, leave the tracker to null.
+ if (videoPortTracker == null)
+ {
+ videoPortTracker
+ = PortTracker.createTracker(minPort, maxPort);
+ }
+ else
+ {
+ videoPortTracker.tryRange(minPort, maxPort);
+ }
+ }
+ }
+
+ //try the AUDIO tracker
+ minPort
+ = cfg.getString(
+ OperationSetBasicTelephony
+ .MIN_AUDIO_PORT_NUMBER_PROPERTY_NAME);
+ if (minPort != null)
+ {
+ maxPort
+ = cfg.getString(
+ OperationSetBasicTelephony
+ .MAX_AUDIO_PORT_NUMBER_PROPERTY_NAME);
+ if (maxPort != null)
+ {
+ //Try the specified range; otherwise, leave the tracker to null.
+ if (audioPortTracker == null)
+ {
+ audioPortTracker
+ = PortTracker.createTracker(minPort, maxPort);
+ }
+ else
+ {
+ audioPortTracker.tryRange(minPort, maxPort);
+ }
+ }
+ }
+
+ //try the DATA CHANNEL tracker
+ minPort
+ = cfg.getString(
+ OperationSetBasicTelephony
+ .MIN_DATA_CHANNEL_PORT_NUMBER_PROPERTY_NAME);
+ if (minPort != null)
+ {
+ maxPort
+ = cfg.getString(
+ OperationSetBasicTelephony
+ .MAX_DATA_CHANNEL_PORT_NUMBER_PROPERTY_NAME);
+ if (maxPort != null)
+ {
+ //Try the specified range; otherwise, leave the tracker to null.
+ if (dataPortTracker == null)
+ {
+ dataPortTracker
+ = PortTracker.createTracker(minPort, maxPort);
+ }
+ else
+ {
+ dataPortTracker.tryRange(minPort, maxPort);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the <tt>InetAddress</tt> that we are using in one of our
+ * <tt>StreamConnector</tt>s or, in case we don't have any connectors yet
+ * the address returned by the our network address manager as the best local
+ * address to use when contacting the <tt>CallPeer</tt> associated with this
+ * <tt>MediaHandler</tt>. This method is primarily meant for use with the
+ * o= and c= fields of a newly created session description. The point is
+ * that we create our <tt>StreamConnector</tt>s when constructing the media
+ * descriptions so we already have a specific local address assigned to them
+ * at the time we get ready to create the c= and o= fields. It is therefore
+ * better to try and return one of these addresses before trying the net
+ * address manager again and running the slight risk of getting a different
+ * address.
+ *
+ * @return an <tt>InetAddress</tt> that we use in one of the
+ * <tt>StreamConnector</tt>s in this class.
+ */
+ public InetAddress getLastUsedLocalHost()
+ {
+ for (MediaType mediaType : MediaType.values())
+ {
+ StreamConnector streamConnector
+ = streamConnectors[mediaType.ordinal()];
+
+ if (streamConnector != null)
+ return streamConnector.getDataSocket().getLocalAddress();
+ }
+
+ NetworkAddressManagerService nam
+ = ProtocolMediaActivator.getNetworkAddressManagerService();
+ InetAddress intendedDestination = getIntendedDestination(getCallPeer());
+
+ return nam.getLocalHost(intendedDestination);
+ }
+
+ /**
+ * Sends empty UDP packets to target destination data/control ports in order
+ * to open ports on NATs or and help RTP proxies latch onto our RTP ports.
+ *
+ * @param target <tt>MediaStreamTarget</tt>
+ * @param type the {@link MediaType} of the connector we'd like to send the
+ * hole punching packet through.
+ */
+ public void sendHolePunchPacket(MediaStreamTarget target, MediaType type)
+ {
+ this.sendHolePunchPacket(target, type, null);
+ }
+
+ /**
+ * Sends empty UDP packets to target destination data/control ports in order
+ * to open ports on NATs or and help RTP proxies latch onto our RTP ports.
+ *
+ * @param target <tt>MediaStreamTarget</tt>
+ * @param type the {@link MediaType} of the connector we'd like to send the
+ * hole punching packet through.
+ * @param packet (optional) use a pre-generated packet that will be sent
+ */
+ public void sendHolePunchPacket(
+ MediaStreamTarget target, MediaType type, RawPacket packet)
+ {
+ logger.info("Send NAT hole punch packets");
+
+ //check how many hole punch packets we would be supposed to send:
+ int packetCount
+ = ProtocolMediaActivator.getConfigurationService().getInt(
+ HOLE_PUNCH_PKT_COUNT_PROPERTY,
+ DEFAULT_HOLE_PUNCH_PKT_COUNT);
+
+ if (packetCount < 0)
+ packetCount = DEFAULT_HOLE_PUNCH_PKT_COUNT;
+ if (packetCount == 0)
+ return;
+
+ try
+ {
+ final StreamConnector connector = getStreamConnector(type);
+
+ if(connector.getProtocol() == StreamConnector.Protocol.TCP)
+ return;
+
+ byte[] buf;
+ if (packet != null)
+ buf = packet.getBuffer();
+ else
+ buf = new byte[0];
+
+ synchronized(connector)
+ {
+ //we may want to send more than one packet in case they get lost
+ for(int i=0; i < packetCount; i++)
+ {
+ DatagramSocket socket;
+
+ // data/RTP
+ if((socket = connector.getDataSocket()) != null)
+ {
+ InetSocketAddress dataAddress = target.getDataAddress();
+
+ socket.send(
+ new DatagramPacket(
+ buf,
+ buf.length,
+ dataAddress.getAddress(),
+ dataAddress.getPort()));
+ }
+
+ // control/RTCP
+ if((socket = connector.getControlSocket()) != null)
+ {
+ InetSocketAddress controlAddress
+ = target.getControlAddress();
+
+ socket.send(
+ new DatagramPacket(
+ buf,
+ buf.length,
+ controlAddress.getAddress(),
+ controlAddress.getPort()));
+ }
+ }
+ }
+ }
+ catch(Exception e)
+ {
+ logger.error("Error cannot send to remote peer", e);
+ }
+ }
+
+ /**
+ * Set traffic class (QoS) for the RTP socket.
+ *
+ * @param target <tt>MediaStreamTarget</tt>
+ * @param type the {@link MediaType} of the connector we'd like to set
+ * traffic class
+ */
+ protected void setTrafficClass(MediaStreamTarget target, MediaType type)
+ {
+ // get traffic class value for RTP audio/video
+ int trafficClass = getDSCP(type);
+
+ if(trafficClass <= 0)
+ return;
+
+ if (logger.isInfoEnabled())
+ logger.info(
+ "Set traffic class for " + type + " to " + trafficClass);
+ try
+ {
+ final StreamConnector connector = getStreamConnector(type);
+
+ synchronized(connector)
+ {
+ if(connector.getProtocol() == StreamConnector.Protocol.TCP)
+ {
+ connector.getDataTCPSocket().setTrafficClass(trafficClass);
+
+ Socket controlTCPSocket = connector.getControlTCPSocket();
+
+ if (controlTCPSocket != null)
+ controlTCPSocket.setTrafficClass(trafficClass);
+ }
+ else
+ {
+ /* data port (RTP) */
+ connector.getDataSocket().setTrafficClass(trafficClass);
+
+ /* control port (RTCP) */
+ DatagramSocket controlSocket = connector.getControlSocket();
+
+ if (controlSocket != null)
+ controlSocket.setTrafficClass(trafficClass);
+ }
+ }
+ }
+ catch(Exception e)
+ {
+ logger.error(
+ "Failed to set traffic class for " + type + " to "
+ + trafficClass,
+ e);
+ }
+ }
+
+ /**
+ * Gets the SIP traffic class associated with a specific <tt>MediaType</tt>
+ * from the configuration.
+ *
+ * @param type the <tt>MediaType</tt> to get the associated SIP traffic
+ * class of
+ * @return the SIP traffic class associated with the specified
+ * <tt>MediaType</tt> or <tt>0</tt> if not configured
+ */
+ private int getDSCP(MediaType type)
+ {
+ String dscpPropertyName;
+
+ switch (type)
+ {
+ case AUDIO:
+ dscpPropertyName = RTP_AUDIO_DSCP_PROPERTY;
+ break;
+ case VIDEO:
+ dscpPropertyName = RTP_VIDEO_DSCP_PROPERTY;
+ break;
+ default:
+ dscpPropertyName = null;
+ break;
+ }
+
+ return
+ (dscpPropertyName == null)
+ ? 0
+ : (ProtocolMediaActivator.getConfigurationService().getInt(
+ dscpPropertyName,
+ 0)
+ << 2);
+ }
+
+ /**
+ * Returns the <tt>InetAddress</tt> that is most likely to be used as a
+ * next hop when contacting the specified <tt>destination</tt>. This is
+ * an utility method that is used whenever we have to choose one of our
+ * local addresses to put in the Via, Contact or (in the case of no
+ * registrar accounts) From headers.
+ *
+ * @param peer the CallPeer that we would contact.
+ *
+ * @return the <tt>InetAddress</tt> that is most likely to be to be used
+ * as a next hop when contacting the specified <tt>destination</tt>.
+ *
+ * @throws IllegalArgumentException if <tt>destination</tt> is not a valid
+ * host/ip/fqdn
+ */
+ protected abstract InetAddress getIntendedDestination(U peer);
+
+ /**
+ * Returns the {@link MediaAwareCallPeer} that this transport manager is
+ * serving.
+ *
+ * @return the {@link MediaAwareCallPeer} that this transport manager is
+ * serving.
+ */
+ public U getCallPeer()
+ {
+ return callPeer;
+ }
+
+ /**
+ * Returns the extended type of the candidate selected if this transport
+ * manager is using ICE.
+ *
+ * @param streamName The stream name (AUDIO, VIDEO);
+ *
+ * @return The extended type of the candidate selected if this transport
+ * manager is using ICE. Otherwise, returns null.
+ */
+ public abstract String getICECandidateExtendedType(String streamName);
+
+ /**
+ * Returns the current state of ICE processing.
+ *
+ * @return the current state of ICE processing if this transport
+ * manager is using ICE. Otherwise, returns null.
+ */
+ public abstract String getICEState();
+
+ /**
+ * Returns the ICE local host address.
+ *
+ * @param streamName The stream name (AUDIO, VIDEO);
+ *
+ * @return the ICE local host address if this transport
+ * manager is using ICE. Otherwise, returns null.
+ */
+ public abstract InetSocketAddress getICELocalHostAddress(String streamName);
+
+ /**
+ * Returns the ICE remote host address.
+ *
+ * @param streamName The stream name (AUDIO, VIDEO);
+ *
+ * @return the ICE remote host address if this transport
+ * manager is using ICE. Otherwise, returns null.
+ */
+ public abstract InetSocketAddress getICERemoteHostAddress(
+ String streamName);
+
+ /**
+ * Returns the ICE local reflexive address (server or peer reflexive).
+ *
+ * @param streamName The stream name (AUDIO, VIDEO);
+ *
+ * @return the ICE local reflexive address. May be null if this transport
+ * manager is not using ICE or if there is no reflexive address for the
+ * local candidate used.
+ */
+ public abstract InetSocketAddress getICELocalReflexiveAddress(
+ String streamName);
+
+ /**
+ * Returns the ICE remote reflexive address (server or peer reflexive).
+ *
+ * @param streamName The stream name (AUDIO, VIDEO);
+ *
+ * @return the ICE remote reflexive address. May be null if this transport
+ * manager is not using ICE or if there is no reflexive address for the
+ * remote candidate used.
+ */
+ public abstract InetSocketAddress getICERemoteReflexiveAddress(
+ String streamName);
+
+ /**
+ * Returns the ICE local relayed address (server or peer relayed).
+ *
+ * @param streamName The stream name (AUDIO, VIDEO);
+ *
+ * @return the ICE local relayed address. May be null if this transport
+ * manager is not using ICE or if there is no relayed address for the
+ * local candidate used.
+ */
+ public abstract InetSocketAddress getICELocalRelayedAddress(
+ String streamName);
+
+ /**
+ * Returns the ICE remote relayed address (server or peer relayed).
+ *
+ * @param streamName The stream name (AUDIO, VIDEO);
+ *
+ * @return the ICE remote relayed address. May be null if this transport
+ * manager is not using ICE or if there is no relayed address for the
+ * remote candidate used.
+ */
+ public abstract InetSocketAddress getICERemoteRelayedAddress(
+ String streamName);
+
+ /**
+ * Returns the total harvesting time (in ms) for all harvesters.
+ *
+ * @return The total harvesting time (in ms) for all the harvesters. 0 if
+ * the ICE agent is null, or if the agent has nevers harvested.
+ */
+ public abstract long getTotalHarvestingTime();
+
+ /**
+ * Returns the harvesting time (in ms) for the harvester given in parameter.
+ *
+ * @param harvesterName The class name if the harvester.
+ *
+ * @return The harvesting time (in ms) for the harvester given in parameter.
+ * 0 if this harvester does not exists, if the ICE agent is null, or if the
+ * agent has never harvested with this harvester.
+ */
+ public abstract long getHarvestingTime(String harvesterName);
+
+ /**
+ * Returns the number of harvesting for this agent.
+ *
+ * @return The number of harvesting for this agent.
+ */
+ public abstract int getNbHarvesting();
+
+ /**
+ * Returns the number of harvesting time for the harvester given in
+ * parameter.
+ *
+ * @param harvesterName The class name if the harvester.
+ *
+ * @return The number of harvesting time for the harvester given in
+ * parameter.
+ */
+ public abstract int getNbHarvesting(String harvesterName);
+
+ /**
+ * Returns the ICE candidate extended type selected by the given agent.
+ *
+ * @param iceAgent The ICE agent managing the ICE offer/answer exchange,
+ * collecting and selecting the candidate.
+ * @param streamName The stream name (AUDIO, VIDEO);
+ *
+ * @return The ICE candidate extended type selected by the given agent. null
+ * if the iceAgent is null or if there is no candidate selected or
+ * available.
+ */
+ public static String getICECandidateExtendedType(
+ Agent iceAgent,
+ String streamName)
+ {
+ if(iceAgent != null)
+ {
+ LocalCandidate localCandidate
+ = iceAgent.getSelectedLocalCandidate(streamName);
+
+ if(localCandidate != null)
+ return localCandidate.getExtendedType().toString();
+ }
+ return null;
+ }
+
+
+ /**
+ * Creates the ICE agent that we would be using in this transport manager
+ * for all negotiation.
+ *
+ * @return the ICE agent to use for all the ICE negotiation that this
+ * transport manager would be going through
+ */
+ protected Agent createIceAgent()
+ {
+ //work in progress
+ return null;
+ }
+
+ /**
+ * Creates an {@link IceMediaStream} with the specified <tt>media</tt>
+ * name.
+ *
+ * @param media the name of the stream we'd like to create.
+ * @param agent the ICE {@link Agent} that we will be appending the stream
+ * to.
+ *
+ * @return the newly created {@link IceMediaStream}
+ *
+ * @throws OperationFailedException if binding on the specified media stream
+ * fails for some reason.
+ */
+ protected IceMediaStream createIceStream(String media, Agent agent)
+ throws OperationFailedException
+ {
+ return null;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/protocol/media/protocol.media.manifest.mf b/src/net/java/sip/communicator/service/protocol/media/protocol.media.manifest.mf
index 4436e93..7bac7aa 100644
--- a/src/net/java/sip/communicator/service/protocol/media/protocol.media.manifest.mf
+++ b/src/net/java/sip/communicator/service/protocol/media/protocol.media.manifest.mf
@@ -15,7 +15,6 @@ Import-Package: javax.xml.parsers,
org.ice4j,
org.ice4j.ice,
org.ice4j.ice.harvest,
- org.ice4j.ice.sdp,
org.ice4j.security,
org.ice4j.socket,
org.ice4j.stack,
diff --git a/src/net/java/sip/communicator/service/protocol/protocol.provider.manifest.mf b/src/net/java/sip/communicator/service/protocol/protocol.provider.manifest.mf
index 271af97..233eb84 100644
--- a/src/net/java/sip/communicator/service/protocol/protocol.provider.manifest.mf
+++ b/src/net/java/sip/communicator/service/protocol/protocol.provider.manifest.mf
@@ -17,12 +17,10 @@ Import-Package: net.java.sip.communicator.service.credentialsstorage,
org.jitsi.util.event,
org.osgi.framework
Export-Package: net.java.sip.communicator.service.protocol,
- net.java.sip.communicator.service.protocol.aimconstants,
net.java.sip.communicator.service.protocol.event,
net.java.sip.communicator.service.protocol.globalstatus,
net.java.sip.communicator.service.protocol.icqconstants,
net.java.sip.communicator.service.protocol.jabber,
net.java.sip.communicator.service.protocol.jabberconstants,
net.java.sip.communicator.service.protocol.sip,
- net.java.sip.communicator.service.protocol.whiteboardobjects,
- net.java.sip.communicator.service.protocol.yahooconstants
+ net.java.sip.communicator.service.protocol.whiteboardobjects
diff --git a/src/net/java/sip/communicator/service/protocol/sip/SIPAccountRegistration.java b/src/net/java/sip/communicator/service/protocol/sip/SIPAccountRegistration.java
index 9719b8c..5355855 100644
--- a/src/net/java/sip/communicator/service/protocol/sip/SIPAccountRegistration.java
+++ b/src/net/java/sip/communicator/service/protocol/sip/SIPAccountRegistration.java
@@ -24,7 +24,7 @@ import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.*;
import org.jitsi.service.neomedia.*;
-
+import org.jitsi.util.StringUtils;
import org.osgi.framework.*;
/**
@@ -257,23 +257,37 @@ public class SIPAccountRegistration
encodingsRegistration.storeProperties(this.accountProperties);
- if (isModification)
+ if(isMessageWaitingIndicationsEnabled())
{
- if (isMessageWaitingIndicationsEnabled())
+ if(!StringUtils.isNullOrEmpty(getVoicemailURI(), true))
+ accountProperties.put(
+ ProtocolProviderFactory.VOICEMAIL_URI,
+ getVoicemailURI());
+ else if(isModification)
+ accountProperties.put(ProtocolProviderFactory.VOICEMAIL_URI, "");
+
+ if(!StringUtils.isNullOrEmpty(
+ getVoicemailCheckURI(), true))
+ accountProperties.put(
+ ProtocolProviderFactory.VOICEMAIL_CHECK_URI,
+ getVoicemailCheckURI());
+ else if(isModification)
+ accountProperties.put(
+ ProtocolProviderFactory.VOICEMAIL_CHECK_URI, "");
+
+ if(isModification)
{
- setVoicemailURI("");
- setVoicemailCheckURI("");
// remove the property as true is by default,
// and null removes property
- removeAccountProperty(
- ProtocolProviderFactory.VOICEMAIL_ENABLED);
- } else
- {
- accountProperties.put(
- ProtocolProviderFactory.VOICEMAIL_ENABLED,
- Boolean.FALSE.toString());
+ accountProperties.put(ProtocolProviderFactory.VOICEMAIL_ENABLED,
+ null);
}
}
+ else if(isModification)
+ {
+ accountProperties.put(ProtocolProviderFactory.VOICEMAIL_ENABLED,
+ Boolean.FALSE.toString());
+ }
super.storeProperties(
protocolIconPath, accountIconPath, accountProperties);
diff --git a/src/net/java/sip/communicator/service/protocol/yahooconstants/YahooStatusEnum.java b/src/net/java/sip/communicator/service/protocol/yahooconstants/YahooStatusEnum.java
deleted file mode 100644
index d21ec033..0000000
--- a/src/net/java/sip/communicator/service/protocol/yahooconstants/YahooStatusEnum.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.service.protocol.yahooconstants;
-
-import java.io.*;
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * An enumeration containing all status instances that MUST be supported by
- * an implementation of the yahoo protocol. Implementations may
- * support other forms of PresenceStatus but they MUST ALL support those
- * enumerated here.
- * <p>
- * For testing purposes, this class also provides a <tt>List</tt> containing
- * all of the status fields.
- *
- * @author Damian Minkov
- */
-public class YahooStatusEnum
- extends PresenceStatus
-{
- /**
- * The <tt>Logger</tt> used by the <tt>YahooStatusEnum</tt> class and its
- * instances for logging output.
- */
- private static Logger logger = Logger.getLogger(YahooStatusEnum.class);
-
- /**
- * The Online status. Indicate that the user is able and willing to
- * communicate.
- */
- public static final YahooStatusEnum AVAILABLE
- = new YahooStatusEnum(65, "Available",
- loadIcon("resources/images/protocol/yahoo/yahoo16x16-online.png"));
-
- /**
- * The Not Available status. Indicates that the user has connectivity
- * but might not be able to immediately act (i.e. even less immediately than
- * when in an Away status ;-P ) upon initiation of communication.
- */
- public static final YahooStatusEnum BE_RIGHT_BACK
- = new YahooStatusEnum(48, "Be Right Back",
- loadIcon("resources/images/protocol/yahoo/yahoo16x16-away.png"));
-
- /**
- * The Idle status. Indicates that the user is not using the messanger.
- */
- public static final YahooStatusEnum IDLE
- = new YahooStatusEnum(46, "Idle",
- loadIcon("resources/images/protocol/yahoo/yahoo16x16-idle.png"));
-
- /**
- * The Invisible status. Indicates that the user has connectivity even
- * though it may appear otherwise to others, to whom she would appear to be
- * offline.
- */
- public static final YahooStatusEnum INVISIBLE
- = new YahooStatusEnum(45, "Invisible",
- loadIcon("resources/images/protocol/yahoo/yahoo16x16-invisible.png"));
-
- /**
- * The STEPPED_OUT status. Indicates that the user has connectivity but might
- * not be able to immediately act upon initiation of communication.
- */
- public static final YahooStatusEnum STEPPED_OUT
- = new YahooStatusEnum(40, "Stepped out",
- loadIcon("resources/images/protocol/yahoo/yahoo16x16-away.png"));
-
- /**
- * The Out to lunch status. Indicates that the user is eating.
- */
- public static final YahooStatusEnum OUT_TO_LUNCH
- = new YahooStatusEnum(39, "Out to lunch",
- loadIcon("resources/images/protocol/yahoo/yahoo16x16-lunch.png"));
-
- /**
- * The Not at home status. Indicates that the user is not at home.
- */
- public static final YahooStatusEnum NOT_AT_HOME
- = new YahooStatusEnum(38, "Not at home",
- loadIcon("resources/images/protocol/yahoo/yahoo16x16-na.png"));
-
- /**
- * The Not at desk status. Indicates that the user is not at his desk, but
- * somewhere in the office.
- */
- public static final YahooStatusEnum NOT_AT_DESK
- = new YahooStatusEnum(36, "Not at desk",
- loadIcon("resources/images/protocol/yahoo/yahoo16x16-na.png"));
-
- /**
- * The Not in office status. Indicates that the user is out of the office.
- */
- public static final YahooStatusEnum NOT_IN_OFFICE
- = new YahooStatusEnum(34, "Not in office",
- loadIcon("resources/images/protocol/yahoo/yahoo16x16-na.png"));
-
- /**
- * The On vacation status. Indicates that the user is somewhere on the
- * beach or skiing.
- */
- public static final YahooStatusEnum ON_VACATION
- = new YahooStatusEnum(33, "On vacation",
- loadIcon("resources/images/protocol/yahoo/yahoo16x16-vacation.png"));
-
- /**
- * The On the phone status. Indicates that the user is talking to the phone.
- */
- public static final YahooStatusEnum ON_THE_PHONE
- = new YahooStatusEnum(31, "On the phone",
- loadIcon("resources/images/protocol/yahoo/yahoo16x16-phone.png"));
-
- /**
- * The DND status. Indicates that the user has connectivity but prefers
- * not to be contacted.
- */
- public static final YahooStatusEnum BUSY
- = new YahooStatusEnum(30, "Busy",
- loadIcon("resources/images/protocol/yahoo/yahoo16x16-busy.png"));
-
- /**
- * The Offline status. Indicates the user does not seem to be connected
- * to the network or at least does not want us to know she is
- */
- public static final YahooStatusEnum OFFLINE
- = new YahooStatusEnum(0, "Offline",
- loadIcon("resources/images/protocol/yahoo/yahoo16x16-offline.png"));
-
- /**
- * The minimal set of states that any implementation must support.
- */
- public static final ArrayList<YahooStatusEnum> yahooStatusSet
- = new ArrayList<YahooStatusEnum>();
- static{
- yahooStatusSet.add(AVAILABLE);
- yahooStatusSet.add(BE_RIGHT_BACK);
- yahooStatusSet.add(BUSY);
- yahooStatusSet.add(IDLE);
- yahooStatusSet.add(INVISIBLE);
- yahooStatusSet.add(NOT_AT_DESK);
- yahooStatusSet.add(NOT_AT_HOME);
- yahooStatusSet.add(NOT_IN_OFFICE);
- yahooStatusSet.add(OFFLINE);
- yahooStatusSet.add(ON_THE_PHONE);
- yahooStatusSet.add(ON_VACATION);
- yahooStatusSet.add(OUT_TO_LUNCH);
- yahooStatusSet.add(STEPPED_OUT);
- }
-
- /**
- * Creates a status with the specified connectivity coeff, name and icon.
- * @param status the connectivity coefficient for the specified status
- * @param statusName String
- * @param statusIcon the icon associated with this status
- */
- protected YahooStatusEnum(int status, String statusName, byte[] statusIcon)
- {
- super(status, statusName, statusIcon);
- }
-
- /**
- * Loads an image from a given image path.
- * @param imagePath The identifier of the image.
- * @return The image for the given identifier.
- */
- public static byte[] loadIcon(String imagePath) {
- InputStream is = YahooStatusEnum.class.getClassLoader()
- .getResourceAsStream(imagePath);
-
- if(is == null)
- return null;
-
- byte[] icon = null;
- try {
- icon = new byte[is.available()];
- is.read(icon);
- } catch (IOException exc) {
- logger.error("Failed to load icon: " + imagePath, exc);
- }
- return icon;
- }
-}
diff --git a/src/net/java/sip/communicator/service/resources/ImageID.java b/src/net/java/sip/communicator/service/resources/ImageID.java
index cc90191..785ca96 100644
--- a/src/net/java/sip/communicator/service/resources/ImageID.java
+++ b/src/net/java/sip/communicator/service/resources/ImageID.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,22 +15,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.resources;
-
-/**
- * Represents the Image Identifier.
- */
-public class ImageID
-{
- private final String id;
-
- public ImageID(String id)
- {
- this.id = id;
- }
-
- public String getId()
- {
- return id;
- }
-}
+package net.java.sip.communicator.service.resources;
+
+/**
+ * Represents the Image Identifier.
+ */
+public class ImageID
+{
+ private final String id;
+
+ public ImageID(String id)
+ {
+ this.id = id;
+ }
+
+ public String getId()
+ {
+ return id;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/resources/ResourceManagementServiceUtils.java b/src/net/java/sip/communicator/service/resources/ResourceManagementServiceUtils.java
index d8570c7..c5d10ac 100644
--- a/src/net/java/sip/communicator/service/resources/ResourceManagementServiceUtils.java
+++ b/src/net/java/sip/communicator/service/resources/ResourceManagementServiceUtils.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,74 +15,74 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.resources;
-
-import java.util.*;
-
-import net.java.sip.communicator.util.*;
-
-import org.jitsi.service.resources.*;
-import org.osgi.framework.*;
-
-/**
- * @author Lubomir Marinov
- */
-public final class ResourceManagementServiceUtils
-{
-
- /**
- * Constructs a new <tt>Locale</tt> instance from a specific locale
- * identifier which can either be a two-letter language code or contain a
- * two-letter language code and a two-letter country code in the form
- * <tt>&lt;language&gt;_&lt;country&gt;</tt>.
- *
- * @param localeId the locale identifier describing the new <tt>Locale</tt>
- * instance to be created
- * @return a new <tt>Locale</tt> instance with language and country (if
- * specified) matching the given locale identifier
- */
- public static Locale getLocale(String localeId)
- {
- int underscoreIndex = localeId.indexOf('_');
- String language;
- String country;
-
- if (underscoreIndex == -1)
- {
- language = localeId;
- country = "";
- }
- else
- {
- language = localeId.substring(0, underscoreIndex);
- country = localeId.substring(underscoreIndex + 1);
- }
- return new Locale(language, country);
- }
-
- /**
- * Gets the <tt>ResourceManagementService</tt> instance registered in a
- * specific <tt>BundleContext</tt> (if any).
- *
- * @param bundleContext the <tt>BundleContext</tt> to be checked for a
- * registered <tt>ResourceManagementService</tt>
- * @return a <tt>ResourceManagementService</tt> instance registered in
- * the specified <tt>BundleContext</tt> if any; otherwise, <tt>null</tt>
- */
- public static ResourceManagementService getService(
- BundleContext bundleContext)
- {
- return
- ServiceUtils.getService(
- bundleContext,
- ResourceManagementService.class);
- }
-
- /**
- * Prevents the creation of <tt>ResourceManagementServiceUtils</tt>
- * instances.
- */
- private ResourceManagementServiceUtils()
- {
- }
-}
+package net.java.sip.communicator.service.resources;
+
+import java.util.*;
+
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.resources.*;
+import org.osgi.framework.*;
+
+/**
+ * @author Lubomir Marinov
+ */
+public final class ResourceManagementServiceUtils
+{
+
+ /**
+ * Constructs a new <tt>Locale</tt> instance from a specific locale
+ * identifier which can either be a two-letter language code or contain a
+ * two-letter language code and a two-letter country code in the form
+ * <tt>&lt;language&gt;_&lt;country&gt;</tt>.
+ *
+ * @param localeId the locale identifier describing the new <tt>Locale</tt>
+ * instance to be created
+ * @return a new <tt>Locale</tt> instance with language and country (if
+ * specified) matching the given locale identifier
+ */
+ public static Locale getLocale(String localeId)
+ {
+ int underscoreIndex = localeId.indexOf('_');
+ String language;
+ String country;
+
+ if (underscoreIndex == -1)
+ {
+ language = localeId;
+ country = "";
+ }
+ else
+ {
+ language = localeId.substring(0, underscoreIndex);
+ country = localeId.substring(underscoreIndex + 1);
+ }
+ return new Locale(language, country);
+ }
+
+ /**
+ * Gets the <tt>ResourceManagementService</tt> instance registered in a
+ * specific <tt>BundleContext</tt> (if any).
+ *
+ * @param bundleContext the <tt>BundleContext</tt> to be checked for a
+ * registered <tt>ResourceManagementService</tt>
+ * @return a <tt>ResourceManagementService</tt> instance registered in
+ * the specified <tt>BundleContext</tt> if any; otherwise, <tt>null</tt>
+ */
+ public static ResourceManagementService getService(
+ BundleContext bundleContext)
+ {
+ return
+ ServiceUtils.getService(
+ bundleContext,
+ ResourceManagementService.class);
+ }
+
+ /**
+ * Prevents the creation of <tt>ResourceManagementServiceUtils</tt>
+ * instances.
+ */
+ private ResourceManagementServiceUtils()
+ {
+ }
+}
diff --git a/src/net/java/sip/communicator/service/sysactivity/SystemActivityChangeListener.java b/src/net/java/sip/communicator/service/sysactivity/SystemActivityChangeListener.java
index e94c49d..98aecdd 100644
--- a/src/net/java/sip/communicator/service/sysactivity/SystemActivityChangeListener.java
+++ b/src/net/java/sip/communicator/service/sysactivity/SystemActivityChangeListener.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,28 +15,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.sysactivity;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.sysactivity.event.*;
-
-/**
- * The <tt>SystemActivityChangeListener</tt> is notified any time an event
- * in the operating system occurs.
- *
- * @author Damian Minkov
- */
-public interface SystemActivityChangeListener
- extends EventListener
-{
- /**
- * This method gets called when a notification action for a particular event
- * type has been changed (for example the corresponding descriptor has
- * changed).
- *
- * @param event the <tt>NotificationActionTypeEvent</tt>, which is
- * dispatched when an action has been changed.
- */
- public void activityChanged(SystemActivityEvent event);
-}
+package net.java.sip.communicator.service.sysactivity;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.sysactivity.event.*;
+
+/**
+ * The <tt>SystemActivityChangeListener</tt> is notified any time an event
+ * in the operating system occurs.
+ *
+ * @author Damian Minkov
+ */
+public interface SystemActivityChangeListener
+ extends EventListener
+{
+ /**
+ * This method gets called when a notification action for a particular event
+ * type has been changed (for example the corresponding descriptor has
+ * changed).
+ *
+ * @param event the <tt>NotificationActionTypeEvent</tt>, which is
+ * dispatched when an action has been changed.
+ */
+ public void activityChanged(SystemActivityEvent event);
+}
diff --git a/src/net/java/sip/communicator/service/sysactivity/SystemActivityNotificationsService.java b/src/net/java/sip/communicator/service/sysactivity/SystemActivityNotificationsService.java
index f7de167..c7069b0 100644
--- a/src/net/java/sip/communicator/service/sysactivity/SystemActivityNotificationsService.java
+++ b/src/net/java/sip/communicator/service/sysactivity/SystemActivityNotificationsService.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,71 +15,71 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.sysactivity;
-
-/**
- * Listens for some system specific events such as sleep, wake, network change,
- * desktop activity, screensaver etc. and informs the registered listeners.
- *
- * @author Damian Minkov
- */
-public interface SystemActivityNotificationsService
-{
- /**
- * Registers a listener that would be notified of changes that have occurred
- * in the underlying system.
- *
- * @param listener the listener that we'd like to register for changes in
- * the underlying system.
- */
- public void addSystemActivityChangeListener(
- SystemActivityChangeListener listener);
-
- /**
- * Remove the specified listener so that it won't receive further
- * notifications of changes that occur in the underlying system
- *
- * @param listener the listener to remove.
- */
- public void removeSystemActivityChangeListener(
- SystemActivityChangeListener listener);
-
- /**
- * Registers a listener that would be notified for idle of the system
- * for <tt>idleTime</tt>.
- *
- * @param idleTime the time in milliseconds after which we will consider
- * system to be idle. This doesn't count when system seems idle as
- * monitor is off or screensaver is on, or desktop is locked.
- * @param listener the listener that we'd like to register for changes in
- * the underlying system.
- */
- public void addIdleSystemChangeListener(
- long idleTime,
- SystemActivityChangeListener listener);
-
- /**
- * Remove the specified listener so that it won't receive further
- * notifications for idle system.
- *
- * @param listener the listener to remove.
- */
- public void removeIdleSystemChangeListener(
- SystemActivityChangeListener listener);
-
- /**
- * Can check whether an event id is supported on
- * current operation system.
- * @param eventID the event to check.
- * @return whether the supplied event id is supported.
- */
- public boolean isSupported(int eventID);
-
- /**
- * The time since last user input. The time the system has been idle.
- * Or -1 if there is no such information or error has occured.
- * @return time the system has been idle.
- */
- public long getTimeSinceLastInput();
-
-}
+package net.java.sip.communicator.service.sysactivity;
+
+/**
+ * Listens for some system specific events such as sleep, wake, network change,
+ * desktop activity, screensaver etc. and informs the registered listeners.
+ *
+ * @author Damian Minkov
+ */
+public interface SystemActivityNotificationsService
+{
+ /**
+ * Registers a listener that would be notified of changes that have occurred
+ * in the underlying system.
+ *
+ * @param listener the listener that we'd like to register for changes in
+ * the underlying system.
+ */
+ public void addSystemActivityChangeListener(
+ SystemActivityChangeListener listener);
+
+ /**
+ * Remove the specified listener so that it won't receive further
+ * notifications of changes that occur in the underlying system
+ *
+ * @param listener the listener to remove.
+ */
+ public void removeSystemActivityChangeListener(
+ SystemActivityChangeListener listener);
+
+ /**
+ * Registers a listener that would be notified for idle of the system
+ * for <tt>idleTime</tt>.
+ *
+ * @param idleTime the time in milliseconds after which we will consider
+ * system to be idle. This doesn't count when system seems idle as
+ * monitor is off or screensaver is on, or desktop is locked.
+ * @param listener the listener that we'd like to register for changes in
+ * the underlying system.
+ */
+ public void addIdleSystemChangeListener(
+ long idleTime,
+ SystemActivityChangeListener listener);
+
+ /**
+ * Remove the specified listener so that it won't receive further
+ * notifications for idle system.
+ *
+ * @param listener the listener to remove.
+ */
+ public void removeIdleSystemChangeListener(
+ SystemActivityChangeListener listener);
+
+ /**
+ * Can check whether an event id is supported on
+ * current operation system.
+ * @param eventID the event to check.
+ * @return whether the supplied event id is supported.
+ */
+ public boolean isSupported(int eventID);
+
+ /**
+ * The time since last user input. The time the system has been idle.
+ * Or -1 if there is no such information or error has occured.
+ * @return time the system has been idle.
+ */
+ public long getTimeSinceLastInput();
+
+}
diff --git a/src/net/java/sip/communicator/service/sysactivity/event/SystemActivityEvent.java b/src/net/java/sip/communicator/service/sysactivity/event/SystemActivityEvent.java
index fa5df51..47183d7 100644
--- a/src/net/java/sip/communicator/service/sysactivity/event/SystemActivityEvent.java
+++ b/src/net/java/sip/communicator/service/sysactivity/event/SystemActivityEvent.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,136 +15,136 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.service.sysactivity.event;
-
-import java.util.*;
-
-/**
- * An event class representing system activity that has occurred.
- * The event id indicates the exact reason for this event.
- * @author Damian Minkov
- */
-public class SystemActivityEvent
- extends EventObject
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * Notify that computers is going to sleep.
- */
- public static final int EVENT_SLEEP = 0;
-
- /**
- * Notify that computer is wakeing up after stand by.
- */
- public static final int EVENT_WAKE = 1;
-
- /**
- * Computer display has stand by.
- */
- public static final int EVENT_DISPLAY_SLEEP = 2;
-
- /**
- * Computer display wakes up after stand by.
- */
- public static final int EVENT_DISPLAY_WAKE = 3;
-
- /**
- * Screensaver has been started.
- */
- public static final int EVENT_SCREENSAVER_START = 4;
-
- /**
- * Screensaver will stop.
- */
- public static final int EVENT_SCREENSAVER_WILL_STOP = 5;
-
- /**
- * Screensaver has been stopped.
- */
- public static final int EVENT_SCREENSAVER_STOP = 6;
-
- /**
- * Screen has been locked.
- */
- public static final int EVENT_SCREEN_LOCKED = 7;
-
- /**
- * Screen has been unlocked.
- */
- public static final int EVENT_SCREEN_UNLOCKED = 8;
-
- /**
- * A change in network configuration has occurred.
- */
- public static final int EVENT_NETWORK_CHANGE = 9;
-
- /**
- * A system idle event has occurred.
- */
- public static final int EVENT_SYSTEM_IDLE = 10;
-
- /**
- * A system was in idle state and now exits.
- */
- public static final int EVENT_SYSTEM_IDLE_END = 11;
-
- /**
- * A change in dns configuration has occurred.
- */
- public static final int EVENT_DNS_CHANGE = 12;
-
- /**
- * Informing that the machine is logging of or shutting down.
- */
- public static final int EVENT_QUERY_ENDSESSION = 13;
-
- /**
- * The log off or shutdown is in process for us, no matter
- * what other process has replied, whether one of them has canceled
- * or not the current end of session. It's like that cause we have answered
- * that we will shutdown.
- */
- public static final int EVENT_ENDSESSION = 14;
-
- /**
- * The type of the event.
- */
- private final int eventID;
-
- /**
- * Constructs a prototypical Event.
- *
- * @param source The object on which the Event initially occurred.
- * @param eventID the type of the event.
- * @throws IllegalArgumentException if source is null.
- */
- public SystemActivityEvent(Object source, int eventID)
- {
- super(source);
-
- this.eventID = eventID;
- }
-
- /**
- * Returns the type of the event.
- * @return the event ID
- */
- public int getEventID()
- {
- return this.eventID;
- }
-
- /**
- * Returns a String representation of this SystemActivityEvent object.
- *
- * @return A a String representation of this SystemActivityEvent object.
- */
- @Override
- public String toString() {
- return getClass().getName() + "[eventID=" + eventID + "]";
- }
-}
+package net.java.sip.communicator.service.sysactivity.event;
+
+import java.util.*;
+
+/**
+ * An event class representing system activity that has occurred.
+ * The event id indicates the exact reason for this event.
+ * @author Damian Minkov
+ */
+public class SystemActivityEvent
+ extends EventObject
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * Notify that computers is going to sleep.
+ */
+ public static final int EVENT_SLEEP = 0;
+
+ /**
+ * Notify that computer is wakeing up after stand by.
+ */
+ public static final int EVENT_WAKE = 1;
+
+ /**
+ * Computer display has stand by.
+ */
+ public static final int EVENT_DISPLAY_SLEEP = 2;
+
+ /**
+ * Computer display wakes up after stand by.
+ */
+ public static final int EVENT_DISPLAY_WAKE = 3;
+
+ /**
+ * Screensaver has been started.
+ */
+ public static final int EVENT_SCREENSAVER_START = 4;
+
+ /**
+ * Screensaver will stop.
+ */
+ public static final int EVENT_SCREENSAVER_WILL_STOP = 5;
+
+ /**
+ * Screensaver has been stopped.
+ */
+ public static final int EVENT_SCREENSAVER_STOP = 6;
+
+ /**
+ * Screen has been locked.
+ */
+ public static final int EVENT_SCREEN_LOCKED = 7;
+
+ /**
+ * Screen has been unlocked.
+ */
+ public static final int EVENT_SCREEN_UNLOCKED = 8;
+
+ /**
+ * A change in network configuration has occurred.
+ */
+ public static final int EVENT_NETWORK_CHANGE = 9;
+
+ /**
+ * A system idle event has occurred.
+ */
+ public static final int EVENT_SYSTEM_IDLE = 10;
+
+ /**
+ * A system was in idle state and now exits.
+ */
+ public static final int EVENT_SYSTEM_IDLE_END = 11;
+
+ /**
+ * A change in dns configuration has occurred.
+ */
+ public static final int EVENT_DNS_CHANGE = 12;
+
+ /**
+ * Informing that the machine is logging of or shutting down.
+ */
+ public static final int EVENT_QUERY_ENDSESSION = 13;
+
+ /**
+ * The log off or shutdown is in process for us, no matter
+ * what other process has replied, whether one of them has canceled
+ * or not the current end of session. It's like that cause we have answered
+ * that we will shutdown.
+ */
+ public static final int EVENT_ENDSESSION = 14;
+
+ /**
+ * The type of the event.
+ */
+ private final int eventID;
+
+ /**
+ * Constructs a prototypical Event.
+ *
+ * @param source The object on which the Event initially occurred.
+ * @param eventID the type of the event.
+ * @throws IllegalArgumentException if source is null.
+ */
+ public SystemActivityEvent(Object source, int eventID)
+ {
+ super(source);
+
+ this.eventID = eventID;
+ }
+
+ /**
+ * Returns the type of the event.
+ * @return the event ID
+ */
+ public int getEventID()
+ {
+ return this.eventID;
+ }
+
+ /**
+ * Returns a String representation of this SystemActivityEvent object.
+ *
+ * @return A a String representation of this SystemActivityEvent object.
+ */
+ @Override
+ public String toString() {
+ return getClass().getName() + "[eventID=" + eventID + "]";
+ }
+}
diff --git a/src/net/java/sip/communicator/service/systray/AbstractSystrayService.java b/src/net/java/sip/communicator/service/systray/AbstractSystrayService.java
index 6b4c430..60114f9 100644
--- a/src/net/java/sip/communicator/service/systray/AbstractSystrayService.java
+++ b/src/net/java/sip/communicator/service/systray/AbstractSystrayService.java
@@ -128,6 +128,15 @@ public abstract class AbstractSystrayService
}
/**
+ * Stub method that does nothing.
+ * @param count ignored
+ */
+ @Override
+ public void setNotificationCount(int count)
+ {
+ }
+
+ /**
* Implements the <tt>SystrayService.addPopupMessageListener</tt> method.
* If <tt>activePopupHandler</tt> is still not available record the listener
* so we can add him later.
diff --git a/src/net/java/sip/communicator/service/systray/SystrayService.java b/src/net/java/sip/communicator/service/systray/SystrayService.java
index b9ada84..9d88852 100644
--- a/src/net/java/sip/communicator/service/systray/SystrayService.java
+++ b/src/net/java/sip/communicator/service/systray/SystrayService.java
@@ -17,6 +17,8 @@
*/
package net.java.sip.communicator.service.systray;
+import java.util.*;
+
import net.java.sip.communicator.service.systray.event.*;
/**
@@ -27,6 +29,9 @@ import net.java.sip.communicator.service.systray.event.*;
*/
public interface SystrayService
{
+ public static final String PNMAE_TRAY_MODE =
+ "net.java.sip.communicator.osdependent.systemtray.MODE";
+
/**
* Message type corresponding to an error message.
*/
@@ -78,11 +83,6 @@ public interface SystrayService
public static final int SC_IMG_EXTENDED_AWAY_TYPE = 6;
/**
- * Image type corresponding to the envelope icon
- */
- public static final int ENVELOPE_IMG_TYPE = 1;
-
- /**
* Shows the given <tt>PopupMessage</tt>
*
* @param popupMessage the message to show
@@ -129,4 +129,31 @@ public interface SystrayService
* Selects the best available popup message handler
*/
public void selectBestPopupMessageHandler();
+
+ /**
+ * Checks if the systray icon has been initialized.
+ * @return True if the systray is initialized, false otherwise.
+ */
+ public boolean checkInitialized();
+
+ /**
+ * Set the number that should be shown as an overlay on the try icon.
+ * @param count The number of pending notifications.
+ */
+ public void setNotificationCount(int count);
+
+ /**
+ * Gets a map of systray modes and resource-keys that describe them.
+ * @return key: mode for config property, value: resource key
+ */
+ public Map<String, String> getSystrayModes();
+
+ /**
+ * Gets the systray mode that was chosen at startup, either by default or as
+ * an override selected by the user.
+ *
+ * @return The selected mode or {@code disabled} if the user selected mode
+ * is not available.
+ */
+ public String getActiveSystrayMode();
}
diff --git a/src/net/java/sip/communicator/util/ConfigurationUtils.java b/src/net/java/sip/communicator/util/ConfigurationUtils.java
index 05e4f09..d24426d 100644
--- a/src/net/java/sip/communicator/util/ConfigurationUtils.java
+++ b/src/net/java/sip/communicator/util/ConfigurationUtils.java
@@ -92,6 +92,11 @@ public class ConfigurationUtils
private static boolean isQuitWarningShown = true;
/**
+ * Indicates if the main frame should be minimized instead of hidden.
+ */
+ private static boolean minimizeInsteadOfHide = false;
+
+ /**
* Indicates if typing notifications should be sent.
*/
private static boolean isSendTypingNotifications;
@@ -433,17 +438,9 @@ public class ConfigurationUtils
autoPopupNewMessage = true;
// Load the "sendMessageCommand" property.
- String messageCommandProperty
- = "service.gui.SEND_MESSAGE_COMMAND";
- String messageCommand = configService.getString(messageCommandProperty);
-
- if(messageCommand == null)
- messageCommand
- = UtilActivator.getResources()
- .getSettingsString(messageCommandProperty);
-
- if(messageCommand == null || messageCommand.length() == 0)
- sendMessageCommand = messageCommand;
+ String messageCommandProperty = "service.gui.SEND_MESSAGE_COMMAND";
+ sendMessageCommand = UtilActivator.getResources()
+ .getSettingsString(messageCommandProperty);
// Load the showCallPanel property.
String callPanelShown = configService.getString(
@@ -479,6 +476,10 @@ public class ConfigurationUtils
= Boolean.parseBoolean(quitWarningShown);
}
+ minimizeInsteadOfHide = configService.getBoolean(
+ "net.java.sip.communicator.impl.gui.minimizeInsteadOfHide",
+ isPinnedToTaskBar());
+
// Load the "sendTypingNotifications" property.
String isSendTypingNotifProperty =
"service.gui.SEND_TYPING_NOTIFICATIONS_ENABLED";
@@ -964,6 +965,37 @@ public class ConfigurationUtils
);
}
+ private static boolean isPinnedToTaskBar()
+ {
+ if (!OSUtils.IS_WINDOWS)
+ {
+ return false;
+ }
+
+ File taskbar = new File(System.getenv("appdata"),
+ "Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\TaskBar");
+ File[] pins = taskbar.listFiles(new FileFilter()
+ {
+ @Override
+ public boolean accept(File f)
+ {
+ return f.getName().endsWith(".lnk");
+ }
+ });
+
+ String title = UtilActivator.getResources()
+ .getSettingsString("service.gui.APPLICATION_NAME");
+ for (File pin : pins)
+ {
+ if (pin.getName().contains(title))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
/**
* Checks whether font support is disabled, checking in default
* settings for the default value.
@@ -1055,6 +1087,30 @@ public class ConfigurationUtils
}
/**
+ * Gets whether the application should be minimized and not hidden when
+ * clicking close on the main frame.
+ * @return <tt>true</tt> when the main frame should be minimized,
+ * <tt>false</tt> otherwise
+ */
+ public static boolean isMinimizeInsteadOfHide()
+ {
+ return minimizeInsteadOfHide;
+ }
+
+ /**
+ * Sets whether the application should be minimized and not hidden when
+ * clicking close on the main frame.
+ * @param value <tt>true</tt> when the main frame should be minimized,
+ * <tt>false</tt> otherwise
+ */
+ public static void setIsMinimizeInsteadOfHide(boolean value)
+ {
+ minimizeInsteadOfHide = value;
+ configService.setProperty(
+ "net.java.sip.communicator.impl.gui.minimizeInsteadOfHide", value);
+ }
+
+ /**
* Return TRUE if "quitWarningShown" property is true, otherwise -
* return FALSE. Indicates to the user interface whether the quit warning
* dialog should be shown when user clicks on the X button.
diff --git a/src/net/java/sip/communicator/util/GenericBuffer.java b/src/net/java/sip/communicator/util/GenericBuffer.java
index 756d22f..3647174 100644
--- a/src/net/java/sip/communicator/util/GenericBuffer.java
+++ b/src/net/java/sip/communicator/util/GenericBuffer.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,117 +15,117 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.util;
-
-import java.util.*;
-
-/**
- * The GenericBuffer class provides a way to minimize the effort needed to
- * buffer any kind of information. This class is particularly suited to
- * optimizations based on reusing already computed data.
- *
- * @author Benoit Pradelle
- */
-public class GenericBuffer<T>
-{
- private final Hashtable<String, GenericBufferPair> buffer;
-
- private int minAge = 0;
-
- private int curAge = 0;
-
- private final int maxCapacity;
-
- /**
- * Sole constructor.
- *
- * @param bufferSize The buffer size. Adding data to a full buffer will
- * cause the oldest data present in the buffer to be overwritten;
- */
- public GenericBuffer(final int bufferSize)
- {
- assert bufferSize > 0;
-
- buffer = new Hashtable<String, GenericBufferPair>(bufferSize);
- maxCapacity = bufferSize;
- }
-
- /**
- * Adds a value to the buffer. If the buffer is full, the oldest value in
- * the buffer will be overwritten by this new value.
- *
- * @param value The value to add. Can't be null.
- * @param context The context for which this value is valid. This basically
- * represents the current value of all the variables which
- * control the value is correct. The context is used to find this
- * value in the buffer. If the context is already associated in
- * the buffer with a value, nothing is added nor modified.
- */
- public void addValue(final T value, final String context)
- {
- assert value != null && context != null;
-
- GenericBufferPair storage = buffer.get(context);
-
- if (storage == null)
- {
- storage = new GenericBufferPair();
- }
- else
- {
- return; // don't override values
- }
-
- // if the amount of data has reach the limit, search the oldest data
- if (buffer.size() == maxCapacity)
- {
- for (Map.Entry<String, GenericBufferPair> e : buffer.entrySet())
- {
- if (e.getValue().age == minAge)
- {
- buffer.remove(e.getKey());
- minAge++;
- break;
- }
- }
- }
-
- storage.age = curAge++;
- storage.value = value;
-
- buffer.put(context, storage);
- }
-
- /**
- * Retrieves the value in the buffer corresponding to the context if it
- * exists.
- *
- * @param context The context of the searched value. The context represents
- * all the variables values for which this value is correct.
- * @return The bufferized value with the searched context if it exists or
- * null if no value is found.
- */
- public T getValue(final String context)
- {
- assert context != null;
-
- GenericBufferPair res = buffer.get(context);
-
- if (res == null)
- {
- return null;
- }
-
- return res.value;
- }
-
- /**
- * This class is a simple structure to store a pair context-value
- */
- private class GenericBufferPair
- {
- public T value = null;
-
- public int age = 0;
- }
-}
+package net.java.sip.communicator.util;
+
+import java.util.*;
+
+/**
+ * The GenericBuffer class provides a way to minimize the effort needed to
+ * buffer any kind of information. This class is particularly suited to
+ * optimizations based on reusing already computed data.
+ *
+ * @author Benoit Pradelle
+ */
+public class GenericBuffer<T>
+{
+ private final Hashtable<String, GenericBufferPair> buffer;
+
+ private int minAge = 0;
+
+ private int curAge = 0;
+
+ private final int maxCapacity;
+
+ /**
+ * Sole constructor.
+ *
+ * @param bufferSize The buffer size. Adding data to a full buffer will
+ * cause the oldest data present in the buffer to be overwritten;
+ */
+ public GenericBuffer(final int bufferSize)
+ {
+ assert bufferSize > 0;
+
+ buffer = new Hashtable<String, GenericBufferPair>(bufferSize);
+ maxCapacity = bufferSize;
+ }
+
+ /**
+ * Adds a value to the buffer. If the buffer is full, the oldest value in
+ * the buffer will be overwritten by this new value.
+ *
+ * @param value The value to add. Can't be null.
+ * @param context The context for which this value is valid. This basically
+ * represents the current value of all the variables which
+ * control the value is correct. The context is used to find this
+ * value in the buffer. If the context is already associated in
+ * the buffer with a value, nothing is added nor modified.
+ */
+ public void addValue(final T value, final String context)
+ {
+ assert value != null && context != null;
+
+ GenericBufferPair storage = buffer.get(context);
+
+ if (storage == null)
+ {
+ storage = new GenericBufferPair();
+ }
+ else
+ {
+ return; // don't override values
+ }
+
+ // if the amount of data has reach the limit, search the oldest data
+ if (buffer.size() == maxCapacity)
+ {
+ for (Map.Entry<String, GenericBufferPair> e : buffer.entrySet())
+ {
+ if (e.getValue().age == minAge)
+ {
+ buffer.remove(e.getKey());
+ minAge++;
+ break;
+ }
+ }
+ }
+
+ storage.age = curAge++;
+ storage.value = value;
+
+ buffer.put(context, storage);
+ }
+
+ /**
+ * Retrieves the value in the buffer corresponding to the context if it
+ * exists.
+ *
+ * @param context The context of the searched value. The context represents
+ * all the variables values for which this value is correct.
+ * @return The bufferized value with the searched context if it exists or
+ * null if no value is found.
+ */
+ public T getValue(final String context)
+ {
+ assert context != null;
+
+ GenericBufferPair res = buffer.get(context);
+
+ if (res == null)
+ {
+ return null;
+ }
+
+ return res.value;
+ }
+
+ /**
+ * This class is a simple structure to store a pair context-value
+ */
+ private class GenericBufferPair
+ {
+ public T value = null;
+
+ public int age = 0;
+ }
+}
diff --git a/src/net/java/sip/communicator/util/JitsiDnsNameService.java b/src/net/java/sip/communicator/util/JitsiDnsNameService.java
new file mode 100644
index 0000000..cf68ad5
--- /dev/null
+++ b/src/net/java/sip/communicator/util/JitsiDnsNameService.java
@@ -0,0 +1,151 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2016 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.util;
+
+import java.lang.reflect.Method;
+import java.net.*;
+
+import org.xbill.DNS.*;
+
+import sun.net.spi.nameservice.*;
+
+/**
+ * JNDI DNS service to send DNS lookup through the dnsjava <tt>Lookup</tt>
+ * infrastructure. This is needed to catch lookups that are not made
+ * through the DNSSEC-aware <tt>NetworkUtils</tt>.
+ *
+ * @author Ingo Bauersachs
+ */
+public class JitsiDnsNameService
+ implements NameService
+{
+ private static boolean v6first;
+ private static Name localhostName = null;
+ private static InetAddress[] localhostAddresses = null;
+ private static InetAddress[] localhostNamedAddresses = null;
+ private static boolean addressesLoaded = false;
+
+ static
+ {
+ v6first = Boolean.getBoolean("java.net.preferIPv6Addresses");
+ try
+ {
+ // retrieve the name from the system that is used as localhost
+ Class<?> inClass = Class.forName("java.net.InetAddressImplFactory");
+ Method create = inClass.getDeclaredMethod("create");
+ create.setAccessible(true);
+
+ Object impl = create.invoke(null);
+ Class<?> clazz = Class.forName("java.net.InetAddressImpl");
+ Method hostname = clazz.getMethod("getLocalHostName");
+ hostname.setAccessible(true);
+ localhostName = new Name((String) hostname.invoke(impl));
+ Method lookup = clazz.getMethod("lookupAllHostAddr", String.class);
+ lookup.setAccessible(true);
+
+ localhostNamedAddresses = (InetAddress[])lookup.invoke(impl,
+ localhostName.toString());
+ localhostAddresses = (InetAddress[])lookup.invoke(impl,
+ "localhost");
+
+ addressesLoaded = true;
+ }
+ catch (Exception e)
+ {
+ System.err.println("Could not obtain localhost: " + e);
+ }
+ }
+
+ @Override
+ public String getHostByAddr(final byte[] bytes)
+ throws UnknownHostException
+ {
+ InetAddress addr = InetAddress.getByAddress(bytes);
+ if (addr.isLoopbackAddress())
+ {
+ return "localhost";
+ }
+
+ Name name = ReverseMap.fromAddress(addr);
+ Lookup l = new Lookup(name, Type.PTR);
+ Record[] records = l.run();
+ if (records == null)
+ {
+ throw new UnknownHostException();
+ }
+
+ return ((PTRRecord) records[0]).getTarget().toString();
+ }
+
+ @Override
+ public InetAddress[] lookupAllHostAddr(final String host)
+ throws UnknownHostException
+ {
+ Name n;
+ try
+ {
+ n = new Name(host);
+ // Avoid sending queries to a nameserver for localhost
+ // and the machine's hostname. Unless in an enterprise environment
+ // the nameserver wouldn't know about that machine name anyway.
+ if (addressesLoaded)
+ {
+ if (n.equals(localhostName))
+ {
+ return localhostNamedAddresses;
+ }
+ else if (host.equals("localhost"))
+ {
+ return localhostAddresses;
+ }
+ }
+ }
+ catch (TextParseException e)
+ {
+ throw new UnknownHostException(host);
+ }
+
+ Lookup l = new Lookup(n, v6first ? Type.AAAA : Type.A);
+ Record[] r = l.run();
+ if (r == null || r.length == 0)
+ {
+ l = new Lookup(n, v6first ? Type.A : Type.AAAA);
+ r = l.run();
+ }
+
+ if (r == null || r.length == 0)
+ {
+ throw new UnknownHostException(host);
+ }
+
+ InetAddress[] results = new InetAddress[r.length];
+ for (int i = 0; i < r.length; i++)
+ {
+ if (r[i] instanceof AAAARecord)
+ {
+ results[i] = ((AAAARecord) r[i]).getAddress();
+ }
+ else if (r[i] instanceof ARecord)
+ {
+ results[i] = ((ARecord) r[i]).getAddress();
+ }
+ }
+
+ return results;
+ }
+}
diff --git a/src/net/java/sip/communicator/util/JitsiDnsNameServiceDescriptor.java b/src/net/java/sip/communicator/util/JitsiDnsNameServiceDescriptor.java
new file mode 100644
index 0000000..559646a
--- /dev/null
+++ b/src/net/java/sip/communicator/util/JitsiDnsNameServiceDescriptor.java
@@ -0,0 +1,58 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright @ 2016 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.java.sip.communicator.util;
+
+import sun.net.spi.nameservice.*;
+
+/**
+ * A name service descriptor for Jitsi's DNS service. It is instantiated by the
+ * JRE when DNSSEC is enabled in Jitsi's options.
+ *
+ * @author Ingo Bauersachs
+ */
+public class JitsiDnsNameServiceDescriptor
+ implements NameServiceDescriptor
+{
+ /**
+ * Gets and creates an instance of the Jitsi's name service.
+ *
+ * @return an instance of the Jitsi's name service.
+ */
+ public NameService createNameService()
+ {
+ return new JitsiDnsNameService();
+ }
+
+ /**
+ * Gets the type of this name service.
+ * @return the string <tt>dns</tt>
+ */
+ public String getType()
+ {
+ return "dns";
+ }
+
+ /**
+ * Gets the name of this name service.
+ * @return the string <tt>jitsi</tt>
+ */
+ public String getProviderName()
+ {
+ return "jitsi";
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/util/NetworkUtils.java b/src/net/java/sip/communicator/util/NetworkUtils.java
index 5b641b9..2bb4c2b 100644
--- a/src/net/java/sip/communicator/util/NetworkUtils.java
+++ b/src/net/java/sip/communicator/util/NetworkUtils.java
@@ -107,6 +107,14 @@ public class NetworkUtils
*/
private static final Random random = new Random();
+ static
+ {
+ String prefer6 = System.getProperty("java.net.preferIPv6Addresses");
+ String prefer4 = System.getProperty("java.net.preferIPv4Stack");
+ logger.info("java.net.preferIPv6Addresses=" + prefer6);
+ logger.info("java.net.preferIPv4Stack=" + prefer4);
+ }
+
/**
* Determines whether the address is the result of windows auto configuration.
* (i.e. One that is in the 169.254.0.0 network)
@@ -420,6 +428,15 @@ public class NetworkUtils
colonIndex = -1;
int i = 0, j = 0;
+
+ // Can be wrapped in []
+ if (addrBuff[i] == '[')
+ {
+ ++i;
+ if (scopeID == -1)
+ --srcb_length;
+ }
+
// Starting : mean we need to have at least one more.
if (addrBuff[i] == ':')
if (addrBuff[++i] != ':')
@@ -752,30 +769,38 @@ public class NetworkUtils
return null;
}
- String[][] recVals = new String[records.length][4];
+ List<String[]> recVals = new ArrayList<>(records.length);
for (int i = 0; i < records.length; i++)
{
+ String[] recVal = new String[4];
NAPTRRecord r = (NAPTRRecord)records[i];
// todo - check here for broken records as missing transport
- recVals[i][0] = "" + r.getOrder();
- recVals[i][1] = getProtocolFromNAPTRRecords(r.getService());
+ recVal[0] = "" + r.getOrder();
+ recVal[1] = getProtocolFromNAPTRRecords(r.getService());
+ if (recVal[1] == null)
+ {
+ // we don't understand this NAPTR, maybe it's not for SIP?
+ continue;
+ }
+
String replacement = r.getReplacement().toString();
if (replacement.endsWith("."))
{
- recVals[i][2] =
+ recVal[2] =
replacement.substring(0, replacement.length() - 1);
}
else
{
- recVals[i][2] = replacement;
+ recVal[2] = replacement;
}
- recVals[i][3] = "" + r.getPreference();
+ recVal[3] = "" + r.getPreference();
+ recVals.add(recVal);
}
// sort the SRV RRs by RR value (lower is preferred)
- Arrays.sort(recVals, new Comparator<String[]>()
+ Collections.sort(recVals, new Comparator<String[]>()
{
// Sorts NAPTR records by ORDER (low number first), PREFERENCE (low
// number first) and PROTOCOL (0-TLS, 1-TCP, 2-UDP).
@@ -806,10 +831,12 @@ public class NetworkUtils
}
});
+ String[][] arrayResult = new String[recVals.size()][4];
+ arrayResult = recVals.toArray(arrayResult);
if(logger.isTraceEnabled())
logger.trace("NAPTRs for " + domain + "="
- + Arrays.toString(recVals));
- return recVals;
+ + Arrays.toString(arrayResult));
+ return arrayResult;
}
/**
diff --git a/src/net/java/sip/communicator/util/ScLogFormatter.java b/src/net/java/sip/communicator/util/ScLogFormatter.java
index ad2129b..5d22db5 100644
--- a/src/net/java/sip/communicator/util/ScLogFormatter.java
+++ b/src/net/java/sip/communicator/util/ScLogFormatter.java
@@ -33,11 +33,53 @@ import java.util.logging.*;
public class ScLogFormatter
extends java.util.logging.Formatter
{
+
+ /**
+ * Program name logging property name
+ */
+ private static final String PROGRAM_NAME_PROPERTY = ".programname";
+
+ /**
+ * Disable timestamp logging property name.
+ */
+ private static final String DISABLE_TIMESTAMP_PROPERTY
+ = ".disableTimestamp";
+
+ /**
+ * Line separator used by current platform
+ */
private static String lineSeparator = System.getProperty("line.separator");
+
+ /**
+ * Two digit <tt>DecimalFormat</tt> instance, used to format datetime
+ */
private static DecimalFormat twoDigFmt = new DecimalFormat("00");
+
+ /**
+ * Three digit <tt>DecimalFormat</tt> instance, used to format datetime
+ */
private static DecimalFormat threeDigFmt = new DecimalFormat("000");
/**
+ * The application name used to generate this log
+ */
+ private static String programName;
+
+ /**
+ * Whether logger will add date to the logs, enabled by default.
+ */
+ private static boolean timestampDisabled = false;
+
+ /**
+ * The default constructor for <tt>ScLogFormatter</tt> which loads
+ * program name property from logging.properties file, if it exists
+ */
+ public ScLogFormatter()
+ {
+ loadConfigProperties();
+ }
+
+ /**
* Format the given LogRecord.
* @param record the log record to be formatted.
* @return a formatted log record
@@ -46,24 +88,36 @@ public class ScLogFormatter
public synchronized String format(LogRecord record)
{
StringBuffer sb = new StringBuffer();
+
+
+ if (programName != null)
+ {
+ // Program name
+ sb.append(programName);
+
+ sb.append(' ');
+ }
- //current time
- Calendar cal = Calendar.getInstance();
- int year = cal.get(Calendar.YEAR);
- int month = cal.get(Calendar.MONTH) + 1;
- int day = cal.get(Calendar.DAY_OF_MONTH);
- int hour = cal.get(Calendar.HOUR_OF_DAY);
- int minutes = cal.get(Calendar.MINUTE);
- int seconds = cal.get(Calendar.SECOND);
- int millis = cal.get(Calendar.MILLISECOND);
-
- sb.append(year).append('-');
- sb.append(twoDigFmt.format(month)).append('-');
- sb.append(twoDigFmt.format(day)).append(' ');
- sb.append(twoDigFmt.format(hour)).append(':');
- sb.append(twoDigFmt.format(minutes)).append(':');
- sb.append(twoDigFmt.format(seconds)).append('.');
- sb.append(threeDigFmt.format(millis)).append(' ');
+ if(!timestampDisabled)
+ {
+ //current time
+ Calendar cal = Calendar.getInstance();
+ int year = cal.get(Calendar.YEAR);
+ int month = cal.get(Calendar.MONTH) + 1;
+ int day = cal.get(Calendar.DAY_OF_MONTH);
+ int hour = cal.get(Calendar.HOUR_OF_DAY);
+ int minutes = cal.get(Calendar.MINUTE);
+ int seconds = cal.get(Calendar.SECOND);
+ int millis = cal.get(Calendar.MILLISECOND);
+
+ sb.append(year).append('-');
+ sb.append(twoDigFmt.format(month)).append('-');
+ sb.append(twoDigFmt.format(day)).append(' ');
+ sb.append(twoDigFmt.format(hour)).append(':');
+ sb.append(twoDigFmt.format(minutes)).append(':');
+ sb.append(twoDigFmt.format(seconds)).append('.');
+ sb.append(threeDigFmt.format(millis)).append(' ');
+ }
//log level
sb.append(record.getLevel().getLocalizedName());
@@ -146,7 +200,8 @@ public class ScLogFormatter
}
ix++;
}
- // Now search for the first frame before the SIP Communicator Logger class.
+ // Now search for the first frame
+ // before the SIP Communicator Logger class.
while (ix < stack.length)
{
StackTraceElement frame = stack[ix];
@@ -164,4 +219,36 @@ public class ScLogFormatter
return lineNumber;
}
+
+ /**
+ * Loads all config properties.
+ */
+ private void loadConfigProperties()
+ {
+ loadProgramNameProperty();
+ loadTimestampDisabledProperty();
+ }
+
+ /**
+ * Checks and loads timestamp disabled property if any.
+ */
+ private static void loadTimestampDisabledProperty()
+ {
+ LogManager manager = LogManager.getLogManager();
+ String cname = ScLogFormatter.class.getName();
+ timestampDisabled = Boolean.parseBoolean(
+ manager.getProperty(cname + DISABLE_TIMESTAMP_PROPERTY));
+ }
+
+ /**
+ * Load the programname property to be used in logs to identify Jitsi-based
+ * application which produced the logs
+ */
+ private static void loadProgramNameProperty()
+ {
+ LogManager manager = LogManager.getLogManager();
+ String cname = ScLogFormatter.class.getName();
+ programName = manager.getProperty(cname + PROGRAM_NAME_PROPERTY);
+ }
+
}
diff --git a/src/net/java/sip/communicator/util/UtilActivator.java b/src/net/java/sip/communicator/util/UtilActivator.java
index c2ee299..6dff186 100644
--- a/src/net/java/sip/communicator/util/UtilActivator.java
+++ b/src/net/java/sip/communicator/util/UtilActivator.java
@@ -22,6 +22,7 @@ import java.util.*;
import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.resources.*;
+import net.java.sip.communicator.service.systray.*;
import org.jitsi.service.configuration.*;
import org.jitsi.service.fileaccess.*;
@@ -65,6 +66,8 @@ public class UtilActivator
private static AlertUIService alertUIService;
+ private static SystrayService systrayService;
+
/**
* Calls <tt>Thread.setUncaughtExceptionHandler()</tt>
*
@@ -184,6 +187,21 @@ public class UtilActivator
}
/**
+ * Gets the <tt>SystrayService</tt> instance registered in the
+ * <tt>BundleContext</tt> of the <tt>UtilActivator</tt>.
+ *
+ * @return the <tt>SystrayService</tt> instance registered in the
+ * <tt>BundleContext</tt> of the <tt>UtilActivator</tt>
+ */
+ public static SystrayService getSystrayService()
+ {
+ if (systrayService == null)
+ systrayService =
+ ServiceUtils.getService(bundleContext, SystrayService.class);
+ return systrayService;
+ }
+
+ /**
* Returns the <tt>FileAccessService</tt> obtained from the bundle context.
*
* @return the <tt>FileAccessService</tt> obtained from the bundle context
diff --git a/src/net/java/sip/communicator/util/account/AccountStatusUtils.java b/src/net/java/sip/communicator/util/account/AccountStatusUtils.java
index 583fb0a..e5152b4 100644
--- a/src/net/java/sip/communicator/util/account/AccountStatusUtils.java
+++ b/src/net/java/sip/communicator/util/account/AccountStatusUtils.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,196 +15,196 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.util.account;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.globalstatus.*;
-import net.java.sip.communicator.util.*;
-
-import java.util.*;
-
-/**
- * The <tt>AccountStatusUtils</tt> provides utility methods for account status
- * management.
- *
- * @author Yana Stamcheva
- */
-public class AccountStatusUtils
-{
- private static GlobalStatusService globalStatusService;
-
- /**
- * If the protocol provider supports presence operation set searches the
- * last status which was selected, otherwise returns null.
- *
- * @param protocolProvider the protocol provider we're interested in.
- * @return the last protocol provider presence status, or null if this
- * provider doesn't support presence operation set
- */
- public static Object getProtocolProviderLastStatus(
- ProtocolProviderService protocolProvider)
- {
- if(getProtocolPresenceOpSet(protocolProvider) != null)
- return getLastPresenceStatus(protocolProvider);
- else
- return getGlobalStatusService()
- .getLastStatusString(protocolProvider);
- }
-
- /**
- * Returns the presence operation set for the given protocol provider.
- *
- * @param protocolProvider The protocol provider for which the
- * presence operation set is searched.
- * @return the presence operation set for the given protocol provider.
- */
- public static OperationSetPresence getProtocolPresenceOpSet(
- ProtocolProviderService protocolProvider)
- {
- OperationSet opSet
- = protocolProvider.getOperationSet(OperationSetPresence.class);
-
- return
- (opSet instanceof OperationSetPresence)
- ? (OperationSetPresence) opSet
- : null;
- }
-
- /**
- * Returns the last status that was stored in the configuration xml for the
- * given protocol provider.
- *
- * @param protocolProvider the protocol provider
- * @return the last status that was stored in the configuration xml for the
- * given protocol provider
- */
- public static PresenceStatus getLastPresenceStatus(
- ProtocolProviderService protocolProvider)
- {
- if (getGlobalStatusService() != null)
- return getGlobalStatusService().getLastPresenceStatus(
- protocolProvider);
-
- return null;
- }
-
- /**
- * Returns the current status for protocol provider.
- *
- * @param protocolProvider the protocol provider
- * @return the current status for protocol provider
- */
- public static PresenceStatus getPresenceStatus(
- ProtocolProviderService protocolProvider)
- {
- PresenceStatus status = null;
-
- OperationSetPresence opSet
- = protocolProvider.getOperationSet(OperationSetPresence.class);
-
- if(opSet != null)
- status = opSet.getPresenceStatus();
-
- return status;
- }
-
- /**
- * Returns the online status of provider.
- * @param protocolProvider the protocol provider
- * @return the online status of provider.
- */
- public static PresenceStatus getOnlineStatus(
- ProtocolProviderService protocolProvider)
- {
- PresenceStatus onlineStatus = null;
-
- OperationSetPresence presence
- = protocolProvider.getOperationSet(OperationSetPresence.class);
-
- // presence can be not supported
- if(presence != null)
- {
- Iterator<PresenceStatus> statusIterator
- = presence.getSupportedStatusSet();
- while (statusIterator.hasNext())
- {
- PresenceStatus status = statusIterator.next();
- int connectivity = status.getStatus();
-
- if ((onlineStatus != null
- && (onlineStatus.getStatus() < connectivity))
- || (onlineStatus == null
- && (connectivity > 50 && connectivity < 80)))
- {
- onlineStatus = status;
- }
- }
- }
-
- return onlineStatus;
- }
-
- /**
- * Returns the offline status of provider.
- * @param protocolProvider the protocol provider
- * @return the offline status of provider.
- */
- public static PresenceStatus getOfflineStatus(
- ProtocolProviderService protocolProvider)
- {
- PresenceStatus offlineStatus = null;
-
- OperationSetPresence presence
- = protocolProvider.getOperationSet(OperationSetPresence.class);
-
- // presence can be not supported
- if(presence != null)
- {
- Iterator<PresenceStatus> statusIterator
- = presence.getSupportedStatusSet();
- while (statusIterator.hasNext())
- {
- PresenceStatus status = statusIterator.next();
- int connectivity = status.getStatus();
-
- if (connectivity < 1)
- {
- offlineStatus = status;
- }
- }
- }
-
- return offlineStatus;
- }
-
- /**
- * Returns the last contact status saved in the configuration.
- *
- * @param protocolProvider the protocol provider to which the status
- * corresponds
- * @return the last contact status saved in the configuration.
- */
- public String getLastStatusString(ProtocolProviderService protocolProvider)
- {
- return getGlobalStatusService().getLastStatusString(protocolProvider);
- }
-
- /**
- * Returns the <tt>GlobalStatusService</tt> obtained from the bundle
- * context.
- * @return the <tt>GlobalStatusService</tt> obtained from the bundle
- * context
- */
- public static GlobalStatusService getGlobalStatusService()
- {
- if (globalStatusService == null)
- {
- globalStatusService
- = ServiceUtils.getService(
- UtilActivator.bundleContext,
- GlobalStatusService.class);
- }
-
- return globalStatusService;
- }
+package net.java.sip.communicator.util.account;
+
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.globalstatus.*;
+import net.java.sip.communicator.util.*;
+
+import java.util.*;
+
+/**
+ * The <tt>AccountStatusUtils</tt> provides utility methods for account status
+ * management.
+ *
+ * @author Yana Stamcheva
+ */
+public class AccountStatusUtils
+{
+ private static GlobalStatusService globalStatusService;
+
+ /**
+ * If the protocol provider supports presence operation set searches the
+ * last status which was selected, otherwise returns null.
+ *
+ * @param protocolProvider the protocol provider we're interested in.
+ * @return the last protocol provider presence status, or null if this
+ * provider doesn't support presence operation set
+ */
+ public static Object getProtocolProviderLastStatus(
+ ProtocolProviderService protocolProvider)
+ {
+ if(getProtocolPresenceOpSet(protocolProvider) != null)
+ return getLastPresenceStatus(protocolProvider);
+ else
+ return getGlobalStatusService()
+ .getLastStatusString(protocolProvider);
+ }
+
+ /**
+ * Returns the presence operation set for the given protocol provider.
+ *
+ * @param protocolProvider The protocol provider for which the
+ * presence operation set is searched.
+ * @return the presence operation set for the given protocol provider.
+ */
+ public static OperationSetPresence getProtocolPresenceOpSet(
+ ProtocolProviderService protocolProvider)
+ {
+ OperationSet opSet
+ = protocolProvider.getOperationSet(OperationSetPresence.class);
+
+ return
+ (opSet instanceof OperationSetPresence)
+ ? (OperationSetPresence) opSet
+ : null;
+ }
+
+ /**
+ * Returns the last status that was stored in the configuration xml for the
+ * given protocol provider.
+ *
+ * @param protocolProvider the protocol provider
+ * @return the last status that was stored in the configuration xml for the
+ * given protocol provider
+ */
+ public static PresenceStatus getLastPresenceStatus(
+ ProtocolProviderService protocolProvider)
+ {
+ if (getGlobalStatusService() != null)
+ return getGlobalStatusService().getLastPresenceStatus(
+ protocolProvider);
+
+ return null;
+ }
+
+ /**
+ * Returns the current status for protocol provider.
+ *
+ * @param protocolProvider the protocol provider
+ * @return the current status for protocol provider
+ */
+ public static PresenceStatus getPresenceStatus(
+ ProtocolProviderService protocolProvider)
+ {
+ PresenceStatus status = null;
+
+ OperationSetPresence opSet
+ = protocolProvider.getOperationSet(OperationSetPresence.class);
+
+ if(opSet != null)
+ status = opSet.getPresenceStatus();
+
+ return status;
+ }
+
+ /**
+ * Returns the online status of provider.
+ * @param protocolProvider the protocol provider
+ * @return the online status of provider.
+ */
+ public static PresenceStatus getOnlineStatus(
+ ProtocolProviderService protocolProvider)
+ {
+ PresenceStatus onlineStatus = null;
+
+ OperationSetPresence presence
+ = protocolProvider.getOperationSet(OperationSetPresence.class);
+
+ // presence can be not supported
+ if(presence != null)
+ {
+ Iterator<PresenceStatus> statusIterator
+ = presence.getSupportedStatusSet();
+ while (statusIterator.hasNext())
+ {
+ PresenceStatus status = statusIterator.next();
+ int connectivity = status.getStatus();
+
+ if ((onlineStatus != null
+ && (onlineStatus.getStatus() < connectivity))
+ || (onlineStatus == null
+ && (connectivity > 50 && connectivity < 80)))
+ {
+ onlineStatus = status;
+ }
+ }
+ }
+
+ return onlineStatus;
+ }
+
+ /**
+ * Returns the offline status of provider.
+ * @param protocolProvider the protocol provider
+ * @return the offline status of provider.
+ */
+ public static PresenceStatus getOfflineStatus(
+ ProtocolProviderService protocolProvider)
+ {
+ PresenceStatus offlineStatus = null;
+
+ OperationSetPresence presence
+ = protocolProvider.getOperationSet(OperationSetPresence.class);
+
+ // presence can be not supported
+ if(presence != null)
+ {
+ Iterator<PresenceStatus> statusIterator
+ = presence.getSupportedStatusSet();
+ while (statusIterator.hasNext())
+ {
+ PresenceStatus status = statusIterator.next();
+ int connectivity = status.getStatus();
+
+ if (connectivity < 1)
+ {
+ offlineStatus = status;
+ }
+ }
+ }
+
+ return offlineStatus;
+ }
+
+ /**
+ * Returns the last contact status saved in the configuration.
+ *
+ * @param protocolProvider the protocol provider to which the status
+ * corresponds
+ * @return the last contact status saved in the configuration.
+ */
+ public String getLastStatusString(ProtocolProviderService protocolProvider)
+ {
+ return getGlobalStatusService().getLastStatusString(protocolProvider);
+ }
+
+ /**
+ * Returns the <tt>GlobalStatusService</tt> obtained from the bundle
+ * context.
+ * @return the <tt>GlobalStatusService</tt> obtained from the bundle
+ * context
+ */
+ public static GlobalStatusService getGlobalStatusService()
+ {
+ if (globalStatusService == null)
+ {
+ globalStatusService
+ = ServiceUtils.getService(
+ UtilActivator.bundleContext,
+ GlobalStatusService.class);
+ }
+
+ return globalStatusService;
+ }
}
diff --git a/src/net/java/sip/communicator/util/account/AccountUtils.java b/src/net/java/sip/communicator/util/account/AccountUtils.java
index ec69aca..82c9108 100644
--- a/src/net/java/sip/communicator/util/account/AccountUtils.java
+++ b/src/net/java/sip/communicator/util/account/AccountUtils.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,305 +15,305 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.util.account;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * The <tt>AccountUtils</tt> provides utility methods helping us to easily
- * obtain an account or a groups of accounts or protocol providers by some
- * specific criteria.
- *
- * @author Yana Stamcheva
- */
-public class AccountUtils
-{
- /**
- * The logger.
- */
- private static Logger logger = Logger.getLogger(AccountUtils.class);
-
- /**
- * Returns an iterator over a list of all stored <tt>AccountID</tt>-s.
- *
- * @return an iterator over a list of all stored <tt>AccountID</tt>-s
- */
- public static Collection<AccountID> getStoredAccounts()
- {
- AccountManager accountManager
- = ServiceUtils.getService( UtilActivator.bundleContext,
- AccountManager.class);
-
- return accountManager.getStoredAccounts();
- }
-
- /**
- * Return the <tt>AccountID</tt> corresponding to the given string account
- * identifier.
- *
- * @param accountID the account identifier string
- * @return the <tt>AccountID</tt> corresponding to the given string account
- * identifier
- */
- public static AccountID getAccountForID(String accountID)
- {
- Collection<AccountID> allAccounts = getStoredAccounts();
-
- for(AccountID account : allAccounts)
- {
- if(account.getAccountUniqueID().equals(accountID))
- return account;
- }
- return null;
- }
-
- /**
- * Returns a list of all currently registered providers, which support the
- * given <tt>operationSetClass</tt>.
- *
- * @param opSetClass the operation set class for which we're looking
- * for providers
- * @return a list of all currently registered providers, which support the
- * given <tt>operationSetClass</tt>
- */
- public static List<ProtocolProviderService> getRegisteredProviders(
- Class<? extends OperationSet> opSetClass)
- {
- List<ProtocolProviderService> opSetProviders
- = new LinkedList<ProtocolProviderService>();
-
- for (ProtocolProviderFactory providerFactory
- : UtilActivator.getProtocolProviderFactories().values())
- {
- for (AccountID accountID : providerFactory.getRegisteredAccounts())
- {
- ServiceReference<ProtocolProviderService> ref
- = providerFactory.getProviderForAccount(accountID);
-
- if (ref != null)
- {
- ProtocolProviderService protocolProvider
- = UtilActivator.bundleContext.getService(ref);
-
- if ((protocolProvider.getOperationSet(opSetClass) != null)
- && protocolProvider.isRegistered())
- {
- opSetProviders.add(protocolProvider);
- }
- }
- }
- }
- return opSetProviders;
- }
-
-
- /**
- * Returns a list of all currently registered telephony providers for the
- * given protocol name.
- * @param protocolName the protocol name
- * @param opSetClass the operation set class for which we're looking for
- * providers
- * @return a list of all currently registered providers for the given
- * <tt>protocolName</tt> and supporting the given <tt>operationSetClass</tt>
- */
- public static List<ProtocolProviderService> getRegisteredProviders(
- String protocolName,
- Class<? extends OperationSet> opSetClass)
- {
- List<ProtocolProviderService> opSetProviders
- = new LinkedList<ProtocolProviderService>();
- ProtocolProviderFactory providerFactory
- = getProtocolProviderFactory(protocolName);
-
- if (providerFactory != null)
- {
- for (AccountID accountID : providerFactory.getRegisteredAccounts())
- {
- ServiceReference<ProtocolProviderService> ref
- = providerFactory.getProviderForAccount(accountID);
-
- if (ref != null)
- {
- ProtocolProviderService protocolProvider
- = UtilActivator.bundleContext.getService(ref);
-
- if ((protocolProvider.getOperationSet(opSetClass) != null)
- && protocolProvider.isRegistered())
- {
- opSetProviders.add(protocolProvider);
- }
- }
- }
- }
- return opSetProviders;
- }
-
- /**
- * Returns a list of all registered protocol providers that could be used
- * for the operation given by the operation set. Prefers the given preferred
- * protocol provider and preferred protocol name if they're available and
- * registered.
- *
- * @param opSet
- * @param preferredProvider
- * @param preferredProtocolName
- * @return a list of all registered protocol providers that could be used
- * for the operation given by the operation set
- */
- public static List<ProtocolProviderService> getOpSetRegisteredProviders(
- Class<? extends OperationSet> opSet,
- ProtocolProviderService preferredProvider,
- String preferredProtocolName)
- {
- List<ProtocolProviderService> providers
- = new ArrayList<ProtocolProviderService>();
-
- if (preferredProvider != null)
- {
- if (preferredProvider.isRegistered())
- {
- providers.add(preferredProvider);
- }
- // If we have a provider, but it's not registered we try to
- // obtain all registered providers for the same protocol as the
- // given preferred provider.
- else
- {
- providers
- = getRegisteredProviders(
- preferredProvider.getProtocolName(),
- opSet);
- }
- }
- // If we don't have a preferred provider we try to obtain a
- // preferred protocol name and all registered providers for it.
- else
- {
- if (preferredProtocolName != null)
- {
- providers
- = getRegisteredProviders(preferredProtocolName, opSet);
- }
- // If the protocol name is null we simply obtain all telephony
- // providers.
- else
- {
- providers = getRegisteredProviders(opSet);
- }
- }
-
- return providers;
- }
-
- /**
- * Returns the <tt>ProtocolProviderService</tt> corresponding to the given
- * account identifier that is registered in the given factory
- * @param accountID the identifier of the account
- * @return the <tt>ProtocolProviderService</tt> corresponding to the given
- * account identifier that is registered in the given factory
- */
- public static ProtocolProviderService getRegisteredProviderForAccount(
- AccountID accountID)
- {
- for (ProtocolProviderFactory factory
- : UtilActivator.getProtocolProviderFactories().values())
- {
- if (factory.getRegisteredAccounts().contains(accountID))
- {
- ServiceReference<ProtocolProviderService> ref
- = factory.getProviderForAccount(accountID);
-
- if (ref != null)
- {
- return UtilActivator.bundleContext.getService(ref);
- }
- }
- }
- return null;
- }
-
- /**
- * Returns a <tt>ProtocolProviderFactory</tt> for a given protocol
- * provider.
- * @param protocolProvider the <tt>ProtocolProviderService</tt>, which
- * factory we're looking for
- * @return a <tt>ProtocolProviderFactory</tt> for a given protocol
- * provider
- */
- public static ProtocolProviderFactory getProtocolProviderFactory(
- ProtocolProviderService protocolProvider)
- {
- return getProtocolProviderFactory(protocolProvider.getProtocolName());
- }
-
- /**
- * Returns a <tt>ProtocolProviderFactory</tt> for a given protocol
- * provider.
- * @param protocolName the name of the protocol
- * @return a <tt>ProtocolProviderFactory</tt> for a given protocol
- * provider
- */
- public static ProtocolProviderFactory getProtocolProviderFactory(
- String protocolName)
- {
- String osgiFilter
- = "(" + ProtocolProviderFactory.PROTOCOL + "=" + protocolName + ")";
- ProtocolProviderFactory protocolProviderFactory = null;
-
- try
- {
- Collection<ServiceReference<ProtocolProviderFactory>> refs
- = UtilActivator.bundleContext.getServiceReferences(
- ProtocolProviderFactory.class,
- osgiFilter);
-
- if ((refs != null) && !refs.isEmpty())
- {
- protocolProviderFactory
- = UtilActivator.bundleContext.getService(
- refs.iterator().next());
- }
- }
- catch (InvalidSyntaxException ex)
- {
- logger.error("AccountUtils : " + ex);
- }
- return protocolProviderFactory;
- }
-
-
- /**
- * Returns all registered protocol providers.
- *
- * @return a list of all registered providers
- */
- public static Collection<ProtocolProviderService> getRegisteredProviders()
- {
- List<ProtocolProviderService> registeredProviders
- = new LinkedList<ProtocolProviderService>();
-
- for (ProtocolProviderFactory providerFactory
- : UtilActivator.getProtocolProviderFactories().values())
- {
- for (AccountID accountID : providerFactory.getRegisteredAccounts())
- {
- ServiceReference<ProtocolProviderService> ref
- = providerFactory.getProviderForAccount(accountID);
-
- if (ref != null)
- {
- ProtocolProviderService protocolProvider
- = UtilActivator.bundleContext.getService(ref);
-
- registeredProviders.add(protocolProvider);
- }
- }
- }
- return registeredProviders;
- }
-}
+package net.java.sip.communicator.util.account;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * The <tt>AccountUtils</tt> provides utility methods helping us to easily
+ * obtain an account or a groups of accounts or protocol providers by some
+ * specific criteria.
+ *
+ * @author Yana Stamcheva
+ */
+public class AccountUtils
+{
+ /**
+ * The logger.
+ */
+ private static Logger logger = Logger.getLogger(AccountUtils.class);
+
+ /**
+ * Returns an iterator over a list of all stored <tt>AccountID</tt>-s.
+ *
+ * @return an iterator over a list of all stored <tt>AccountID</tt>-s
+ */
+ public static Collection<AccountID> getStoredAccounts()
+ {
+ AccountManager accountManager
+ = ServiceUtils.getService( UtilActivator.bundleContext,
+ AccountManager.class);
+
+ return accountManager.getStoredAccounts();
+ }
+
+ /**
+ * Return the <tt>AccountID</tt> corresponding to the given string account
+ * identifier.
+ *
+ * @param accountID the account identifier string
+ * @return the <tt>AccountID</tt> corresponding to the given string account
+ * identifier
+ */
+ public static AccountID getAccountForID(String accountID)
+ {
+ Collection<AccountID> allAccounts = getStoredAccounts();
+
+ for(AccountID account : allAccounts)
+ {
+ if(account.getAccountUniqueID().equals(accountID))
+ return account;
+ }
+ return null;
+ }
+
+ /**
+ * Returns a list of all currently registered providers, which support the
+ * given <tt>operationSetClass</tt>.
+ *
+ * @param opSetClass the operation set class for which we're looking
+ * for providers
+ * @return a list of all currently registered providers, which support the
+ * given <tt>operationSetClass</tt>
+ */
+ public static List<ProtocolProviderService> getRegisteredProviders(
+ Class<? extends OperationSet> opSetClass)
+ {
+ List<ProtocolProviderService> opSetProviders
+ = new LinkedList<ProtocolProviderService>();
+
+ for (ProtocolProviderFactory providerFactory
+ : UtilActivator.getProtocolProviderFactories().values())
+ {
+ for (AccountID accountID : providerFactory.getRegisteredAccounts())
+ {
+ ServiceReference<ProtocolProviderService> ref
+ = providerFactory.getProviderForAccount(accountID);
+
+ if (ref != null)
+ {
+ ProtocolProviderService protocolProvider
+ = UtilActivator.bundleContext.getService(ref);
+
+ if ((protocolProvider.getOperationSet(opSetClass) != null)
+ && protocolProvider.isRegistered())
+ {
+ opSetProviders.add(protocolProvider);
+ }
+ }
+ }
+ }
+ return opSetProviders;
+ }
+
+
+ /**
+ * Returns a list of all currently registered telephony providers for the
+ * given protocol name.
+ * @param protocolName the protocol name
+ * @param opSetClass the operation set class for which we're looking for
+ * providers
+ * @return a list of all currently registered providers for the given
+ * <tt>protocolName</tt> and supporting the given <tt>operationSetClass</tt>
+ */
+ public static List<ProtocolProviderService> getRegisteredProviders(
+ String protocolName,
+ Class<? extends OperationSet> opSetClass)
+ {
+ List<ProtocolProviderService> opSetProviders
+ = new LinkedList<ProtocolProviderService>();
+ ProtocolProviderFactory providerFactory
+ = getProtocolProviderFactory(protocolName);
+
+ if (providerFactory != null)
+ {
+ for (AccountID accountID : providerFactory.getRegisteredAccounts())
+ {
+ ServiceReference<ProtocolProviderService> ref
+ = providerFactory.getProviderForAccount(accountID);
+
+ if (ref != null)
+ {
+ ProtocolProviderService protocolProvider
+ = UtilActivator.bundleContext.getService(ref);
+
+ if ((protocolProvider.getOperationSet(opSetClass) != null)
+ && protocolProvider.isRegistered())
+ {
+ opSetProviders.add(protocolProvider);
+ }
+ }
+ }
+ }
+ return opSetProviders;
+ }
+
+ /**
+ * Returns a list of all registered protocol providers that could be used
+ * for the operation given by the operation set. Prefers the given preferred
+ * protocol provider and preferred protocol name if they're available and
+ * registered.
+ *
+ * @param opSet
+ * @param preferredProvider
+ * @param preferredProtocolName
+ * @return a list of all registered protocol providers that could be used
+ * for the operation given by the operation set
+ */
+ public static List<ProtocolProviderService> getOpSetRegisteredProviders(
+ Class<? extends OperationSet> opSet,
+ ProtocolProviderService preferredProvider,
+ String preferredProtocolName)
+ {
+ List<ProtocolProviderService> providers
+ = new ArrayList<ProtocolProviderService>();
+
+ if (preferredProvider != null)
+ {
+ if (preferredProvider.isRegistered())
+ {
+ providers.add(preferredProvider);
+ }
+ // If we have a provider, but it's not registered we try to
+ // obtain all registered providers for the same protocol as the
+ // given preferred provider.
+ else
+ {
+ providers
+ = getRegisteredProviders(
+ preferredProvider.getProtocolName(),
+ opSet);
+ }
+ }
+ // If we don't have a preferred provider we try to obtain a
+ // preferred protocol name and all registered providers for it.
+ else
+ {
+ if (preferredProtocolName != null)
+ {
+ providers
+ = getRegisteredProviders(preferredProtocolName, opSet);
+ }
+ // If the protocol name is null we simply obtain all telephony
+ // providers.
+ else
+ {
+ providers = getRegisteredProviders(opSet);
+ }
+ }
+
+ return providers;
+ }
+
+ /**
+ * Returns the <tt>ProtocolProviderService</tt> corresponding to the given
+ * account identifier that is registered in the given factory
+ * @param accountID the identifier of the account
+ * @return the <tt>ProtocolProviderService</tt> corresponding to the given
+ * account identifier that is registered in the given factory
+ */
+ public static ProtocolProviderService getRegisteredProviderForAccount(
+ AccountID accountID)
+ {
+ for (ProtocolProviderFactory factory
+ : UtilActivator.getProtocolProviderFactories().values())
+ {
+ if (factory.getRegisteredAccounts().contains(accountID))
+ {
+ ServiceReference<ProtocolProviderService> ref
+ = factory.getProviderForAccount(accountID);
+
+ if (ref != null)
+ {
+ return UtilActivator.bundleContext.getService(ref);
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns a <tt>ProtocolProviderFactory</tt> for a given protocol
+ * provider.
+ * @param protocolProvider the <tt>ProtocolProviderService</tt>, which
+ * factory we're looking for
+ * @return a <tt>ProtocolProviderFactory</tt> for a given protocol
+ * provider
+ */
+ public static ProtocolProviderFactory getProtocolProviderFactory(
+ ProtocolProviderService protocolProvider)
+ {
+ return getProtocolProviderFactory(protocolProvider.getProtocolName());
+ }
+
+ /**
+ * Returns a <tt>ProtocolProviderFactory</tt> for a given protocol
+ * provider.
+ * @param protocolName the name of the protocol
+ * @return a <tt>ProtocolProviderFactory</tt> for a given protocol
+ * provider
+ */
+ public static ProtocolProviderFactory getProtocolProviderFactory(
+ String protocolName)
+ {
+ String osgiFilter
+ = "(" + ProtocolProviderFactory.PROTOCOL + "=" + protocolName + ")";
+ ProtocolProviderFactory protocolProviderFactory = null;
+
+ try
+ {
+ Collection<ServiceReference<ProtocolProviderFactory>> refs
+ = UtilActivator.bundleContext.getServiceReferences(
+ ProtocolProviderFactory.class,
+ osgiFilter);
+
+ if ((refs != null) && !refs.isEmpty())
+ {
+ protocolProviderFactory
+ = UtilActivator.bundleContext.getService(
+ refs.iterator().next());
+ }
+ }
+ catch (InvalidSyntaxException ex)
+ {
+ logger.error("AccountUtils : " + ex);
+ }
+ return protocolProviderFactory;
+ }
+
+
+ /**
+ * Returns all registered protocol providers.
+ *
+ * @return a list of all registered providers
+ */
+ public static Collection<ProtocolProviderService> getRegisteredProviders()
+ {
+ List<ProtocolProviderService> registeredProviders
+ = new LinkedList<ProtocolProviderService>();
+
+ for (ProtocolProviderFactory providerFactory
+ : UtilActivator.getProtocolProviderFactories().values())
+ {
+ for (AccountID accountID : providerFactory.getRegisteredAccounts())
+ {
+ ServiceReference<ProtocolProviderService> ref
+ = providerFactory.getProviderForAccount(accountID);
+
+ if (ref != null)
+ {
+ ProtocolProviderService protocolProvider
+ = UtilActivator.bundleContext.getService(ref);
+
+ registeredProviders.add(protocolProvider);
+ }
+ }
+ }
+ return registeredProviders;
+ }
+}
diff --git a/src/net/java/sip/communicator/util/account/LoginManager.java b/src/net/java/sip/communicator/util/account/LoginManager.java
index 1dffaf8..09b3092 100644
--- a/src/net/java/sip/communicator/util/account/LoginManager.java
+++ b/src/net/java/sip/communicator/util/account/LoginManager.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,577 +15,577 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.util.account;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.service.protocol.globalstatus.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * The <tt>LoginManager</tt> manages the login operation. Here we obtain the
- * <tt>ProtocolProviderFactory</tt>, we make the account installation and we
- * handle all events related to the registration state.
- * <p>
- * The <tt>LoginManager</tt> is the one that opens one or more
- * <tt>LoginWindow</tt>s for each <tt>ProtocolProviderFactory</tt>. The
- * <tt>LoginWindow</tt> is where user could enter an identifier and password.
- * <p>
- * Note that the behavior of this class will be changed when the Configuration
- * Service is ready.
- *
- * @author Yana Stamcheva
- */
-public class LoginManager
- implements ServiceListener,
- RegistrationStateChangeListener,
- AccountManagerListener
-{
- private static final Logger logger = Logger.getLogger(LoginManager.class);
-
- private boolean manuallyDisconnected = false;
-
- private final LoginRenderer loginRenderer;
-
- /**
- * Creates an instance of the <tt>LoginManager</tt>, by specifying the main
- * application window.
- *
- * @param loginRenderer the main application window
- */
- public LoginManager(LoginRenderer loginRenderer)
- {
- this.loginRenderer = loginRenderer;
-
- UtilActivator.bundleContext.addServiceListener(this);
- }
-
- /**
- * Registers the given protocol provider.
- *
- * @param protocolProvider the ProtocolProviderService to register.
- */
- public void login(ProtocolProviderService protocolProvider)
- {
- loginRenderer.startConnectingUI(protocolProvider);
-
- new RegisterProvider(protocolProvider,
- loginRenderer.getSecurityAuthorityImpl(protocolProvider)).start();
- }
-
- /**
- * Unregisters the given protocol provider.
- *
- * @param protocolProvider the ProtocolProviderService to unregister
- */
- public static void logoff(ProtocolProviderService protocolProvider)
- {
- new UnregisterProvider(protocolProvider).start();
- }
-
- /**
- * Shows login window for each registered account.
- */
- public void runLogin()
- {
- // if someone is late registering catch it
- UtilActivator.getAccountManager().addListener(this);
-
- for (ProtocolProviderFactory providerFactory : UtilActivator
- .getProtocolProviderFactories().values())
- {
- addAccountsForProtocolProviderFactory(providerFactory);
- }
- }
-
- /**
- * Notifies that the loading of the stored accounts of a
- * specific <code>ProtocolProviderFactory</code> has finished.
- *
- * @param event the <code>AccountManagerEvent</code> describing the
- * <code>AccountManager</code> firing the notification and the
- * other details of the specific notification.
- */
- public void handleAccountManagerEvent(AccountManagerEvent event)
- {
- if(event.getType()
- == AccountManagerEvent.STORED_ACCOUNTS_LOADED)
- {
- addAccountsForProtocolProviderFactory(event.getFactory());
- }
- }
-
- /**
- * Handles stored accounts for a protocol provider factory and add them
- * to the UI and register them if needed.
- * @param providerFactory the factory to handle.
- */
- private void addAccountsForProtocolProviderFactory(
- ProtocolProviderFactory providerFactory)
- {
- for (AccountID accountID : providerFactory.getRegisteredAccounts())
- {
- ServiceReference<ProtocolProviderService> serRef
- = providerFactory.getProviderForAccount(accountID);
- ProtocolProviderService protocolProvider
- = UtilActivator.bundleContext.getService(serRef);
-
- handleProviderAdded(protocolProvider);
- }
- }
-
- /**
- * The method is called by a ProtocolProvider implementation whenever a
- * change in the registration state of the corresponding provider had
- * occurred.
- *
- * @param evt ProviderStatusChangeEvent the event describing the status
- * change.
- */
- public void registrationStateChanged(RegistrationStateChangeEvent evt)
- {
- RegistrationState newState = evt.getNewState();
- ProtocolProviderService protocolProvider = evt.getProvider();
- AccountID accountID = protocolProvider.getAccountID();
-
- if (logger.isTraceEnabled())
- logger.trace("Protocol provider: " + protocolProvider
- + " changed its state to: " + evt.getNewState().getStateName());
-
- if (newState.equals(RegistrationState.REGISTERED)
- || newState.equals(RegistrationState.UNREGISTERED)
- || newState.equals(RegistrationState.EXPIRED)
- || newState.equals(RegistrationState.AUTHENTICATION_FAILED)
- || newState.equals(RegistrationState.CONNECTION_FAILED)
- || newState.equals(RegistrationState.CHALLENGED_FOR_AUTHENTICATION)
- || newState.equals(RegistrationState.REGISTERED))
- {
- loginRenderer.stopConnectingUI(protocolProvider);
- }
-
- if (newState.equals(RegistrationState.REGISTERED))
- {
- loginRenderer.protocolProviderConnected(protocolProvider,
- System.currentTimeMillis());
- }
- else
- {
- String msgText;
- if (newState.equals(RegistrationState.AUTHENTICATION_FAILED))
- {
- switch (evt.getReasonCode())
- {
- case RegistrationStateChangeEvent
- .REASON_RECONNECTION_RATE_LIMIT_EXCEEDED:
-
- msgText = UtilActivator.getResources().getI18NString(
- "service.gui.RECONNECTION_LIMIT_EXCEEDED", new String[]
- { accountID.getUserID(), accountID.getService() });
-
- UtilActivator.getAlertUIService().showAlertDialog(
- UtilActivator.getResources()
- .getI18NString("service.gui.ERROR"),
- msgText);
- break;
-
- case RegistrationStateChangeEvent.REASON_NON_EXISTING_USER_ID:
- msgText = UtilActivator.getResources().getI18NString(
- "service.gui.NON_EXISTING_USER_ID",
- new String[]
- { protocolProvider.getProtocolDisplayName() });
-
- UtilActivator.getAlertUIService().showAlertDialog(
- UtilActivator.getResources()
- .getI18NString("service.gui.ERROR"),
- msgText);
- break;
- case RegistrationStateChangeEvent.REASON_TLS_REQUIRED:
- msgText = UtilActivator.getResources().getI18NString(
- "service.gui.NON_SECURE_CONNECTION",
- new String[]
- { accountID.getAccountAddress() });
-
- UtilActivator.getAlertUIService().showAlertDialog(
- UtilActivator.getResources()
- .getI18NString("service.gui.ERROR"),
- msgText);
- break;
- default:
- break;
- }
-
- if (logger.isTraceEnabled())
- logger.trace(evt.getReason());
- }
-// CONNECTION_FAILED events are now dispatched in reconnect plugin
-// else if (newState.equals(RegistrationState.CONNECTION_FAILED))
-// {
-// loginRenderer.protocolProviderConnectionFailed(
-// protocolProvider,
-// this);
-//
-// logger.trace(evt.getReason());
-// }
- else if (newState.equals(RegistrationState.EXPIRED))
- {
- msgText = UtilActivator.getResources().getI18NString(
- "service.gui.CONNECTION_EXPIRED_MSG",
- new String[]
- { protocolProvider.getProtocolDisplayName() });
-
- UtilActivator.getAlertUIService().showAlertDialog(
- UtilActivator.getResources()
- .getI18NString("service.gui.ERROR"),
- msgText);
-
- logger.error(evt.getReason());
- }
- else if (newState.equals(RegistrationState.UNREGISTERED))
- {
- if (!manuallyDisconnected)
- {
- if (evt.getReasonCode() == RegistrationStateChangeEvent
- .REASON_MULTIPLE_LOGINS)
- {
- msgText = UtilActivator.getResources().getI18NString(
- "service.gui.MULTIPLE_LOGINS",
- new String[]
- { accountID.getUserID(), accountID.getService() });
-
- UtilActivator.getAlertUIService().showAlertDialog(
- UtilActivator.getResources()
- .getI18NString("service.gui.ERROR"),
- msgText);
- }
- else if (evt.getReasonCode() == RegistrationStateChangeEvent
- .REASON_CLIENT_LIMIT_REACHED_FOR_IP)
- {
- msgText = UtilActivator.getResources().getI18NString(
- "service.gui.LIMIT_REACHED_FOR_IP", new String[]
- { protocolProvider.getProtocolDisplayName() });
-
- UtilActivator.getAlertUIService().showAlertDialog(
- UtilActivator.getResources()
- .getI18NString("service.gui.ERROR"),
- msgText);
- }
- else if (evt.getReasonCode() == RegistrationStateChangeEvent
- .REASON_USER_REQUEST)
- {
- // do nothing
- }
- else
- {
- msgText = UtilActivator.getResources().getI18NString(
- "service.gui.UNREGISTERED_MESSAGE", new String[]
- { accountID.getUserID(), accountID.getService() });
-
- UtilActivator.getAlertUIService().showAlertDialog(
- UtilActivator.getResources()
- .getI18NString("service.gui.ERROR"),
- msgText);
- }
- if (logger.isTraceEnabled())
- logger.trace(evt.getReason());
- }
- }
- }
- }
-
- /**
- * Implements the <tt>ServiceListener</tt> method. Verifies whether the
- * passed event concerns a <tt>ProtocolProviderService</tt> and adds the
- * corresponding UI controls.
- *
- * @param event The <tt>ServiceEvent</tt> object.
- */
- public void serviceChanged(ServiceEvent event)
- {
- ServiceReference<?> serviceRef = event.getServiceReference();
-
- // if the event is caused by a bundle being stopped, we don't want to
- // know
- if (serviceRef.getBundle().getState() == Bundle.STOPPING)
- return;
-
- Object service = UtilActivator.bundleContext.getService(serviceRef);
-
- // we don't care if the source service is not a protocol provider
- if (!(service instanceof ProtocolProviderService))
- return;
-
- switch (event.getType())
- {
- case ServiceEvent.REGISTERED:
- handleProviderAdded((ProtocolProviderService) service);
- break;
- case ServiceEvent.UNREGISTERING:
- handleProviderRemoved((ProtocolProviderService) service);
- break;
- }
- }
-
- /**
- * Adds all UI components (status selector box, etc) related to the given
- * protocol provider.
- *
- * @param protocolProvider the <tt>ProtocolProviderService</tt>
- */
- private void handleProviderAdded(ProtocolProviderService protocolProvider)
- {
- if (logger.isTraceEnabled())
- logger.trace("The following protocol provider was just added: "
- + protocolProvider.getAccountID().getAccountAddress());
-
- synchronized(loginRenderer)
- {
- if(!loginRenderer.containsProtocolProviderUI(protocolProvider))
- {
- protocolProvider.addRegistrationStateChangeListener(this);
- loginRenderer.addProtocolProviderUI(protocolProvider);
- }
- // we have already added this provider and scheduled
- // a login if needed
- // we've done our work, if it fails or something else
- // reconnect or other plugins will take care
- else
- return;
- }
-
- Object status = AccountStatusUtils
- .getProtocolProviderLastStatus(protocolProvider);
-
- if (status == null
- || status.equals(GlobalStatusEnum.ONLINE_STATUS)
- || ((status instanceof PresenceStatus) && (((PresenceStatus) status)
- .getStatus() >= PresenceStatus.ONLINE_THRESHOLD)))
- {
- login(protocolProvider);
- }
- }
-
- /**
- * Removes all UI components related to the given protocol provider.
- *
- * @param protocolProvider the <tt>ProtocolProviderService</tt>
- */
- private void handleProviderRemoved(ProtocolProviderService protocolProvider)
- {
- loginRenderer.removeProtocolProviderUI(protocolProvider);
- }
-
- /**
- * Returns <tt>true</tt> to indicate the jitsi has been manually
- * disconnected, <tt>false</tt> - otherwise.
- *
- * @return <tt>true</tt> to indicate the jitsi has been manually
- * disconnected, <tt>false</tt> - otherwise
- */
- public boolean isManuallyDisconnected()
- {
- return manuallyDisconnected;
- }
-
- /**
- * Sets the manually disconnected property.
- *
- * @param manuallyDisconnected <tt>true</tt> to indicate the jitsi has been
- * manually disconnected, <tt>false</tt> - otherwise
- */
- public void setManuallyDisconnected(boolean manuallyDisconnected)
- {
- this.manuallyDisconnected = manuallyDisconnected;
- }
-
- /**
- * Registers a protocol provider in a separate thread.
- */
- private class RegisterProvider
- extends Thread
- {
- private final ProtocolProviderService protocolProvider;
-
- private final SecurityAuthority secAuth;
-
- RegisterProvider( ProtocolProviderService protocolProvider,
- SecurityAuthority secAuth)
- {
- this.protocolProvider = protocolProvider;
- this.secAuth = secAuth;
-
- if(logger.isTraceEnabled())
- logger.trace("Registering provider: "
- + protocolProvider.getAccountID().getAccountAddress(),
- new Exception(
- "Just tracing, provider registering, not an error!"));
- }
-
- /**
- * Registers the contained protocol provider and process all possible
- * errors that may occur during the registration process.
- */
- @Override
- public void run()
- {
- try
- {
- protocolProvider.register(secAuth);
- }
- catch (OperationFailedException ex)
- {
- handleOperationFailedException(ex);
- }
- catch (Throwable ex)
- {
- logger.error("Failed to register protocol provider. ", ex);
-
- AccountID accountID = protocolProvider.getAccountID();
- UtilActivator.getAlertUIService().showAlertDialog(
- UtilActivator.getResources()
- .getI18NString("service.gui.ERROR"),
- UtilActivator.getResources()
- .getI18NString("service.gui.LOGIN_GENERAL_ERROR",
- new String[]
- { accountID.getUserID(),
- accountID.getProtocolName(),
- accountID.getService() }));
- }
- }
-
- private void handleOperationFailedException(OperationFailedException ex)
- {
- String errorMessage = "";
-
- switch (ex.getErrorCode())
- {
- case OperationFailedException.GENERAL_ERROR:
- {
- logger.error("Provider could not be registered"
- + " due to the following general error: ", ex);
-
- AccountID accountID = protocolProvider.getAccountID();
- errorMessage =
- UtilActivator.getResources().getI18NString(
- "service.gui.LOGIN_GENERAL_ERROR",
- new String[]
- { accountID.getUserID(),
- accountID.getProtocolName(),
- accountID.getService() });
-
- UtilActivator.getAlertUIService().showAlertDialog(
- UtilActivator.getResources()
- .getI18NString("service.gui.ERROR"), errorMessage, ex);
- }
- break;
- case OperationFailedException.INTERNAL_ERROR:
- {
- logger.error("Provider could not be registered"
- + " due to the following internal error: ", ex);
-
- AccountID accountID = protocolProvider.getAccountID();
- errorMessage =
- UtilActivator.getResources().getI18NString(
- "service.gui.LOGIN_INTERNAL_ERROR",
- new String[]
- { accountID.getUserID(), accountID.getService() });
-
- UtilActivator.getAlertUIService().showAlertDialog(
- UtilActivator.getResources().getI18NString(
- "service.gui.ERROR"), errorMessage, ex);
- }
- break;
- case OperationFailedException.NETWORK_FAILURE:
- {
- if (logger.isInfoEnabled())
- {
- logger.info("Provider could not be registered"
- + " due to a network failure: " + ex);
- }
-
- loginRenderer.protocolProviderConnectionFailed(
- protocolProvider,
- LoginManager.this);
- }
- break;
- case OperationFailedException.INVALID_ACCOUNT_PROPERTIES:
- {
- logger.error("Provider could not be registered"
- + " due to an invalid account property: ", ex);
-
- AccountID accountID = protocolProvider.getAccountID();
- errorMessage =
- UtilActivator.getResources().getI18NString(
- "service.gui.LOGIN_INVALID_PROPERTIES_ERROR",
- new String[]
- { accountID.getUserID(), accountID.getService() });
-
- UtilActivator.getAlertUIService().showAlertDialog(
- UtilActivator.getResources()
- .getI18NString("service.gui.ERROR"),
- errorMessage, ex);
- }
- break;
- default:
- logger.error("Provider could not be registered.", ex);
- }
- }
- }
-
- /**
- * Unregisters a protocol provider in a separate thread.
- */
- private static class UnregisterProvider
- extends Thread
- {
- ProtocolProviderService protocolProvider;
-
- UnregisterProvider(ProtocolProviderService protocolProvider)
- {
- this.protocolProvider = protocolProvider;
- }
-
- /**
- * Unregisters the contained protocol provider and process all possible
- * errors that may occur during the un-registration process.
- */
- @Override
- public void run()
- {
- try
- {
- protocolProvider.unregister(true);
- }
- catch (OperationFailedException ex)
- {
- int errorCode = ex.getErrorCode();
-
- if (errorCode == OperationFailedException.GENERAL_ERROR)
- {
- logger.error("Provider could not be unregistered"
- + " due to the following general error: " + ex);
- }
- else if (errorCode == OperationFailedException.INTERNAL_ERROR)
- {
- logger.error("Provider could not be unregistered"
- + " due to the following internal error: " + ex);
- }
- else if (errorCode == OperationFailedException.NETWORK_FAILURE)
- {
- logger.error("Provider could not be unregistered"
- + " due to a network failure: " + ex);
- }
-
- UtilActivator.getAlertUIService().showAlertDialog(
- UtilActivator.getResources()
- .getI18NString("service.gui.ERROR"),
- UtilActivator.getResources()
- .getI18NString("service.gui.LOGOFF_NOT_SUCCEEDED",
- new String[]
- { protocolProvider.getAccountID().getUserID(),
- protocolProvider.getAccountID().getService() }));
- }
- }
- }
-}
+package net.java.sip.communicator.util.account;
+
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.service.protocol.globalstatus.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * The <tt>LoginManager</tt> manages the login operation. Here we obtain the
+ * <tt>ProtocolProviderFactory</tt>, we make the account installation and we
+ * handle all events related to the registration state.
+ * <p>
+ * The <tt>LoginManager</tt> is the one that opens one or more
+ * <tt>LoginWindow</tt>s for each <tt>ProtocolProviderFactory</tt>. The
+ * <tt>LoginWindow</tt> is where user could enter an identifier and password.
+ * <p>
+ * Note that the behavior of this class will be changed when the Configuration
+ * Service is ready.
+ *
+ * @author Yana Stamcheva
+ */
+public class LoginManager
+ implements ServiceListener,
+ RegistrationStateChangeListener,
+ AccountManagerListener
+{
+ private static final Logger logger = Logger.getLogger(LoginManager.class);
+
+ private boolean manuallyDisconnected = false;
+
+ private final LoginRenderer loginRenderer;
+
+ /**
+ * Creates an instance of the <tt>LoginManager</tt>, by specifying the main
+ * application window.
+ *
+ * @param loginRenderer the main application window
+ */
+ public LoginManager(LoginRenderer loginRenderer)
+ {
+ this.loginRenderer = loginRenderer;
+
+ UtilActivator.bundleContext.addServiceListener(this);
+ }
+
+ /**
+ * Registers the given protocol provider.
+ *
+ * @param protocolProvider the ProtocolProviderService to register.
+ */
+ public void login(ProtocolProviderService protocolProvider)
+ {
+ loginRenderer.startConnectingUI(protocolProvider);
+
+ new RegisterProvider(protocolProvider,
+ loginRenderer.getSecurityAuthorityImpl(protocolProvider)).start();
+ }
+
+ /**
+ * Unregisters the given protocol provider.
+ *
+ * @param protocolProvider the ProtocolProviderService to unregister
+ */
+ public static void logoff(ProtocolProviderService protocolProvider)
+ {
+ new UnregisterProvider(protocolProvider).start();
+ }
+
+ /**
+ * Shows login window for each registered account.
+ */
+ public void runLogin()
+ {
+ // if someone is late registering catch it
+ UtilActivator.getAccountManager().addListener(this);
+
+ for (ProtocolProviderFactory providerFactory : UtilActivator
+ .getProtocolProviderFactories().values())
+ {
+ addAccountsForProtocolProviderFactory(providerFactory);
+ }
+ }
+
+ /**
+ * Notifies that the loading of the stored accounts of a
+ * specific <code>ProtocolProviderFactory</code> has finished.
+ *
+ * @param event the <code>AccountManagerEvent</code> describing the
+ * <code>AccountManager</code> firing the notification and the
+ * other details of the specific notification.
+ */
+ public void handleAccountManagerEvent(AccountManagerEvent event)
+ {
+ if(event.getType()
+ == AccountManagerEvent.STORED_ACCOUNTS_LOADED)
+ {
+ addAccountsForProtocolProviderFactory(event.getFactory());
+ }
+ }
+
+ /**
+ * Handles stored accounts for a protocol provider factory and add them
+ * to the UI and register them if needed.
+ * @param providerFactory the factory to handle.
+ */
+ private void addAccountsForProtocolProviderFactory(
+ ProtocolProviderFactory providerFactory)
+ {
+ for (AccountID accountID : providerFactory.getRegisteredAccounts())
+ {
+ ServiceReference<ProtocolProviderService> serRef
+ = providerFactory.getProviderForAccount(accountID);
+ ProtocolProviderService protocolProvider
+ = UtilActivator.bundleContext.getService(serRef);
+
+ handleProviderAdded(protocolProvider);
+ }
+ }
+
+ /**
+ * The method is called by a ProtocolProvider implementation whenever a
+ * change in the registration state of the corresponding provider had
+ * occurred.
+ *
+ * @param evt ProviderStatusChangeEvent the event describing the status
+ * change.
+ */
+ public void registrationStateChanged(RegistrationStateChangeEvent evt)
+ {
+ RegistrationState newState = evt.getNewState();
+ ProtocolProviderService protocolProvider = evt.getProvider();
+ AccountID accountID = protocolProvider.getAccountID();
+
+ if (logger.isTraceEnabled())
+ logger.trace("Protocol provider: " + protocolProvider
+ + " changed its state to: " + evt.getNewState().getStateName());
+
+ if (newState.equals(RegistrationState.REGISTERED)
+ || newState.equals(RegistrationState.UNREGISTERED)
+ || newState.equals(RegistrationState.EXPIRED)
+ || newState.equals(RegistrationState.AUTHENTICATION_FAILED)
+ || newState.equals(RegistrationState.CONNECTION_FAILED)
+ || newState.equals(RegistrationState.CHALLENGED_FOR_AUTHENTICATION)
+ || newState.equals(RegistrationState.REGISTERED))
+ {
+ loginRenderer.stopConnectingUI(protocolProvider);
+ }
+
+ if (newState.equals(RegistrationState.REGISTERED))
+ {
+ loginRenderer.protocolProviderConnected(protocolProvider,
+ System.currentTimeMillis());
+ }
+ else
+ {
+ String msgText;
+ if (newState.equals(RegistrationState.AUTHENTICATION_FAILED))
+ {
+ switch (evt.getReasonCode())
+ {
+ case RegistrationStateChangeEvent
+ .REASON_RECONNECTION_RATE_LIMIT_EXCEEDED:
+
+ msgText = UtilActivator.getResources().getI18NString(
+ "service.gui.RECONNECTION_LIMIT_EXCEEDED", new String[]
+ { accountID.getUserID(), accountID.getService() });
+
+ UtilActivator.getAlertUIService().showAlertDialog(
+ UtilActivator.getResources()
+ .getI18NString("service.gui.ERROR"),
+ msgText);
+ break;
+
+ case RegistrationStateChangeEvent.REASON_NON_EXISTING_USER_ID:
+ msgText = UtilActivator.getResources().getI18NString(
+ "service.gui.NON_EXISTING_USER_ID",
+ new String[]
+ { protocolProvider.getProtocolDisplayName() });
+
+ UtilActivator.getAlertUIService().showAlertDialog(
+ UtilActivator.getResources()
+ .getI18NString("service.gui.ERROR"),
+ msgText);
+ break;
+ case RegistrationStateChangeEvent.REASON_TLS_REQUIRED:
+ msgText = UtilActivator.getResources().getI18NString(
+ "service.gui.NON_SECURE_CONNECTION",
+ new String[]
+ { accountID.getAccountAddress() });
+
+ UtilActivator.getAlertUIService().showAlertDialog(
+ UtilActivator.getResources()
+ .getI18NString("service.gui.ERROR"),
+ msgText);
+ break;
+ default:
+ break;
+ }
+
+ if (logger.isTraceEnabled())
+ logger.trace(evt.getReason());
+ }
+// CONNECTION_FAILED events are now dispatched in reconnect plugin
+// else if (newState.equals(RegistrationState.CONNECTION_FAILED))
+// {
+// loginRenderer.protocolProviderConnectionFailed(
+// protocolProvider,
+// this);
+//
+// logger.trace(evt.getReason());
+// }
+ else if (newState.equals(RegistrationState.EXPIRED))
+ {
+ msgText = UtilActivator.getResources().getI18NString(
+ "service.gui.CONNECTION_EXPIRED_MSG",
+ new String[]
+ { protocolProvider.getProtocolDisplayName() });
+
+ UtilActivator.getAlertUIService().showAlertDialog(
+ UtilActivator.getResources()
+ .getI18NString("service.gui.ERROR"),
+ msgText);
+
+ logger.error(evt.getReason());
+ }
+ else if (newState.equals(RegistrationState.UNREGISTERED))
+ {
+ if (!manuallyDisconnected)
+ {
+ if (evt.getReasonCode() == RegistrationStateChangeEvent
+ .REASON_MULTIPLE_LOGINS)
+ {
+ msgText = UtilActivator.getResources().getI18NString(
+ "service.gui.MULTIPLE_LOGINS",
+ new String[]
+ { accountID.getUserID(), accountID.getService() });
+
+ UtilActivator.getAlertUIService().showAlertDialog(
+ UtilActivator.getResources()
+ .getI18NString("service.gui.ERROR"),
+ msgText);
+ }
+ else if (evt.getReasonCode() == RegistrationStateChangeEvent
+ .REASON_CLIENT_LIMIT_REACHED_FOR_IP)
+ {
+ msgText = UtilActivator.getResources().getI18NString(
+ "service.gui.LIMIT_REACHED_FOR_IP", new String[]
+ { protocolProvider.getProtocolDisplayName() });
+
+ UtilActivator.getAlertUIService().showAlertDialog(
+ UtilActivator.getResources()
+ .getI18NString("service.gui.ERROR"),
+ msgText);
+ }
+ else if (evt.getReasonCode() == RegistrationStateChangeEvent
+ .REASON_USER_REQUEST)
+ {
+ // do nothing
+ }
+ else
+ {
+ msgText = UtilActivator.getResources().getI18NString(
+ "service.gui.UNREGISTERED_MESSAGE", new String[]
+ { accountID.getUserID(), accountID.getService() });
+
+ UtilActivator.getAlertUIService().showAlertDialog(
+ UtilActivator.getResources()
+ .getI18NString("service.gui.ERROR"),
+ msgText);
+ }
+ if (logger.isTraceEnabled())
+ logger.trace(evt.getReason());
+ }
+ }
+ }
+ }
+
+ /**
+ * Implements the <tt>ServiceListener</tt> method. Verifies whether the
+ * passed event concerns a <tt>ProtocolProviderService</tt> and adds the
+ * corresponding UI controls.
+ *
+ * @param event The <tt>ServiceEvent</tt> object.
+ */
+ public void serviceChanged(ServiceEvent event)
+ {
+ ServiceReference<?> serviceRef = event.getServiceReference();
+
+ // if the event is caused by a bundle being stopped, we don't want to
+ // know
+ if (serviceRef.getBundle().getState() == Bundle.STOPPING)
+ return;
+
+ Object service = UtilActivator.bundleContext.getService(serviceRef);
+
+ // we don't care if the source service is not a protocol provider
+ if (!(service instanceof ProtocolProviderService))
+ return;
+
+ switch (event.getType())
+ {
+ case ServiceEvent.REGISTERED:
+ handleProviderAdded((ProtocolProviderService) service);
+ break;
+ case ServiceEvent.UNREGISTERING:
+ handleProviderRemoved((ProtocolProviderService) service);
+ break;
+ }
+ }
+
+ /**
+ * Adds all UI components (status selector box, etc) related to the given
+ * protocol provider.
+ *
+ * @param protocolProvider the <tt>ProtocolProviderService</tt>
+ */
+ private void handleProviderAdded(ProtocolProviderService protocolProvider)
+ {
+ if (logger.isTraceEnabled())
+ logger.trace("The following protocol provider was just added: "
+ + protocolProvider.getAccountID().getAccountAddress());
+
+ synchronized(loginRenderer)
+ {
+ if(!loginRenderer.containsProtocolProviderUI(protocolProvider))
+ {
+ protocolProvider.addRegistrationStateChangeListener(this);
+ loginRenderer.addProtocolProviderUI(protocolProvider);
+ }
+ // we have already added this provider and scheduled
+ // a login if needed
+ // we've done our work, if it fails or something else
+ // reconnect or other plugins will take care
+ else
+ return;
+ }
+
+ Object status = AccountStatusUtils
+ .getProtocolProviderLastStatus(protocolProvider);
+
+ if (status == null
+ || status.equals(GlobalStatusEnum.ONLINE_STATUS)
+ || ((status instanceof PresenceStatus) && (((PresenceStatus) status)
+ .getStatus() >= PresenceStatus.ONLINE_THRESHOLD)))
+ {
+ login(protocolProvider);
+ }
+ }
+
+ /**
+ * Removes all UI components related to the given protocol provider.
+ *
+ * @param protocolProvider the <tt>ProtocolProviderService</tt>
+ */
+ private void handleProviderRemoved(ProtocolProviderService protocolProvider)
+ {
+ loginRenderer.removeProtocolProviderUI(protocolProvider);
+ }
+
+ /**
+ * Returns <tt>true</tt> to indicate the jitsi has been manually
+ * disconnected, <tt>false</tt> - otherwise.
+ *
+ * @return <tt>true</tt> to indicate the jitsi has been manually
+ * disconnected, <tt>false</tt> - otherwise
+ */
+ public boolean isManuallyDisconnected()
+ {
+ return manuallyDisconnected;
+ }
+
+ /**
+ * Sets the manually disconnected property.
+ *
+ * @param manuallyDisconnected <tt>true</tt> to indicate the jitsi has been
+ * manually disconnected, <tt>false</tt> - otherwise
+ */
+ public void setManuallyDisconnected(boolean manuallyDisconnected)
+ {
+ this.manuallyDisconnected = manuallyDisconnected;
+ }
+
+ /**
+ * Registers a protocol provider in a separate thread.
+ */
+ private class RegisterProvider
+ extends Thread
+ {
+ private final ProtocolProviderService protocolProvider;
+
+ private final SecurityAuthority secAuth;
+
+ RegisterProvider( ProtocolProviderService protocolProvider,
+ SecurityAuthority secAuth)
+ {
+ this.protocolProvider = protocolProvider;
+ this.secAuth = secAuth;
+
+ if(logger.isTraceEnabled())
+ logger.trace("Registering provider: "
+ + protocolProvider.getAccountID().getAccountAddress(),
+ new Exception(
+ "Just tracing, provider registering, not an error!"));
+ }
+
+ /**
+ * Registers the contained protocol provider and process all possible
+ * errors that may occur during the registration process.
+ */
+ @Override
+ public void run()
+ {
+ try
+ {
+ protocolProvider.register(secAuth);
+ }
+ catch (OperationFailedException ex)
+ {
+ handleOperationFailedException(ex);
+ }
+ catch (Throwable ex)
+ {
+ logger.error("Failed to register protocol provider. ", ex);
+
+ AccountID accountID = protocolProvider.getAccountID();
+ UtilActivator.getAlertUIService().showAlertDialog(
+ UtilActivator.getResources()
+ .getI18NString("service.gui.ERROR"),
+ UtilActivator.getResources()
+ .getI18NString("service.gui.LOGIN_GENERAL_ERROR",
+ new String[]
+ { accountID.getUserID(),
+ accountID.getProtocolName(),
+ accountID.getService() }));
+ }
+ }
+
+ private void handleOperationFailedException(OperationFailedException ex)
+ {
+ String errorMessage = "";
+
+ switch (ex.getErrorCode())
+ {
+ case OperationFailedException.GENERAL_ERROR:
+ {
+ logger.error("Provider could not be registered"
+ + " due to the following general error: ", ex);
+
+ AccountID accountID = protocolProvider.getAccountID();
+ errorMessage =
+ UtilActivator.getResources().getI18NString(
+ "service.gui.LOGIN_GENERAL_ERROR",
+ new String[]
+ { accountID.getUserID(),
+ accountID.getProtocolName(),
+ accountID.getService() });
+
+ UtilActivator.getAlertUIService().showAlertDialog(
+ UtilActivator.getResources()
+ .getI18NString("service.gui.ERROR"), errorMessage, ex);
+ }
+ break;
+ case OperationFailedException.INTERNAL_ERROR:
+ {
+ logger.error("Provider could not be registered"
+ + " due to the following internal error: ", ex);
+
+ AccountID accountID = protocolProvider.getAccountID();
+ errorMessage =
+ UtilActivator.getResources().getI18NString(
+ "service.gui.LOGIN_INTERNAL_ERROR",
+ new String[]
+ { accountID.getUserID(), accountID.getService() });
+
+ UtilActivator.getAlertUIService().showAlertDialog(
+ UtilActivator.getResources().getI18NString(
+ "service.gui.ERROR"), errorMessage, ex);
+ }
+ break;
+ case OperationFailedException.NETWORK_FAILURE:
+ {
+ if (logger.isInfoEnabled())
+ {
+ logger.info("Provider could not be registered"
+ + " due to a network failure: " + ex);
+ }
+
+ loginRenderer.protocolProviderConnectionFailed(
+ protocolProvider,
+ LoginManager.this);
+ }
+ break;
+ case OperationFailedException.INVALID_ACCOUNT_PROPERTIES:
+ {
+ logger.error("Provider could not be registered"
+ + " due to an invalid account property: ", ex);
+
+ AccountID accountID = protocolProvider.getAccountID();
+ errorMessage =
+ UtilActivator.getResources().getI18NString(
+ "service.gui.LOGIN_INVALID_PROPERTIES_ERROR",
+ new String[]
+ { accountID.getUserID(), accountID.getService() });
+
+ UtilActivator.getAlertUIService().showAlertDialog(
+ UtilActivator.getResources()
+ .getI18NString("service.gui.ERROR"),
+ errorMessage, ex);
+ }
+ break;
+ default:
+ logger.error("Provider could not be registered.", ex);
+ }
+ }
+ }
+
+ /**
+ * Unregisters a protocol provider in a separate thread.
+ */
+ private static class UnregisterProvider
+ extends Thread
+ {
+ ProtocolProviderService protocolProvider;
+
+ UnregisterProvider(ProtocolProviderService protocolProvider)
+ {
+ this.protocolProvider = protocolProvider;
+ }
+
+ /**
+ * Unregisters the contained protocol provider and process all possible
+ * errors that may occur during the un-registration process.
+ */
+ @Override
+ public void run()
+ {
+ try
+ {
+ protocolProvider.unregister(true);
+ }
+ catch (OperationFailedException ex)
+ {
+ int errorCode = ex.getErrorCode();
+
+ if (errorCode == OperationFailedException.GENERAL_ERROR)
+ {
+ logger.error("Provider could not be unregistered"
+ + " due to the following general error: " + ex);
+ }
+ else if (errorCode == OperationFailedException.INTERNAL_ERROR)
+ {
+ logger.error("Provider could not be unregistered"
+ + " due to the following internal error: " + ex);
+ }
+ else if (errorCode == OperationFailedException.NETWORK_FAILURE)
+ {
+ logger.error("Provider could not be unregistered"
+ + " due to a network failure: " + ex);
+ }
+
+ UtilActivator.getAlertUIService().showAlertDialog(
+ UtilActivator.getResources()
+ .getI18NString("service.gui.ERROR"),
+ UtilActivator.getResources()
+ .getI18NString("service.gui.LOGOFF_NOT_SUCCEEDED",
+ new String[]
+ { protocolProvider.getAccountID().getUserID(),
+ protocolProvider.getAccountID().getService() }));
+ }
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/util/account/LoginRenderer.java b/src/net/java/sip/communicator/util/account/LoginRenderer.java
index ee39940..e1ae850 100644
--- a/src/net/java/sip/communicator/util/account/LoginRenderer.java
+++ b/src/net/java/sip/communicator/util/account/LoginRenderer.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,94 +15,94 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.util.account;
-
-import net.java.sip.communicator.service.protocol.*;
-
-/**
- * The <tt>LoginRenderer</tt> is the renderer of all login related operations.
- *
- * @author Yana Stamcheva
- */
-public interface LoginRenderer
-{
- /**
- * Adds the user interface related to the given protocol provider.
- *
- * @param protocolProvider the protocol provider for which we add the user
- * interface
- */
- public void addProtocolProviderUI(
- ProtocolProviderService protocolProvider);
-
- /**
- * Removes the user interface related to the given protocol provider.
- *
- * @param protocolProvider the protocol provider to remove
- */
- public void removeProtocolProviderUI(
- ProtocolProviderService protocolProvider);
-
- /**
- * Starts the connecting user interface for the given protocol provider.
- *
- * @param protocolProvider the protocol provider for which we add the
- * connecting user interface
- */
- public void startConnectingUI(ProtocolProviderService protocolProvider);
-
- /**
- * Stops the connecting user interface for the given protocol provider.
- *
- * @param protocolProvider the protocol provider for which we remove the
- * connecting user interface
- */
- public void stopConnectingUI(ProtocolProviderService protocolProvider);
-
- /**
- * Indicates that the given protocol provider is now connected.
- *
- * @param protocolProvider the <tt>ProtocolProviderService</tt> that is
- * connected
- * @param date the date on which the event occured
- */
- public void protocolProviderConnected(
- ProtocolProviderService protocolProvider,
- long date);
-
- /**
- * Indicates that a protocol provider connection has failed.
- *
- * @param protocolProvider the <tt>ProtocolProviderService</tt>, which
- * connection failed
- * @param loginManagerCallback the <tt>LoginManager</tt> implementation,
- * which is managing the process
- */
- public void protocolProviderConnectionFailed(
- ProtocolProviderService protocolProvider,
- LoginManager loginManagerCallback);
-
- /**
- * Returns the <tt>SecurityAuthority</tt> implementation related to this
- * login renderer.
- *
- * @param protocolProvider the specific <tt>ProtocolProviderService</tt>,
- * for which we're obtaining a security authority
- * @return the <tt>SecurityAuthority</tt> implementation related to this
- * login renderer
- */
- public SecurityAuthority getSecurityAuthorityImpl(
- ProtocolProviderService protocolProvider);
-
- /**
- * Indicates if the given <tt>protocolProvider</tt> related user interface
- * is already rendered.
- *
- * @param protocolProvider the <tt>ProtocolProviderService</tt>, which
- * related user interface we're looking for
- * @return <tt>true</tt> if the given <tt>protocolProvider</tt> related user
- * interface is already rendered
- */
- public boolean containsProtocolProviderUI(
- ProtocolProviderService protocolProvider);
+package net.java.sip.communicator.util.account;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The <tt>LoginRenderer</tt> is the renderer of all login related operations.
+ *
+ * @author Yana Stamcheva
+ */
+public interface LoginRenderer
+{
+ /**
+ * Adds the user interface related to the given protocol provider.
+ *
+ * @param protocolProvider the protocol provider for which we add the user
+ * interface
+ */
+ public void addProtocolProviderUI(
+ ProtocolProviderService protocolProvider);
+
+ /**
+ * Removes the user interface related to the given protocol provider.
+ *
+ * @param protocolProvider the protocol provider to remove
+ */
+ public void removeProtocolProviderUI(
+ ProtocolProviderService protocolProvider);
+
+ /**
+ * Starts the connecting user interface for the given protocol provider.
+ *
+ * @param protocolProvider the protocol provider for which we add the
+ * connecting user interface
+ */
+ public void startConnectingUI(ProtocolProviderService protocolProvider);
+
+ /**
+ * Stops the connecting user interface for the given protocol provider.
+ *
+ * @param protocolProvider the protocol provider for which we remove the
+ * connecting user interface
+ */
+ public void stopConnectingUI(ProtocolProviderService protocolProvider);
+
+ /**
+ * Indicates that the given protocol provider is now connected.
+ *
+ * @param protocolProvider the <tt>ProtocolProviderService</tt> that is
+ * connected
+ * @param date the date on which the event occured
+ */
+ public void protocolProviderConnected(
+ ProtocolProviderService protocolProvider,
+ long date);
+
+ /**
+ * Indicates that a protocol provider connection has failed.
+ *
+ * @param protocolProvider the <tt>ProtocolProviderService</tt>, which
+ * connection failed
+ * @param loginManagerCallback the <tt>LoginManager</tt> implementation,
+ * which is managing the process
+ */
+ public void protocolProviderConnectionFailed(
+ ProtocolProviderService protocolProvider,
+ LoginManager loginManagerCallback);
+
+ /**
+ * Returns the <tt>SecurityAuthority</tt> implementation related to this
+ * login renderer.
+ *
+ * @param protocolProvider the specific <tt>ProtocolProviderService</tt>,
+ * for which we're obtaining a security authority
+ * @return the <tt>SecurityAuthority</tt> implementation related to this
+ * login renderer
+ */
+ public SecurityAuthority getSecurityAuthorityImpl(
+ ProtocolProviderService protocolProvider);
+
+ /**
+ * Indicates if the given <tt>protocolProvider</tt> related user interface
+ * is already rendered.
+ *
+ * @param protocolProvider the <tt>ProtocolProviderService</tt>, which
+ * related user interface we're looking for
+ * @return <tt>true</tt> if the given <tt>protocolProvider</tt> related user
+ * interface is already rendered
+ */
+ public boolean containsProtocolProviderUI(
+ ProtocolProviderService protocolProvider);
}
diff --git a/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java b/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java
index 90041fc..d5cbf14 100644
--- a/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java
+++ b/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java
@@ -299,6 +299,11 @@ public class LaunchArgHandler
// do nothing already handled by startup script/binary
continue;
}
+ else if (args[i].startsWith("--notray"))
+ {
+ System.setProperty("disable-tray", "true");
+ continue;
+ }
//if this is the last arg and it's not an option then it's probably
//an URI
else if ( i == args.length - 1
@@ -521,6 +526,7 @@ public class LaunchArgHandler
System.out.println(" -6, --ipv6 prefer IPv6 addresses where possible only");
System.out.println(" -4, --ipv4 forces use of IPv4 only");
System.out.println(" -v, --version display the current version and exit");
+ System.out.println(" -n, --notray disable the tray icon and show the GUI");
}
/**
diff --git a/src/net/java/sip/communicator/util/util.manifest.mf b/src/net/java/sip/communicator/util/util.manifest.mf
index 7de9af7..b50df6b 100644
--- a/src/net/java/sip/communicator/util/util.manifest.mf
+++ b/src/net/java/sip/communicator/util/util.manifest.mf
@@ -32,6 +32,7 @@ Import-Package: com.sun.awt,
net.java.sip.communicator.service.gui,
net.java.sip.communicator.service.gui.call,
net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.service.systray,
net.java.sip.communicator.service.keybindings,
net.java.sip.communicator.service.msghistory,
net.java.sip.communicator.service.contactlist,
@@ -56,8 +57,7 @@ Import-Package: com.sun.awt,
sun.awt.shell,
sun.net.dns,
sun.net.util
-Export-Package: org.xbill.DNS,
- net.java.sip.communicator.util,
+Export-Package: net.java.sip.communicator.util,
net.java.sip.communicator.util.launchutils,
net.java.sip.communicator.util.skin,
net.java.sip.communicator.util.xml,
diff --git a/test/net/java/sip/communicator/slick/configuration/ConfigurationServiceLick.java b/test/net/java/sip/communicator/slick/configuration/ConfigurationServiceLick.java
index 175f9ab..f56e755 100644
--- a/test/net/java/sip/communicator/slick/configuration/ConfigurationServiceLick.java
+++ b/test/net/java/sip/communicator/slick/configuration/ConfigurationServiceLick.java
@@ -52,7 +52,7 @@ public class ConfigurationServiceLick
properties.put("service.pid", getName());
addTestSuite(TestConfigurationService.class);
- addTestSuite(TestConfigurationServicePersistency.class);
+ //addTestSuite(TestConfigurationServicePersistency.class);
addTestSuite(TestConfigurationSlickFinalizer.class);
bundleContext.registerService(getClass().getName(), this, properties);
diff --git a/test/net/java/sip/communicator/slick/popupmessagehandler/PopupMessageHandlerSLick.java b/test/net/java/sip/communicator/slick/popupmessagehandler/PopupMessageHandlerSLick.java
index 10a89bc..0cc63a8 100644
--- a/test/net/java/sip/communicator/slick/popupmessagehandler/PopupMessageHandlerSLick.java
+++ b/test/net/java/sip/communicator/slick/popupmessagehandler/PopupMessageHandlerSLick.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,54 +15,54 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.slick.popupmessagehandler;
-
-import java.util.*;
-
-import junit.framework.*;
-import net.java.sip.communicator.service.systray.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- *
- * @author Symphorien Wanko
- */
-public class PopupMessageHandlerSLick extends TestSuite implements BundleActivator
-{
- /** Logger for this class */
- private static Logger logger =
- Logger.getLogger(PopupMessageHandlerSLick.class);
-
- /** our bundle context */
- protected static BundleContext bundleContext = null;
-
- /** implements BundleActivator.start() */
- public void start(BundleContext bc) throws Exception
- {
- logger.info("starting popup message test ");
-
- bundleContext = bc;
-
- setName("PopupMessageHandlerSLick");
-
- Hashtable<String, String> properties = new Hashtable<String, String>();
-
- properties.put("service.pid", getName());
-
- // we maybe are running on machine without WM and systray
- // (test server machine), skip tests
- if(ServiceUtils.getService(bc, SystrayService.class) != null)
- {
- addTest(TestPopupMessageHandler.suite());
- }
-
- bundleContext.registerService(getClass().getName(), this, properties);
- }
-
- /** implements BundleActivator.stop() */
- public void stop(BundleContext bc) throws Exception
- {}
-
-}
+package net.java.sip.communicator.slick.popupmessagehandler;
+
+import java.util.*;
+
+import junit.framework.*;
+import net.java.sip.communicator.service.systray.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ *
+ * @author Symphorien Wanko
+ */
+public class PopupMessageHandlerSLick extends TestSuite implements BundleActivator
+{
+ /** Logger for this class */
+ private static Logger logger =
+ Logger.getLogger(PopupMessageHandlerSLick.class);
+
+ /** our bundle context */
+ protected static BundleContext bundleContext = null;
+
+ /** implements BundleActivator.start() */
+ public void start(BundleContext bc) throws Exception
+ {
+ logger.info("starting popup message test ");
+
+ bundleContext = bc;
+
+ setName("PopupMessageHandlerSLick");
+
+ Hashtable<String, String> properties = new Hashtable<String, String>();
+
+ properties.put("service.pid", getName());
+
+ // we maybe are running on machine without WM and systray
+ // (test server machine), skip tests
+ if(ServiceUtils.getService(bc, SystrayService.class) != null)
+ {
+ addTest(TestPopupMessageHandler.suite());
+ }
+
+ bundleContext.registerService(getClass().getName(), this, properties);
+ }
+
+ /** implements BundleActivator.stop() */
+ public void stop(BundleContext bc) throws Exception
+ {}
+
+}
diff --git a/test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetAdHocMultiUserChat.java b/test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetAdHocMultiUserChat.java
index 13e5092..1f7db0f 100644
--- a/test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetAdHocMultiUserChat.java
+++ b/test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetAdHocMultiUserChat.java
@@ -138,10 +138,6 @@ public abstract class TestOperationSetAdHocMultiUserChat extends TestCase
* -Then they will leave the room. They will be invited again in another
* test.
*
- * NOTE that this test will be especially used by Yahoo! protocol because of
- * the fact that creating a conference chat with this protocol fails if any
- * participants are given to the dedicated constructor of the library.
- *
* @throws OperationNotSupportedException
* @throws OperationFailedException
*/
@@ -160,7 +156,6 @@ public abstract class TestOperationSetAdHocMultiUserChat extends TestCase
opSetAHMUC3, AHMUCEventCollector.INVITATION_EVENT);
// We create the room with the given contacts:
- // (NOTE that in Yahoo! adHocChatRoomName won't be considered!)
AdHocChatRoom room = opSetAHMUC1.createAdHocChatRoom(
adHocChatRoomName, contacts, invitationReason);
@@ -440,7 +435,7 @@ public abstract class TestOperationSetAdHocMultiUserChat extends TestCase
/**
* Make sure that invitations have been received on both side (user2 and
* user3). Note that it only make sense to use this method with protocol
- * who support invitations (Yahoo! and ICQ).
+ * who support invitations (ICQ).
*
* We will first test that after having accept an invitation the concerned
* user joins the room and be a part of participants.
diff --git a/test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetFileTransfer.java b/test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetFileTransfer.java
index e123bd3..d29092d 100644
--- a/test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetFileTransfer.java
+++ b/test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetFileTransfer.java
@@ -605,9 +605,8 @@ public abstract class TestOperationSetFileTransfer
,FileTransferStatusChangeEvent.PREPARING
,stat1.getNewStatus());
- // now wait if some protocol filres inProgress
+ // now wait if some protocol fires inProgress
// jabber doesn't fire inProgress here
- // yahoo fires it
receiverStatusListener.waitForEvent(14000);
// wait in_progress
diff --git a/test/net/java/sip/communicator/slick/protocol/icq/icq.provider.slick.manifest.mf b/test/net/java/sip/communicator/slick/protocol/icq/icq.provider.slick.manifest.mf
index 68d09e2..d1420bd 100644
--- a/test/net/java/sip/communicator/slick/protocol/icq/icq.provider.slick.manifest.mf
+++ b/test/net/java/sip/communicator/slick/protocol/icq/icq.provider.slick.manifest.mf
@@ -12,6 +12,5 @@ Import-Package: junit.framework,
net.java.sip.communicator.service.dns,
net.java.sip.communicator.service.protocol,
net.java.sip.communicator.service.protocol.icqconstants,
- net.java.sip.communicator.service.protocol.aimconstants,
net.java.sip.communicator.service.protocol.event,
org.jitsi.service.fileaccess
diff --git a/test/net/java/sip/communicator/slick/protocol/sip/SipProtocolProviderServiceLick.java b/test/net/java/sip/communicator/slick/protocol/sip/SipProtocolProviderServiceLick.java
index 9d192fe..d599b80 100644
--- a/test/net/java/sip/communicator/slick/protocol/sip/SipProtocolProviderServiceLick.java
+++ b/test/net/java/sip/communicator/slick/protocol/sip/SipProtocolProviderServiceLick.java
@@ -120,7 +120,7 @@ public class SipProtocolProviderServiceLick
addTest(TestOperationSetPersistentPresence.suite());
//IM test
- addTest(TestOperationSetBasicInstantMessaging.suite());
+ //addTest(TestOperationSetBasicInstantMessaging.suite());
// telephony
addTestSuite(TestOperationSetBasicTelephonySipImpl.class);
diff --git a/test/net/java/sip/communicator/slick/protocol/sip/TestAutoProxyDetection.java b/test/net/java/sip/communicator/slick/protocol/sip/TestAutoProxyDetection.java
index 948dd9d..e5e9511 100644
--- a/test/net/java/sip/communicator/slick/protocol/sip/TestAutoProxyDetection.java
+++ b/test/net/java/sip/communicator/slick/protocol/sip/TestAutoProxyDetection.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,487 +15,487 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.slick.protocol.sip;
-
-import static net.java.sip.communicator.service.protocol.ProtocolProviderFactory.USER_ID;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-
-import java.net.*;
-import java.text.*;
-
-import junit.framework.*;
-import net.java.sip.communicator.impl.protocol.sip.*;
-import net.java.sip.communicator.impl.protocol.sip.net.*;
-import net.java.sip.communicator.service.dns.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Tests all variations of automatic proxy detection through (simulated) DNS.
- *
- * @author Ingo Bauersachs
- */
-public class TestAutoProxyDetection
- extends TestCase
-{
- private static class TestedAutoProxyDetection extends AutoProxyConnection
- {
- public TestedAutoProxyDetection(SipAccountIDImpl account,
- String defaultTransport)
- {
- super(account, defaultTransport);
- }
-
- @Override
- public void setNetworkUtils(LocalNetworkUtils nu)
- {
- super.setNetworkUtils(nu);
- }
-
- public static class NetworkUtils extends LocalNetworkUtils
- {
- }
- }
-
- private SipAccountIDImpl account;
- private TestedAutoProxyDetection.NetworkUtils nu;
- private SRVRecord srv1;
- private SRVRecord srv2;
- private SRVRecord srv3;
- private InetSocketAddress a1;
- private InetSocketAddress a2;
- private InetSocketAddress a3;
- private InetSocketAddress a4;
- private final static String DOMAIN = "example.com";
- private InetAddress ia1;
- private InetAddress ia2;
- private InetAddress ia3;
- private InetAddress ia4;
- private TestedAutoProxyDetection apd;
-
- @Override
- public void setUp()
- {
- account = createMock(SipAccountIDImpl.class);
- expect(account.getAccountPropertyString(USER_ID))
- .andReturn("unit@" + DOMAIN);
- replay(account);
-
- nu = createMock(TestedAutoProxyDetection.NetworkUtils.class);
- apd = new TestedAutoProxyDetection(account, "UDP");
- apd.setNetworkUtils(nu);
-
- srv1 = createMock(SRVRecord.class);
- expect(srv1.getTarget()).andReturn("proxy1."+DOMAIN);
- expect(srv1.getPort()).andReturn(5060);
- srv2 = createMock(SRVRecord.class);
- expect(srv2.getTarget()).andReturn("proxy2."+DOMAIN);
- expect(srv2.getPort()).andReturn(5061);
- srv3 = createMock(SRVRecord.class);
- expect(srv3.getTarget()).andReturn("proxy3."+DOMAIN);
- expect(srv3.getPort()).andReturn(5062);
- try
- {
- ia1 = InetAddress.getByAddress("proxy1." + DOMAIN,
- new byte[]{0x7f,0,0,1});
- ia2 = InetAddress.getByAddress("proxy2." + DOMAIN,
- new byte[]{0x7f,0,0,2});
- ia3 = InetAddress.getByAddress("proxy3." + DOMAIN,
- new byte[]{0x7f,0,0,3});
- ia4 = InetAddress.getByAddress("proxy4." + DOMAIN,
- new byte[]{0x7f,0,0,4});
- }
- catch (UnknownHostException e)
- {
- fail("unable to initialize: " + e.getMessage());
- }
- a1 = new InetSocketAddress(ia1, 5060);
- a2 = new InetSocketAddress(ia2, 5061);
- a3 = new InetSocketAddress(ia3, 5062);
- a4 = new InetSocketAddress(ia4, 5063);
- }
-
- private void prepareOneNaptrOneSrv() throws ParseException, DnssecException
- {
- expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{
- {"0", "udp", "_sip._udp." + DOMAIN}
- });
- expect(nu.getSRVRecords("_sip._udp."+DOMAIN))
- .andReturn(new SRVRecord[]{ srv1 });
- }
-
- private void prepareOneNaptrTwoSrv() throws ParseException, DnssecException
- {
- expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{
- {"0", "udp", "_sip._udp." + DOMAIN}
- });
- expect(nu.getSRVRecords("_sip._udp."+DOMAIN))
- .andReturn(new SRVRecord[]{ srv1, srv2 });
- }
-
- public void testOneNaptrNoSrv() throws ParseException, DnssecException
- {
- expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{
- {"0", "udp", "_sip._udp." + DOMAIN}
- });
- expect(nu.getSRVRecords("_sip._udp." + DOMAIN)).andReturn(null);
- replay(nu);
-
- assertFalse(apd.getNextAddress());
- verify(account, nu);
- }
-
- public void testOneNaptrOneSrvOneA() throws ParseException, DnssecException
- {
- prepareOneNaptrOneSrv();
- expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
- .andReturn(new InetSocketAddress[]{a1});
- replay(nu, srv1);
-
- assertTrue(apd.getNextAddress());
- assertEquals(a1, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertFalse(apd.getNextAddress());
- verify(account, nu, srv1);
- }
-
- public void testOneNaptrOneSrvTwoA() throws ParseException, DnssecException
- {
- prepareOneNaptrOneSrv();
- expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
- .andReturn(new InetSocketAddress[]{a1, a2});
- replay(nu, srv1);
-
- assertTrue(apd.getNextAddress());
- assertEquals(a1, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
- assertTrue(apd.getNextAddress());
- assertEquals(a2, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertFalse(apd.getNextAddress());
- verify(account, nu, srv1);
- }
-
- //-----------------------
-
- public void testOneNaptrTwoSrvOneA() throws ParseException, DnssecException
- {
- prepareOneNaptrTwoSrv();
- expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
- .andReturn(new InetSocketAddress[]{a1});
- expect(nu.getAandAAAARecords("proxy2." + DOMAIN, 5061))
- .andReturn(new InetSocketAddress[]{a2});
- replay(nu, srv1, srv2);
-
- assertTrue(apd.getNextAddress());
- assertEquals(a1, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
- assertTrue(apd.getNextAddress());
- assertEquals(a2, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertFalse(apd.getNextAddress());
- verify(account, nu, srv1, srv2);
- }
-
- public void testOneNaptrTwoSrvTwoA() throws ParseException, DnssecException
- {
- prepareOneNaptrTwoSrv();
- expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
- .andReturn(new InetSocketAddress[]{a1, a2});
- expect(nu.getAandAAAARecords("proxy2." + DOMAIN, 5061))
- .andReturn(new InetSocketAddress[]{a3, a4});
- replay(nu, srv1, srv2);
-
- assertTrue(apd.getNextAddress());
- assertEquals(a1, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertTrue(apd.getNextAddress());
- assertEquals(a2, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertTrue(apd.getNextAddress());
- assertEquals(a3, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertTrue(apd.getNextAddress());
- assertEquals(a4, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertFalse(apd.getNextAddress());
- verify(account, nu, srv1, srv2);
- }
-
- //-------------------
-
- public void testThreeNaptrOneSrvEachOneAEach()
- throws ParseException,
- DnssecException
- {
- expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{
- {"0", "udp", "_sip._udp." + DOMAIN},
- {"0", "tcp", "_sip._tcp." + DOMAIN},
- {"0", "tls", "_sips._tcp." + DOMAIN}
- });
- expect(nu.getSRVRecords("_sip._udp."+DOMAIN))
- .andReturn(new SRVRecord[]{ srv1 });
- expect(nu.getSRVRecords("_sip._tcp."+DOMAIN))
- .andReturn(new SRVRecord[]{ srv2 });
- expect(nu.getSRVRecords("_sips._tcp."+DOMAIN))
- .andReturn(new SRVRecord[]{ srv3 });
- expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
- .andReturn(new InetSocketAddress[]{a1});
- expect(nu.getAandAAAARecords("proxy2." + DOMAIN, 5061))
- .andReturn(new InetSocketAddress[]{a1});
- expect(nu.getAandAAAARecords("proxy3." + DOMAIN, 5062))
- .andReturn(new InetSocketAddress[]{a1});
-
- replay(nu, srv1, srv2, srv3);
-
- assertTrue(apd.getNextAddress());
- assertEquals(a1, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertTrue(apd.getNextAddress());
- assertEquals(a1, apd.getAddress());
- assertEquals("TCP", apd.getTransport());
-
- assertTrue(apd.getNextAddress());
- assertEquals(a1, apd.getAddress());
- assertEquals("TLS", apd.getTransport());
-
- assertFalse(apd.getNextAddress());
- verify(account, nu, srv1, srv2, srv3);
- }
-
- //-----------------------
-
- public void testNoSrvOneA() throws ParseException, DnssecException
- {
- expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
- expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
- expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
- expect(nu.getSRVRecords("sip", "UDP", DOMAIN)).andReturn(null);
- expect(nu.getAandAAAARecords(DOMAIN, 5060))
- .andReturn(new InetSocketAddress[]{a1});
-
- replay(nu);
-
- assertTrue(apd.getNextAddress());
- assertEquals(a1, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertFalse(apd.getNextAddress());
- verify(account, nu);
- }
-
- public void testOneSrvNoA() throws ParseException, DnssecException
- {
- expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
- expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
- expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
- expect(nu.getSRVRecords("sip", "UDP", DOMAIN))
- .andReturn(new SRVRecord[]{srv1});
- expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
- .andReturn(null);
-
- replay(nu, srv1);
-
- assertFalse(apd.getNextAddress());
- verify(account, nu, srv1);
- }
-
- public void testOneSrvOneA() throws ParseException, DnssecException
- {
- expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
- expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
- expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
- expect(nu.getSRVRecords("sip", "UDP", DOMAIN))
- .andReturn(new SRVRecord[]{srv1});
- expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
- .andReturn(new InetSocketAddress[]{a1});
-
- replay(nu, srv1);
-
- assertTrue(apd.getNextAddress());
- assertEquals(a1, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertFalse(apd.getNextAddress());
- verify(account, nu, srv1);
- }
-
- public void testOneSrvTwoA() throws ParseException, DnssecException
- {
- expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
- expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
- expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
- expect(nu.getSRVRecords("sip", "UDP", DOMAIN))
- .andReturn(new SRVRecord[]{srv1});
- expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
- .andReturn(new InetSocketAddress[]{a1, a2});
-
- replay(nu, srv1);
-
- assertTrue(apd.getNextAddress());
- assertEquals(a1, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertTrue(apd.getNextAddress());
- assertEquals(a2, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertFalse(apd.getNextAddress());
- verify(account, nu, srv1);
- }
-
- public void testTwoSrvOneA() throws ParseException, DnssecException
- {
- expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
- expect(nu.getSRVRecords("sips", "TCP", DOMAIN))
- .andReturn(new SRVRecord[]{srv2});
- expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
- expect(nu.getSRVRecords("sip", "UDP", DOMAIN))
- .andReturn(new SRVRecord[]{srv1});
- expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
- .andReturn(new InetSocketAddress[]{a1});
- expect(nu.getAandAAAARecords("proxy2." + DOMAIN, 5061))
- .andReturn(new InetSocketAddress[]{a2});
-
- replay(nu, srv1, srv2);
-
- assertTrue(apd.getNextAddress());
- assertEquals(a2, apd.getAddress());
- assertEquals("TLS", apd.getTransport());
-
- assertTrue(apd.getNextAddress());
- assertEquals(a1, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertFalse(apd.getNextAddress());
- verify(account, nu, srv1, srv2);
- }
-
- public void testTwoSameSrvOneA() throws ParseException, DnssecException
- {
- expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
- expect(nu.getSRVRecords("sips", "TCP", DOMAIN))
- .andReturn(new SRVRecord[]{srv1, srv2});
- expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
- expect(nu.getSRVRecords("sip", "UDP", DOMAIN)).andReturn(null);
- expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
- .andReturn(new InetSocketAddress[]{a1});
- expect(nu.getAandAAAARecords("proxy2." + DOMAIN, 5061))
- .andReturn(new InetSocketAddress[]{a2});
-
- replay(nu, srv1, srv2);
-
- assertTrue(apd.getNextAddress());
- assertEquals(a1, apd.getAddress());
- assertEquals("TLS", apd.getTransport());
- assertEquals(5060, apd.getAddress().getPort());
-
- assertTrue(apd.getNextAddress());
- assertEquals(a2, apd.getAddress());
- assertEquals("TLS", apd.getTransport());
- assertEquals(5061, apd.getAddress().getPort());
-
- assertFalse(apd.getNextAddress());
- verify(account, nu, srv1, srv2);
- }
-
- //----------------------
-
- public void testNoA() throws ParseException, DnssecException
- {
- expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
- expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
- expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
- expect(nu.getSRVRecords("sip", "UDP", DOMAIN)).andReturn(null);
- expect(nu.getAandAAAARecords(DOMAIN, 5060))
- .andReturn(new InetSocketAddress[]{});
-
- replay(nu);
-
- assertFalse(apd.getNextAddress());
- verify(account, nu);
- }
-
- public void testOneA() throws ParseException, DnssecException
- {
- expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
- expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
- expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
- expect(nu.getSRVRecords("sip", "UDP", DOMAIN)).andReturn(null);
- expect(nu.getAandAAAARecords(DOMAIN, 5060))
- .andReturn(new InetSocketAddress[]{a1});
-
- replay(nu);
-
- assertTrue(apd.getNextAddress());
- assertEquals(a1, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertFalse(apd.getNextAddress());
- verify(account, nu);
- }
-
- public void testTwoA() throws ParseException, DnssecException
- {
- expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
- expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
- expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
- expect(nu.getSRVRecords("sip", "UDP", DOMAIN)).andReturn(null);
- expect(nu.getAandAAAARecords(DOMAIN, 5060))
- .andReturn(new InetSocketAddress[]{a1, a2});
-
- replay(nu);
-
- assertTrue(apd.getNextAddress());
- assertEquals(a1, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertTrue(apd.getNextAddress());
- assertEquals(a2, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertFalse(apd.getNextAddress());
- verify(account, nu);
- }
-
- public void testNotReturningSameAddressTwice()
- throws ParseException,
- DnssecException
- {
- expect(srv1.getTarget()).andReturn("proxy1."+DOMAIN);
- expect(srv1.getPort()).andReturn(5060);
- expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{
- {"0", "udp", "_sip._udp." + DOMAIN},
- {"1", "udp", "_sip._udp." + DOMAIN}
- });
- expect(nu.getSRVRecords("_sip._udp."+DOMAIN)).andReturn(new SRVRecord[]{
- srv1
- });
- expect(nu.getSRVRecords("_sip._udp."+DOMAIN)).andReturn(new SRVRecord[]{
- srv1
- });
- expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
- .andReturn(new InetSocketAddress[]{a1});
- expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
- .andReturn(new InetSocketAddress[]{a1});
-
- replay(nu, srv1);
-
- assertTrue(apd.getNextAddress());
- assertEquals(a1, apd.getAddress());
- assertEquals("UDP", apd.getTransport());
-
- assertFalse(apd.getNextAddress());
- verify(account, nu, srv1);
- }
-}
+package net.java.sip.communicator.slick.protocol.sip;
+
+import static net.java.sip.communicator.service.protocol.ProtocolProviderFactory.USER_ID;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import java.net.*;
+import java.text.*;
+
+import junit.framework.*;
+import net.java.sip.communicator.impl.protocol.sip.*;
+import net.java.sip.communicator.impl.protocol.sip.net.*;
+import net.java.sip.communicator.service.dns.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Tests all variations of automatic proxy detection through (simulated) DNS.
+ *
+ * @author Ingo Bauersachs
+ */
+public class TestAutoProxyDetection
+ extends TestCase
+{
+ private static class TestedAutoProxyDetection extends AutoProxyConnection
+ {
+ public TestedAutoProxyDetection(SipAccountIDImpl account,
+ String defaultTransport)
+ {
+ super(account, defaultTransport);
+ }
+
+ @Override
+ public void setNetworkUtils(LocalNetworkUtils nu)
+ {
+ super.setNetworkUtils(nu);
+ }
+
+ public static class NetworkUtils extends LocalNetworkUtils
+ {
+ }
+ }
+
+ private SipAccountIDImpl account;
+ private TestedAutoProxyDetection.NetworkUtils nu;
+ private SRVRecord srv1;
+ private SRVRecord srv2;
+ private SRVRecord srv3;
+ private InetSocketAddress a1;
+ private InetSocketAddress a2;
+ private InetSocketAddress a3;
+ private InetSocketAddress a4;
+ private final static String DOMAIN = "example.com";
+ private InetAddress ia1;
+ private InetAddress ia2;
+ private InetAddress ia3;
+ private InetAddress ia4;
+ private TestedAutoProxyDetection apd;
+
+ @Override
+ public void setUp()
+ {
+ account = createMock(SipAccountIDImpl.class);
+ expect(account.getAccountPropertyString(USER_ID))
+ .andReturn("unit@" + DOMAIN);
+ replay(account);
+
+ nu = createMock(TestedAutoProxyDetection.NetworkUtils.class);
+ apd = new TestedAutoProxyDetection(account, "UDP");
+ apd.setNetworkUtils(nu);
+
+ srv1 = createMock(SRVRecord.class);
+ expect(srv1.getTarget()).andReturn("proxy1."+DOMAIN);
+ expect(srv1.getPort()).andReturn(5060);
+ srv2 = createMock(SRVRecord.class);
+ expect(srv2.getTarget()).andReturn("proxy2."+DOMAIN);
+ expect(srv2.getPort()).andReturn(5061);
+ srv3 = createMock(SRVRecord.class);
+ expect(srv3.getTarget()).andReturn("proxy3."+DOMAIN);
+ expect(srv3.getPort()).andReturn(5062);
+ try
+ {
+ ia1 = InetAddress.getByAddress("proxy1." + DOMAIN,
+ new byte[]{0x7f,0,0,1});
+ ia2 = InetAddress.getByAddress("proxy2." + DOMAIN,
+ new byte[]{0x7f,0,0,2});
+ ia3 = InetAddress.getByAddress("proxy3." + DOMAIN,
+ new byte[]{0x7f,0,0,3});
+ ia4 = InetAddress.getByAddress("proxy4." + DOMAIN,
+ new byte[]{0x7f,0,0,4});
+ }
+ catch (UnknownHostException e)
+ {
+ fail("unable to initialize: " + e.getMessage());
+ }
+ a1 = new InetSocketAddress(ia1, 5060);
+ a2 = new InetSocketAddress(ia2, 5061);
+ a3 = new InetSocketAddress(ia3, 5062);
+ a4 = new InetSocketAddress(ia4, 5063);
+ }
+
+ private void prepareOneNaptrOneSrv() throws ParseException, DnssecException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{
+ {"0", "udp", "_sip._udp." + DOMAIN}
+ });
+ expect(nu.getSRVRecords("_sip._udp."+DOMAIN))
+ .andReturn(new SRVRecord[]{ srv1 });
+ }
+
+ private void prepareOneNaptrTwoSrv() throws ParseException, DnssecException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{
+ {"0", "udp", "_sip._udp." + DOMAIN}
+ });
+ expect(nu.getSRVRecords("_sip._udp."+DOMAIN))
+ .andReturn(new SRVRecord[]{ srv1, srv2 });
+ }
+
+ public void testOneNaptrNoSrv() throws ParseException, DnssecException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{
+ {"0", "udp", "_sip._udp." + DOMAIN}
+ });
+ expect(nu.getSRVRecords("_sip._udp." + DOMAIN)).andReturn(null);
+ replay(nu);
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu);
+ }
+
+ public void testOneNaptrOneSrvOneA() throws ParseException, DnssecException
+ {
+ prepareOneNaptrOneSrv();
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+ replay(nu, srv1);
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1);
+ }
+
+ public void testOneNaptrOneSrvTwoA() throws ParseException, DnssecException
+ {
+ prepareOneNaptrOneSrv();
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1, a2});
+ replay(nu, srv1);
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+ assertTrue(apd.getNextAddress());
+ assertEquals(a2, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1);
+ }
+
+ //-----------------------
+
+ public void testOneNaptrTwoSrvOneA() throws ParseException, DnssecException
+ {
+ prepareOneNaptrTwoSrv();
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+ expect(nu.getAandAAAARecords("proxy2." + DOMAIN, 5061))
+ .andReturn(new InetSocketAddress[]{a2});
+ replay(nu, srv1, srv2);
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+ assertTrue(apd.getNextAddress());
+ assertEquals(a2, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1, srv2);
+ }
+
+ public void testOneNaptrTwoSrvTwoA() throws ParseException, DnssecException
+ {
+ prepareOneNaptrTwoSrv();
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1, a2});
+ expect(nu.getAandAAAARecords("proxy2." + DOMAIN, 5061))
+ .andReturn(new InetSocketAddress[]{a3, a4});
+ replay(nu, srv1, srv2);
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a2, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a3, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a4, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1, srv2);
+ }
+
+ //-------------------
+
+ public void testThreeNaptrOneSrvEachOneAEach()
+ throws ParseException,
+ DnssecException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{
+ {"0", "udp", "_sip._udp." + DOMAIN},
+ {"0", "tcp", "_sip._tcp." + DOMAIN},
+ {"0", "tls", "_sips._tcp." + DOMAIN}
+ });
+ expect(nu.getSRVRecords("_sip._udp."+DOMAIN))
+ .andReturn(new SRVRecord[]{ srv1 });
+ expect(nu.getSRVRecords("_sip._tcp."+DOMAIN))
+ .andReturn(new SRVRecord[]{ srv2 });
+ expect(nu.getSRVRecords("_sips._tcp."+DOMAIN))
+ .andReturn(new SRVRecord[]{ srv3 });
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+ expect(nu.getAandAAAARecords("proxy2." + DOMAIN, 5061))
+ .andReturn(new InetSocketAddress[]{a1});
+ expect(nu.getAandAAAARecords("proxy3." + DOMAIN, 5062))
+ .andReturn(new InetSocketAddress[]{a1});
+
+ replay(nu, srv1, srv2, srv3);
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("TCP", apd.getTransport());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("TLS", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1, srv2, srv3);
+ }
+
+ //-----------------------
+
+ public void testNoSrvOneA() throws ParseException, DnssecException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
+ expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "UDP", DOMAIN)).andReturn(null);
+ expect(nu.getAandAAAARecords(DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+
+ replay(nu);
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu);
+ }
+
+ public void testOneSrvNoA() throws ParseException, DnssecException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
+ expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "UDP", DOMAIN))
+ .andReturn(new SRVRecord[]{srv1});
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(null);
+
+ replay(nu, srv1);
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1);
+ }
+
+ public void testOneSrvOneA() throws ParseException, DnssecException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
+ expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "UDP", DOMAIN))
+ .andReturn(new SRVRecord[]{srv1});
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+
+ replay(nu, srv1);
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1);
+ }
+
+ public void testOneSrvTwoA() throws ParseException, DnssecException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
+ expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "UDP", DOMAIN))
+ .andReturn(new SRVRecord[]{srv1});
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1, a2});
+
+ replay(nu, srv1);
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a2, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1);
+ }
+
+ public void testTwoSrvOneA() throws ParseException, DnssecException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
+ expect(nu.getSRVRecords("sips", "TCP", DOMAIN))
+ .andReturn(new SRVRecord[]{srv2});
+ expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "UDP", DOMAIN))
+ .andReturn(new SRVRecord[]{srv1});
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+ expect(nu.getAandAAAARecords("proxy2." + DOMAIN, 5061))
+ .andReturn(new InetSocketAddress[]{a2});
+
+ replay(nu, srv1, srv2);
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a2, apd.getAddress());
+ assertEquals("TLS", apd.getTransport());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1, srv2);
+ }
+
+ public void testTwoSameSrvOneA() throws ParseException, DnssecException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
+ expect(nu.getSRVRecords("sips", "TCP", DOMAIN))
+ .andReturn(new SRVRecord[]{srv1, srv2});
+ expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "UDP", DOMAIN)).andReturn(null);
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+ expect(nu.getAandAAAARecords("proxy2." + DOMAIN, 5061))
+ .andReturn(new InetSocketAddress[]{a2});
+
+ replay(nu, srv1, srv2);
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("TLS", apd.getTransport());
+ assertEquals(5060, apd.getAddress().getPort());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a2, apd.getAddress());
+ assertEquals("TLS", apd.getTransport());
+ assertEquals(5061, apd.getAddress().getPort());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1, srv2);
+ }
+
+ //----------------------
+
+ public void testNoA() throws ParseException, DnssecException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
+ expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "UDP", DOMAIN)).andReturn(null);
+ expect(nu.getAandAAAARecords(DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{});
+
+ replay(nu);
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu);
+ }
+
+ public void testOneA() throws ParseException, DnssecException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
+ expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "UDP", DOMAIN)).andReturn(null);
+ expect(nu.getAandAAAARecords(DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+
+ replay(nu);
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu);
+ }
+
+ public void testTwoA() throws ParseException, DnssecException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
+ expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "UDP", DOMAIN)).andReturn(null);
+ expect(nu.getAandAAAARecords(DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1, a2});
+
+ replay(nu);
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a2, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu);
+ }
+
+ public void testNotReturningSameAddressTwice()
+ throws ParseException,
+ DnssecException
+ {
+ expect(srv1.getTarget()).andReturn("proxy1."+DOMAIN);
+ expect(srv1.getPort()).andReturn(5060);
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{
+ {"0", "udp", "_sip._udp." + DOMAIN},
+ {"1", "udp", "_sip._udp." + DOMAIN}
+ });
+ expect(nu.getSRVRecords("_sip._udp."+DOMAIN)).andReturn(new SRVRecord[]{
+ srv1
+ });
+ expect(nu.getSRVRecords("_sip._udp."+DOMAIN)).andReturn(new SRVRecord[]{
+ srv1
+ });
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+
+ replay(nu, srv1);
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1);
+ }
+}
diff --git a/test/net/java/sip/communicator/slick/protocol/sip/TestProtocolProviderServiceSipImpl.java b/test/net/java/sip/communicator/slick/protocol/sip/TestProtocolProviderServiceSipImpl.java
index b475ac9..a799668 100644
--- a/test/net/java/sip/communicator/slick/protocol/sip/TestProtocolProviderServiceSipImpl.java
+++ b/test/net/java/sip/communicator/slick/protocol/sip/TestProtocolProviderServiceSipImpl.java
@@ -19,7 +19,9 @@ package net.java.sip.communicator.slick.protocol.sip;
import java.util.*;
+import javax.sip.address.*;
import junit.framework.*;
+import net.java.sip.communicator.impl.protocol.sip.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
@@ -150,7 +152,7 @@ public class TestProtocolProviderServiceSipImpl
/**
- * Verifies that all operation sets have the type they are declarded to
+ * Verifies that all operation sets have the type they are declared to
* have.
*
* @throws java.lang.Exception if a class indicated in one of the keys
@@ -175,6 +177,27 @@ public class TestProtocolProviderServiceSipImpl
}
/**
+ * Tests the <tt>equals()</tt> implementation of the SIP Contact class
+ */
+ public void testContactSipImpl() throws Exception
+ {
+ ProtocolProviderServiceSipImpl provider =
+ (ProtocolProviderServiceSipImpl) fixture.provider1;
+ Address reference =
+ provider.parseAddressString("sip:User@Host");
+ Contact referenceContact = new ContactSipImpl(reference, provider);
+
+ assertTrue("Cannot find user-only part in a SIP Contact compare",
+ referenceContact.equals("User"));
+ assertTrue("Cannot find SIP Contact using strings",
+ referenceContact.equals("sip:User@Host"));
+ assertTrue("Cannot find SIP Contact when protocol is secure",
+ referenceContact.equals("sips:User@Host"));
+ assertTrue("Cannot find SIP Contact when port is specified",
+ referenceContact.equals("sip:User@Host:5060"));
+ }
+
+ /**
* A class that would plugin as a registration listener to a protocol
* provider and simply record all events that it sees and notifyAll()
* if it sees an event that notifies us of a completed
diff --git a/test/net/java/sip/communicator/slick/protocol/yahoo/TestAccountInstallation.java b/test/net/java/sip/communicator/slick/protocol/yahoo/TestAccountInstallation.java
deleted file mode 100644
index 0df8b3c..0000000
--- a/test/net/java/sip/communicator/slick/protocol/yahoo/TestAccountInstallation.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.slick.protocol.yahoo;
-
-import java.util.*;
-
-import junit.framework.*;
-import net.java.sip.communicator.service.protocol.*;
-
-import org.osgi.framework.*;
-
-public class TestAccountInstallation
- extends TestCase
-{
-
- /**
- * Creates the test with the specified method name.
- * @param name the name of the method to execute.
- */
- public TestAccountInstallation(String name)
- {
- super(name);
- }
-
- /**
- * JUnit setup method.
- * @throws Exception in case anything goes wrong.
- */
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
- }
-
- /**
- * JUnit teardown method.
- * @throws Exception in case anything goes wrong.
- */
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- }
-
- /**
- * Installs an account and verifies whether the installation has gone well.
- */
- public void testInstallAccount()
- {
- // first obtain a reference to the provider factory
- ServiceReference[] serRefs = null;
- String osgiFilter = "(" + ProtocolProviderFactory.PROTOCOL
- + "="+ProtocolNames.YAHOO+")";
- try{
- serRefs = YahooSlickFixture.bc.getServiceReferences(
- ProtocolProviderFactory.class.getName(), osgiFilter);
- }
- catch (InvalidSyntaxException ex)
- {
- //this really shouldhn't occur as the filter expression is static.
- fail(osgiFilter + " is not a valid osgi filter");
- }
-
- assertTrue(
- "Failed to find a provider factory service for protocol Yahoo",
- serRefs != null && serRefs.length > 0);
-
- //Keep the reference for later usage.
- ProtocolProviderFactory yahooProviderFactory = (ProtocolProviderFactory)
- YahooSlickFixture.bc.getService(serRefs[0]);
-
- //make sure the account is empty
- assertTrue("There was an account registered with the account mananger "
- +"before we've installed any",
- yahooProviderFactory.getRegisteredAccounts().size() == 0);
-
-
- //Prepare the properties of the first yahoo account.
-
- Hashtable<String, String> yahooAccount1Properties = getAccountProperties(
- YahooProtocolProviderServiceLick.ACCOUNT_1_PREFIX);
- Hashtable<String, String> yahooAccount2Properties = getAccountProperties(
- YahooProtocolProviderServiceLick.ACCOUNT_2_PREFIX);
- Hashtable<String, String> yahooAccount3Properties = getAccountProperties(
- YahooProtocolProviderServiceLick.ACCOUNT_3_PREFIX);
-
- //try to install an account with a null account id
- try{
- yahooProviderFactory.installAccount(
- null, yahooAccount1Properties);
- fail("installing an account with a null account id must result "
- +"in a NullPointerException");
- }catch(NullPointerException exc)
- {
- //that's what had to happen
- }
-
- //now really install the accounts
- yahooProviderFactory.installAccount(
- yahooAccount1Properties.get(ProtocolProviderFactory.USER_ID)
- , yahooAccount1Properties);
- yahooProviderFactory.installAccount(
- yahooAccount2Properties.get(ProtocolProviderFactory.USER_ID)
- , yahooAccount2Properties);
- yahooProviderFactory.installAccount(
- yahooAccount3Properties.get(ProtocolProviderFactory.USER_ID)
- , yahooAccount3Properties);
-
-
- //try to install one of the accounts one more time and verify that an
- //excepion is thrown.
- try{
- yahooProviderFactory.installAccount(
- yahooAccount1Properties.get(ProtocolProviderFactory.USER_ID)
- , yahooAccount1Properties);
-
- fail("An IllegalStateException must be thrown when trying to "+
- "install a duplicate account");
-
- }catch(IllegalStateException exc)
- {
- //that's what supposed to happen.
- }
-
- //Verify that the provider factory is aware of our installation
- assertTrue(
- "The newly installed account was not in the acc man's "
- +"registered accounts!",
- yahooProviderFactory.getRegisteredAccounts().size() == 3);
-
- //Verify protocol providers corresponding to the new account have
- //been properly registered with the osgi framework.
-
- osgiFilter =
- "(&("+ProtocolProviderFactory.PROTOCOL +"="+ProtocolNames.YAHOO+")"
- +"(" + ProtocolProviderFactory.USER_ID
- + "=" + yahooAccount1Properties.get(
- ProtocolProviderFactory.USER_ID)
- + "))";
-
- try
- {
- serRefs = YahooSlickFixture.bc.getServiceReferences(
- ProtocolProviderService.class.getName(),
- osgiFilter);
- }
- catch (InvalidSyntaxException ex)
- {
- //this really shouldhn't occur as the filter expression is static.
- fail(osgiFilter + "is not a valid osgi filter");
- }
-
- assertTrue("An protocol provider was apparently not installed as "
- + "requested."
- , serRefs != null && serRefs.length > 0);
-
- Object yahooProtocolProvider
- = YahooSlickFixture.bc.getService(serRefs[0]);
-
- assertTrue("The installed protocol provider does not implement "
- + "the protocol provider service."
- ,yahooProtocolProvider instanceof ProtocolProviderService);
- }
-
- /**
- * Returns all properties necessary for the intialization of the account
- * with <tt>accountPrefix</tt>.
- * @param accountPrefix the prefix contained by all property names for the
- * the account we'd like to initialized
- * @return a Hashtable that can be used when creating the account in a
- * protocol provider factory.
- */
- private Hashtable<String, String> getAccountProperties(String accountPrefix)
- {
- Hashtable<String, String> table = new Hashtable<String, String>();
-
- String userID = System.getProperty(
- accountPrefix + ProtocolProviderFactory.USER_ID, null);
-
- assertNotNull(
- "The system property named "
- + accountPrefix + ProtocolProviderFactory.USER_ID
- +" has to tontain a valid yahoo address that could be used during "
- +"SIP Communicator's tests."
- , userID);
-
- table.put(ProtocolProviderFactory.USER_ID, userID);
-
- String passwd = System.getProperty(
- accountPrefix + ProtocolProviderFactory.PASSWORD, null );
-
- assertNotNull(
- "The system property named "
- + accountPrefix + ProtocolProviderFactory.PASSWORD
- +" has to contain the password corresponding to the account "
- + "specified in "
- + accountPrefix + ProtocolProviderFactory.USER_ID
- , passwd);
-
- table.put(ProtocolProviderFactory.PASSWORD, passwd);
-
- String serverAddress = System.getProperty(
- accountPrefix + ProtocolProviderFactory.SERVER_ADDRESS, null);
-
- // optional
- if(serverAddress != null)
- table.put(ProtocolProviderFactory.SERVER_ADDRESS, serverAddress);
-
- String serverPort = System.getProperty(
- accountPrefix + ProtocolProviderFactory.SERVER_PORT, null);
-
- // optional
- if(serverPort != null)
- table.put(ProtocolProviderFactory.SERVER_PORT, serverPort);
-
- return table;
- }
-}
diff --git a/test/net/java/sip/communicator/slick/protocol/yahoo/TestAccountUninstallation.java b/test/net/java/sip/communicator/slick/protocol/yahoo/TestAccountUninstallation.java
deleted file mode 100644
index 7b04758..0000000
--- a/test/net/java/sip/communicator/slick/protocol/yahoo/TestAccountUninstallation.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.slick.protocol.yahoo;
-
-import junit.framework.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.slick.protocol.generic.*;
-
-import org.osgi.framework.*;
-
-/**
- * Tests whether accounts are uninstalled properly. It is important that
- * tests from this class be called last since they will install the accounts
- * that have been used to test the implementations. Apart from uninstallation
- * tests the class also contains tests that remove and reinstall the protocol
- * provider bundle in order to verify that accounts are persistent.
- *
- * @author Emil Ivov
- * @author Valentin Martinet
- */
-public class TestAccountUninstallation
- extends TestCase
-{
- private YahooSlickFixture fixture = new YahooSlickFixture();
-
- /**
- * Constructs a test instance
- * @param name The name of the test.
- */
- public TestAccountUninstallation(String name)
- {
- super(name);
- }
-
- /**
- * JUnit setup method.
- * @throws Exception in case anything goes wrong.
- */
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
- fixture.setUp();
- }
-
- /**
- * JUnit teardown method.
- * @throws Exception in case anything goes wrong.
- */
- @Override
- protected void tearDown() throws Exception
- {
- fixture.tearDown();
- super.tearDown();
- }
-
- /**
- * Returns a suite containing tests in this class in the order that we'd
- * like them executed.
- * @return a Test suite containing tests in this class in the order that
- * we'd like them executed.
- */
- public static Test suite()
- {
- TestSuite suite = new TestSuite();
-
- suite.addTest(
- new TestAccountUninstallation("testInstallationPersistency"));
- suite.addTest(
- new TestAccountUninstallation("testUninstallAccount"));
-
- return suite;
- }
-
- /**
- * Stops and removes the tested bundle, verifies that it has unregistered
- * its provider, then reloads and restarts the bundle and verifies that
- * the protocol provider is reRegistered in the bundle context.
- *
- * @throws java.lang.Exception if an exception occurs during testing.
- */
- public void testInstallationPersistency() throws Exception
- {
- Bundle providerBundle
- = AdHocMultiUserChatSlickFixture.findProtocolProviderBundle(fixture.provider1);
-
- //set the global providerBundle reference that we will be using
- //in the last series of tests (Account uninstallation persistency)
- YahooSlickFixture.providerBundle = providerBundle;
-
- assertNotNull("Couldn't find a bundle for the tested provider"
- , providerBundle);
-
- providerBundle.stop();
-
- assertTrue("Couldn't stop the protocol provider bundle. State was "
- + providerBundle.getState()
- , Bundle.ACTIVE != providerBundle.getState()
- && Bundle.STOPPING != providerBundle.getState());
-
- providerBundle.uninstall();
-
- assertEquals("Couldn't stop the protocol provider bundle."
- , Bundle.UNINSTALLED, providerBundle.getState());
-
- //verify that the provider is no longer available
- ServiceReference[] yahooProviderRefs = null;
- try
- {
- yahooProviderRefs = AdHocMultiUserChatSlickFixture.bc.getServiceReferences(
- ProtocolProviderService.class.getName(),
- "(&"
- + "(" + ProtocolProviderFactory.PROTOCOL
- + "=" +ProtocolNames.YAHOO + ")"
- + "(" + ProtocolProviderFactory.USER_ID
- + "="+ fixture.userID1 + ")"
- + ")");
- }
- catch (InvalidSyntaxException ex)
- {
- fail("We apparently got our filter wrong: " + ex.getMessage());
- }
-
- //make sure we didn't see a service
- assertTrue("A Protocol Provider Service was still regged as an osgi service "
- +"for yahoo URI:" + fixture.userID1
- + "After it was explicitly uninstalled"
- ,yahooProviderRefs == null || yahooProviderRefs.length == 0);
-
- //verify that the provider factory knows that we have uninstalled the
- //provider.
- assertTrue(
- "The yahoo provider factory kept a reference to the provider we just "
- +"uninstalled (uri="+fixture.userID1+")",
- fixture.providerFactory.getRegisteredAccounts().isEmpty()
- && fixture.providerFactory.getProviderForAccount(
- fixture.provider1.getAccountID())
- == null);
-
- //Now reinstall the bundle
- providerBundle = AdHocMultiUserChatSlickFixture.bc.installBundle(providerBundle.getLocation());
-
- //set the global providerBundle reference that we will be using
- //in the last series of tests (Account uninstallation persistency)
- YahooSlickFixture.providerBundle = providerBundle;
-
- assertEquals("Couldn't re-install protocol provider bundle."
- , Bundle.INSTALLED, providerBundle.getState());
-
- AccountManagerUtils.startBundleAndWaitStoredAccountsLoaded(AdHocMultiUserChatSlickFixture.bc,
- providerBundle, ProtocolNames.YAHOO);
- assertEquals("Couldn't re-start protocol provider bundle."
- , Bundle.ACTIVE, providerBundle.getState());
-
- //Make sure that the provider is there again.
- //verify that the provider is no longer available
- try
- {
- yahooProviderRefs = AdHocMultiUserChatSlickFixture.bc.getServiceReferences(
- ProtocolProviderService.class.getName(),
- "(&"
- + "(" + ProtocolProviderFactory.PROTOCOL
- + "=" +ProtocolNames.YAHOO + ")"
- + "(" + ProtocolProviderFactory.USER_ID
- + "="+ fixture.userID1 + ")"
- + ")");
- }
- catch (InvalidSyntaxException ex)
- {
- fail("We apparently got our filter wrong " + ex.getMessage());
- }
-
- //make sure we didn't see a service
- assertTrue("A Protocol Provider Service was not restored after being"
- +"reinstalled. yahoo URI:" + fixture.userID1
- ,yahooProviderRefs != null && yahooProviderRefs.length > 0);
-
- ServiceReference[] yahooFactoryRefs = null;
- try
- {
- yahooFactoryRefs = AdHocMultiUserChatSlickFixture.bc.getServiceReferences(
- ProtocolProviderFactory.class.getName(),
- "(" + ProtocolProviderFactory.PROTOCOL
- + "=" +ProtocolNames.YAHOO + ")");
- }
- catch (InvalidSyntaxException ex)
- {
- fail("We apparently got our filter wrong " + ex.getMessage());
- }
-
- //we're the ones who've reinstalled the factory so it's our
- //responsibility to update the fixture.
- fixture.providerFactory
- = (ProtocolProviderFactory)AdHocMultiUserChatSlickFixture.bc.getService(yahooFactoryRefs[0]);
- fixture.provider1
- = (ProtocolProviderService)AdHocMultiUserChatSlickFixture.bc.getService(yahooProviderRefs[0]);
-
-
- //verify that the provider is also restored in the provider factory
- //itself
- assertTrue(
- "The yahoo provider did not restore its own reference to the provider "
- +"that we just reinstalled (URI="+fixture.userID1+")",
- !fixture.providerFactory.getRegisteredAccounts().isEmpty()
- && fixture.providerFactory.getProviderForAccount(
- fixture.provider1.getAccountID())
- != null);
-
- }
-
- /**
- * Uninstalls our test account and makes sure it really has been removed.
- *
- */
- public void testUninstallAccount()
- {
- assertFalse("No installed accounts found",
- fixture.providerFactory.getRegisteredAccounts().isEmpty());
-
- assertNotNull(
- "Found no provider corresponding to URI " + fixture.userID1
- ,fixture.providerFactory.getProviderForAccount(
- fixture.provider1.getAccountID()));
-
- assertTrue(
- "Failed to remove a provider corresponding to URI "
- + fixture.userID1
- ,fixture.providerFactory.uninstallAccount(
- fixture.provider1.getAccountID()));
- assertTrue(
- "Failed to remove a provider corresponding to URI "
- + fixture.userID2
- ,fixture.providerFactory.uninstallAccount(
- fixture.provider2.getAccountID()));
- assertTrue(
- "Failed to remove a provider corresponding to URI "
- + fixture.userID3
- ,fixture.providerFactory.uninstallAccount(
- fixture.provider3.getAccountID()));
-
- //make sure no providers have remained installed.
- ServiceReference[] yahooProviderRefs = null;
- try
- {
- yahooProviderRefs = AdHocMultiUserChatSlickFixture.bc.getServiceReferences(
- ProtocolProviderService.class.getName(),
- "(" + ProtocolProviderFactory.PROTOCOL
- + "=" +ProtocolNames.YAHOO + ")");
- }
- catch (InvalidSyntaxException ex)
- {
- fail("We apparently got our filter wrong " + ex.getMessage());
- }
-
- //make sure we didn't see a service
- assertTrue("A Protocol Provider Service was still regged as an osgi "
- + "service for yahoo URI:" + fixture.userID1
- + "After it was explicitly uninstalled"
- ,yahooProviderRefs == null || yahooProviderRefs.length == 0);
-
- //verify that the provider factory knows that we have uninstalled the
- //provider.
- assertTrue(
- "The yahoo provider factory kept a reference to the provider we just "
- +"uninstalled (uri="+fixture.userID1+")",
- fixture.providerFactory.getRegisteredAccounts().isEmpty()
- && fixture.providerFactory.getProviderForAccount(
- fixture.provider1.getAccountID())
- == null);
-
- }
-}
diff --git a/test/net/java/sip/communicator/slick/protocol/yahoo/TestAccountUninstallationPersistence.java b/test/net/java/sip/communicator/slick/protocol/yahoo/TestAccountUninstallationPersistence.java
deleted file mode 100644
index d87a238..0000000
--- a/test/net/java/sip/communicator/slick/protocol/yahoo/TestAccountUninstallationPersistence.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.slick.protocol.yahoo;
-
-import junit.framework.*;
-import net.java.sip.communicator.service.protocol.*;
-
-import org.jitsi.service.configuration.*;
-import org.osgi.framework.*;
-
-/**
- * Contains tests verifying persistence of account uninstallation. In other
- * words we try to make sure that once uninstalled an account remains
- * uninstalled.
- *
- * @author Emil Ivov
- */
-public class TestAccountUninstallationPersistence
- extends TestCase
-{
- /**
- * Creates a new test instance wrapper around the test with the specified
- * name.
- * @param testName the name of the test that we will be executing.
- */
- public TestAccountUninstallationPersistence(String testName)
- {
- super(testName);
- }
-
- /**
- * Retrieves a reference to the yahoo bundle, stops it and uninstalls it and
- * then reinstalls it in order to make sure that accounts are not reloaded
- * once removed.
- *
- * @throws java.lang.Exception if something goes wrong while manipulating
- * the bundles.
- */
- public void testAccountUninstallationPersistence()
- throws Exception
- {
- Bundle providerBundle = YahooSlickFixture.providerBundle;
-
- providerBundle.stop();
-
- assertTrue("Couldn't stop the protocol provider bundle. State was "
- + providerBundle.getState()
- , Bundle.ACTIVE != providerBundle.getState()
- && Bundle.STOPPING != providerBundle.getState());
-
- providerBundle.uninstall();
-
- assertEquals("Couldn't stop the protocol provider bundle."
- , Bundle.UNINSTALLED, providerBundle.getState());
-
- //Now reinstall the bundle and restart the provider
- providerBundle
- = YahooSlickFixture.bc.installBundle(providerBundle.getLocation());
-
- assertEquals("Couldn't re-install protocol provider bundle."
- , Bundle.INSTALLED, providerBundle.getState());
-
- AccountManagerUtils.startBundleAndWaitStoredAccountsLoaded(
- YahooSlickFixture.bc, providerBundle, ProtocolNames.YAHOO);
- assertEquals("Couldn't re-start protocol provider bundle."
- , Bundle.ACTIVE, providerBundle.getState());
-
-
- //verify that the provider is not reinstalled
- ServiceReference[] yahooProviderRefs = null;
- try
- {
- yahooProviderRefs = YahooSlickFixture.bc.getServiceReferences(
- ProtocolProviderService.class.getName(),
- "(" + ProtocolProviderFactory.PROTOCOL
- + "=" +ProtocolNames.YAHOO + ")");
- }
- catch (InvalidSyntaxException ex)
- {
- fail("We apparently got our filter wrong " + ex.getMessage());
- }
-
- //make sure we didn't retrieve a service
- assertTrue("A yahoo Protocol Provider Service was still regged as an "
- +"osgi service after it was explicitly uninstalled"
- ,yahooProviderRefs == null || yahooProviderRefs.length == 0);
-
- //and a nasty hack at the end - delete the configuration file so that
- //we get a fresh start on next run.
- ServiceReference confReference
- = YahooSlickFixture.bc.getServiceReference(
- ConfigurationService.class.getName());
- ConfigurationService configurationService
- = (ConfigurationService) YahooSlickFixture.bc.getService(confReference);
-
- configurationService.purgeStoredConfiguration();
- }
-}
diff --git a/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetAdHocMultiUserChatYahooImpl.java b/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetAdHocMultiUserChatYahooImpl.java
deleted file mode 100644
index 3f66045..0000000
--- a/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetAdHocMultiUserChatYahooImpl.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.slick.protocol.yahoo;
-
-import java.util.*;
-
-import junit.framework.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.slick.protocol.generic.*;
-
-/**
- * Tests for the Yahoo! ad-hoc multi-user chat operation set.
- *
- * @author Valentin Martinet
- */
-public class TestOperationSetAdHocMultiUserChatYahooImpl
-extends TestOperationSetAdHocMultiUserChat
-{
- /**
- * Creates the test with the specified method name.
- *
- * @param name the name of the method to execute.
- */
- public TestOperationSetAdHocMultiUserChatYahooImpl(String name)
- {
- super(name);
- }
-
-
- /**
- * Creates a test suite containing tests of this class in a specific order.
- *
- * @return Test a testsuite containing all tests to execute.
- */
- public static TestSuite suite()
- {
- TestSuite suite = new TestSuite();
-
- suite.addTest(new TestOperationSetAdHocMultiUserChatYahooImpl(
- "testRegisterAccount3"));
- suite.addTest(new TestOperationSetAdHocMultiUserChatYahooImpl(
- "prepareContactList"));
- suite.addTest(new TestOperationSetAdHocMultiUserChatYahooImpl(
- "testCreateRoomWithParticipants"));
- suite.addTest(new TestOperationSetAdHocMultiUserChatYahooImpl(
- "testInvitations"));
- suite.addTest(new TestOperationSetAdHocMultiUserChatYahooImpl(
- "testSendIM"));
- suite.addTest(new TestOperationSetAdHocMultiUserChatYahooImpl(
- "testPeerLeaved"));
-
- return suite;
- }
-
- /**
- * Register the third testing account.
- *
- * @throws OperationFailedException
- */
- public void testRegisterAccount3() throws OperationFailedException
- {
- fixture.provider3.register(
- new SecurityAuthorityImpl(
- System.getProperty(
- YahooProtocolProviderServiceLick.ACCOUNT_3_PREFIX
- + ProtocolProviderFactory.PASSWORD).toCharArray()));
-
- assertEquals(fixture.provider3.getRegistrationState(),
- RegistrationState.REGISTERED);
- }
-
- /**
- * JUnit setUp method.
- * @throws Exception
- *
- * @throws Exception
- */
- @Override
- public void start() throws Exception
- {
- fixture = new YahooSlickFixture();
- fixture.setUp();
-
- // Supported operation sets by each protocol provider.
- Map<String, OperationSet>
- supportedOpSets1, supportedOpSets2, supportedOpSets3;
-
- supportedOpSets1 = fixture.provider1.getSupportedOperationSets();
- supportedOpSets2 = fixture.provider2.getSupportedOperationSets();
- supportedOpSets3 = fixture.provider3.getSupportedOperationSets();
-
- //
- // Initialization of operation sets for the first testing account:
- //
-
- if (supportedOpSets1 == null || supportedOpSets1.size() < 1)
- throw new NullPointerException(
- "No OperationSet implementations are supported by " +
- "this implementation. ");
-
- opSetAHMUC1 = (OperationSetAdHocMultiUserChat) supportedOpSets1.get(
- OperationSetAdHocMultiUserChat.class.getName());
-
- if (opSetAHMUC1 == null)
- throw new NullPointerException(
- "No implementation for multi user chat was found");
-
- opSetPresence1 = (OperationSetPresence) supportedOpSets1.get(
- OperationSetPresence.class.getName());
-
- if (opSetPresence1 == null)
- throw new NullPointerException(
- "An implementation of the service must provide an " +
- "implementation of at least one of the PresenceOperationSets");
-
-
- //
- // Initialization of operation sets for the second testing account:
- //
-
- if (supportedOpSets2 == null || supportedOpSets2.size() < 1)
- throw new NullPointerException(
- "No OperationSet implementations are supported by " +
- "this implementation. ");
-
- opSetAHMUC2 = (OperationSetAdHocMultiUserChat) supportedOpSets2.get(
- OperationSetAdHocMultiUserChat.class.getName());
-
- if (opSetAHMUC2 == null)
- throw new NullPointerException(
- "No implementation for ad hoc multi user chat was found");
-
- opSetPresence2 = (OperationSetPresence) supportedOpSets2.get(
- OperationSetPresence.class.getName());
-
- if (opSetPresence2 == null)
- throw new NullPointerException(
- "An implementation of the service must provide an " +
- "implementation of at least one of the PresenceOperationSets");
-
-
- //
- // Initialization of operation sets for the third testing account:
- //
-
- if (supportedOpSets3 == null || supportedOpSets3.size() < 1)
- throw new NullPointerException(
- "No OperationSet implementations are supported by " +
- "this implementation. ");
-
- opSetAHMUC3 = (OperationSetAdHocMultiUserChat) supportedOpSets3.get(
- OperationSetAdHocMultiUserChat.class.getName());
-
- if (opSetAHMUC3 == null)
- throw new NullPointerException(
- "No implementation for ad hoc multi user chat was found");
-
- opSetPresence3 = (OperationSetPresence) supportedOpSets3.get(
- OperationSetPresence.class.getName());
-
- if (opSetPresence3 == null)
- throw new NullPointerException(
- "An implementation of the service must provide an " +
- "implementation of at least one of the PresenceOperationSets");
- }
-
-}
diff --git a/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetBasicInstantMessaging.java b/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetBasicInstantMessaging.java
deleted file mode 100644
index 9b8fa7b..0000000
--- a/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetBasicInstantMessaging.java
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.slick.protocol.yahoo;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-import junit.framework.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Performs testing of the basic instant messaging operation set. Tests include
- * going over basic functionality such as sending a message from the tested
- * implementation and asserting reception by the tester agent and vice versa.
- * @author Emil Ivov
- */
-public class TestOperationSetBasicInstantMessaging
- extends TestCase
-{
- private static final Logger logger =
- Logger.getLogger(TestOperationSetBasicInstantMessaging.class);
-
- private YahooSlickFixture fixture = new YahooSlickFixture();
-
- private OperationSetBasicInstantMessaging opSetBasicIM1 = null;
- private OperationSetBasicInstantMessaging opSetBasicIM2 = null;
-
- private OperationSetPresence opSetPresence1 = null;
- private OperationSetPresence opSetPresence2 = null;
-
- public TestOperationSetBasicInstantMessaging(String name)
- {
- super(name);
- }
-
- /**
- * Get a reference to the basic IM operation set.
- * @throws Exception if this is not a good day.
- */
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
- fixture.setUp();
-
- Map<String, OperationSet> supportedOperationSets1 =
- fixture.provider1.getSupportedOperationSets();
-
- if ( supportedOperationSets1 == null
- || supportedOperationSets1.size() < 1)
- throw new NullPointerException(
- "No OperationSet implementations are supported by "
- +"this implementation. ");
-
- //get the operation set presence here.
- opSetBasicIM1 =
- (OperationSetBasicInstantMessaging)supportedOperationSets1.get(
- OperationSetBasicInstantMessaging.class.getName());
-
- if (opSetBasicIM1 == null)
- {
- throw new NullPointerException(
- "No implementation for basic IM was found");
- }
-
- //we also need the presence op set in order to retrieve contacts.
- opSetPresence1 =
- (OperationSetPresence)supportedOperationSets1.get(
- OperationSetPresence.class.getName());
-
- //if the op set is null show that we're not happy.
- if (opSetPresence1 == null)
- {
- throw new NullPointerException(
- "An implementation of the service must provide an "
- + "implementation of at least one of the PresenceOperationSets");
- }
-
- Map<String, OperationSet> supportedOperationSets2 =
- fixture.provider2.getSupportedOperationSets();
-
- if ( supportedOperationSets2 == null
- || supportedOperationSets2.size() < 1)
- throw new NullPointerException(
- "No OperationSet implementations are supported by "
- +"this implementation. ");
-
- //get the operation set presence here.
- opSetBasicIM2 =
- (OperationSetBasicInstantMessaging)supportedOperationSets2.get(
- OperationSetBasicInstantMessaging.class.getName());
-
- if (opSetBasicIM2 == null)
- {
- throw new NullPointerException(
- "No implementation for basic IM was found");
- }
-
- opSetPresence2 =
- (OperationSetPresence) supportedOperationSets2.get(
- OperationSetPresence.class.getName());
-
- //if the op set is null show that we're not happy.
- if (opSetPresence2 == null)
- {
- throw new NullPointerException(
- "An implementation of the service must provide an "
- + "implementation of at least one of the PresenceOperationSets");
- }
-
- }
-
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
-
- fixture.tearDown();
- }
-
- /**
- * Creates a test suite containing tests of this class in a specific order.
- * We'll first execute tests beginning with the "test" prefix and then go to
- * ordered tests.We first execture tests for receiving messagese, so that
- * a volatile contact is created for the sender. we'll then be able to
- * retrieve this volatile contact and send them a message on our turn.
- * We need to do things this way as the contact corresponding to the tester
- * agent has been removed in the previous test and we no longer have it
- * in our contact list.
- *
- * @return Test a testsuite containing all tests to execute.
- */
- public static Test suite()
- {
- TestSuite suite = new TestSuite();
-
- suite.addTest(new TestOperationSetBasicInstantMessaging(
- "prepareContactList"));
-
- suite.addTestSuite(TestOperationSetBasicInstantMessaging.class);
-
- //the following 2 need to be run in the specified order.
- suite.addTest(new TestOperationSetBasicInstantMessaging(
- "firstTestReceiveMessage"));
- suite.addTest(new TestOperationSetBasicInstantMessaging(
- "thenTestSendMessage"));
-
- return suite;
- }
-
- /**
- * Create the list to be sure that contacts exchanging messages
- * exists in each other lists
- * @throws Exception
- */
- public void prepareContactList()
- throws Exception
- {
- fixture.clearProvidersLists();
-
- Object o = new Object();
- synchronized(o)
- {
- o.wait(2000);
- }
-
- try
- {
- opSetPresence1.subscribe(fixture.userID2);
- }
- catch (OperationFailedException ex)
- {
- // the contact already exist its OK
- }
-
- try
- {
- opSetPresence2.subscribe(fixture.userID1);
- }
- catch (OperationFailedException ex1)
- {
- // the contact already exist its OK
- }
-
- synchronized(o)
- {
- o.wait(2000);
- }
- }
-
- /**
- * Send an instant message from the tested operation set and assert
- * reception by the tester agent.
- */
- public void firstTestReceiveMessage()
- {
- ContactGroup rootGroup
- = ((OperationSetPersistentPresence)opSetPresence2).getServerStoredContactListRoot();
-
- logger.debug("=========== Server Stored Contact List =================");
-
- logger.debug("rootGroup="+rootGroup.getGroupName()
- +" rootGroup.childContacts="+rootGroup.countContacts()
- + "rootGroup.childGroups="+rootGroup.countSubgroups()
- + "Printing rootGroupContents=\n"+rootGroup.toString());
-
- String body = "This is an IM coming from the tester agent"
- + " on " + new Date().toString();
-
- ImEventCollector evtCollector = new ImEventCollector();
-
- //add a msg listener and register to the op set and send an instant
- //msg from the tester agent.
- opSetBasicIM1.addMessageListener(evtCollector);
-
- Contact testerAgentContact
- = opSetPresence2.findContactByID(fixture.userID1);
-
- logger.debug("Will send message " + body + " to: " + testerAgentContact);
-
- opSetBasicIM2.sendInstantMessage(testerAgentContact,
- opSetBasicIM2.createMessage(body));
-
- evtCollector.waitForEvent(10000);
-
- opSetBasicIM1.removeMessageListener(evtCollector);
-
- //assert reception of a message event
- assertTrue( "No events delivered upon a received message"
- , evtCollector.collectedEvents.size() > 0);
-
- //assert event instance of Message Received Evt
- assertTrue( "Received evt was not an instance of "
- + MessageReceivedEvent.class.getName()
- , evtCollector.collectedEvents.get(0)
- instanceof MessageReceivedEvent);
-
- //assert source contact == testAgent.uin
- MessageReceivedEvent evt
- = (MessageReceivedEvent)evtCollector.collectedEvents.get(0);
- assertEquals("message sender "
- , evt.getSourceContact().getAddress()
- , fixture.userID2);
-
- //assert messageBody == body
- assertEquals("message body", body, evt.getSourceMessage().getContent());
- }
-
- /**
- * Send an instant message from the tester agent and assert reception by
- * the tested implementation
- */
- public void thenTestSendMessage()
- {
- String body = "This is an IM coming from the tested implementation"
- + " on " + new Date().toString();
-
- //create the message
- net.java.sip.communicator.service.protocol.Message msg
- = opSetBasicIM1.createMessage(body);
-
- //register a listener in the op set
- ImEventCollector imEvtCollector1 = new ImEventCollector();
- opSetBasicIM1.addMessageListener(imEvtCollector1);
-
- //register a listener in the tester agent
- ImEventCollector imEvtCollector2 = new ImEventCollector();
- opSetBasicIM2.addMessageListener(imEvtCollector2);
-
- Contact testerAgentContact
- = opSetPresence1.findContactByID(fixture.userID2);
-
- opSetBasicIM1.sendInstantMessage(testerAgentContact, msg);
-
- imEvtCollector1.waitForEvent(10000);
- imEvtCollector2.waitForEvent(10000);
-
- opSetBasicIM1.removeMessageListener(imEvtCollector1);
- opSetBasicIM2.removeMessageListener(imEvtCollector2);
-
- //verify that the message delivered event was dispatched
- assertTrue( "No events delivered when sending a message"
- , imEvtCollector1.collectedEvents.size() > 0);
-
- assertTrue( "Received evt was not an instance of "
- + MessageDeliveredEvent.class.getName()
- , imEvtCollector1.collectedEvents.get(0)
- instanceof MessageDeliveredEvent);
-
- MessageDeliveredEvent evt
- = (MessageDeliveredEvent)imEvtCollector1.collectedEvents.get(0);
- assertEquals("message destination "
- , evt.getDestinationContact().getAddress()
- , fixture.userID2);
-
- assertSame("source message", msg, evt.getSourceMessage());
-
-
- //verify that the message has successfully arived at the destination
- assertTrue( "No messages received by the tester agent"
- , imEvtCollector2.collectedEvents.size() > 0);
- String receivedBody =
- ((MessageReceivedEvent)imEvtCollector2.collectedEvents
- .get(0)).getSourceMessage().getContent();
-
- assertEquals("received message body", msg.getContent(), receivedBody);
- }
-
- /**
- * Creates an Message through the simple createMessage() method and inspects
- * its parameters.
- */
- public void testCreateMessage1()
- {
- String body = "This is an IM coming from the tested implementation"
- + " on " + new Date().toString();
- net.java.sip.communicator.service.protocol.Message msg
- = opSetBasicIM1.createMessage(body);
-
- assertEquals("message body", body, msg.getContent());
- assertTrue("message body bytes"
- , Arrays.equals(body.getBytes(), msg.getRawData()));
- assertEquals("message length", body.length(), msg.getSize());
- assertEquals("message content type"
- , OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE
- , msg.getContentType());
-
- assertEquals("message encoding"
- , OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING
- , msg.getEncoding());
-
- assertNotNull("message uid", msg.getMessageUID());
-
- //a further test on message uid.
- net.java.sip.communicator.service.protocol.Message msg2
- = opSetBasicIM1.createMessage(body);
- assertFalse("message uid", msg.getMessageUID().equals(
- msg2.getMessageUID()));
- }
-
- /**
- * Creates an Message through the advance createMessage() method and
- * inspects its parameters.
- */
- public void testCreateMessage2()
- throws UnsupportedEncodingException
- {
- String body = "This is an IM coming from the tested implementation"
- + " on " + new Date().toString();
- String contentType = "text/html";
- String encoding = "UTF-16";
- String subject = "test message";
- net.java.sip.communicator.service.protocol.Message msg =
- opSetBasicIM1.createMessage(body, contentType, encoding, subject);
- byte[] bodyBytes = body.getBytes(encoding);
-
- assertEquals("message body", body, msg.getContent());
- assertTrue("message body bytes"
- , Arrays.equals(bodyBytes, msg.getRawData()));
- assertEquals("message length", bodyBytes.length, msg.getSize());
- assertEquals("message content type", contentType, msg.getContentType());
- assertEquals("message encoding", encoding, msg.getEncoding());
- assertNotNull("message uid", msg.getMessageUID());
-
- //a further test on message uid.
- net.java.sip.communicator.service.protocol.Message msg2
- = opSetBasicIM1.createMessage(body);
- assertFalse("message uid", msg.getMessageUID().equals(
- msg2.getMessageUID()));
- }
-
- /**
- * Collects instant messaging events.
- */
- private class ImEventCollector implements MessageListener
- {
- private List<EventObject> collectedEvents = new LinkedList<EventObject>();
- /**
- * Called when a new incoming <tt>Message</tt> has been received.
- * @param evt the <tt>MessageReceivedEvent</tt> containing the newly
- * received message, its sender and other details.
- */
- public void messageReceived(MessageReceivedEvent evt)
- {
- logger.debug("Received a MessageReceivedEvent: " + evt);
-
- synchronized(this)
- {
- collectedEvents.add(evt);
- notifyAll();
- }
- }
-
- /**
- * Called to indicated that delivery of a message sent earlier has failed.
- * Reason code and phrase are contained by the <tt>MessageFailedEvent</tt>
- * @param evt the <tt>MessageFailedEvent</tt> containing the ID of the
- * message whose delivery has failed.
- */
- public void messageDeliveryFailed(MessageDeliveryFailedEvent evt)
- {
- logger.debug("Received a MessageDeliveryFailedEvent: " + evt);
-
- synchronized(this)
- {
- collectedEvents.add(evt);
- notifyAll();
- }
- }
-
-
- /**
- * Called when the underlying implementation has received an indication
- * that a message, sent earlier has been successfully received by the
- * destination.
- * @param evt the MessageDeliveredEvent containing the id of the message
- * that has caused the event.
- */
- public void messageDelivered(MessageDeliveredEvent evt)
- {
- logger.debug("Received a MessageDeliveredEvent: " + evt);
-
- synchronized(this)
- {
- collectedEvents.add(evt);
- notifyAll();
- }
- }
-
- /**
- * Blocks until at least one event is received or until waitFor
- * miliseconds pass (whichever happens first).
- *
- * @param waitFor the number of miliseconds that we should be waiting
- * for an event before simply bailing out.
- */
- public void waitForEvent(long waitFor)
- {
- synchronized(this)
- {
-
- if(collectedEvents.size() > 0)
- {
- logger.trace("ImEvent already received. " + collectedEvents);
- return;
- }
-
- try{
- wait(waitFor);
- }
- catch (InterruptedException ex)
- {
- logger.debug(
- "Interrupted while waiting for a message evt", ex);
- }
- }
- }
- }
-
- /**
- * A method that would simply send messages to a group of people so that
- * they would get notified that tests are being run.
- */
- public void testSendFunMessages()
- {
- String hostname = "";
-
- try{
- hostname = java.net.InetAddress.getLocalHost().getHostName() + ": ";
- }catch (UnknownHostException ex){}
-
- String message = hostname
- + "Hello this is the SIP Communicator (version "
- + System.getProperty("sip-communicator.version")
- + ") build on: "
- + new Date().toString()
- + ". Have a very nice day!";
-
- String list = System.getProperty("accounts.reporting.YAHOO_REPORT_LIST");
-
- logger.debug("Will send message " + message + " to: " + list);
-
- //if no property is specified - return
- if(list == null || list.trim().length() == 0)
- return;
-
- StringTokenizer tokenizer = new StringTokenizer(list, " ");
-
- while(tokenizer.hasMoreTokens())
- {
- String contactID = tokenizer.nextToken();
- Contact contact
- = opSetPresence2.findContactByID(contactID);
-
- if(contact == null)
- {
- try
- {
- opSetPresence2.subscribe(contactID);
- Object o = new Object();
- synchronized (o)
- {
- o.wait(2000);
- }
- }
- catch (Exception ex1)
- {
- continue;
- }
- }
-
- contact
- = opSetPresence2.findContactByID(contactID);
-
- opSetBasicIM2.sendInstantMessage(contact,
- opSetBasicIM2.createMessage(message));
- }
- }
-}
diff --git a/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetFileTransferImpl.java b/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetFileTransferImpl.java
deleted file mode 100644
index 90a2ff3..0000000
--- a/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetFileTransferImpl.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.slick.protocol.yahoo;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.slick.protocol.generic.*;
-import net.java.sip.communicator.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * Implementation for generic file transfer.
- * @author Damian Minkov
- */
-public class TestOperationSetFileTransferImpl
- extends TestOperationSetFileTransfer
-{
- private static final Logger logger =
- Logger.getLogger(TestOperationSetFileTransferImpl.class);
-
- private YahooSlickFixture fixture = new YahooSlickFixture();
-
- private OperationSetPresence opSetPresence1 = null;
- private OperationSetPresence opSetPresence2 = null;
-
- private OperationSetFileTransfer opSetFT1 = null;
- private OperationSetFileTransfer opSetFT2 = null;
-
- private static Contact contact1 = null;
- private static Contact contact2 = null;
-
- @Override
- public Contact getContact1()
- {
- if(contact1 == null)
- {
- contact1 = opSetPresence1.findContactByID(fixture.userID2);
- }
-
- return contact1;
- }
-
- @Override
- public Contact getContact2()
- {
- if(contact2 == null)
- {
- contact2 = opSetPresence2.findContactByID(fixture.userID1);
- }
-
- return contact2;
- }
-
- @Override
- public void start()
- throws Exception
- {
- fixture.setUp();
-
- Map<String, OperationSet> supportedOperationSets1 =
- fixture.provider1.getSupportedOperationSets();
-
- if ( supportedOperationSets1 == null
- || supportedOperationSets1.size() < 1)
- throw new NullPointerException(
- "No OperationSet implementations are supported by "
- +"this implementation. ");
-
- //we also need the presence op set in order to retrieve contacts.
- opSetPresence1 =
- (OperationSetPresence)supportedOperationSets1.get(
- OperationSetPresence.class.getName());
-
- //if the op set is null show that we're not happy.
- if (opSetPresence1 == null)
- {
- throw new NullPointerException(
- "An implementation of the service must provide an "
- + "implementation of at least one of the PresenceOperationSets");
- }
-
- opSetFT1 =
- (OperationSetFileTransfer)supportedOperationSets1.get(
- OperationSetFileTransfer.class.getName());
-
- //if the op set is null show that we're not happy.
- if (opSetFT1 == null)
- {
- throw new NullPointerException(
- "An implementation of the service must provide an "
- + "implementation of at least one of the FileTransferOperationSets");
- }
-
- Map<String, OperationSet> supportedOperationSets2 =
- fixture.provider2.getSupportedOperationSets();
-
- if ( supportedOperationSets2 == null
- || supportedOperationSets2.size() < 1)
- throw new NullPointerException(
- "No OperationSet implementations are supported by "
- +"this implementation. ");
-
- opSetPresence2 =
- (OperationSetPresence) supportedOperationSets2.get(
- OperationSetPresence.class.getName());
-
- //if the op set is null show that we're not happy.
- if (opSetPresence2 == null)
- {
- throw new NullPointerException(
- "An implementation of the service must provide an "
- + "implementation of at least one of the PresenceOperationSets");
- }
-
- opSetFT2 =
- (OperationSetFileTransfer)supportedOperationSets2.get(
- OperationSetFileTransfer.class.getName());
-
- //if the op set is null show that we're not happy.
- if (opSetFT2 == null)
- {
- throw new NullPointerException(
- "An implementation of the service must provide an "
- + "implementation of at least one of the FileTransferOperationSets");
- }
-
- prepareContactList();
- }
-
- @Override
- public void stop()
- throws Exception
- {
- fixture.tearDown();
- }
-
- /**
- * Create the list to be sure that contacts exchanging messages
- * exists in each other lists
- * @throws Exception
- */
- public void prepareContactList()
- throws Exception
- {
- // clear the provider the first time we run a filetransfer list
- if(getContact1() == null && getContact2() == null)
- fixture.clearProvidersLists();
-
- if(getContact1() == null)
- {
- Object o = new Object();
- synchronized(o)
- {
- o.wait(2000);
- }
-
- try
- {
- opSetPresence1.setAuthorizationHandler(new AuthHandler());
- opSetPresence1.subscribe(fixture.userID2);
- }
- catch (OperationFailedException ex)
- {
- // the contact already exist its OK
- }
- }
-
- if(getContact2() == null)
- {
- try
- {
- opSetPresence2.setAuthorizationHandler(new AuthHandler());
- opSetPresence2.subscribe(fixture.userID1);
- }
- catch (OperationFailedException ex1)
- {
- // the contact already exist its OK
- }
-
- logger.info("will wait till the list prepare is completed");
- Object o = new Object();
- synchronized(o)
- {
- o.wait(4000);
- }
- }
- }
-
- @Override
- public OperationSetFileTransfer getOpSetFilTransfer1()
- {
- return opSetFT1;
- }
-
- @Override
- public OperationSetFileTransfer getOpSetFilTransfer2()
- {
- return opSetFT2;
- }
-
- @Override
- public BundleContext getContext()
- {
- return AdHocMultiUserChatSlickFixture.bc;
- }
-
- @Override
- public boolean enableTestSendAndReceive()
- {
- return true;
- }
-
- @Override
- public boolean enableTestSenderCancelBeforeAccepted()
- {
- return true;
- }
-
- @Override
- public boolean enableTestReceiverDecline()
- {
- return true;
- }
-
- @Override
- public boolean enableTestReceiverCancelsWhileTransfering()
- {
- return true;
- }
-
- @Override
- public boolean enableTestSenderCancelsWhileTransfering()
- {
- return true;
- }
-}
diff --git a/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetPersistentPresence.java b/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetPersistentPresence.java
deleted file mode 100644
index 2ebf0e6..0000000
--- a/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetPersistentPresence.java
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.slick.protocol.yahoo;
-
-import java.util.*;
-
-import junit.framework.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.slick.protocol.generic.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * @author Damian Minkov
- */
-public class TestOperationSetPersistentPresence
- extends TestCase
-{
- private static final Logger logger =
- Logger.getLogger(TestOperationSetPersistentPresence.class);
-
- private YahooSlickFixture fixture = new YahooSlickFixture();
- private OperationSetPersistentPresence opSetPersPresence1 = null;
- private OperationSetPersistentPresence opSetPersPresence2 = null;
- private static final String testGroupName = "NewGroup";
- private static final String testGroupName2 = "Renamed";
-
- public TestOperationSetPersistentPresence(String name)
- {
- super(name);
- }
-
- /**
- * Creates a test suite containing all tests of this class followed by
- * test methods that we want executed in a specified order.
- * @return the Test suite to run
- */
- public static Test suite()
- {
- TestSuite suite =
- new TestSuite();
-
- //the following 2 need to be run in the specified order.
- //(postTestRemoveGroup() needs the group created from
- //postTestCreateGroup() )
- suite.addTest(
- new TestOperationSetPersistentPresence("postTestCreateGroup"));
-
- //rename
- //suite.addTest( new TestOperationSetPersistentPresence(
- // "postTestRenameGroup"));
-
- suite.addTest(
- new TestOperationSetPersistentPresence("postTestRemoveGroup"));
-
- // create the contact list
- suite.addTest(
- new TestOperationSetPersistentPresence("prepareContactList"));
-
- suite.addTestSuite(TestOperationSetPersistentPresence.class);
-
- return suite;
- }
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
- fixture.setUp();
-
- Map<String, OperationSet> supportedOperationSets1 =
- fixture.provider1.getSupportedOperationSets();
-
- if ( supportedOperationSets1 == null
- || supportedOperationSets1.size() < 1)
- throw new NullPointerException(
- "No OperationSet implementations are supported by "
- +"this Yahoo implementation. ");
-
- //get the operation set presence here.
- opSetPersPresence1 =
- (OperationSetPersistentPresence)supportedOperationSets1.get(
- OperationSetPersistentPresence.class.getName());
-
- //if still null then the implementation doesn't offer a presence
- //operation set which is unacceptable for yahoo.
- if (opSetPersPresence1 == null)
- throw new NullPointerException(
- "An implementation of the Yahoo service must provide an "
- + "implementation of at least the one of the Presence "
- + "Operation Sets");
-
- // lets do it once again for the second provider
- Map<String, OperationSet> supportedOperationSets2 =
- fixture.provider2.getSupportedOperationSets();
-
- if (supportedOperationSets2 == null
- || supportedOperationSets2.size() < 1)
- throw new NullPointerException(
- "No OperationSet implementations are supported by "
- + "this Yahoo implementation. ");
-
- //get the operation set presence here.
- opSetPersPresence2 =
- (OperationSetPersistentPresence) supportedOperationSets2.get(
- OperationSetPersistentPresence.class.getName());
-
- //if still null then the implementation doesn't offer a presence
- //operation set which is unacceptable for yahoo.
- if (opSetPersPresence2 == null)
- throw new NullPointerException(
- "An implementation of the yahoo service must provide an "
- + "implementation of at least the one of the Presence "
- + "Operation Sets");
- }
-
- @Override
- protected void tearDown() throws Exception
- {
- fixture.tearDown();
- super.tearDown();
- }
-
- /**
- * Retrieves a server stored contact list and checks whether it contains
- * all contacts that have been added there during the initialization
- * phase by the testerAgent.
- */
- public void testRetrievingServerStoredContactList()
- {
- ContactGroup rootGroup
- = opSetPersPresence1.getServerStoredContactListRoot();
-
- logger.debug("=========== Server Stored Contact List =================");
-
- logger.debug("rootGroup="+rootGroup.getGroupName()
- +" rootGroup.childContacts="+rootGroup.countContacts()
- + "rootGroup.childGroups="+rootGroup.countSubgroups()
- + "Printing rootGroupContents=\n"+rootGroup.toString());
-
- Hashtable<String, List<String>> expectedContactList
- = AdHocMultiUserChatSlickFixture.preInstalledBuddyList;
-
- logger.debug("============== Expected Contact List ===================");
- logger.debug(expectedContactList);
-
- //Go through the contact list retrieved by the persistence presence set
- //and remove the name of every contact and group that we find there from
- //the expected contct list hashtable.
- Iterator<ContactGroup> groups = rootGroup.subgroups();
- while (groups.hasNext() )
- {
- ContactGroup group = groups.next();
-
- List<String> expectedContactsInGroup
- = expectedContactList.get(group.getGroupName());
-
- // When sending the offline message
- // the sever creates a group NotInContactList,
- // because the buddy we are sending message to is not in
- // the contactlist. So this group must be ignored
- // Also we must ignore the group created by default
- // from the yahoo lib
- if(!group.getGroupName().equals("NotInContactList") &&
- !group.getGroupName().equals("Default group"))
- {
- assertNotNull("Group " + group.getGroupName() +
- " was returned by "
- +
- "the server but was not in the expected contact list."
- , expectedContactsInGroup);
-
- Iterator<Contact> contactsIter = group.contacts();
- while(contactsIter.hasNext())
- {
- String contactID = contactsIter.next().getAddress();
- expectedContactsInGroup.remove(contactID);
- }
-
- //If we've removed all the sub contacts, remove the group too.
- if(expectedContactsInGroup.size() == 0)
- expectedContactList.remove(group.getGroupName());
- }
- }
-
- //whatever we now have in the expected contact list snapshot are groups,
- //that have been added by the testerAgent but that were not retrieved
- //by the persistent presence operation set.
- assertTrue("The following contacts were on the server sidec contact "
- +"list, but were not returned by the pers. pres. op. set"
- + expectedContactList.toString()
- , expectedContactList.isEmpty());
- }
-
- /**
- * Creates a group in the server stored contact list, makes sure that the
- * corresponding event has been generated and verifies that the group is
- * in the list.
- *
- * @throws java.lang.Exception
- */
- public void postTestCreateGroup()
- throws Exception
- {
- // first clear the list
- fixture.clearProvidersLists();
-
- waitFor(5000);
-
- logger.trace("testing creation of server stored groups");
- //first add a listener
- GroupChangeCollector groupChangeCollector = new GroupChangeCollector();
- opSetPersPresence1
- .addServerStoredGroupChangeListener(groupChangeCollector);
-
- //create the group
- opSetPersPresence1.createServerStoredContactGroup(
- opSetPersPresence1.getServerStoredContactListRoot(), testGroupName);
-
- groupChangeCollector.waitForEvent(10000);
-
- opSetPersPresence1
- .removeServerStoredGroupChangeListener(groupChangeCollector);
-
- // check whether we got group created event
- assertEquals("Collected Group Change events: ",
- 1, groupChangeCollector.collectedEvents.size());
-
- assertEquals("Group name.", testGroupName,
- ((ServerStoredGroupEvent)groupChangeCollector.collectedEvents
- .get(0)).getSourceGroup().getGroupName());
-
- // check whether the group is retrievable
- ContactGroup group = opSetPersPresence1.getServerStoredContactListRoot()
- .getGroup(testGroupName);
-
- assertNotNull("A newly created group was not in the contact list.",
- group);
-
- assertEquals("New group name", testGroupName, group.getGroupName());
-
- // when opearting with groups . the group must have entries
- // so changes to take effect. Otherwise group will be lost after loggingout
- try
- {
- opSetPersPresence1.subscribe(group, fixture.userID2);
-
- waitFor(1500);
- }
- catch (Exception ex)
- {
- fail("error adding entry to group : " +
- group.getGroupName() + " " +
- ex.getMessage());
- }
- }
-
-
- /**
- * Removes the group created in the server stored contact list by the create
- * group test, makes sure that the corresponding event has been generated
- * and verifies that the group is not in the list any more.
- */
- public void postTestRemoveGroup()
- {
- logger.trace("testing removal of server stored groups");
-
- //first add a listener
- GroupChangeCollector groupChangeCollector = new GroupChangeCollector();
- opSetPersPresence1
- .addServerStoredGroupChangeListener(groupChangeCollector);
-
- try
- {
- //remove the group
- opSetPersPresence1.removeServerStoredContactGroup(
- opSetPersPresence1.getServerStoredContactListRoot()
- .getGroup(testGroupName));
- }
- catch(OperationFailedException ex)
- {
- logger.error("error removing group", ex);
- }
-
- groupChangeCollector.waitForEvent(10000);
-
- opSetPersPresence1
- .removeServerStoredGroupChangeListener(groupChangeCollector);
-
- // check whether we got group created event
- assertEquals("Collected Group Change event",
- 1, groupChangeCollector.collectedEvents.size());
-
- assertEquals("Group name.", testGroupName,
- ((ServerStoredGroupEvent)groupChangeCollector.collectedEvents
- .get(0)).getSourceGroup().getGroupName());
-
- // check whether the group is still on the contact list
- ContactGroup group = opSetPersPresence1.getServerStoredContactListRoot()
- .getGroup(testGroupName);
-
- assertNull("A freshly removed group was still on the contact list. - " + group,
- group);
- }
-
- /**
- * Renames our test group and checks whether corresponding events are
- * triggered. Verifies whether the group has really changed its name and
- * whether it is findable by its new name. Also makes sure that it does
- * not exist under its previous name any more.
- */
- public void postTestRenameGroup()
- {
- logger.trace("Testing renaming groups.");
-
- ContactGroup group = opSetPersPresence1.getServerStoredContactListRoot()
- .getGroup(testGroupName);
-
- //first add a listener
- GroupChangeCollector groupChangeCollector = new GroupChangeCollector();
- opSetPersPresence1
- .addServerStoredGroupChangeListener(groupChangeCollector);
-
- //change the name and wait for a confirmation event
- opSetPersPresence1.renameServerStoredContactGroup(group, testGroupName2);
-
- groupChangeCollector.waitForEvent(10000);
-
- opSetPersPresence1
- .removeServerStoredGroupChangeListener(groupChangeCollector);
-
- //examine the event
- assertEquals("Collected Group Change event",
- 1, groupChangeCollector.collectedEvents.size());
-
- assertEquals("Group name.", testGroupName2,
- ((ServerStoredGroupEvent)groupChangeCollector.collectedEvents
- .get(0)).getSourceGroup().getGroupName());
-
- // check whether the group is still on the contact list
- ContactGroup oldGroup = opSetPersPresence1.getServerStoredContactListRoot()
- .getGroup(testGroupName);
-
- assertNull("A group was still findable by its old name after renaming.",
- oldGroup);
-
- //make sure that we could find the group by its new name.
- ContactGroup newGroup = opSetPersPresence1.getServerStoredContactListRoot()
- .getGroup(testGroupName2);
-
- assertNotNull("Could not find a renamed group by its new name.",
- newGroup);
- }
-
- /**
- * Create the contact list. Later will be test to be sure that creating is ok
- * @throws Exception
- */
- public void prepareContactList()
- throws Exception
- {
- logger.trace("prepareContactList");
-
- fixture.clearProvidersLists();
-
- waitFor(3000);
-
- String contactList = System.getProperty(
- YahooProtocolProviderServiceLick.CONTACT_LIST_PROPERTY_NAME, null);
-
- logger.debug("The "
- + YahooProtocolProviderServiceLick.CONTACT_LIST_PROPERTY_NAME
- + " property is set to=" + contactList);
-
- if( contactList == null
- || contactList.trim().length() < 6)//at least 4 for a UIN, 1 for the
- // dot and 1 for the grp name
- throw new IllegalArgumentException(
- "The " +
- YahooProtocolProviderServiceLick.CONTACT_LIST_PROPERTY_NAME +
- " property did not contain a contact list.");
- StringTokenizer tokenizer = new StringTokenizer(contactList, " \n\t");
-
- logger.debug("tokens contained by the CL tokenized="
- +tokenizer.countTokens());
-
- Hashtable<String, List<String>> contactListToCreate = new Hashtable<String, List<String>>();
-
- //go over all group.uin tokens
- while (tokenizer.hasMoreTokens())
- {
- String groupUinToken = tokenizer.nextToken();
- int dotIndex = groupUinToken.indexOf(".");
-
- if ( dotIndex == -1 )
- {
- throw new IllegalArgumentException(groupUinToken
- + " is not a valid Group.UIN token");
- }
-
- String groupName = groupUinToken.substring(0, dotIndex);
- String uin = groupUinToken.substring(dotIndex + 1);
-
- if( groupName.trim().length() < 1
- || uin.trim().length() < 4 )
- {
- throw new IllegalArgumentException(
- groupName + " or " + uin +
- " are not a valid group name or yahoo UIN.");
- }
-
- //check if we've already seen this group and if not - add it
- List<String> uinInThisGroup = contactListToCreate.get(groupName);
- if (uinInThisGroup == null)
- {
- uinInThisGroup = new ArrayList<String>();
- contactListToCreate.put(groupName, uinInThisGroup);
- }
-
- uinInThisGroup.add(uin);
- }
-
- // now init the list
- Enumeration<String> newGroupsEnum = contactListToCreate.keys();
-
- GroupChangeCollector groupChangeCollector = new GroupChangeCollector();
- opSetPersPresence1.addServerStoredGroupChangeListener(groupChangeCollector);
-
- //go over all groups in the contactsToAdd table
- while (newGroupsEnum.hasMoreElements())
- {
- String groupName = newGroupsEnum.nextElement();
- logger.debug("Will add group " + groupName);
-
- opSetPersPresence1.createServerStoredContactGroup(
- opSetPersPresence1.getServerStoredContactListRoot(), groupName);
-
- groupChangeCollector.waitForEvent(3000);
-
- ContactGroup newlyCreatedGroup =
- opSetPersPresence1.getServerStoredContactListRoot().getGroup(groupName);
-
- Iterator<String> contactsToAddToThisGroup
- = contactListToCreate.get(groupName).iterator();
- while (contactsToAddToThisGroup.hasNext())
- {
- String id = contactsToAddToThisGroup.next();
-
- logger.debug("Will add buddy " + id);
- opSetPersPresence1.subscribe(newlyCreatedGroup, id);
- }
- }
-
- waitFor(4000);
-
- //store the created contact list for later reference
- YahooSlickFixture.preInstalledBuddyList = contactListToCreate;
- }
-
- private void waitFor(long time)
- throws Exception
- {
- Object o = new Object();
- synchronized(o)
- {
- o.wait(time);
- }
- }
-
- /**
- * The class would listen for and store received events delivered to
- * <tt>ServerStoredGroupListener</tt>s.
- */
- private class GroupChangeCollector implements ServerStoredGroupListener
- {
- public ArrayList<EventObject> collectedEvents = new ArrayList<EventObject>();
-
- /**
- * Blocks until at least one event is received or until waitFor
- * miliseconds pass (whicever happens first).
- *
- * @param waitFor the number of miliseconds that we should be waiting
- * for an event before simply bailing out.
- */
- public void waitForEvent(long waitFor)
- {
- synchronized(this)
- {
- if(collectedEvents.size() > 0)
- return;
-
- try{
- wait(waitFor);
- }
- catch (InterruptedException ex)
- {
- logger.debug(
- "Interrupted while waiting for a subscription evt", ex);
- }
- }
- }
-
- /**
- * Called whnever an indication is received that a new server stored
- * group is created.
- * @param evt a ServerStoredGroupChangeEvent containing a reference to
- * the newly created group.
- */
- public void groupCreated(ServerStoredGroupEvent evt)
- {
- synchronized(this)
- {
- logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
- collectedEvents.add(evt);
- notifyAll();
- }
- }
-
- /**
- * Called when an indication is received that the name of a server stored
- * contact group has changed.
- * @param evt a ServerStoredGroupChangeEvent containing the details of the
- * name change.
- */
- public void groupNameChanged(ServerStoredGroupEvent evt)
- {
- synchronized(this)
- {
- logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
- collectedEvents.add(evt);
- notifyAll();
- }
- }
-
- /**
- * Called whnever an indication is received that an existing server stored
- * group has been removed.
- * @param evt a ServerStoredGroupChangeEvent containing a reference to the
- * newly created group.
- */
- public void groupRemoved(ServerStoredGroupEvent evt)
- {
- synchronized(this)
- {
- logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
- collectedEvents.add(evt);
- notifyAll();
- }
- }
-
- /**
- * Called whnever an indication is received that an existing server
- * stored group has been resolved.
- * @param evt a ServerStoredGroupChangeEvent containing a reference to
- * the resolved group.
- */
- public void groupResolved(ServerStoredGroupEvent evt)
- {
- synchronized(this)
- {
- logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
- collectedEvents.add(evt);
- notifyAll();
- }
- }
- }
-}
diff --git a/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetPresence.java b/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetPresence.java
deleted file mode 100644
index 1413a42..0000000
--- a/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetPresence.java
+++ /dev/null
@@ -1,1003 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.slick.protocol.yahoo;
-
-import java.beans.*;
-import java.util.*;
-
-import junit.framework.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.service.protocol.yahooconstants.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Tests yahoo implementations of a Presence Operation Set. Tests in this class
- * verify functionality such as: Changing local (our own) status and
- * corresponding event dispatching; Querying status of contacts, Subscribing
- * for presence notifications upong status changes of specific contacts.
- * <p>
- * Using a custom suite() method, we make sure that apart from standard test
- * methods (those with a <tt>test</tt> prefix) we also execute those that
- * we want run in a specific order like for example - postTestSubscribe() and
- * postTestUnsubscribe().
- * <p>
- * @author Damian Minkov
- */
-public class TestOperationSetPresence
- extends TestCase
-{
- private static final Logger logger =
- Logger.getLogger(TestOperationSetPresence.class);
-
- private YahooSlickFixture fixture = new YahooSlickFixture();
- private OperationSetPresence operationSetPresence1 = null;
- private OperationSetPresence operationSetPresence2 = null;
-
- private AuthHandler authHandler1 = null;
- private AuthHandler authHandler2 = null;
-
- public TestOperationSetPresence(String name)
- {
- super(name);
- }
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
- fixture.setUp();
-
- Map<String, OperationSet> supportedOperationSets1 =
- fixture.provider1.getSupportedOperationSets();
-
- if ( supportedOperationSets1 == null
- || supportedOperationSets1.size() < 1)
- throw new NullPointerException(
- "No OperationSet implementations are supported by "
- +"this implementation. ");
-
- //get the operation set presence here.
- operationSetPresence1 =
- (OperationSetPresence)supportedOperationSets1.get(
- OperationSetPresence.class.getName());
-
- //if the op set is null then the implementation doesn't offer a presence
- //operation set which is unacceptable for yahoo.
- if (operationSetPresence1 == null)
- {
- throw new NullPointerException(
- "An implementation of the yahoo service must provide an "
- + "implementation of at least the one of the Presence "
- + "Operation Sets");
- }
-
- // do it once again for the second provider
- Map<String, OperationSet> supportedOperationSets2 =
- fixture.provider2.getSupportedOperationSets();
-
- if ( supportedOperationSets2 == null
- || supportedOperationSets2.size() < 1)
- throw new NullPointerException(
- "No OperationSet implementations are supported by "
- +"this yahoo implementation. ");
-
- //get the operation set presence here.
- operationSetPresence2 =
- (OperationSetPresence)supportedOperationSets2.get(
- OperationSetPresence.class.getName());
-
- //if the op set is null then the implementation doesn't offer a presence
- //operation set which is unacceptable for yahoo.
- if (operationSetPresence2 == null)
- {
- throw new NullPointerException(
- "An implementation of the yahoo service must provide an "
- + "implementation of at least the one of the Presence "
- + "Operation Sets");
- }
-
- if(authHandler1 == null)
- {
- authHandler1 = new AuthHandler(operationSetPresence1);
- operationSetPresence1.setAuthorizationHandler(authHandler1);
- }
-
- if(authHandler2 == null)
- {
- authHandler2 = new AuthHandler(operationSetPresence2);
- operationSetPresence2.setAuthorizationHandler(authHandler2);
- }
- }
-
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
-
- fixture.tearDown();
- }
-
- /**
- * Creates a test suite containing all tests of this class followed by
- * test methods that we want executed in a specified order.
- * @return Test
- */
- public static Test suite()
- {
- //return an (almost) empty suite if we're running in offline mode.
- if(YahooSlickFixture.onlineTestingDisabled)
- {
- TestSuite suite = new TestSuite();
- //the only test around here that we could run without net
- //connectivity
- suite.addTest(
- new TestOperationSetPresence(
- "testSupportedStatusSetForCompleteness"));
- return suite;
- }
-
- TestSuite suite = new TestSuite();
-
- // clear the lists before subscribing users
- suite.addTest(new TestOperationSetPresence("clearLists"));
-
- // first postTestSubscribe. to be sure that contacts are in the
- // list so we can further continue and test presences each other
- suite.addTest(new TestOperationSetPresence("postTestSubscribe"));
-
- // add other tests
- suite.addTestSuite(TestOperationSetPresence.class);
-
- // now test unsubscribe
- suite.addTest(new TestOperationSetPresence("postTestUnsubscribe"));
-
- return suite;
- }
-
- /**
- * Verifies that all necessary yahoo test states are supported by the
- * implementation.
- */
- public void testSupportedStatusSetForCompleteness()
- {
- //first create a local list containing the presence status instances
- //supported by the underlying implementation.
- Iterator<PresenceStatus> supportedStatusSetIter =
- operationSetPresence1.getSupportedStatusSet();
-
- List<PresenceStatus> supportedStatusSet
- = new LinkedList<PresenceStatus>();
- while (supportedStatusSetIter.hasNext()){
- supportedStatusSet.add(supportedStatusSetIter.next());
- }
-
- //create a copy of the MUST status set and remove any matching status
- //that is also present in the supported set.
- List<?> requiredStatusSetCopy
- = (List<?>) YahooStatusEnum.yahooStatusSet.clone();
-
- requiredStatusSetCopy.removeAll(supportedStatusSet);
-
- //if we have anything left then the implementation is wrong.
- int unsupported = requiredStatusSetCopy.size();
- assertTrue( "There are " + unsupported + " statuses as follows:"
- + requiredStatusSetCopy,
- unsupported == 0);
- }
-
- /**
- * Verify that changing state to STEPPED_OUT works as supposed to and that it
- * generates the corresponding event.
- * @throws Exception in case a failure occurs while the operation set
- * is switching to the new state.
- */
- public void testChangingStateToSteppedOut() throws Exception
- {
- subtestStateTransition(YahooStatusEnum.STEPPED_OUT);
- }
-
- /**
- * Verify that changing state to NOT_IN_OFFICE works as supposed to and that it
- * generates the corresponding event.
- * @throws Exception in case a failure occurs while the operation set
- * is switching to the new state.
- */
- public void testChangingStateToNotInOffice() throws Exception
- {
- subtestStateTransition(YahooStatusEnum.NOT_IN_OFFICE);
- }
-
- /**
- * Verify that changing state to BUSY works as supposed to and that it
- * generates the corresponding event.
- * @throws Exception in case a failure occurs while the operation set
- * is switching to the new state.
- */
- public void testChangingStateToBusy() throws Exception
- {
- subtestStateTransition(YahooStatusEnum.BUSY);
- }
-
- /**
- * Verify that changing state to FREE_FOR_CHAT works as supposed to and that it
- * generates the corresponding event.
- * @throws Exception in case a failure occurs while the operation set
- * is switching to the new state.
- */
- public void testChangingStateToIdle() throws Exception
- {
- subtestStateTransition(YahooStatusEnum.IDLE);
- }
-
- /**
- * Verify that changing state to BE_RIGHT_BACK works as supposed to and that it
- * generates the corresponding event.
- * @throws Exception in case a failure occurs while the operation set
- * is switching to the new state.
- */
- public void testChangingStateToBRB() throws Exception
- {
- subtestStateTransition(YahooStatusEnum.BE_RIGHT_BACK);
- }
-
- /**
- * Verify that changing state to OUT_TO_LUNCH works as supposed to and that it
- * generates the corresponding event.
- * @throws Exception in case a failure occurs while the operation set
- * is switching to the new state.
- */
- public void testChangingStateToOutToLunch() throws Exception
- {
- subtestStateTransition(YahooStatusEnum.OUT_TO_LUNCH);
- }
-
- /**
- * Verify that changing state to ON_THE_PHONE works as supposed to and that it
- * generates the corresponding event.
- * @throws Exception in case a failure occurs while the operation set
- * is switching to the new state.
- */
- public void testChangingStateToOnThePhone() throws Exception
- {
- subtestStateTransition(YahooStatusEnum.ON_THE_PHONE);
- }
-
- /**
- * Used by methods testing state transiotions
- *
- * @param newStatus the YahooStatusEnum field corresponding to the status
- * that we'd like the opeation set to enter.
- *
- * @throws Exception in case changing the state causes an exception
- */
- public void subtestStateTransition( YahooStatusEnum newStatus)
- throws Exception
- {
- logger.trace(" --=== beginning state transition test ===--");
-
- PresenceStatus oldStatus = operationSetPresence2.getPresenceStatus();
-
- logger.debug( "old status is=" + oldStatus.getStatusName()
- + " new status=" + newStatus.getStatusName()
- + " for contact : " + fixture.userID2);
-
- //First register a listener to make sure that all corresponding
- //events have been generated.
- PresenceStatusEventCollector statusEventCollector2
- = new PresenceStatusEventCollector();
- ContactPresenceEventCollector statusEventCollector1
- = new ContactPresenceEventCollector(fixture.userID2, newStatus);
- operationSetPresence2.addProviderPresenceStatusListener(
- statusEventCollector2);
- operationSetPresence1.addContactPresenceStatusListener(
- statusEventCollector1);
-
- //change the status
- operationSetPresence2.publishPresenceStatus(newStatus, null);
-
- //test event notification.
- statusEventCollector2.waitForPresEvent(10000);
- statusEventCollector1.waitForEvent(10000);
-
- operationSetPresence2.removeProviderPresenceStatusListener(
- statusEventCollector2);
- operationSetPresence1.removeContactPresenceStatusListener(
- statusEventCollector1);
-
- assertEquals("Events dispatched during an event transition.",
- 1, statusEventCollector2.collectedPresEvents.size());
- assertEquals("A status changed event contained wrong old status.",
- oldStatus,
- ((ProviderPresenceStatusChangeEvent)
- statusEventCollector2.collectedPresEvents.get(0))
- .getOldStatus());
- assertEquals("A status changed event contained wrong new status.",
- newStatus,
- ((ProviderPresenceStatusChangeEvent)
- statusEventCollector2.collectedPresEvents.get(0))
- .getNewStatus());
-
- // verify that the operation set itself is aware of the status change
- assertEquals("opSet.getPresenceStatus() did not return properly.",
- newStatus,
- operationSetPresence2.getPresenceStatus());
-
- YahooStatusEnum actualStatus = (YahooStatusEnum)
- operationSetPresence1.queryContactStatus(fixture.userID2);
-
- assertEquals("The underlying implementation did not switch to the "
- +"requested presence status.",
- newStatus,
- actualStatus);
-
- logger.trace(" --=== finished test ===--");
- }
-
- /**
- * The method would add a subscription for a contact, wait for a
- * subscription event confirming the subscription, then change the status
- * of the newly added contact (which is actually the testerAgent) and
- * make sure that the corresponding notification events have been generated.
- *
- * @throws java.lang.Exception if an exception occurs during testing.
- */
- public void postTestSubscribe()
- throws Exception
- {
- logger.debug("Testing Subscription and Subscription Event Dispatch.");
-
- dumplists();
-
- SubscriptionEventCollector subEvtCollector
- = new SubscriptionEventCollector();
- operationSetPresence1.addSubscriptionListener(subEvtCollector);
-
-
- synchronized (subEvtCollector){
- operationSetPresence1.subscribe(fixture.userID2);
- //we may already have the event, but it won't hurt to check.
- subEvtCollector.waitForEvent(10000);
- operationSetPresence1.removeSubscriptionListener(subEvtCollector);
- }
-
- assertEquals("Subscription event dispatching failed."
- , 1, subEvtCollector.collectedEvents.size());
- SubscriptionEvent subEvt =
- (SubscriptionEvent)subEvtCollector.collectedEvents.get(0);
-
- assertEquals("SubscriptionEvent Source:",
- fixture.userID2,
- ((Contact)subEvt.getSource()).getAddress());
- assertEquals("SubscriptionEvent Source Contact:",
- fixture.userID2,
- subEvt.getSourceContact().getAddress());
- assertSame("SubscriptionEvent Source Provider:",
- fixture.provider1,
- subEvt.getSourceProvider());
-
- subEvtCollector.collectedEvents.clear();
-
- // make the user agent tester change its states and make sure we are
- // notified
- logger.debug("Testing presence notifications.");
- YahooStatusEnum oldStatus
- = (YahooStatusEnum)operationSetPresence2.getPresenceStatus();
-
-
- YahooStatusEnum newStatus = YahooStatusEnum.ON_THE_PHONE;
-
- //in case we are by any chance already in a ON_THE_PHONE status, we'll
- //be changing to something else
- if(oldStatus.equals(newStatus)){
- newStatus = YahooStatusEnum.BUSY;
- }
-
- //now do the actual status notification testing
- ContactPresenceEventCollector contactPresEvtCollector
- = new ContactPresenceEventCollector(
- fixture.userID2, newStatus);
- operationSetPresence1.addContactPresenceStatusListener(
- contactPresEvtCollector);
-
- synchronized (contactPresEvtCollector){
- operationSetPresence2.publishPresenceStatus(newStatus, "new status");
- //we may already have the event, but it won't hurt to check.
- contactPresEvtCollector.waitForEvent(10000);
- operationSetPresence1
- .removeContactPresenceStatusListener(contactPresEvtCollector);
- }
-
- // something happened. the friend is not added correctly will
- // try to remove it and add it again
- if(contactPresEvtCollector.collectedEvents.size() == 0)
- {
- logger.info("ATTENTION: Yahoo friend not added correctly will remove and add him again");
-
- // remove it
- operationSetPresence1.unsubscribe(subEvt.getSourceContact());
-
- // wait remove to be finished
- Object lock = new Object();
- synchronized(lock){
- try{
- lock.wait(3000);
- }catch (Exception e){}
- }
-
- // add it
- operationSetPresence1.addSubscriptionListener(subEvtCollector);
- subEvtCollector.collectedEvents.clear();
- synchronized (subEvtCollector){
- operationSetPresence1.subscribe(fixture.userID2);
- //we may already have the event, but it won't hurt to check.
- subEvtCollector.waitForEvent(10000);
- operationSetPresence1.removeSubscriptionListener(subEvtCollector);
- }
- subEvtCollector.collectedEvents.clear();
-
- if(newStatus.equals(YahooStatusEnum.BUSY)){
- newStatus = YahooStatusEnum.OUT_TO_LUNCH;
- }
- else
- newStatus = YahooStatusEnum.BUSY;
-
- // query it again for the status
- contactPresEvtCollector = new ContactPresenceEventCollector(
- fixture.userID2, newStatus);
- operationSetPresence1.addContactPresenceStatusListener(
- contactPresEvtCollector);
-
- synchronized (contactPresEvtCollector){
-// operationSetPresence2.publishPresenceStatus(newStatus, "new status");
- operationSetPresence2.publishPresenceStatus(newStatus, null);
- //we may already have the event, but it won't hurt to check.
- contactPresEvtCollector.waitForEvent(10000);
- operationSetPresence1
- .removeContactPresenceStatusListener(contactPresEvtCollector);
- }
- }
-
- assertEquals("Presence Notif. event dispatching failed."
- , 1, contactPresEvtCollector.collectedEvents.size());
- ContactPresenceStatusChangeEvent presEvt =
- (ContactPresenceStatusChangeEvent)
- contactPresEvtCollector.collectedEvents.get(0);
-
- assertEquals("Presence Notif. event Source:",
- fixture.userID2,
- ((Contact)presEvt.getSource()).getAddress());
- assertEquals("Presence Notif. event Source Contact:",
- fixture.userID2,
- presEvt.getSourceContact().getAddress());
- assertSame("Presence Notif. event Source Provider:",
- fixture.provider1,
- presEvt.getSourceProvider());
-
- PresenceStatus reportedNewStatus = presEvt.getNewStatus();
- PresenceStatus reportedOldStatus = presEvt.getOldStatus();
-
- assertEquals( "Reported new PresenceStatus: ",
- newStatus, reportedNewStatus );
-
- //don't require equality between the reported old PresenceStatus and
- //the actual presence status of the tester agent because a first
- //notification is not supposed to have the old status as it really was.
- assertNotNull( "Reported old PresenceStatus: ", reportedOldStatus );
-
- try
- {
- // add the the user to the reverse side needed for status tests
- subEvtCollector.collectedEvents.clear();
- operationSetPresence2.addSubscriptionListener(subEvtCollector);
-
- synchronized (subEvtCollector)
- {
- operationSetPresence2.subscribe(fixture.userID1);
- //we may already have the event, but it won't hurt to check.
- subEvtCollector.waitForEvent(10000);
- operationSetPresence2.removeSubscriptionListener(
- subEvtCollector);
- }
- }
- catch (OperationFailedException ex)
- {
- // happens if the user is already subscribed
- }
- }
-
- /**
- * We unsubscribe from presence notification deliveries concerning
- * testerAgent's presence status and verify that we receive the
- * subscription removed event. We then make the tester agent change status
- * and make sure that no notifications are delivered.
- *
- * @throws java.lang.Exception in case unsubscribing fails.
- */
- public void postTestUnsubscribe()
- throws Exception
- {
- logger.debug("Testing Unsubscribe and unsubscription event dispatch.");
-
- // First create a subscription and verify that it really gets created.
- SubscriptionEventCollector subEvtCollector
- = new SubscriptionEventCollector();
- operationSetPresence1.addSubscriptionListener(subEvtCollector);
-
- Contact yahooTesterAgentContact = operationSetPresence1
- .findContactByID(fixture.userID2);
-
- assertNotNull(
- "Failed to find an existing subscription for the tester agent"
- , yahooTesterAgentContact);
-
- synchronized(subEvtCollector){
- operationSetPresence1.unsubscribe(yahooTesterAgentContact);
- subEvtCollector.waitForEvent(10000);
- //don't want any more events
- operationSetPresence1.removeSubscriptionListener(subEvtCollector);
- }
-
- assertEquals("Subscription event dispatching failed."
- , 1, subEvtCollector.collectedEvents.size());
- SubscriptionEvent subEvt =
- (SubscriptionEvent)subEvtCollector.collectedEvents.get(0);
-
- assertEquals("SubscriptionEvent Source:",
- yahooTesterAgentContact, subEvt.getSource());
-
- assertEquals("SubscriptionEvent Source Contact:",
- yahooTesterAgentContact, subEvt.getSourceContact());
-
- assertSame("SubscriptionEvent Source Provider:",
- fixture.provider1,
- subEvt.getSourceProvider());
-
- subEvtCollector.collectedEvents.clear();
-
- // make the user agent tester change its states and make sure we don't
- // get notifications as we're now unsubscribed.
- logger.debug("Testing (lack of) presence notifications.");
- YahooStatusEnum oldStatus
- = (YahooStatusEnum)operationSetPresence2.getPresenceStatus();
- YahooStatusEnum newStatus = YahooStatusEnum.ON_THE_PHONE;
-
- //in case we are by any chance already in a ON_THE_PHONE status, we'll
- //be changing to something else
- if(oldStatus.equals(newStatus)){
- newStatus = YahooStatusEnum.BUSY;
- }
-
- //now do the actual status notification testing
- ContactPresenceEventCollector contactPresEvtCollector
- = new ContactPresenceEventCollector(fixture.userID2, null);
- operationSetPresence1.addContactPresenceStatusListener(
- contactPresEvtCollector);
-
- synchronized (contactPresEvtCollector){
- operationSetPresence2.publishPresenceStatus(newStatus, "new status");
-
- //we may already have the event, but it won't hurt to check.
- contactPresEvtCollector.waitForEvent(10000);
- operationSetPresence1
- .removeContactPresenceStatusListener(contactPresEvtCollector);
- }
-
- assertEquals("Presence Notifications were received after unsubscibing."
- , 0, contactPresEvtCollector.collectedEvents.size());
- }
-
- public void clearLists()
- throws Exception
- {
- logger.debug("Clear the two lists before tests");
-
- // wait a moment if any event hes left from the previous tests
- Object o = new Object();
- synchronized(o)
- {
- o.wait(2000);
- }
-
- // wait for a moment
- // give time the impl to get the lists
- logger.debug("start clearing");
- fixture.clearProvidersLists();
-
- synchronized(o)
- {
- o.wait(3000);
- }
- }
-
- /**
- * An event collector that would collect all events generated by a
- * provider after a status change. The collector would also do a notidyAll
- * every time it receives an event.
- */
- private class PresenceStatusEventCollector
- implements ProviderPresenceStatusListener
- {
- public ArrayList<EventObject> collectedPresEvents = new ArrayList<EventObject>();
- public ArrayList<EventObject> collectedStatMsgEvents = new ArrayList<EventObject>();
-
- public void providerStatusChanged(ProviderPresenceStatusChangeEvent evt)
- {
- synchronized(this)
- {
- logger.debug("Collected evt("+collectedPresEvents.size()+")= "+evt);
- collectedPresEvents.add(evt);
- notifyAll();
- }
- }
-
- public void providerStatusMessageChanged(PropertyChangeEvent evt)
- {
- synchronized(this)
- {
- logger.debug("Collected stat.msg. evt("
- +collectedPresEvents.size()+")= "+evt);
- collectedStatMsgEvents.add(evt);
- notifyAll();
- }
- }
-
- /**
- * Blocks until at least one event is received or until waitFor
- * miliseconds pass (whicever happens first).
- *
- * @param waitFor the number of miliseconds that we should be waiting
- * for an event before simply bailing out.
- */
- public void waitForPresEvent(long waitFor)
- {
- logger.trace("Waiting for a change in provider status.");
- synchronized(this)
- {
- if(collectedPresEvents.size() > 0){
- logger.trace("Change already received. " + collectedPresEvents);
- return;
- }
-
- try{
- wait(waitFor);
- if(collectedPresEvents.size() > 0)
- logger.trace("Received a change in provider status.");
- else
- logger.trace("No change received for "+waitFor+"ms.");
- }
- catch (InterruptedException ex){
- logger.debug("Interrupted while waiting for a provider evt"
- , ex);
- }
- }
- }
-
- /**
- * Blocks until at least one staus message event is received or until
- * waitFor miliseconds pass (whichever happens first).
- *
- * @param waitFor the number of miliseconds that we should be waiting
- * for a status message event before simply bailing out.
- */
- public void waitForStatMsgEvent(long waitFor)
- {
- logger.trace("Waiting for a provider status message event.");
- synchronized(this)
- {
- if(collectedStatMsgEvents.size() > 0){
- logger.trace("Stat msg. evt already received. "
- + collectedStatMsgEvents);
- return;
- }
-
- try{
- wait(waitFor);
- if(collectedStatMsgEvents.size() > 0)
- logger.trace("Received a prov. stat. msg. evt.");
- else
- logger.trace("No prov. stat msg. received for "
- +waitFor+"ms.");
- }
- catch (InterruptedException ex){
- logger.debug("Interrupted while waiting for a status msg evt"
- , ex);
- }
- }
- }
- }
-
- /**
- * The class would listen for and store received subscription modification
- * events.
- */
- private class SubscriptionEventCollector implements SubscriptionListener
- {
- public ArrayList<EventObject> collectedEvents = new ArrayList<EventObject>();
-
- /**
- * Blocks until at least one event is received or until waitFor
- * miliseconds pass (whicever happens first).
- *
- * @param waitFor the number of miliseconds that we should be waiting
- * for an event before simply bailing out.
- */
- public void waitForEvent(long waitFor)
- {
- synchronized(this)
- {
- if(collectedEvents.size() > 0)
- {
- logger.trace("Event already received. " + collectedEvents);
- return;
- }
-
- try{
- wait(waitFor);
- }
- catch (InterruptedException ex)
- {
- logger.debug(
- "Interrupted while waiting for a subscription evt", ex);
- }
- }
- }
-
- /**
- * Stores the received subsctiption and notifies all waiting on this
- * object
- * @param evt the SubscriptionEvent containing the corresponding contact
- */
- public void subscriptionCreated(SubscriptionEvent evt)
- {
- synchronized(this)
- {
- logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
- collectedEvents.add(evt);
- notifyAll();
- }
- }
-
- /**
- * Stores the received subsctiption and notifies all waiting on this
- * object
- * @param evt the SubscriptionEvent containing the corresponding contact
- */
- public void subscriptionRemoved(SubscriptionEvent evt)
- {
- synchronized(this)
- {
- logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
- collectedEvents.add(evt);
- notifyAll();
- }
- }
-
- /**
- * Stores the received subsctiption and notifies all waiting on this
- * object
- * @param evt the SubscriptionEvent containing the corresponding contact
- */
- public void contactModified(ContactPropertyChangeEvent evt)
- {
- synchronized(this)
- {
- logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
- collectedEvents.add(evt);
- notifyAll();
- }
- }
-
-
- /**
- * Stores the received subsctiption and notifies all waiting on this
- * object
- * @param evt the SubscriptionEvent containing the corresponding contact
- */
- public void subscriptionMoved(SubscriptionMovedEvent evt)
- {
- synchronized(this)
- {
- logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
- collectedEvents.add(evt);
- notifyAll();
- }
- }
-
- /**
- * Stores the received subsctiption and notifies all waiting on this
- * object
- * @param evt the SubscriptionEvent containing the corresponding contact
- */
- public void subscriptionFailed(SubscriptionEvent evt)
- {
- synchronized(this)
- {
- logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
- collectedEvents.add(evt);
- notifyAll();
- }
- }
-
- /**
- * Stores the received subsctiption and notifies all waiting on this
- * object
- * @param evt the SubscriptionEvent containing the corresponding contact
- */
- public void subscriptionResolved(SubscriptionEvent evt)
- {
- synchronized(this)
- {
- logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
- collectedEvents.add(evt);
- notifyAll();
- }
- }
-
- }
-
- /**
- * The class would listen for and store received events caused by changes
- * in contact presence states.
- */
- private class ContactPresenceEventCollector
- implements ContactPresenceStatusListener
- {
- public ArrayList<EventObject> collectedEvents = new ArrayList<EventObject>();
- private String trackedScreenName = null;
- private YahooStatusEnum status = null;
-
- ContactPresenceEventCollector(String screenname,
- YahooStatusEnum wantedStatus)
- {
- this.trackedScreenName = screenname;
- this.status = wantedStatus;
- }
-
- /**
- * Blocks until at least one event is received or until waitFor
- * miliseconds pass (whicever happens first).
- *
- * @param waitFor the number of miliseconds that we should be waiting
- * for an event before simply bailing out.
- */
- public void waitForEvent(long waitFor)
- {
- synchronized(this)
- {
- if(collectedEvents.size() > 0)
- return;
-
- try{
- wait(waitFor);
- if(collectedEvents.size() > 0)
- logger.trace("Received a change in contact status.");
- else
- logger.trace("No change received for "+waitFor+"ms.");
- }
- catch (InterruptedException ex)
- {
- logger.debug(
- "Interrupted while waiting for a subscription evt", ex);
- }
- }
- }
-
- /**
- * Stores the received status change event and notifies all waiting on
- * this object
- * @param evt the SubscriptionEvent containing the corresponding contact
- */
- public void contactPresenceStatusChanged(
- ContactPresenceStatusChangeEvent evt)
- {
- synchronized(this)
- {
- //if the user has specified event details and the received
- //event does not match - then ignore it.
- if( this.trackedScreenName != null
- && !evt.getSourceContact().getAddress()
- .equals(trackedScreenName))
- return;
- if( status != null
- && status != evt.getNewStatus())
- return;
-
- logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
- collectedEvents.add(evt);
- notifyAll();
- }
- }
- }
-
- /**
- * AuthorizationHandler which accepts all requests!
- */
- private class AuthHandler
- implements AuthorizationHandler
- {
- private OperationSetPresence opset = null;
- AuthHandler(OperationSetPresence opset)
- {
- this.opset = opset;
- }
-
- public AuthorizationResponse processAuthorisationRequest(
- AuthorizationRequest req, Contact sourceContact)
- {
-// try{
-// opset.subscribe(sourceContact.getAddress());
-// }catch(Exception ex){}
-
- return
- new AuthorizationResponse(AuthorizationResponse.ACCEPT, "");
- }
- public AuthorizationRequest createAuthorizationRequest(Contact contact )
- {
- return new AuthorizationRequest();
- }
- public void processAuthorizationResponse(
- AuthorizationResponse response, Contact sourceContact){}
- }
-
- private void dumplists()
- {
- // just wait a little all modification events to be received
- Object o = new Object();
- synchronized(o)
- {
- try{o.wait(3000);}catch (InterruptedException ex){}
- }
-
- OperationSetPersistentPresence op1 = (OperationSetPersistentPresence)operationSetPresence1;
- OperationSetPersistentPresence op2 = (OperationSetPersistentPresence)operationSetPresence2;
-
- logger.info("------------ START DUMP LIST " + fixture.userID1 + " ------------");
- ContactGroup rootGroup = op1.getServerStoredContactListRoot();
- Iterator<ContactGroup> groups = rootGroup.subgroups();
- while (groups.hasNext() )
- {
- ContactGroup group = groups.next();
- logger.info("group " + group.getGroupName());
-
- Iterator<Contact> contactsIter = group.contacts();
- while(contactsIter.hasNext())
- {
- logger.info("\tcontact " + contactsIter.next());
- }
- }
- logger.info("------------ END DUMP LIST " + fixture.userID1 + " ------------");
-
-
- logger.info("------------ START DUMP LIST " + fixture.userID2 + " ------------");
- rootGroup = op2.getServerStoredContactListRoot();
- groups = rootGroup.subgroups();
- while (groups.hasNext() )
- {
- ContactGroup group = groups.next();
- logger.info("group " + group.getGroupName());
-
- Iterator<Contact> contactsIter = group.contacts();
- while(contactsIter.hasNext())
- {
- logger.info("\tcontact " + contactsIter.next());
- }
- }
- logger.info("------------ END DUMP LIST " + fixture.userID2 + " ------------");
- }
-}
diff --git a/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetTypingNotifications.java b/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetTypingNotifications.java
deleted file mode 100644
index 5138fed..0000000
--- a/test/net/java/sip/communicator/slick/protocol/yahoo/TestOperationSetTypingNotifications.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.slick.protocol.yahoo;
-
-import java.util.*;
-
-import junit.framework.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Tests functionality of the typing notifications operation set.
- *
- * @author Damian Minkov
- */
-public class TestOperationSetTypingNotifications
- extends TestCase
-{
- private static final Logger logger =
- Logger.getLogger(TestOperationSetTypingNotifications.class);
-
- private YahooSlickFixture fixture = new YahooSlickFixture();
- private OperationSetTypingNotifications opSetTypingNotifs1 = null;
- private OperationSetPresence opSetPresence1 = null;
- private OperationSetTypingNotifications opSetTypingNotifs2 = null;
- private OperationSetPresence opSetPresence2 = null;
-
- private OperationSetBasicInstantMessaging opSetBasicIM1 = null;
- private OperationSetBasicInstantMessaging opSetBasicIM2 = null;
-
-
- public TestOperationSetTypingNotifications(String name)
- {
- super(name);
- }
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
- fixture.setUp();
-
- Map<String, OperationSet> supportedOperationSets1 =
- fixture.provider1.getSupportedOperationSets();
-
- if ( supportedOperationSets1 == null
- || supportedOperationSets1.size() < 1)
- throw new NullPointerException(
- "No OperationSet implementations are supported by "
- +"this implementation. ");
-
- //get the operation set presence here.
- opSetTypingNotifs1 =
- (OperationSetTypingNotifications)supportedOperationSets1.get(
- OperationSetTypingNotifications.class.getName());
-
- //if the op set is null then the implementation doesn't offer a typing.n
- //operation set which is unacceptable.
- if (opSetTypingNotifs1 == null)
- {
- throw new NullPointerException(
- "No implementation for typing notifications was found");
- }
-
- opSetBasicIM1 =
- (OperationSetBasicInstantMessaging)supportedOperationSets1.get(
- OperationSetBasicInstantMessaging.class.getName());
-
- if (opSetBasicIM1 == null)
- {
- throw new NullPointerException(
- "No implementation for basic IM was found");
- }
-
-
- //we also need the presence op set in order to retrieve contacts.
- opSetPresence1 =
- (OperationSetPresence)supportedOperationSets1.get(
- OperationSetPresence.class.getName());
-
- //if the op set is null show that we're not happy.
- if (opSetPresence1 == null)
- {
- throw new NullPointerException(
- "An implementation of the service must provide an "
- + "implementation of at least one of the PresenceOperationSets");
- }
-
- Map<String, OperationSet> supportedOperationSets2 =
- fixture.provider2.getSupportedOperationSets();
-
- if ( supportedOperationSets2 == null
- || supportedOperationSets2.size() < 1)
- throw new NullPointerException(
- "No OperationSet implementations are supported by "
- +"this implementation. ");
-
- //get the operation set presence here.
- opSetTypingNotifs2 =
- (OperationSetTypingNotifications)supportedOperationSets2.get(
- OperationSetTypingNotifications.class.getName());
-
- //if the op set is null then the implementation doesn't offer a typing.n
- //operation set which is unacceptable for.
- if (opSetTypingNotifs2 == null)
- {
- throw new NullPointerException(
- "No implementation for typing notifications was found");
- }
-
- opSetBasicIM2 =
- (OperationSetBasicInstantMessaging)supportedOperationSets2.get(
- OperationSetBasicInstantMessaging.class.getName());
-
- if (opSetBasicIM2 == null)
- {
- throw new NullPointerException(
- "No implementation for basic IM was found");
- }
-
-
- //we also need the presence op set in order to retrieve contacts.
- opSetPresence2 =
- (OperationSetPresence)supportedOperationSets2.get(
- OperationSetPresence.class.getName());
-
- //if the op set is null show that we're not happy.
- if (opSetPresence2 == null)
- {
- throw new NullPointerException(
- "An implementation of the service must provide an "
- + "implementation of at least one of the PresenceOperationSets");
- }
- }
-
- /**
- * Create the list to be sure that contacts exchanging messages
- * exists in each other lists
- * @throws Exception
- */
- public void prepareContactList() throws Exception
- {
- // be sure that contacts are in their lists
- try{
- opSetPresence1.subscribe(fixture.userID2);
- }
- catch (OperationFailedException ex){
- // the contact already exist its OK
- }
-
- try{
- opSetPresence2.subscribe(fixture.userID1);
- }
- catch (OperationFailedException ex1){
- // the contact already exist its OK
- }
-
- Object o = new Object();
- synchronized (o)
- {
- o.wait(2000);
- }
- }
-
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
-
- fixture.tearDown();
- }
-
- /**
- * Creates a test suite containing tests of this class in a specific order.
- * We'll first execute a test where we receive a typing notification, and
- * a volatile contact is created for the sender. we'll then be able to
- * retrieve this volatile contact and them a notification on our turn.
- * We need to do things this way as the contact corresponding to the tester
- * agent has been removed in the previous test and we no longer have it
- * in our contact list.
- *
- * @return Test a testsuite containing all tests to execute.
- */
- public static Test suite()
- {
- TestSuite suite = new TestSuite();
-
- suite.addTest(new TestOperationSetTypingNotifications(
- "prepareContactList"));
-
- //the following 2 need to be run in the specified order.
- suite.addTest(new TestOperationSetTypingNotifications(
- "testTypingNotificationsEventDelivery"));
- return suite;
- }
-
- /**
- * Sends a typing notification and verifies
- * whether it is properly received by the tested implementation
- */
- public void testTypingNotificationsEventDelivery()
- {
- TypingEventCollector evtCollector = new TypingEventCollector();
-
- // send message so request for receiving notifications also to be set
- Contact notifingContact =
- opSetPresence1.findContactByID(fixture.userID2);
- opSetBasicIM1.sendInstantMessage(notifingContact,
- opSetBasicIM1.createMessage("ping"));
-
- opSetTypingNotifs1.addTypingNotificationsListener(evtCollector);
-
- Contact contactToNotify =
- opSetPresence2.findContactByID(fixture.userID1);
-
- opSetBasicIM2.sendInstantMessage(contactToNotify,
- opSetBasicIM2.createMessage("pong"));
-
- Object w = new Object();
- synchronized(w){try {w.wait(500);}catch (Exception e) {}}
-
- opSetTypingNotifs2.sendTypingNotification(
- contactToNotify, OperationSetTypingNotifications.STATE_TYPING);
-
- evtCollector.waitForEvent(10000);
-
- opSetTypingNotifs1.removeTypingNotificationsListener(evtCollector);
-
- //check event dispatching
- assertTrue("Number of typing events received was zero."
- , evtCollector.collectedEvents.size() > 0);
-
- TypingNotificationEvent evt = (TypingNotificationEvent)evtCollector
- .collectedEvents.get(0);
-
- assertEquals("Source of the typing notification event"
- , fixture.userID2
- , evt.getSourceContact().getAddress() );
-
- assertEquals("Source of the typing notification event"
- , OperationSetTypingNotifications.STATE_TYPING
- , evt.getTypingState());
- }
-
- /**
- * Simply collects allre received events and provides a mechanisim for
- * waiting for the next event.
- */
- private class TypingEventCollector implements TypingNotificationsListener
- {
- private List<EventObject> collectedEvents = new LinkedList<EventObject>();
- /**
- * Called to indicate that a remote <tt>Contact</tt> has sent us a typing
- * notification. The method adds the <tt>event</tt> to the list of
- * captured events.
- * @param event a <tt>TypingNotificationEvent</tt> containing the sender
- * of the notification and its type.
- */
- public void typingNotificationReceived(TypingNotificationEvent event)
- {
- logger.debug("Received a typing notification: " + event);
- synchronized (this)
- {
- collectedEvents.add(event);
- notifyAll();
- }
- }
-
- /**
- * Called to indicate that sending typing notification has failed.
- *
- * @param event a <tt>TypingNotificationEvent</tt> containing the sender
- * of the notification and its type.
- */
- public void typingNotificationDeliveryFailed(TypingNotificationEvent event)
- {}
-
- /**
- * Blocks until at least one event is received or until waitFor
- * miliseconds pass (whicever happens first).
- *
- * @param waitFor the number of miliseconds that we should be waiting
- * for an event before simply bailing out.
- */
- public void waitForEvent(long waitFor)
- {
- synchronized(this){
-
- if(collectedEvents.size() > 0)
- return;
-
- try{
- wait(waitFor);
- }
- catch (InterruptedException ex){
- logger.debug(
- "Interrupted while waiting for a subscription evt", ex);
- }
- }
- }
- }
-}
diff --git a/test/net/java/sip/communicator/slick/protocol/yahoo/TestProtocolProviderServiceYahooImpl.java b/test/net/java/sip/communicator/slick/protocol/yahoo/TestProtocolProviderServiceYahooImpl.java
deleted file mode 100644
index 87c07f3..0000000
--- a/test/net/java/sip/communicator/slick/protocol/yahoo/TestProtocolProviderServiceYahooImpl.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.slick.protocol.yahoo;
-
-import java.util.*;
-
-import junit.framework.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.slick.protocol.generic.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Performs testing on protocol provider methods.
- * @todo add more detailed docs once the tests are written.
- * @author Damian Minkov
- */
-public class TestProtocolProviderServiceYahooImpl
- extends TestCase
-{
- private static final Logger logger =
- Logger.getLogger(TestProtocolProviderServiceYahooImpl.class);
-
- private YahooSlickFixture fixture = new YahooSlickFixture();
-
- /**
- * An event adapter that would collec registation state change events
- */
- public RegistrationEventCollector regEvtCollector1
- = new RegistrationEventCollector();
-
- /**
- * An event adapter that would collec registation state change events
- */
- public RegistrationEventCollector regEvtCollector2
- = new RegistrationEventCollector();
-
- /**
- * An event adapter that would collec registation state change events
- */
- public RegistrationEventCollector regEvtCollector3
- = new RegistrationEventCollector();
-
- /**
- * Creates a test encapsulator for the method with the specified name.
- * @param name the name of the method this test should run.
- */
- public TestProtocolProviderServiceYahooImpl(String name)
- {
- super(name);
- }
-
- /**
- * Initializes the fixture.
- * @throws Exception if super.setUp() throws one.
- */
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
- fixture.setUp();
- }
-
- /**
- * Tears the fixture down.
- * @throws Exception if fixture.tearDown() fails.
- */
- @Override
- protected void tearDown() throws Exception
- {
- fixture.tearDown();
- super.tearDown();
- }
-
- /**
- * Makes sure that the instance of the Yahoo protocol provider that we're
- * going to use for testing is properly initialized and registered with
- * a Yahoo registrar. This MUST be called before any other online testing
- * of the Yahoo provider so that we won't have to reregister for every single
- * test.
- * <p>
- * The method also verifies that a registration event is fired upon
- * succesful registration and collected by our event collector.
- *
- * @throws OperationFailedException if provider.register() fails.
- */
- public void testRegister()
- throws OperationFailedException
- {
- //add an event collector that will collect all events during the
- //registration and allow us to later inspect them and make sure
- //they were properly dispatched.
- fixture.provider1.addRegistrationStateChangeListener(regEvtCollector1);
- fixture.provider2.addRegistrationStateChangeListener(regEvtCollector2);
-
- //register our three providers
- fixture.provider1.register(new SecurityAuthorityImpl(
- System.getProperty(YahooProtocolProviderServiceLick.ACCOUNT_1_PREFIX
- + ProtocolProviderFactory.PASSWORD).toCharArray()));
- fixture.provider2.register(new SecurityAuthorityImpl(
- System.getProperty(YahooProtocolProviderServiceLick.ACCOUNT_2_PREFIX
- + ProtocolProviderFactory.PASSWORD).toCharArray()));
-
- //give it enough time to register. We won't really have to wait all this
- //time since the registration event collector would notify us the moment
- //we get signed on.
- logger.debug("Waiting for registration to complete ...");
-
- regEvtCollector1.waitForEvent(15000);
- regEvtCollector2.waitForEvent(40000);
-
- //make sure that the registration process trigerred the corresponding
- //events.
- assertTrue(
- "No events were dispatched during the registration process."
- ,regEvtCollector1.collectedNewStates.size() > 0);
-
- assertTrue(
- "No registration event notifying of registration was dispatched. "
- +"All events were: " + regEvtCollector1.collectedNewStates
- ,regEvtCollector1.collectedNewStates
- .contains(RegistrationState.REGISTERED));
-
- //now the same for provider 2
- assertTrue(
- "No events were dispatched during the registration process "
- +"of provider2."
- ,regEvtCollector2.collectedNewStates.size() > 0);
-
- assertTrue(
- "No registration event notifying of registration was dispatched. "
- +"All events were: " + regEvtCollector2.collectedNewStates
- ,regEvtCollector2.collectedNewStates
- .contains(RegistrationState.REGISTERED));
-
- fixture.provider1
- .removeRegistrationStateChangeListener(regEvtCollector1);
- fixture.provider2
- .removeRegistrationStateChangeListener(regEvtCollector2);
- }
-
-
- /**
- * Verifies that all operation sets have the type they are declarded to
- * have.
- *
- * @throws java.lang.Exception if a class indicated in one of the keys
- * could not be forName()ed.
- */
- public void testOperationSetTypes() throws Exception
- {
- Map<String, OperationSet> supportedOperationSets =
- fixture.provider1.getSupportedOperationSets();
-
- // make sure that keys (which are supposed to be class names) correspond
- // what the class of the values recorded against them.
- for (Map.Entry<String, OperationSet> entry : supportedOperationSets
- .entrySet())
- {
- String setName = entry.getKey();
- Object opSet = entry.getValue();
-
- assertTrue(opSet + " was not an instance of " + setName
- + " as declared", Class.forName(setName).isInstance(opSet));
- }
- }
-
- /**
- * A class that would plugin as a registration listener to a protocol
- * provider and simply record all events that it sees and notifyAll()
- * if it sees an event that notifies us of a completed
- * registration.
- */
- public class RegistrationEventCollector
- implements RegistrationStateChangeListener
- {
- public List<RegistrationState> collectedNewStates = new LinkedList<RegistrationState>();
-
- /**
- * The method would simply register all received events so that they
- * could be available for later inspection by the unit tests. In the
- * case where a registraiton event notifying us of a completed
- * registration is seen, the method would call notifyAll().
- *
- * @param evt ProviderStatusChangeEvent the event describing the status
- * change.
- */
- public void registrationStateChanged(RegistrationStateChangeEvent evt)
- {
- logger.debug("Received a RegistrationStateChangeEvent: " + evt);
-
- collectedNewStates.add(evt.getNewState());
-
- if (evt.getNewState().equals(RegistrationState.REGISTERED))
- {
- logger.debug("We're registered and will notify those who wait");
- synchronized (this)
- {
- notifyAll();
- }
- }
- }
-
- /**
- * Blocks until an event notifying us of the awaited state change is
- * received or until waitFor miliseconds pass (whichever happens first).
- *
- * @param waitFor the number of miliseconds that we should be waiting
- * for an event before simply bailing out.
- */
- public void waitForEvent(long waitFor)
- {
- logger.trace("Waiting for a RegistrationStateChangeEvent ");
-
- synchronized (this)
- {
- if (collectedNewStates.contains(RegistrationState.REGISTERED))
- {
- logger.trace("Event already received. "
- + collectedNewStates);
- return;
- }
-
- try
- {
- wait(waitFor);
-
- if (collectedNewStates.size() > 0)
- logger.trace(
- "Received a RegistrationStateChangeEvent.");
- else
- logger.trace(
- "No RegistrationStateChangeEvent received for "
- + waitFor + "ms.");
-
- }
- catch (InterruptedException ex)
- {
- logger.debug(
- "Interrupted while waiting for a "
- +"RegistrationStateChangeEvent"
- , ex);
- }
- }
- }
- }
-}
diff --git a/test/net/java/sip/communicator/slick/protocol/yahoo/YahooProtocolProviderServiceLick.java b/test/net/java/sip/communicator/slick/protocol/yahoo/YahooProtocolProviderServiceLick.java
deleted file mode 100644
index a9dc75d..0000000
--- a/test/net/java/sip/communicator/slick/protocol/yahoo/YahooProtocolProviderServiceLick.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.slick.protocol.yahoo;
-
-import java.util.*;
-
-import junit.framework.*;
-
-import org.osgi.framework.*;
-
-/**
- * Yahoo specific testing for a Yahoo Protocol Provider Service implementation.
- * The test suite registers three accounts for
- *
- * @author Damian Minkov
- * @author Valentin Martinet
- */
-public class YahooProtocolProviderServiceLick
- extends TestSuite
- implements BundleActivator
-{
- /**
- * The prefix used for property names containing settings for our first
- * testing account.
- */
- public static final String ACCOUNT_1_PREFIX
- = "accounts.yahoo.account1.";
-
- /**
- * The prefix used for property names containing settings for our second
- * testing account.
- */
- public static final String ACCOUNT_2_PREFIX
- = "accounts.yahoo.account2.";
-
- /**
- * The prefix used for property names containing settings for our third
- * testing account.
- */
- public static final String ACCOUNT_3_PREFIX
- = "accounts.yahoo.account3.";
-
- /**
- * The name of the property that indicates whether the user would like to
- * only run the offline tests.
- */
- public static final String DISABLE_ONLINE_TESTS_PROPERTY_NAME
- = "accounts.yahoo.DISABLE_ONLINE_TESTING";
-
- /**
- * The name of the property the value of which is a formatted string that
- * contains the contact list that.
- */
- public static final String CONTACT_LIST_PROPERTY_NAME
- = "accounts.yahoo.CONTACT_LIST";
-
- /**
- * Initializes and registers all tests that we'll run as a part of this
- * slick.
- *
- * @param context a currently valid bundle context.
- */
- public void start(BundleContext context)
- {
- setName("YahooProtocolProviderSlick");
-
- Hashtable<String, String> properties = new Hashtable<String, String>();
- properties.put("service.pid", getName());
-
- YahooSlickFixture.bc = context;
-
- // verify whether the user wants to avoid online testing
- String offlineMode = System.getProperty(
- DISABLE_ONLINE_TESTS_PROPERTY_NAME, null);
-
- if (offlineMode != null && offlineMode.equalsIgnoreCase("true"))
- YahooSlickFixture.onlineTestingDisabled = true;
-
-
- addTestSuite(TestAccountInstallation.class);
- addTestSuite(TestProtocolProviderServiceYahooImpl.class);
-
- addTest(TestOperationSetPresence.suite());
-
- //the following should only be run when we want online testing.
- if(!YahooSlickFixture.onlineTestingDisabled)
- {
- addTest(TestOperationSetPersistentPresence.suite());
-
- addTest(TestOperationSetBasicInstantMessaging.suite());
-
- addTest(TestOperationSetTypingNotifications.suite());
-
- addTestSuite(TestOperationSetFileTransferImpl.class);
-
- //addTest(TestOperationSetAdHocMultiUserChatYahooImpl.suite());
- }
-
- addTest(TestAccountUninstallation.suite());
- addTestSuite(TestAccountUninstallationPersistence.class);
-
- context.registerService(getClass().getName(), this, properties);
- }
-
- /**
- * Prepares the slick for shutdown.
- *
- * @param context a currently valid bundle context.
- */
- public void stop(BundleContext context)
- {
-
- }
-}
diff --git a/test/net/java/sip/communicator/slick/protocol/yahoo/YahooSlickFixture.java b/test/net/java/sip/communicator/slick/protocol/yahoo/YahooSlickFixture.java
deleted file mode 100644
index 88d36f5..0000000
--- a/test/net/java/sip/communicator/slick/protocol/yahoo/YahooSlickFixture.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.slick.protocol.yahoo;
-
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.slick.protocol.generic.*;
-
-import org.osgi.framework.*;
-
-/**
- * Contains fields and methods used by most or all tests in the yahoo slick.
- *
- * @author Damian Minkov
- * @author Valentin Martinet
- */
-public class YahooSlickFixture
- extends AdHocMultiUserChatSlickFixture
-{
- /**
- * Constructor
- */
- public YahooSlickFixture()
- {
- super();
- }
-
- /**
- * Initializes protocol provider references and whatever else there is to
- * initialize.
- *
- * @throws InvalidSyntaxException in case we meet problems while retrieving
- * protocol providers through OSGI
- */
- @Override
- public void setUp() throws InvalidSyntaxException
- {
- // first obtain a reference to the provider factory
- ServiceReference[] serRefs = null;
- String osgiFilter = "(" + ProtocolProviderFactory.PROTOCOL
- + "="+ProtocolNames.YAHOO+")";
- try{
- serRefs = bc.getServiceReferences(
- ProtocolProviderFactory.class.getName(), osgiFilter);
- }
- catch (InvalidSyntaxException ex){
- //this really shouldhn't occur as the filter expression is static.
- fail(osgiFilter + " is not a valid osgi filter");
- }
-
- assertTrue(
- "Failed to find a provider factory service for protocol yahoo",
- (serRefs != null) && (serRefs.length > 0));
-
- //Keep the reference for later usage.
- providerFactory = (ProtocolProviderFactory)bc.getService(serRefs[0]);
-
- userID1 =
- System.getProperty(
- YahooProtocolProviderServiceLick.ACCOUNT_1_PREFIX
- + ProtocolProviderFactory.USER_ID);
-
- userID2 =
- System.getProperty(
- YahooProtocolProviderServiceLick.ACCOUNT_2_PREFIX
- + ProtocolProviderFactory.USER_ID);
-
- userID3 =
- System.getProperty(
- YahooProtocolProviderServiceLick.ACCOUNT_3_PREFIX
- + ProtocolProviderFactory.USER_ID);
-
- //find the protocol providers exported for the three accounts
- ServiceReference[] yahooProvider1Refs
- = bc.getServiceReferences(
- ProtocolProviderService.class.getName(),
- "(&"
- +"("+ProtocolProviderFactory.PROTOCOL+"="+ProtocolNames.YAHOO+")"
- +"("+ProtocolProviderFactory.USER_ID+"="
- + userID1 +")"
- +")");
-
- //make sure we found a service
- assertNotNull("No Protocol Provider was found for yahoo account1:"
- + userID1
- , yahooProvider1Refs);
- assertTrue("No Protocol Provider was found for yahoo account1:"+userID1,
- yahooProvider1Refs.length > 0);
-
- ServiceReference[] yahooProvider2Refs
- = bc.getServiceReferences(
- ProtocolProviderService.class.getName(),
- "(&"
- +"("+ProtocolProviderFactory.PROTOCOL+"="+ProtocolNames.YAHOO+")"
- +"("+ProtocolProviderFactory.USER_ID+"="
- + userID2 +")"
- +")");
-
- //again make sure we found a service.
- assertNotNull("No Protocol Provider was found for yahoo account2:"
- + userID2
- , yahooProvider2Refs);
- assertTrue("No Protocol Provider was found for yahoo account2:"+userID2,
- yahooProvider2Refs.length > 0);
-
- ServiceReference[] yahooProvider3Refs
- = bc.getServiceReferences(
- ProtocolProviderService.class.getName(),
- "(&"
- +"("+ProtocolProviderFactory.PROTOCOL+"="+ProtocolNames.YAHOO+")"
- +"("+ProtocolProviderFactory.USER_ID+"="
- + userID3 +")"
- +")");
-
- //again make sure we found a service.
- assertNotNull("No Protocol Provider was found for yahoo account3:"
- + userID3
- , yahooProvider3Refs);
- assertTrue("No Protocol Provider was found for yahoo account2:"+userID3,
- yahooProvider3Refs.length > 0);
-
- //save the service for other tests to use.
- provider1ServiceRef = yahooProvider1Refs[0];
- provider1 = (ProtocolProviderService)bc.getService(provider1ServiceRef);
- provider2ServiceRef = yahooProvider2Refs[0];
- provider2 = (ProtocolProviderService)bc.getService(provider2ServiceRef);
- provider3ServiceRef = yahooProvider3Refs[0];
- provider3 = (ProtocolProviderService)bc.getService(provider3ServiceRef);
- }
-}
diff --git a/test/net/java/sip/communicator/slick/protocol/yahoo/yahoo.provider.slick.manifest.mf b/test/net/java/sip/communicator/slick/protocol/yahoo/yahoo.provider.slick.manifest.mf
deleted file mode 100644
index e57e344..0000000
--- a/test/net/java/sip/communicator/slick/protocol/yahoo/yahoo.provider.slick.manifest.mf
+++ /dev/null
@@ -1,17 +0,0 @@
-Bundle-Activator: net.java.sip.communicator.slick.protocol.yahoo.YahooProtocolProviderServiceLick
-Bundle-Name: Yahoo Protocol Provider Service Leveraging Implementation Compatibility Kit
-Bundle-Description: A Service Leveraging Implementation Compatibility Kit for the Yahoo implementation of the ProtocolProvider Service
-Bundle-Vendor: sip-communicator.org
-Bundle-Version: 0.0.1
-System-Bundle: yes
-Import-Package: org.jitsi.service.configuration,
- junit.framework,
- org.osgi.framework,
- javax.net.ssl,
- javax.xml.parsers,
- net.java.sip.communicator.util,
- net.java.sip.communicator.service.dns,
- net.java.sip.communicator.service.protocol,
- net.java.sip.communicator.service.protocol.yahooconstants,
- net.java.sip.communicator.service.protocol.event,
- org.jitsi.service.fileaccess
diff --git a/web-start/WebStartBuild.xml b/web-start/WebStartBuild.xml
index 46e38d0..2289cab 100644
--- a/web-start/WebStartBuild.xml
+++ b/web-start/WebStartBuild.xml
@@ -31,7 +31,6 @@
<!-- Exclusion of unsupported os's -->
<patternset id="unsupported.os.exclude">
<exclude name="**/freebsd*/**" />
- <exclude name="**/solaris*/**" />
</patternset>
<!-- Excluded Bundles or Libs -->
diff --git a/www/alm-process/snippets/page.xml b/www/alm-process/snippets/page.xml
deleted file mode 100644
index 725def6..0000000
--- a/www/alm-process/snippets/page.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<page visibility="1"><component_list><component visibility="1" type="ProjectMetadata" order="1"><title localize="false"></title></component><component visibility="1" type="Html" order="2"><title localize="false"></title><filename>index.html</filename></component><component visibility="1" type="Subproject" order="3"><title localize="true">Subprojects</title></component></component_list></page>
diff --git a/www/images/pixel.gif b/www/images/pixel.gif
deleted file mode 100644
index e565824..0000000
--- a/www/images/pixel.gif
+++ /dev/null
Binary files differ
diff --git a/www/images/sc_logo136x169.jpg b/www/images/sc_logo136x169.jpg
deleted file mode 100644
index c2373c7..0000000
--- a/www/images/sc_logo136x169.jpg
+++ /dev/null
Binary files differ
diff --git a/www/images/sc_logo136x169.png b/www/images/sc_logo136x169.png
deleted file mode 100644
index 10bd72a..0000000
--- a/www/images/sc_logo136x169.png
+++ /dev/null
Binary files differ
diff --git a/www/images/sc_logo139x208.white.png b/www/images/sc_logo139x208.white.png
deleted file mode 100644
index 28acc45..0000000
--- a/www/images/sc_logo139x208.white.png
+++ /dev/null
Binary files differ
diff --git a/www/images/sc_logo50x62.jpg b/www/images/sc_logo50x62.jpg
deleted file mode 100644
index 1da6246..0000000
--- a/www/images/sc_logo50x62.jpg
+++ /dev/null
Binary files differ
diff --git a/www/images/sc_logo50x62.png b/www/images/sc_logo50x62.png
deleted file mode 100644
index 0a393de..0000000
--- a/www/images/sc_logo50x62.png
+++ /dev/null
Binary files differ
diff --git a/www/images/sip-communicator.jpg b/www/images/sip-communicator.jpg
deleted file mode 100644
index fd88b68..0000000
--- a/www/images/sip-communicator.jpg
+++ /dev/null
Binary files differ
diff --git a/www/images/sip-communicator.logo.jpg b/www/images/sip-communicator.logo.jpg
deleted file mode 100644
index 0b9e450..0000000
--- a/www/images/sip-communicator.logo.jpg
+++ /dev/null
Binary files differ
diff --git a/www/images/sip-communicator.logo.png b/www/images/sip-communicator.logo.png
deleted file mode 100644
index f2ae776..0000000
--- a/www/images/sip-communicator.logo.png
+++ /dev/null
Binary files differ
diff --git a/www/index-jn.html b/www/index-jn.html
deleted file mode 100644
index 37b5586..0000000
--- a/www/index-jn.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <table width="100%" cellpadding="0" bordercolor="#111111" border="0" style="border-collapse: collapse" id="AutoNumber2"> <tbody><tr> <td valign="middle" style="width: 20%"> <p align="center"> <a href="http://sip-communicator.org"><img border="0" alt="sip-communicator.org" src="images/sip-communicator.logo.png" /></a><br /> SIP Communicator <br />Open Source VoIP &amp; IM </p> <br /> </td> <td style="width: 90%"> <p align="justify"> SIP Communicator is an audio/video Internet phone and instant messenger that support some of the most popular instant messaging and telephony protocols such as SIP, Jabber, AIM/ICQ, MSN and soon others like Yahoo and IRC. </p> <p align="justify"> SIP Communicator is completely <a href="http://www.opensource.org/">Open Source</a> / <a href="http://www.gnu.org/philosophy/free-sw.html">Free Software</a>, and is freely available under the terms of the <a href="http://www.gnu.org/licenses/lgpl.html">GNU Lesser General Public License</a>. </p> <table width="100%" cellspacing="2" cellpadding="2" border="0" style="background-color: white"> <tbody><tr><td style="background-color: lightgray"> <p> RESOURCES: The SIP Communicator <a class="wikilink" href="http://www.sip-communicator.org/index.php/Documentation/FAQ">FAQ</a> can usually answer most questions. You can also ask on the <a class="wikilink" href="http://www.sip-communicator.org/index.php/Development/MailingLists#users">users</a> mailing list, or at the <a class="urllink" rel="nofollow" href="http://www.sip-communicator.org/irc/irc.cgi">irc channel</a> #sip-communicator at irc.freenode.net. </p> </td></tr> </tbody></table> <p><em> <strong>Note:</strong> Right now SIP Communicator is still a work in progress and as such is still unstable. If you would like to help or follow project progress check the <a class="wikilink" href="http://www.sip-communicator.org/index.php/Development/Roadmap">Project Roadmap</a> or join our <a class="wikilink" href="http://www.sip-communicator.org/index.php/Development/MailingLists">Mailing Lists</a>. You can also have a look at the SIP Communicator <a class="wikilink" href="http://www.sip-communicator.org/index.php/Main/Screenshots">screenshots</a> </em> </p> <p> <strong> Thanks for your patience and continuing support! <br /> <a href="https://sip-communicator.org/wiki/index.php/Development/TeamAndContributors"> The SIP Communicator team</a></strong></p> </td> </tr> </tbody></table>
diff --git a/www/index.html b/www/index.html
deleted file mode 100644
index 4897c3e..0000000
--- a/www/index.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<html>
- <head>
-
- <title>Jitsi - The most advanced open source communicator</title>
- <meta HTTP-EQUIV="refresh" CONTENT="0;URL=http://www.jitsi.org">
-</head>
-<body>
- <p>
- <script>
- document.location.replace("http://jitsi.org/");
- </script>
- </p>
-</body>
-</html>
diff --git a/www/role-approval.policy b/www/role-approval.policy
deleted file mode 100644
index 8395eb5..0000000
--- a/www/role-approval.policy
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<rules>
- <!--
- The following rule says automatically approve an observer
- request role to the project.
- -->
- <rule role="Observer" action="approve" />
-
- <!--
- The following rule says automatically deny a project owner
- and developer role requests.
-
- The text in the tag will be sent to the requester,
- as a part of the e-mail from the java.net system.
- -->
- <rule role="Project Owner, Developer, Content Developer" action="deny"><![CDATA[
- Developer roles in the SIP Communicator project are only granted to team members and confirmed contributors. This means that you'll first have to participate in mailing list discussions and submit some fixes, patches, or other contributions before being accepted as a developer in the project.
- You can start by applying for the Observer role ( https://sip-communicator.dev.java.net/servlets/ProjectMembershipRequest ).
-]]></rule>
-</rules>
diff --git a/www/sc_logo16x16.png b/www/sc_logo16x16.png
deleted file mode 100644
index 6c8ba4d..0000000
--- a/www/sc_logo16x16.png
+++ /dev/null
Binary files differ